diff --git a/browser/brave_vpn/brave_vpn_service_factory.cc b/browser/brave_vpn/brave_vpn_service_factory.cc index 632cf9cb3d8..539bd7ef207 100644 --- a/browser/brave_vpn/brave_vpn_service_factory.cc +++ b/browser/brave_vpn/brave_vpn_service_factory.cc @@ -39,10 +39,22 @@ #endif // IS_WIN #endif // ENABLE_BRAVE_VPN_V1 +#if BUILDFLAG(ENABLE_BRAVE_VPN_V2) +#include "brave/components/brave_vpn/browser/v2/brave_vpn_service_impl.h" +#endif // BUILDFLAG(ENABLE_BRAVE_VPN_V2) + namespace brave_vpn { namespace { -#if BUILDFLAG(ENABLE_BRAVE_VPN_V1) +#if BUILDFLAG(ENABLE_BRAVE_VPN_V2) + +std::unique_ptr BuildVpnService_V2( + content::BrowserContext* context) { + // Return stub implementation. + return std::make_unique(); +} + +#elif BUILDFLAG(ENABLE_BRAVE_VPN_V1) std::unique_ptr BuildVpnService_V1( content::BrowserContext* context) { @@ -102,7 +114,9 @@ std::unique_ptr BuildVpnService( if (!brave_vpn::IsAllowedForContext(context)) { return nullptr; } -#if BUILDFLAG(ENABLE_BRAVE_VPN_V1) +#if BUILDFLAG(ENABLE_BRAVE_VPN_V2) + return BuildVpnService_V2(context); +#elif BUILDFLAG(ENABLE_BRAVE_VPN_V1) return BuildVpnService_V1(context); #else NOTREACHED() << "No VPN implementation available"; diff --git a/browser/sources.gni b/browser/sources.gni index a7ed8be2a4d..7a563b62973 100644 --- a/browser/sources.gni +++ b/browser/sources.gni @@ -554,7 +554,10 @@ if (enable_brave_vpn) { } if (enable_brave_vpn_v2) { - brave_chrome_browser_deps += [ "//brave/third_party/boringtun" ] + brave_chrome_browser_deps += [ + "//brave/components/brave_vpn/browser/v2:browser", + "//brave/third_party/boringtun", + ] } if (is_android) { diff --git a/components/brave_vpn/browser/DEPS b/components/brave_vpn/browser/DEPS index a87ceab21eb..5334527a57d 100644 --- a/components/brave_vpn/browser/DEPS +++ b/components/brave_vpn/browser/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "-components/brave_vpn/browser/v2", "+components/grit/brave_components_strings.h", "+components/keyed_service", "+components/prefs", diff --git a/components/brave_vpn/browser/v2/BUILD.gn b/components/brave_vpn/browser/v2/BUILD.gn new file mode 100644 index 00000000000..38d64fc7492 --- /dev/null +++ b/components/brave_vpn/browser/v2/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2026 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +import("//brave/components/brave_vpn/common/buildflags/buildflags.gni") + +assert(enable_brave_vpn_v2) + +static_library("browser") { + sources = [ + "brave_vpn_service_impl.cc", + "brave_vpn_service_impl.h", + ] + + if (is_android) { + sources += [ "brave_vpn_service_impl_android.cc" ] + } else if (is_linux || is_mac || is_win) { + sources += [ "brave_vpn_service_impl_desktop.cc" ] + } + + public_deps = [ + "//brave/components/brave_vpn/browser", + "//brave/components/skus/browser", + "//brave/components/skus/common:mojom", + ] + + deps = [ + "//base", + "//brave/components/brave_vpn/common", + ] +} diff --git a/components/brave_vpn/browser/v2/DEPS b/components/brave_vpn/browser/v2/DEPS new file mode 100644 index 00000000000..b83a9b0d043 --- /dev/null +++ b/components/brave_vpn/browser/v2/DEPS @@ -0,0 +1,10 @@ +include_rules = [ + "-brave/components/brave_vpn/browser", + "-brave/components/brave_vpn/common", + "+brave/components/brave_vpn/browser/v2", + "+brave/components/brave_vpn/browser/brave_vpn_service.h", + "+brave/components/brave_vpn/common/brave_vpn_constants.h", + "+brave/components/brave_vpn/common/brave_vpn_utils.h", + "+brave/components/brave_vpn/common/buildflags", + "+brave/components/brave_vpn/common/mojom", +] diff --git a/components/brave_vpn/browser/v2/brave_vpn_service_impl.cc b/components/brave_vpn/browser/v2/brave_vpn_service_impl.cc new file mode 100644 index 00000000000..2d06054ca9d --- /dev/null +++ b/components/brave_vpn/browser/v2/brave_vpn_service_impl.cc @@ -0,0 +1,60 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_vpn/browser/v2/brave_vpn_service_impl.h" + +#include "base/notimplemented.h" +#include "brave/components/skus/browser/skus_utils.h" + +namespace brave_vpn { +namespace v2 { + +BraveVpnServiceImpl::BraveVpnServiceImpl() + : connection_state_(mojom::ConnectionState::DISCONNECTED), + purchased_state_(mojom::PurchasedState::NOT_PURCHASED) {} + +BraveVpnServiceImpl::~BraveVpnServiceImpl() = default; + +bool BraveVpnServiceImpl::IsBraveVPNEnabled() const { + NOTIMPLEMENTED(); + return false; +} + +bool BraveVpnServiceImpl::IsPurchased() const { + NOTIMPLEMENTED(); + return purchased_state_ == mojom::PurchasedState::PURCHASED; +} + +void BraveVpnServiceImpl::ReloadPurchasedState() { + NOTIMPLEMENTED(); +} + +std::string BraveVpnServiceImpl::GetCurrentEnvironment() const { + NOTIMPLEMENTED(); + return skus::kEnvProduction; +} + +void BraveVpnServiceImpl::GetPurchasedState( + GetPurchasedStateCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run( + mojom::PurchasedInfo::New(purchased_state_, std::nullopt)); +} + +void BraveVpnServiceImpl::LoadPurchasedState(const std::string& domain) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetAllRegions(GetAllRegionsCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run({}); +} + +void BraveVpnServiceImpl::Shutdown() { + BraveVpnService::Shutdown(); +} + +} // namespace v2 +} // namespace brave_vpn diff --git a/components/brave_vpn/browser/v2/brave_vpn_service_impl.h b/components/brave_vpn/browser/v2/brave_vpn_service_impl.h new file mode 100644 index 00000000000..fc413a28da7 --- /dev/null +++ b/components/brave_vpn/browser/v2/brave_vpn_service_impl.h @@ -0,0 +1,123 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_VPN_BROWSER_V2_BRAVE_VPN_SERVICE_IMPL_H_ +#define BRAVE_COMPONENTS_BRAVE_VPN_BROWSER_V2_BRAVE_VPN_SERVICE_IMPL_H_ + +#include "brave/components/brave_vpn/browser/brave_vpn_service.h" +#include "build/build_config.h" + +namespace brave_vpn { +namespace v2 { + +class BraveVpnServiceImpl : public BraveVpnService { + public: + BraveVpnServiceImpl(); + ~BraveVpnServiceImpl() override; + + BraveVpnServiceImpl(const BraveVpnServiceImpl&) = delete; + BraveVpnServiceImpl& operator=(const BraveVpnServiceImpl&) = delete; + + // BraveVpnService overrides: + // Implementation of public interface exposed to other components. + bool IsBraveVPNEnabled() const override; + bool IsPurchased() const override; + void ReloadPurchasedState() override; + std::string GetCurrentEnvironment() const override; + + // mojom::ServiceHandler overrides: + void GetPurchasedState(GetPurchasedStateCallback callback) override; + void LoadPurchasedState(const std::string& domain) override; + void GetAllRegions(GetAllRegionsCallback callback) override; + +#if !BUILDFLAG(IS_ANDROID) + // BraveVpnService overrides: + bool IsConnected() const override; + void ToggleConnection() override; + mojom::ConnectionState GetConnectionState() const override; + void RecordWidgetUsageMetrics(bool new_usage) override; + + // mojom::ServiceHandler overrides: + void GetConnectionState(GetConnectionStateCallback callback) override; + void Connect() override; + void Disconnect() override; + void GetSelectedRegion(GetSelectedRegionCallback callback) override; + void SetSelectedRegion(mojom::RegionPtr region) override; + void ClearSelectedRegion() override; + void GetProductUrls(GetProductUrlsCallback callback) override; + void CreateSupportTicket(const std::string& email, + const std::string& subject, + const std::string& body, + CreateSupportTicketCallback callback) override; + void GetSupportData(GetSupportDataCallback callback) override; + void ResetConnectionState() override; + void EnableOnDemand(bool enable) override; + void GetOnDemandState(GetOnDemandStateCallback callback) override; + void EnableSmartProxyRouting(bool enable) override; + void GetSmartProxyRoutingState( + GetSmartProxyRoutingStateCallback callback) override; +#else // !BUILDFLAG(IS_ANDROID) + // mojom::ServiceHandler overrides: + void GetPurchaseToken(GetPurchaseTokenCallback callback) override; + + // Implementation of public interface for Android native worker. + void GetTimezonesForRegions(ResponseCallback callback) override; + void GetHostnamesForRegion(ResponseCallback callback, + const std::string& region, + const std::string& region_precision) override; + void GetProfileCredentials(ResponseCallback callback, + const std::string& subscriber_credential, + const std::string& hostname) override; + void GetWireguardProfileCredentials(ResponseCallback callback, + const std::string& subscriber_credential, + const std::string& public_key, + const std::string& hostname) override; + void VerifyCredentials(ResponseCallback callback, + const std::string& hostname, + const std::string& client_id, + const std::string& subscriber_credential, + const std::string& api_auth_token) override; + void InvalidateCredentials(ResponseCallback callback, + const std::string& hostname, + const std::string& client_id, + const std::string& subscriber_credential, + const std::string& api_auth_token) override; + void VerifyPurchaseToken(ResponseCallback callback, + const std::string& purchase_token, + const std::string& product_id, + const std::string& product_type, + const std::string& bundle_id) override; + void GetSubscriberCredential(ResponseCallback callback, + const std::string& product_type, + const std::string& product_id, + const std::string& validation_method, + const std::string& purchase_token, + const std::string& bundle_id) override; + void GetSubscriberCredentialV12(ResponseCallback callback) override; + void RecordAllMetrics() override; + void RecordAndroidBackgroundP3A(int64_t session_start_time_ms, + int64_t session_end_time_ms) override; +#endif // BUILDFLAG(IS_ANDROID) + + private: + // KeyedService overrides: + void Shutdown() override; + + // BraveVpnService overrides: +#if !BUILDFLAG(IS_ANDROID) + void SetConnectionStateForTesting(mojom::ConnectionState state) override; + void SetPurchasedStateForTesting(const std::string& env, + mojom::PurchasedState state) override; +#endif // !BUILDFLAG(IS_ANDROID) + + private: + [[maybe_unused]] mojom::ConnectionState connection_state_; + mojom::PurchasedState purchased_state_; +}; + +} // namespace v2 +} // namespace brave_vpn + +#endif // BRAVE_COMPONENTS_BRAVE_VPN_BROWSER_V2_BRAVE_VPN_SERVICE_IMPL_H_ diff --git a/components/brave_vpn/browser/v2/brave_vpn_service_impl_android.cc b/components/brave_vpn/browser/v2/brave_vpn_service_impl_android.cc new file mode 100644 index 00000000000..82ae54c5afd --- /dev/null +++ b/components/brave_vpn/browser/v2/brave_vpn_service_impl_android.cc @@ -0,0 +1,96 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_vpn/browser/v2/brave_vpn_service_impl.h" + +#include "base/notimplemented.h" + +namespace brave_vpn { +namespace v2 { + +void BraveVpnServiceImpl::GetPurchaseToken(GetPurchaseTokenCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run({}); +} + +void BraveVpnServiceImpl::GetTimezonesForRegions(ResponseCallback callback) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetHostnamesForRegion( + ResponseCallback callback, + const std::string& region, + const std::string& region_precision) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetProfileCredentials( + ResponseCallback callback, + const std::string& subscriber_credential, + const std::string& hostname) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetWireguardProfileCredentials( + ResponseCallback callback, + const std::string& subscriber_credential, + const std::string& public_key, + const std::string& hostname) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::VerifyCredentials( + ResponseCallback callback, + const std::string& hostname, + const std::string& client_id, + const std::string& subscriber_credential, + const std::string& api_auth_token) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::InvalidateCredentials( + ResponseCallback callback, + const std::string& hostname, + const std::string& client_id, + const std::string& subscriber_credential, + const std::string& api_auth_token) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::VerifyPurchaseToken(ResponseCallback callback, + const std::string& purchase_token, + const std::string& product_id, + const std::string& product_type, + const std::string& bundle_id) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetSubscriberCredential( + ResponseCallback callback, + const std::string& product_type, + const std::string& product_id, + const std::string& validation_method, + const std::string& purchase_token, + const std::string& bundle_id) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetSubscriberCredentialV12( + ResponseCallback callback) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::RecordAllMetrics() { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::RecordAndroidBackgroundP3A( + int64_t session_start_time_ms, + int64_t session_end_time_ms) { + NOTIMPLEMENTED(); +} + +} // namespace v2 +} // namespace brave_vpn diff --git a/components/brave_vpn/browser/v2/brave_vpn_service_impl_desktop.cc b/components/brave_vpn/browser/v2/brave_vpn_service_impl_desktop.cc new file mode 100644 index 00000000000..515a37219bd --- /dev/null +++ b/components/brave_vpn/browser/v2/brave_vpn_service_impl_desktop.cc @@ -0,0 +1,118 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "base/notimplemented.h" +#include "brave/components/brave_vpn/browser/v2/brave_vpn_service_impl.h" +#include "brave/components/brave_vpn/common/brave_vpn_constants.h" +#include "brave/components/brave_vpn/common/brave_vpn_utils.h" + +namespace brave_vpn { +namespace v2 { + +bool BraveVpnServiceImpl::IsConnected() const { + NOTIMPLEMENTED(); + return connection_state_ == mojom::ConnectionState::CONNECTED && + IsPurchased(); +} + +void BraveVpnServiceImpl::ToggleConnection() { + NOTIMPLEMENTED(); +} + +mojom::ConnectionState BraveVpnServiceImpl::GetConnectionState() const { + NOTIMPLEMENTED(); + return connection_state_; +} + +void BraveVpnServiceImpl::RecordWidgetUsageMetrics(bool new_usage) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetConnectionState( + GetConnectionStateCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(connection_state_); +} + +void BraveVpnServiceImpl::Connect() { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::Disconnect() { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetSelectedRegion( + GetSelectedRegionCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run({}); +} + +void BraveVpnServiceImpl::SetSelectedRegion(mojom::RegionPtr region) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::ClearSelectedRegion() { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetProductUrls(GetProductUrlsCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(mojom::ProductUrls::New( + kFeedbackUrl, kAboutUrl, GetManageUrl(GetCurrentEnvironment()))); +} + +void BraveVpnServiceImpl::CreateSupportTicket( + const std::string& email, + const std::string& subject, + const std::string& body, + CreateSupportTicketCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(false, {}); +} + +void BraveVpnServiceImpl::GetSupportData(GetSupportDataCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run({}, {}, {}, {}); +} + +void BraveVpnServiceImpl::ResetConnectionState() { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::EnableOnDemand(bool /*enable*/) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetOnDemandState(GetOnDemandStateCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(false, false); +} + +void BraveVpnServiceImpl::EnableSmartProxyRouting(bool /*enable*/) { + NOTIMPLEMENTED(); +} + +void BraveVpnServiceImpl::GetSmartProxyRoutingState( + GetSmartProxyRoutingStateCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(false); +} + +void BraveVpnServiceImpl::SetConnectionStateForTesting( // IN-TEST + mojom::ConnectionState state) { + connection_state_ = state; + NotifyConnectionStateChanged(state); +} + +void BraveVpnServiceImpl::SetPurchasedStateForTesting( // IN-TEST + const std::string& env, + mojom::PurchasedState state) { + purchased_state_ = state; + NotifyPurchasedStateChanged(state, std::nullopt); +} + +} // namespace v2 +} // namespace brave_vpn