[iOS] Prepare CWVWebView web embedder for use in iOS (#26957)

This commit is contained in:
Kyle Hickinson
2025-02-27 12:01:40 -05:00
committed by GitHub
parent aeddc95a23
commit 1f2ba134c5
73 changed files with 2631 additions and 164 deletions
+2
View File
@@ -0,0 +1,2 @@
# Common linting false posititives from Obj-C syntax in headers
filter=-readability/casting,-whitespace/parens,-whitespace/operators
+2
View File
@@ -3,6 +3,8 @@ include_rules = [
"+brave/common",
"+brave/components/ai_chat",
"+brave/components/constants",
"+brave/components/https_upgrade_exceptions/browser",
"+brave/ios/browser/application_context",
"+components/component_updater",
"+components/gcm_driver/gcm_driver.h",
"+components/history/core/browser",
@@ -6,13 +6,16 @@
#include "ios/chrome/browser/profile/model/keyed_service_factories.h"
#include "brave/ios/browser/profile/model/brave_keyed_service_factories.h"
#include "ios/chrome/browser/affiliations/model/ios_chrome_affiliation_service_factory.h"
#include "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h"
#include "ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h"
#include "ios/chrome/browser/autofill/model/autofill_log_router_factory.h"
#include "ios/chrome/browser/autofill/model/personal_data_manager_factory.h"
#include "ios/chrome/browser/bookmarks/model/account_bookmark_sync_service_factory.h"
#include "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h"
#include "ios/chrome/browser/bookmarks/model/bookmark_undo_service_factory.h"
#include "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_sync_service_factory.h"
#include "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h"
#include "ios/chrome/browser/consent_auditor/model/consent_auditor_factory.h"
#include "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h"
#include "ios/chrome/browser/credential_provider/model/credential_provider_buildflags.h"
@@ -22,25 +25,33 @@
#include "ios/chrome/browser/favicon/model/ios_chrome_favicon_loader_factory.h"
#include "ios/chrome/browser/favicon/model/ios_chrome_large_icon_cache_factory.h"
#include "ios/chrome/browser/favicon/model/ios_chrome_large_icon_service_factory.h"
#include "ios/chrome/browser/gcm/model/ios_chrome_gcm_profile_service_factory.h"
#include "ios/chrome/browser/history/model/history_service_factory.h"
#include "ios/chrome/browser/history/model/top_sites_factory.h"
#include "ios/chrome/browser/history/model/web_history_service_factory.h"
#include "ios/chrome/browser/https_upgrades/model/https_upgrade_service_factory.h"
#include "ios/chrome/browser/invalidation/model/ios_chrome_profile_invalidation_provider_factory.h"
#include "ios/chrome/browser/language/model/accept_languages_service_factory.h"
#include "ios/chrome/browser/language/model/language_model_manager_factory.h"
#include "ios/chrome/browser/language/model/url_language_histogram_factory.h"
#include "ios/chrome/browser/metrics/model/google_groups_manager_factory.h"
#include "ios/chrome/browser/optimization_guide/model/optimization_guide_service_factory.h"
#include "ios/chrome/browser/page_info/about_this_site_service_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_account_password_store_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_bulk_leak_check_service_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_password_receiver_service_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_password_reuse_manager_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_password_sender_service_factory.h"
#include "ios/chrome/browser/passwords/model/ios_chrome_profile_password_store_factory.h"
#include "ios/chrome/browser/passwords/model/ios_password_manager_settings_service_factory.h"
#include "ios/chrome/browser/passwords/model/ios_password_requirements_service_factory.h"
#include "ios/chrome/browser/passwords/model/password_manager_log_router_factory.h"
#include "ios/chrome/browser/plus_addresses/model/plus_address_service_factory.h"
#include "ios/chrome/browser/plus_addresses/model/plus_address_setting_service_factory.h"
#include "ios/chrome/browser/power_bookmarks/model/power_bookmark_service_factory.h"
#include "ios/chrome/browser/push_notification/model/push_notification_profile_service_factory.h"
#include "ios/chrome/browser/reading_list/model/reading_list_model_factory.h"
#include "ios/chrome/browser/safe_browsing/model/safe_browsing_client_factory.h"
#include "ios/chrome/browser/safe_browsing/model/safe_browsing_metrics_collector_factory.h"
#include "ios/chrome/browser/saved_tab_groups/model/tab_group_sync_service_factory.h"
#include "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
@@ -50,6 +61,7 @@
#include "ios/chrome/browser/signin/model/account_consistency_service_factory.h"
#include "ios/chrome/browser/signin/model/account_reconcilor_factory.h"
#include "ios/chrome/browser/signin/model/identity_manager_factory.h"
#include "ios/chrome/browser/signin/model/signin_client_factory.h"
#include "ios/chrome/browser/supervised_user/model/child_account_service_factory.h"
#include "ios/chrome/browser/supervised_user/model/list_family_members_service_factory.h"
#include "ios/chrome/browser/supervised_user/model/supervised_user_service_factory.h"
@@ -70,20 +82,22 @@
#endif
void EnsureProfileKeyedServiceFactoriesBuilt() {
autofill::AutofillLogRouterFactory::GetInstance();
autofill::PersonalDataManagerFactory::GetInstance();
data_sharing::DataSharingServiceFactory::GetInstance();
ios::AccountBookmarkSyncServiceFactory::GetInstance();
ios::AccountConsistencyServiceFactory::GetInstance();
ios::AccountReconcilorFactory::GetInstance();
ios::AutocompleteClassifierFactory::GetInstance();
ios::BookmarkModelFactory::GetInstance();
ios::BookmarkUndoServiceFactory::GetInstance();
ios::FaviconServiceFactory::GetInstance();
ios::HistoryServiceFactory::GetInstance();
ios::LocalOrSyncableBookmarkSyncServiceFactory::GetInstance();
ios::TopSitesFactory::GetInstance();
ios::AutocompleteClassifierFactory::GetInstance();
ios::HostContentSettingsMapFactory::GetInstance();
ios::LocalOrSyncableBookmarkSyncServiceFactory::GetInstance();
ios::PasswordManagerLogRouterFactory::GetInstance();
ios::TemplateURLServiceFactory::GetInstance();
ios::TopSitesFactory::GetInstance();
ios::WebDataServiceFactory::GetInstance();
ios::WebHistoryServiceFactory::GetInstance();
ios::ZeroSuggestCacheServiceFactory::GetInstance();
@@ -91,26 +105,33 @@ void EnsureProfileKeyedServiceFactoriesBuilt() {
tab_groups::TabGroupSyncServiceFactory::GetInstance();
translate::TranslateRankerFactory::GetInstance();
AboutThisSiteServiceFactory::GetInstance();
AcceptLanguagesServiceFactory::GetInstance();
BackgroundDownloadServiceFactory::GetInstance();
BrowserListFactory::GetInstance();
BrowsingDataRemoverFactory::GetInstance();
ChildAccountServiceFactory::GetInstance();
ConsentAuditorFactory::GetInstance();
DeviceInfoSyncServiceFactory::GetInstance();
GoogleGroupsManagerFactory::GetInstance();
HttpsUpgradeServiceFactory::GetInstance();
IdentityManagerFactory::GetInstance();
IOSChromeAccountPasswordStoreFactory::GetInstance();
IOSChromeAffiliationServiceFactory::GetInstance();
IOSChromeBulkLeakCheckServiceFactory::GetInstance();
IOSChromeFaviconLoaderFactory::GetInstance();
IOSChromeGCMProfileServiceFactory::GetInstance();
IOSChromeLargeIconCacheFactory::GetInstance();
IOSChromeLargeIconServiceFactory::GetInstance();
IOSChromePasswordReceiverServiceFactory::GetInstance();
IOSChromePasswordReuseManagerFactory::GetInstance();
IOSChromePasswordSenderServiceFactory::GetInstance();
IOSChromeProfilePasswordStoreFactory::GetInstance();
IOSChromeProfileInvalidationProviderFactory::GetInstance();
IOSChromeProfilePasswordStoreFactory::GetInstance();
IOSPasskeyModelFactory::GetInstance();
IOSPasswordManagerSettingsServiceFactory::GetInstance();
IOSPasswordRequirementsServiceFactory::GetInstance();
IOSUserEventServiceFactory::GetInstance();
HttpsUpgradeServiceFactory::GetInstance();
LanguageModelManagerFactory::GetInstance();
ListFamilyMembersServiceFactory::GetInstance();
OptimizationGuideServiceFactory::GetInstance();
DataTypeStoreServiceFactory::GetInstance();
@@ -122,11 +143,17 @@ void EnsureProfileKeyedServiceFactoriesBuilt() {
SyncServiceFactory::GetInstance();
UnifiedConsentServiceFactory::GetInstance();
ReadingListModelFactory::GetInstance();
SafeBrowsingClientFactory::GetInstance();
SafeBrowsingMetricsCollectorFactory::GetInstance();
SendTabToSelfSyncServiceFactory::GetInstance();
SessionRestorationServiceFactory::GetInstance();
SessionSyncServiceFactory::GetInstance();
SigninClientFactory::GetInstance();
SupervisedUserServiceFactory::GetInstance();
SupervisedUserSettingsServiceFactory::GetInstance();
SyncServiceFactory::GetInstance();
UnifiedConsentServiceFactory::GetInstance();
UrlLanguageHistogramFactory::GetInstance();
#if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED)
CredentialProviderServiceFactory::GetInstance();
@@ -26,6 +26,7 @@
#include "brave/components/skus/browser/skus_utils.h"
#include "brave/ios/browser/brave_stats/brave_stats_prefs.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "ios/chrome/browser/shared/model/prefs/pref_names.h"
void BraveRegisterBrowserStatePrefs(
user_prefs::PrefRegistrySyncable* registry) {
@@ -5,14 +5,25 @@
#import "ios/chrome/browser/tabs/model/tab_helper_util.h"
#import "components/omnibox/common/omnibox_features.h"
#include "ios/chrome/browser/complex_tasks/model/ios_task_tab_helper.h"
#import "ios/chrome/browser/https_upgrades/model/https_only_mode_upgrade_tab_helper.h"
#import "ios/chrome/browser/https_upgrades/model/https_upgrade_service_factory.h"
#import "ios/chrome/browser/https_upgrades/model/typed_navigation_upgrade_tab_helper.h"
#import "ios/chrome/browser/prerender/model/prerender_service_factory.h"
#include "ios/chrome/browser/sessions/model/ios_chrome_session_tab_helper.h"
#import "ios/chrome/browser/sessions/model/web_session_state_tab_helper.h"
#include "ios/chrome/browser/sessions/model/web_session_state_tab_helper.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios.h"
#include "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h"
#import "ios/components/security_interstitials/https_only_mode/https_only_mode_container.h"
#import "ios/components/security_interstitials/ios_blocking_page_tab_helper.h"
void AttachTabHelpers(web::WebState* web_state, TabHelperFilter filter_flags) {
IOSChromeSessionTabHelper::CreateForWebState(web_state);
IOSChromeSyncedTabDelegate::CreateForWebState(web_state);
WebSessionStateTabHelper::CreateForWebState(web_state);
IOSTaskTabHelper::CreateForWebState(web_state);
security_interstitials::IOSBlockingPageTabHelper::CreateForWebState(
web_state);
}
@@ -0,0 +1,14 @@
// Copyright (c) 2025 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_CHROMIUM_SRC_IOS_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
#include "src/ios/web/navigation/crw_wk_navigation_handler.h" // IWYU pragma: export
@interface BraveCRWWKNavigationHandler : CRWWKNavigationHandler
@end
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
@@ -0,0 +1,61 @@
// Copyright (c) 2024 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 "ios/web/navigation/crw_wk_navigation_handler.h"
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
namespace web {
class WebState;
}
namespace brave {
bool ShouldBlockUniversalLinks(web::WebState* webState, NSURLRequest* request);
bool ShouldBlockJavaScript(web::WebState* webState, NSURLRequest* request);
} // namespace brave
#include "src/ios/web/navigation/crw_wk_navigation_handler.mm"
// Setup a CRWWKNavigationHandler subclass so that we may integrate Brave
// features that Chrome does not support or expose access to (such as the
// requiring the use of WKWebpagePreferences)
@implementation BraveCRWWKNavigationHandler
- (void)webView:(WKWebView*)webView
decidePolicyForNavigationAction:(WKNavigationAction*)action
preferences:(WKWebpagePreferences*)preferences
decisionHandler:(void (^)(WKNavigationActionPolicy,
WKWebpagePreferences*))handler {
auto decisionHandler =
^(WKNavigationActionPolicy policy, WKWebpagePreferences*) {
// Check if we want to block JavaScript execution on the page
// Typically this would go through `ContentSettingsType::JAVASCRIPT`,
// but Chrome iOS does not support this yet.
bool shouldBlockJavaScript = brave::ShouldBlockJavaScript(
static_cast<web::WebState*>(self.webStateImpl), action.request);
if (shouldBlockJavaScript && preferences) {
// Only ever update it to false
preferences.allowsContentJavaScript = false;
}
if (policy == WKNavigationActionPolicyAllow) {
// Check if we want to explicitly block universal links
bool forceBlockUniversalLinks = brave::ShouldBlockUniversalLinks(
static_cast<web::WebState*>(self.webStateImpl), action.request);
if (forceBlockUniversalLinks) {
handler(web::kNavigationActionPolicyAllowAndBlockUniversalLinks,
preferences);
return;
}
}
handler(policy, preferences);
};
[super webView:webView
decidePolicyForNavigationAction:action
preferences:preferences
decisionHandler:decisionHandler];
}
@end
@@ -0,0 +1,34 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_PUBLIC_BROWSER_STATE_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_BROWSER_STATE_H_
#include "base/notreached.h"
class PrefService;
// This override is tied to the replaced implementation of `//ios/web_view`'s
// CWVWebViewConfiguration (see cwv_web_view_configuration_internal.h override)
//
// Since this replaced implementation replaces WebViewBrowserState with
// web::BrowserState, there are a few places that use the GetPrefs method
// exposed on WebViewBrowserState.
//
// This adds a `GetPrefs` method to the public web::BrowserState definition
// to avoid build failures, even though the code that is calling it will never
// be used by us.
#define GetURLLoaderFactory() \
GetURLLoaderFactory(); \
PrefService* GetPrefs() { \
NOTREACHED(); \
return nullptr; \
} \
void Unused()
#include "src/ios/web/public/browser_state.h" // IWYU pragma: export
#undef GetURLLoaderFactory
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_BROWSER_STATE_H_
@@ -6,10 +6,12 @@
#ifndef BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
// This override exposes a few private properties for us to use
#define webViewNavigationProxy \
webViewNavigationProxy_ChromiumImpl; \
@property(weak, nonatomic, readonly) id<CRWWebViewNavigationProxy> \
webViewNavigationProxy
webViewNavigationProxy; \
@property(weak, nonatomic, readonly) WKWebView* webView
#include "src/ios/web/web_state/ui/crw_web_controller.h" // IWYU pragma: export
@@ -9,9 +9,17 @@
#include <Webkit/Webkit.h>
// Replace the underlying CRWWKNavigationHandler with our subclass
#define _navigationHandler \
_navigationHandler = \
[[BraveCRWWKNavigationHandler alloc] initWithDelegate:self]; \
if (false) [[maybe_unused]] \
auto* _
// Support for tab sync
#define webViewNavigationProxy webViewNavigationProxy_ChromiumImpl
#include "src/ios/web/web_state/ui/crw_web_controller.mm"
#undef webViewNavigationProxy
#undef _navigationHandler
#pragma mark - BackForwardList
@@ -0,0 +1,33 @@
/* Copyright (c) 2025 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_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_
// Support for subclassing WKWebViewConfigurationProvider:
// - Add a friend class as the subclass needs access to private fields
// (`configuration_` in this case)
// - Make `ResetWithWebViewConfiguration` virtual so that we can override it
#define browser_state_ \
browser_state_; \
friend class BraveWKWebViewConfigurationProvider
#define ResetWithWebViewConfiguration \
Unused() {} \
virtual void ResetWithWebViewConfiguration
#include "src/ios/web/web_state/ui/wk_web_view_configuration_provider.h" // IWYU pragma: export
#undef ResetWithWebViewConfiguration
#undef browser_state_
namespace web {
class BraveWKWebViewConfigurationProvider
: public WKWebViewConfigurationProvider {
using WKWebViewConfigurationProvider::WKWebViewConfigurationProvider;
void ResetWithWebViewConfiguration(
WKWebViewConfiguration* configuration) override;
};
} // namespace web
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_
@@ -0,0 +1,39 @@
/* Copyright (c) 2024 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/supports_user_data.h"
// Replace the `WKWebViewConfigurationProvider` constructor call with the Brave
// subclass inside of `WKWebViewConfigurationProvider::FromBrowserState`
#define SetUserData(key, ...) \
SetUserData(key, base::WrapUnique(new BraveWKWebViewConfigurationProvider( \
browser_state)));
#include "src/ios/web/web_state/ui/wk_web_view_configuration_provider.mm"
#undef SetUserData
namespace web {
void BraveWKWebViewConfigurationProvider::ResetWithWebViewConfiguration(
WKWebViewConfiguration* configuration) {
WKWebViewConfigurationProvider::ResetWithWebViewConfiguration(configuration);
// Adjusts the underlying WKWebViewConfiguration for settings we don't want
// to inherit from Chromium
// Restore WKWebView long press
@try {
[configuration_ setValue:@YES forKey:@"longPressActionsEnabled"];
} @catch (NSException* exception) {
NOTREACHED() << "Error setting value for longPressActionsEnabled";
}
// Restore Apple's safe browsing implementation
[[configuration_ preferences] setFraudulentWebsiteWarningEnabled:YES];
// Reset fullscreen to default as it wasn't set in Brave
[[configuration_ preferences] setElementFullscreenEnabled:NO];
}
} // namespace web
@@ -0,0 +1,37 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
#include <memory>
#include "components/autofill/core/browser/data_manager/personal_data_manager.h"
#include "components/autofill/ios/browser/autofill_client_ios.h"
#include "components/autofill/ios/browser/autofill_driver_ios_bridge.h"
#include "ios/web/public/browser_state.h"
#include "ios/web/public/web_state.h"
#import "ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h"
namespace autofill {
// We do not use any WebView* specific clients & services since we would instead
// use the Chrome iOS ones.
//
// Replaces the implementation of the WebViewAutofillClientIOS with one that
// does nothing
class WebViewAutofillClientIOS : public AutofillClientIOS {
public:
static std::unique_ptr<WebViewAutofillClientIOS> Create(
FromWebStateImpl from_web_state_impl,
web::WebState* web_state,
id<CWVAutofillClientIOSBridge, AutofillDriverIOSBridge> bridge);
void set_bridge(id<CWVAutofillClientIOSBridge> bridge) {}
};
} // namespace autofill
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
@@ -0,0 +1,18 @@
// Copyright (c) 2024 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 "ios/web_view/internal/autofill/web_view_autofill_client_ios.h"
namespace autofill {
// static
std::unique_ptr<WebViewAutofillClientIOS> WebViewAutofillClientIOS::Create(
FromWebStateImpl from_web_state_impl,
web::WebState* web_state,
id<CWVAutofillClientIOSBridge, AutofillDriverIOSBridge> bridge) {
return nullptr;
}
} // namespace autofill
@@ -0,0 +1,14 @@
// Copyright (c) 2024 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/.
namespace ios_web_view {
void EnsureBrowserStateKeyedServiceFactoriesBuilt() {
// Intentionally left empty, please add any factories that need to be built
// to
// chromium_src/ios/chrome/browser/browser_state/model/browser_state_keyed_service_factories.mm
}
} // namespace ios_web_view
@@ -0,0 +1,12 @@
// Copyright (c) 2024 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 "src/ios/web_view/internal/cwv_ssl_status.mm"
@implementation CWVSSLStatus (Internal)
- (web::SSLStatus)internalStatus {
return _internalStatus;
}
@end
@@ -0,0 +1,18 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_SSL_STATUS_INTERNAL_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_SSL_STATUS_INTERNAL_H_
#include "src/ios/web_view/internal/cwv_ssl_status_internal.h" // IWYU pragma: export
// Expose the underlying web::SSLStatus that is not public so that
// cwv_ssl_status_extras.mm can access the private property and expose
// additional functionality
@interface CWVSSLStatus (Internal)
@property(readonly) web::SSLStatus internalStatus;
@end
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_SSL_STATUS_INTERNAL_H_
@@ -0,0 +1,35 @@
/* Copyright (c) 2024 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 "src/ios/web_view/internal/cwv_web_view.mm"
@implementation CWVWebView (Internal)
- (web::WebState*)webState {
return _webState.get();
}
+ (BOOL)_isRestoreDataValid:(NSData*)data {
NSError* error = nil;
NSKeyedUnarchiver* coder =
[[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
if (error) {
return NO;
}
coder.requiresSecureCoding = NO;
CWVWebViewProtobufStorage* cachedProtobufStorage =
base::apple::ObjCCastStrict<CWVWebViewProtobufStorage>(
[coder decodeObjectForKey:kProtobufStorageKey]);
CRWSessionStorage* cachedSessionStorage =
base::apple::ObjCCastStrict<CRWSessionStorage>(
[coder decodeObjectForKey:kSessionStorageKey]);
return (cachedProtobufStorage != nil || cachedSessionStorage != nil);
}
+ (id)objectFromValue:(const base::Value*)value {
return NSObjectFromValue(value);
}
@end
@@ -0,0 +1,122 @@
// Copyright (c) 2024 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 <memory>
#import "base/memory/raw_ptr.h"
#import "base/notreached.h"
#import "base/threading/thread_restrictions.h"
#import "components/keyed_service/core/service_access_type.h"
#import "components/keyed_service/ios/browser_state_dependency_manager.h"
#import "components/password_manager/core/browser/password_store/password_store_interface.h"
#import "ios/web/public/browser_state.h"
#import "ios/web_view/internal/app/application_context.h"
#import "ios/web_view/internal/autofill/cwv_autofill_data_manager_internal.h"
#import "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h"
#import "ios/web_view/internal/browser_state_keyed_service_factories.h"
#import "ios/web_view/internal/cwv_preferences_internal.h"
#import "ios/web_view/internal/cwv_user_content_controller_internal.h"
#import "ios/web_view/internal/cwv_web_view_configuration_internal.h"
#import "ios/web_view/internal/cwv_web_view_internal.h"
#import "ios/web_view/internal/passwords/web_view_account_password_store_factory.h"
#import "ios/web_view/internal/web_view_global_state_util.h"
// We completely replace the CWVWebViewConfiguration implementation so that
// we can nop certain services such as access to CWVWebView specific wrappers
// around autofill, sync, etc (since we would use Chrome's) and replace
// the exposed browser state to be a plain `web::BrowserState`
@interface CWVWebViewConfiguration () {
// The BrowserState for this configuration.
raw_ptr<web::BrowserState> _browserState;
// Holds all CWVWebViews created with this class. Weak references.
NSHashTable* _webViews;
}
@end
@implementation CWVWebViewConfiguration
+ (void)shutDown {
}
+ (instancetype)defaultConfiguration {
NOTREACHED();
return nil;
}
+ (instancetype)incognitoConfiguration {
NOTREACHED();
return nil;
}
+ (CWVWebViewConfiguration*)nonPersistentConfiguration {
NOTREACHED();
return nil;
}
- (instancetype)initWithBrowserState:(web::BrowserState*)browserState {
self = [super init];
if (self) {
_browserState = browserState;
_webViews = [NSHashTable weakObjectsHashTable];
}
return self;
}
#pragma mark - Unused Services
- (CWVPreferences*)preferences {
// This property is not nullable, so will crash anyways on the Swift side if
// accessed.
NOTREACHED();
return nil;
}
- (CWVUserContentController*)userContentController {
// This property is not nullable, so will crash anyways on the Swift side if
// accessed.
NOTREACHED();
return nil;
}
- (CWVAutofillDataManager*)autofillDataManager {
return nil;
}
- (CWVSyncController*)syncController {
return nil;
}
- (CWVLeakCheckService*)leakCheckService {
return nil;
}
- (CWVReuseCheckService*)reuseCheckService {
return nil;
}
#pragma mark - Public Methods
- (BOOL)isPersistent {
return !_browserState->IsOffTheRecord();
}
#pragma mark - Private Methods
- (web::BrowserState*)browserState {
return _browserState;
}
- (void)registerWebView:(CWVWebView*)webView {
[_webViews addObject:webView];
}
- (void)shutDown {
for (CWVWebView* webView in _webViews) {
[webView shutDown];
}
}
@end
@@ -0,0 +1,49 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_CONFIGURATION_INTERNAL_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_CONFIGURATION_INTERNAL_H_
#import "ios/web_view/public/cwv_web_view_configuration.h"
NS_ASSUME_NONNULL_BEGIN
namespace web {
class BrowserState;
} // namespace web
@class CWVWebView;
// We completely replace the CWVWebViewConfiguration implementation so that
// we can nop certain services such as access to CWVWebView specific wrappers
// around autofill, sync, etc (since we would use Chrome's) and replace
// the exposed browser state to be a plain `web::BrowserState`
@interface CWVWebViewConfiguration ()
// The browser state associated with this configuration.
@property(nonatomic, readonly) web::BrowserState* browserState;
// Calls |shutDown| on the singletons returned by |defaultConfiguration| and
// |incognitoConfiguration|.
+ (void)shutDown;
// Initializes with |browserState| that this instance is to be associated with.
- (instancetype)initWithBrowserState:(web::BrowserState*)browserState
NS_DESIGNATED_INITIALIZER;
// Registers a |webView| so that this class can call |shutDown| on it later on.
// Only weak references are held, so no need for de-register method.
- (void)registerWebView:(CWVWebView*)webView;
// If this instance is going to outlive the globals created in
// ios_web_view::InitializeGlobalState, this method must be called to ensure the
// correct tear down order.
- (void)shutDown;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_CONFIGURATION_INTERNAL_H_
@@ -0,0 +1,28 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_INTERNAL_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_INTERNAL_H_
#include "src/ios/web_view/internal/cwv_web_view_internal.h" // IWYU pragma: export
NS_ASSUME_NONNULL_BEGIN
namespace base {
class Value;
}
// Expose the underlying web::WebState and a few other properties that are not
// public so that cwv_web_view_extras.mm can access the private property and
// implement additional functionality
@interface CWVWebView (Internal)
@property(readonly) web::WebState* webState;
+ (BOOL)_isRestoreDataValid:(NSData*)data;
+ (id)objectFromValue:(const base::Value*)value;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_WEB_VIEW_INTERNAL_H_
@@ -0,0 +1,12 @@
// Copyright (c) 2024 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 "src/ios/web_view/internal/cwv_x509_certificate.mm"
@implementation CWVX509Certificate (Internal)
- (scoped_refptr<net::X509Certificate>)internalCertificate {
return _internalCertificate;
}
@end
@@ -0,0 +1,18 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_X509_CERTIFICATE_INTERNAL_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_X509_CERTIFICATE_INTERNAL_H_
#include "src/ios/web_view/internal/cwv_x509_certificate_internal.h" // IWYU pragma: export
// Expose the underlying net::X509Certificate that is not public so that
// cwv_x509_certificate_extras.mm can access the private property and expose
// additional functionality
@interface CWVX509Certificate (Internal)
@property(readonly) scoped_refptr<net::X509Certificate> internalCertificate;
@end
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_CWV_X509_CERTIFICATE_INTERNAL_H_
@@ -0,0 +1,35 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_PASSWORDS_WEB_VIEW_PASSWORD_MANAGER_CLIENT_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_PASSWORDS_WEB_VIEW_PASSWORD_MANAGER_CLIENT_H_
#include <memory>
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/ios/password_manager_client_bridge.h"
#include "ios/web/public/browser_state.h"
#include "ios/web/public/web_state.h"
namespace ios_web_view {
// We do not use any WebView* specific clients & services since we would instead
// use the Chrome iOS ones.
//
// Replaces the implementation of the WebViewPasswordManagerClient with one that
// does nothing
class WebViewPasswordManagerClient
: public password_manager::PasswordManagerClient {
public:
static std::unique_ptr<WebViewPasswordManagerClient> Create(
web::WebState* web_state,
web::BrowserState* browser_state);
void set_bridge(id<PasswordManagerClientBridge> bridge) {}
};
} // namespace ios_web_view
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_PASSWORDS_WEB_VIEW_PASSWORD_MANAGER_CLIENT_H_
@@ -0,0 +1,17 @@
// Copyright (c) 2024 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 "ios/web_view/internal/passwords/web_view_password_manager_client.h"
namespace ios_web_view {
// static
std::unique_ptr<WebViewPasswordManagerClient>
WebViewPasswordManagerClient::Create(web::WebState* web_state,
web::BrowserState* browser_state) {
return nullptr;
}
} // namespace ios_web_view
@@ -0,0 +1,39 @@
// Copyright (c) 2024 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_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_TRANSLATE_WEB_VIEW_TRANSLATE_CLIENT_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_TRANSLATE_WEB_VIEW_TRANSLATE_CLIENT_H_
#include <memory>
#include "components/translate/core/browser/translate_client.h"
#include "ios/web/public/browser_state.h"
#include "ios/web/public/web_state.h"
#import "ios/web_view/internal/translate/cwv_translation_controller_internal.h"
namespace ios_web_view {
// We do not use any WebView* specific clients & services since we would instead
// use the Chrome iOS ones.
//
// Replaces the implementation of the WebViewTranslateClient with one that
// does nothing
class WebViewTranslateClient : public translate::TranslateClient {
public:
static std::unique_ptr<WebViewTranslateClient> Create(
web::BrowserState* browser_state,
web::WebState* web_state);
void set_translation_controller(CWVTranslationController* controller) {}
void TranslatePage(const std::string& source_lang,
const std::string& target_lang,
bool triggered_from_menu) {}
void RevertTranslation() {}
bool RequestTranslationOffer() { return false; }
};
} // namespace ios_web_view
#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_VIEW_INTERNAL_TRANSLATE_WEB_VIEW_TRANSLATE_CLIENT_H_
@@ -0,0 +1,17 @@
// Copyright (c) 2024 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 "ios/web_view/internal/translate/web_view_translate_client.h"
namespace ios_web_view {
// static
std::unique_ptr<WebViewTranslateClient> WebViewTranslateClient::Create(
web::BrowserState* browser_state,
web::WebState* web_state) {
return nullptr;
}
} // namespace ios_web_view
+9
View File
@@ -16,6 +16,7 @@ import("//brave/ios/browser/api/brave_shields/headers.gni")
import("//brave/ios/browser/api/brave_stats/headers.gni")
import("//brave/ios/browser/api/brave_wallet/headers.gni")
import("//brave/ios/browser/api/certificate/headers.gni")
import("//brave/ios/browser/api/content_settings/headers.gni")
import("//brave/ios/browser/api/credential_provider/headers.gni")
import("//brave/ios/browser/api/de_amp/headers.gni")
import("//brave/ios/browser/api/debounce/headers.gni")
@@ -40,9 +41,11 @@ import("//brave/ios/browser/api/url/headers.gni")
import("//brave/ios/browser/api/url_sanitizer/headers.gni")
import("//brave/ios/browser/api/web/ui/headers.gni")
import("//brave/ios/browser/api/web/web_state/headers.gni")
import("//brave/ios/browser/api/web_view/headers.gni")
import("//brave/ios/browser/api/webcompat_reporter/headers.gni")
import("//brave/ios/browser/debounce/headers.gni")
import("//brave/ios/browser/url_sanitizer/headers.gni")
import("//brave/ios/web_view/headers.gni")
import("//build/apple/tweak_info_plist.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/ios/rules.gni")
@@ -128,9 +131,11 @@ brave_core_public_headers += browser_api_features_public_headers
brave_core_public_headers += credential_provider_public_headers
brave_core_public_headers += developer_options_code_public_headers
brave_core_public_headers += browser_api_storekit_receipt_public_headers
brave_core_public_headers += content_settings_public_headers
brave_core_public_headers += webcompat_reporter_public_headers
brave_core_public_headers += browser_api_translate_public_headers
brave_core_public_headers += browser_api_unicode_public_headers
brave_core_public_headers += brave_web_view_public_headers
action("brave_core_umbrella_header") {
script = "//build/config/ios/generate_umbrella_header.py"
@@ -144,6 +149,7 @@ action("brave_core_umbrella_header") {
]
args += rebase_path(brave_core_public_headers, root_build_dir)
args += rebase_path(ios_web_view_public_headers, root_build_dir)
}
tweak_info_plist("info_plist") {
@@ -174,6 +180,7 @@ ios_framework_bundle("brave_core_ios_framework") {
":brave_core_plist",
":brave_core_umbrella_header",
"//brave/ios/app",
"//brave/ios/web_view",
]
deps += ads_public_deps
@@ -185,9 +192,11 @@ ios_framework_bundle("brave_core_ios_framework") {
deps += webcompat_reporter_public_deps
sources = brave_core_public_headers
sources += ios_web_view_public_headers
public_headers = get_target_outputs(":brave_core_umbrella_header")
public_headers += brave_core_public_headers
public_headers += ios_web_view_public_headers
}
ios_create_xcframework("brave_core_xcframework") {
+6
View File
@@ -48,6 +48,7 @@ source_set("app") {
"//brave/ios/browser/api/brave_stats",
"//brave/ios/browser/api/brave_wallet",
"//brave/ios/browser/api/brave_wallet:wallet_mojom_wrappers",
"//brave/ios/browser/api/content_settings",
"//brave/ios/browser/api/de_amp",
"//brave/ios/browser/api/history",
"//brave/ios/browser/api/https_upgrade_exceptions",
@@ -65,9 +66,11 @@ source_set("app") {
"//brave/ios/browser/api/webcompat_reporter:webcompat_reporter_mojom_wrappers",
"//brave/ios/browser/skus",
"//brave/ios/browser/ui/webui",
"//brave/ios/browser/web",
"//build:blink_buildflags",
"//components/browser_sync",
"//components/component_updater",
"//components/content_settings/core/browser",
"//components/history/core/browser",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
@@ -81,6 +84,8 @@ source_set("app") {
"//ios/chrome/app/startup:startup",
"//ios/chrome/app/startup:startup_basic",
"//ios/chrome/browser/bookmarks/model",
"//ios/chrome/browser/browsing_data/model",
"//ios/chrome/browser/content_settings/model",
"//ios/chrome/browser/credential_provider/model:buildflags",
"//ios/chrome/browser/flags:system_flags",
"//ios/chrome/browser/history/model",
@@ -101,6 +106,7 @@ source_set("app") {
"//ios/public/provider/chrome/browser/ui_utils:ui_utils_api",
"//ios/web/public/init",
"//ios/web/public/webui",
"//ios/web_view:web_view_sources",
# Use the provider API controlled by args.gn.
ios_provider_target,
+1
View File
@@ -4,6 +4,7 @@ inline_file('//ios/chrome/app/DEPS', globals(), locals())
include_rules += [
"+ios/chrome/app",
"+ios/web_view",
"+brave/ios/app",
"+brave/ios/browser",
+11 -2
View File
@@ -27,6 +27,8 @@
@class DeAmpPrefs;
@class AIChat;
@class HTTPSUpgradeExceptionsService;
@class DefaultHostContentSettings;
@class CWVWebViewConfiguration;
@protocol AIChatDelegate;
@protocol IpfsAPI;
@@ -78,9 +80,9 @@ OBJC_EXPORT
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithUserAgent:(NSString*)userAgent;
- (instancetype)initWithUserAgent:(nullable NSString*)userAgent;
- (instancetype)initWithUserAgent:(NSString*)userAgent
- (instancetype)initWithUserAgent:(nullable NSString*)userAgent
additionalSwitches:
(NSArray<BraveCoreSwitch*>*)additionalSwitches;
@@ -103,6 +105,9 @@ OBJC_EXPORT
@property(readonly) NTPBackgroundImagesService* backgroundImagesService;
/// The default content settings for regular browsing windows
@property(readonly) DefaultHostContentSettings* defaultHostContentSettings;
- (AIChat*)aiChatAPIWithDelegate:(id<AIChatDelegate>)delegate;
/// Sets up bundle path overrides and initializes ICU from the BraveCore bundle
@@ -113,6 +118,10 @@ OBJC_EXPORT
+ (void)initializeResourceBundleForTesting;
@property(readonly) CWVWebViewConfiguration* defaultWebViewConfiguration;
@property(readonly) CWVWebViewConfiguration* nonPersistentWebViewConfiguration;
- (void)notifyLastPrivateTabClosed;
@end
NS_ASSUME_NONNULL_END
+143 -2
View File
@@ -35,6 +35,8 @@
#include "brave/ios/browser/api/brave_shields/adblock_service+private.h"
#include "brave/ios/browser/api/brave_stats/brave_stats+private.h"
#include "brave/ios/browser/api/brave_wallet/brave_wallet_api+private.h"
#include "brave/ios/browser/api/content_settings/default_host_content_settings.h"
#include "brave/ios/browser/api/content_settings/default_host_content_settings_internal.h"
#include "brave/ios/browser/api/de_amp/de_amp_prefs+private.h"
#include "brave/ios/browser/api/history/brave_history_api+private.h"
#include "brave/ios/browser/api/https_upgrade_exceptions/https_upgrade_exceptions_service+private.h"
@@ -48,10 +50,11 @@
#include "brave/ios/browser/api/sync/brave_sync_api+private.h"
#include "brave/ios/browser/api/sync/driver/brave_sync_profile_service+private.h"
#include "brave/ios/browser/api/web_image/web_image+private.h"
#include "brave/ios/browser/brave_web_client.h"
#include "brave/ios/browser/ui/webui/brave_web_ui_controller_factory.h"
#include "brave/ios/browser/web/brave_web_client.h"
#import "build/blink_buildflags.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/history/core/browser/history_service.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/password_manager/core/browser/password_store/password_store.h"
@@ -62,6 +65,9 @@
#include "ios/chrome/app/startup/provider_registration.h"
#include "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h"
#include "ios/chrome/browser/bookmarks/model/bookmark_undo_service_factory.h"
#include "ios/chrome/browser/browsing_data/model/browsing_data_remover.h"
#include "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h"
#include "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h"
#include "ios/chrome/browser/credential_provider/model/credential_provider_buildflags.h"
#include "ios/chrome/browser/history/model/history_service_factory.h"
#include "ios/chrome/browser/history/model/web_history_service_factory.h"
@@ -83,6 +89,11 @@
#include "ios/public/provider/chrome/browser/overrides/overrides_api.h"
#include "ios/public/provider/chrome/browser/ui_utils/ui_utils_api.h"
#include "ios/web/public/init/web_main.h"
#include "ios/web/public/thread/web_task_traits.h"
#include "ios/web/public/thread/web_thread.h"
#include "ios/web_view/internal/cwv_web_view_configuration_internal.h"
#include "ios/web_view/internal/web_view_browser_state.h"
#include "ios/web_view/internal/web_view_download_manager.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
@@ -130,6 +141,8 @@ const BraveCoreLogSeverity BraveCoreLogSeverityVerbose =
std::unique_ptr<web::WebMain> _webMain;
std::unique_ptr<Browser> _browser;
std::unique_ptr<Browser> _otr_browser;
std::unique_ptr<ios_web_view::WebViewDownloadManager> _downloadManager;
std::unique_ptr<ios_web_view::WebViewDownloadManager> _otrDownloadManager;
raw_ptr<BrowserList> _browserList;
raw_ptr<BrowserList> _otr_browserList;
raw_ptr<ProfileIOS> _main_profile;
@@ -152,6 +165,9 @@ const BraveCoreLogSeverity BraveCoreLogSeverityVerbose =
@property(nonatomic) NTPBackgroundImagesService* backgroundImagesService;
@property(nonatomic)
HTTPSUpgradeExceptionsService* httpsUpgradeExceptionsService;
@property(nonatomic) DefaultHostContentSettings* defaultHostContentSettings;
@property(nonatomic) CWVWebViewConfiguration* defaultWebViewConfiguration;
@property(nonatomic) CWVWebViewConfiguration* nonPersistentWebViewConfiguration;
@end
@implementation BraveCoreMain
@@ -203,7 +219,9 @@ const BraveCoreLogSeverity BraveCoreLogSeverityVerbose =
// Setup WebClient ([ClientRegistration registerClients])
_webClient.reset(new BraveWebClient());
_webClient->SetUserAgent(base::SysNSStringToUTF8(userAgent));
if (userAgent != nil) {
_webClient->SetLegacyUserAgent(base::SysNSStringToUTF8(userAgent));
}
web::SetWebClient(_webClient.get());
_delegate.reset(new BraveMainDelegate());
@@ -279,6 +297,15 @@ const BraveCoreLogSeverity BraveCoreLogSeverityVerbose =
_tabGeneratorAPI = nil;
_webImageDownloader = nil;
[_nonPersistentWebViewConfiguration shutDown];
[_defaultWebViewConfiguration shutDown];
_nonPersistentWebViewConfiguration = nil;
_defaultWebViewConfiguration = nil;
_downloadManager.reset();
_otrDownloadManager.reset();
_otr_browserList =
BrowserListFactory::GetForProfile(_otr_browser->GetProfile());
[_otr_browser->GetCommandDispatcher() prepareForShutdown];
@@ -320,6 +347,12 @@ const BraveCoreLogSeverity BraveCoreLogSeverityVerbose =
_otr_browser = Browser::Create(otr_last_used_profile, {});
_otr_browserList->AddBrowser(_otr_browser.get());
// Setup download managers for CWVWebView
_downloadManager =
std::make_unique<ios_web_view::WebViewDownloadManager>(profile);
_otrDownloadManager = std::make_unique<ios_web_view::WebViewDownloadManager>(
otr_last_used_profile);
#if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED)
CredentialProviderServiceFactory::GetForProfile(profile);
#endif
@@ -588,4 +621,112 @@ static bool CustomLogHandler(int severity,
}
#endif
- (DefaultHostContentSettings*)defaultHostContentSettings {
if (!_defaultHostContentSettings) {
HostContentSettingsMap* map =
ios::HostContentSettingsMapFactory::GetForProfile(_main_profile);
_defaultHostContentSettings =
[[DefaultHostContentSettings alloc] initWithSettingsMap:map];
}
return _defaultHostContentSettings;
}
- (CWVWebViewConfiguration*)defaultWebViewConfiguration {
if (!_defaultWebViewConfiguration) {
_defaultWebViewConfiguration = [[CWVWebViewConfiguration alloc]
initWithBrowserState:ios_web_view::WebViewBrowserState::
FromBrowserState(_main_profile)];
}
return _defaultWebViewConfiguration;
}
- (CWVWebViewConfiguration*)nonPersistentWebViewConfiguration {
if (!_nonPersistentWebViewConfiguration) {
_nonPersistentWebViewConfiguration = [[CWVWebViewConfiguration alloc]
initWithBrowserState:ios_web_view::WebViewBrowserState::
FromBrowserState(
_main_profile->GetOffTheRecordProfile())];
}
return _nonPersistentWebViewConfiguration;
}
#pragma mark - Handling of destroying the incognito BrowserState
// The incognito BrowserState should be closed when the last incognito tab is
// closed (i.e. if there are other incognito tabs open in another Scene, the
// BrowserState must not be destroyed).
- (BOOL)shouldDestroyAndRebuildIncognitoProfile {
return _main_profile->HasOffTheRecordProfile();
}
// Matches lastIncognitoTabClosed from Chrome's SceneController
- (void)notifyLastPrivateTabClosed {
// If no other window has incognito tab, then destroy and rebuild the
// BrowserState. Otherwise, just do the state transition animation.
if ([self shouldDestroyAndRebuildIncognitoProfile]) {
// Incognito browser state cannot be deleted before all the requests are
// deleted. Queue empty task on IO thread and destroy the BrowserState
// when the task has executed, again verifying that no incognito tabs are
// present. When an incognito tab is moved between browsers, there is
// a point where the tab isn't attached to any web state list. However, when
// this queued cleanup step executes, the moved tab will be attached, so
// the cleanup shouldn't proceed.
auto cleanup = ^{
if ([self shouldDestroyAndRebuildIncognitoProfile]) {
[self destroyAndRebuildIncognitoProfile];
}
};
web::GetIOThreadTaskRunner({})->PostTaskAndReply(
FROM_HERE, base::DoNothing(), base::BindRepeating(cleanup));
}
}
// Matches cleanupBrowser from Chrome's BrowserViewWrangler
- (void)cleanupBrowser:(Browser*)browser {
DCHECK(browser);
// Remove the Browser from the browser list. The browser itself is still
// alive during this call, so any observer can act on it.
ProfileIOS* profile = browser->GetProfile();
BrowserList* browserList = BrowserListFactory::GetForProfile(profile);
browserList->RemoveBrowser(browser);
WebStateList* webStateList = browser->GetWebStateList();
// Close all webstates in `webStateList`. Do this in an @autoreleasepool as
// WebStateList observers will be notified (they are unregistered later). As
// some of them may be implemented in Objective-C and unregister themselves
// in their -dealloc method, ensure the -autorelease introduced by ARC are
// processed before the WebStateList destructor is called.
@autoreleasepool {
CloseAllWebStates(*webStateList, WebStateList::CLOSE_NO_FLAGS);
}
}
- (void)destroyAndRebuildIncognitoProfile {
DCHECK(_main_profile->HasOffTheRecordProfile());
_nonPersistentWebViewConfiguration = nil;
ProfileIOS* otrProfile = _main_profile->GetOffTheRecordProfile();
BrowsingDataRemover* browsingDataRemover =
BrowsingDataRemoverFactory::GetForProfile(otrProfile);
browsingDataRemover->Remove(browsing_data::TimePeriod::ALL_TIME,
BrowsingDataRemoveMask::REMOVE_ALL,
base::DoNothing());
[self cleanupBrowser:_otr_browser.get()];
_otr_browser.reset();
// Destroy and recreate the off-the-record BrowserState.
_main_profile->DestroyOffTheRecordProfile();
otrProfile = _main_profile->GetOffTheRecordProfile();
_otr_browser = Browser::Create(otrProfile, {});
BrowserList* browserList = BrowserListFactory::GetForProfile(otrProfile);
browserList->AddBrowser(_otr_browser.get());
}
@end
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 70;
objects = {
/* Begin PBXBuildFile section */
@@ -23,6 +23,7 @@
272FC5AF2979EA700027C53D /* TopNewsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 272FC5AE2979E9D60027C53D /* TopNewsWidget.swift */; };
27462BEA29DF39EE00715268 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = 27462BE929DF39EE00715268 /* OrderedCollections */; };
27466BB1288EDB9C00584C90 /* RuntimeWarnings in Frameworks */ = {isa = PBXBuildFile; productRef = 27466BB0288EDB9C00584C90 /* RuntimeWarnings */; };
2749F5CA2D088E6500A5DAAB /* BraveCore in Frameworks */ = {isa = PBXBuildFile; productRef = 2749F5C92D088E6500A5DAAB /* BraveCore */; };
2759468D29CCB62F0094BDDE /* GRDWireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2759468C29CCB62F0094BDDE /* GRDWireGuardKit */; };
2759468F29CCB6350094BDDE /* GRDWireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2759468E29CCB6350094BDDE /* GRDWireGuardKit */; };
2787B06A2B7ED260004796F8 /* BraveCore in Frameworks */ = {isa = PBXBuildFile; productRef = 2787B0692B7ED260004796F8 /* BraveCore */; };
@@ -200,6 +201,7 @@
273DFB18284FDB1D007781AF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Shortcuts/ja.lproj/BrowserIntents.strings; sourceTree = "<group>"; };
27444B6A29831BBE002E1EBE /* topics_news.en_US.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = topics_news.en_US.json; sourceTree = "<group>"; };
27465DC3284FDB6F0056FDB2 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = Shortcuts/sv.lproj/BrowserIntents.strings; sourceTree = "<group>"; };
2749F5B72D088E0100A5DAAB /* WebShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WebShell.app; sourceTree = BUILT_PRODUCTS_DIR; };
275A4C39284FDB290016F5A8 /* ko-KR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ko-KR"; path = "Shortcuts/ko-KR.lproj/BrowserIntents.strings"; sourceTree = "<group>"; };
276FEA8B284FDB7A001A0718 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Shortcuts/tr.lproj/BrowserIntents.strings; sourceTree = "<group>"; };
277CA004284FDB34002E8470 /* ms */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ms; path = Shortcuts/ms.lproj/BrowserIntents.strings; sourceTree = "<group>"; };
@@ -482,6 +484,20 @@
F926647A234D4EF400359492 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = System/Library/Frameworks/CoreNFC.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
2749F5CC2D08904200A5DAAB /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 2749F5B62D088E0100A5DAAB /* WebShell */;
};
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
2749F5B82D088E0100A5DAAB /* WebShell */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (2749F5CC2D08904200A5DAAB /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = WebShell; sourceTree = "<group>"; };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
2714EE662AF2D4CD002090A9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
@@ -493,6 +509,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2749F5B42D088E0100A5DAAB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2749F5CA2D088E6500A5DAAB /* BraveCore in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
27F443922135E11200296C58 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -805,6 +829,7 @@
CA0391B7271E1023000EB13C /* BraveWidgets */,
2FD860C329C3D686005AADD1 /* BraveWireGuard */,
2714EE6C2AF2D4CD002090A9 /* AutoFillProvider */,
2749F5B82D088E0100A5DAAB /* WebShell */,
7B604FC11C496005006EEEC3 /* Frameworks */,
F84B21BF1A090F8100AAB793 /* Products */,
);
@@ -823,6 +848,7 @@
2FD860C129C3D677005AADD1 /* BraveWireGuard.appex */,
2FE7D51B2B509DA40039FBA4 /* ActionExtension.appex */,
2714EE692AF2D4CD002090A9 /* AutoFillProvider.appex */,
2749F5B72D088E0100A5DAAB /* WebShell.app */,
);
name = Products;
sourceTree = "<group>";
@@ -861,6 +887,29 @@
productReference = 2714EE692AF2D4CD002090A9 /* AutoFillProvider.appex */;
productType = "com.apple.product-type.app-extension";
};
2749F5B62D088E0100A5DAAB /* WebShell */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2749F5C82D088E0200A5DAAB /* Build configuration list for PBXNativeTarget "WebShell" */;
buildPhases = (
2749F5B32D088E0100A5DAAB /* Sources */,
2749F5B42D088E0100A5DAAB /* Frameworks */,
2749F5B52D088E0100A5DAAB /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
2749F5B82D088E0100A5DAAB /* WebShell */,
);
name = WebShell;
packageProductDependencies = (
2749F5C92D088E6500A5DAAB /* BraveCore */,
);
productName = WebShell;
productReference = 2749F5B72D088E0100A5DAAB /* WebShell.app */;
productType = "com.apple.product-type.application";
};
27F443942135E11200296C58 /* ShareExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 27F443AB2135E11200296C58 /* Build configuration list for PBXNativeTarget "ShareExtension" */;
@@ -1020,13 +1069,16 @@
attributes = {
DefaultBuildSystemTypeForWorkspace = Latest;
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 1530;
LastSwiftUpdateCheck = 1620;
LastUpgradeCheck = 1250;
ORGANIZATIONNAME = Mozilla;
TargetAttributes = {
2714EE682AF2D4CD002090A9 = {
CreatedOnToolsVersion = 15.0.1;
};
2749F5B62D088E0100A5DAAB = {
CreatedOnToolsVersion = 16.2;
};
27F443942135E11200296C58 = {
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1010;
@@ -1129,6 +1181,7 @@
CA0391B1271E1023000EB13C /* BraveWidgetsExtension */,
2FD860C029C3D676005AADD1 /* BraveWireGuard */,
2714EE682AF2D4CD002090A9 /* AutoFillProvider */,
2749F5B62D088E0100A5DAAB /* WebShell */,
);
};
/* End PBXProject section */
@@ -1143,6 +1196,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2749F5B52D088E0100A5DAAB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
27F443932135E11200296C58 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1230,6 +1290,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2749F5B32D088E0100A5DAAB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
27F443912135E11200296C58 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1807,6 +1874,266 @@
};
name = Beta;
};
2749F5C22D088E0200A5DAAB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
2749F5C32D088E0200A5DAAB /* Debug (AppStore) */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = "Debug (AppStore)";
};
2749F5C42D088E0200A5DAAB /* Nightly */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Nightly;
};
2749F5C52D088E0200A5DAAB /* Release (AppStore) */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = "Release (AppStore)";
};
2749F5C62D088E0200A5DAAB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
2749F5C72D088E0200A5DAAB /* Beta */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WebShell/WebShell.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = KL8N8XSYF4;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebShell/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.brave.ios.WebShell;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Beta;
};
2774D3712B682277008A5F42 /* Nightly */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -3502,6 +3829,19 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
2749F5C82D088E0200A5DAAB /* Build configuration list for PBXNativeTarget "WebShell" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2749F5C22D088E0200A5DAAB /* Debug */,
2749F5C32D088E0200A5DAAB /* Debug (AppStore) */,
2749F5C42D088E0200A5DAAB /* Nightly */,
2749F5C52D088E0200A5DAAB /* Release (AppStore) */,
2749F5C62D088E0200A5DAAB /* Release */,
2749F5C72D088E0200A5DAAB /* Beta */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
27F443AB2135E11200296C58 /* Build configuration list for PBXNativeTarget "ShareExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -3644,6 +3984,10 @@
isa = XCSwiftPackageProductDependency;
productName = RuntimeWarnings;
};
2749F5C92D088E6500A5DAAB /* BraveCore */ = {
isa = XCSwiftPackageProductDependency;
productName = BraveCore;
};
2759468C29CCB62F0094BDDE /* GRDWireGuardKit */ = {
isa = XCSwiftPackageProductDependency;
productName = GRDWireGuardKit;
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2749F5B62D088E0100A5DAAB"
BuildableName = "WebShell.app"
BlueprintName = "WebShell"
ReferencedContainer = "container:Client.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(PROJECT_DIR)/Configuration/LLDBInit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2749F5B62D088E0100A5DAAB"
BuildableName = "WebShell.app"
BlueprintName = "WebShell"
ReferencedContainer = "container:Client.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2749F5B62D088E0100A5DAAB"
BuildableName = "WebShell.app"
BlueprintName = "WebShell"
ReferencedContainer = "container:Client.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,35 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,193 @@
// Copyright 2024 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 http://mozilla.org/MPL/2.0/.
import BraveCore
import SwiftUI
private let braveCoreMain: BraveCoreMain = {
let main = BraveCoreMain(userAgent: nil)
main.scheduleLowPriorityStartupTasks()
return main
}()
// Basic nav delegate to test some Brave specific features in the web shell app
private class NavDelegate: NSObject, BraveWebViewNavigationDelegate {
func webView(_ webView: CWVWebView, shouldBlockJavaScriptFor request: URLRequest) -> Bool {
return true
}
func webView(_ webView: CWVWebView, shouldBlockUniversalLinksFor request: URLRequest) -> Bool {
return true
}
}
// A basic observable model to bind observable CWVWebView changes to the SwiftUI view
@dynamicMemberLookup
class WebViewModel: ObservableObject {
private let delegate = NavDelegate()
@Published var webView: BraveWebView {
didSet {
setUpObservers()
self.webView.navigationDelegate = delegate
}
}
init(webView: BraveWebView) {
self.webView = webView
setUpObservers()
self.webView.navigationDelegate = delegate
}
private func setUpObservers() {
func subscriber<Value>(for keyPath: KeyPath<BraveWebView, Value>) -> NSKeyValueObservation {
return webView.observe(keyPath, options: [.prior]) { _, change in
if change.isPrior {
self.objectWillChange.send()
}
}
}
observers = [
subscriber(for: \.title),
subscriber(for: \.visibleURL),
subscriber(for: \.visibleLocationString),
subscriber(for: \.lastCommittedURL),
subscriber(for: \.isLoading),
subscriber(for: \.estimatedProgress),
subscriber(for: \.visibleSSLStatus),
subscriber(for: \.canGoBack),
subscriber(for: \.canGoForward),
]
}
private var observers: [NSKeyValueObservation] = []
public subscript<T>(dynamicMember keyPath: KeyPath<BraveWebView, T>) -> T {
webView[keyPath: keyPath]
}
}
struct WebView: UIViewRepresentable {
var webView: BraveWebView
func makeUIView(context: Context) -> BraveWebView {
webView
}
func updateUIView(_ uiView: BraveWebView, context: Context) {
}
}
struct ContentView: View {
@StateObject private var model: WebViewModel = .init(
webView: .init(frame: .zero, configuration: braveCoreMain.defaultWebViewConfiguration)
)
@State private var isPresentingAlert: Bool = false
@State private var urlSubmitText: String = ""
var body: some View {
NavigationStack {
VStack(spacing: 0) {
WebView(webView: model.webView)
Divider()
VStack {
Button {
isPresentingAlert = true
} label: {
HStack {
Group {
if let status = model.visibleSSLStatus {
switch status.securityStyle {
case .unknown:
Image(systemName: "exclamationmark.circle.fill")
case .authenticationBroken:
Image(systemName: "exclamationmark.octagon.fill")
case .unauthenticated:
Image(systemName: "exclamationmark.triangle.fill")
case .authenticated:
if !status.hasOnlySecureContent {
Image(systemName: "exclamationmark.triangle")
} else {
EmptyView()
}
@unknown default:
EmptyView()
}
}
}
.font(.caption)
VStack {
Text(model.visibleLocationString)
.font(.callout)
if let visibleURL = model.visibleURL,
visibleURL.absoluteString != model.visibleLocationString
{
Text(visibleURL.absoluteString)
.font(.caption)
.lineLimit(1)
}
}
}
.foregroundStyle(.primary)
}
HStack(spacing: 16) {
Button {
model.webView.goBack()
} label: {
Image(systemName: "chevron.left")
}
.disabled(!model.canGoBack)
Button {
model.webView.goForward()
} label: {
Image(systemName: "chevron.right")
}
.disabled(!model.canGoForward)
Spacer()
Button {
model.webView.reload()
} label: {
Image(systemName: "arrow.clockwise")
}
}
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
.imageScale(.large)
.background(Material.bar)
}
}
.alert(
"URL",
isPresented: $isPresentingAlert,
actions: {
TextField("URL or search term", text: $urlSubmitText)
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
.keyboardType(.URL)
Button("Cancel", role: .cancel) {
urlSubmitText = ""
}
Button("Submit") {
let classification = AutocompleteClassifier.classify(urlSubmitText)
if let url = classification?.destinationURL {
model.webView.load(URLRequest(url: url))
}
urlSubmitText = ""
}
},
message: {
}
)
.onAppear {
DispatchQueue.main.async {
model.webView.load(URLRequest(url: URL(string: "https://search.brave.com")!))
}
}
}
}
#Preview {
ContentView()
}
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KSApplicationGroup</key>
<string>group.brave.ios.webshell</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.brave.ios.webshell</string>
</array>
</dict>
</plist>
@@ -0,0 +1,15 @@
// Copyright 2024 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 http://mozilla.org/MPL/2.0/.
import SwiftUI
@main
struct WebShellApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
+4 -35
View File
@@ -6,14 +6,7 @@
import("//build/config/ios/rules.gni")
import("//ios/build/config.gni")
source_set("browser") {
sources = [
"brave_web_client.h",
"brave_web_client.mm",
"brave_web_main_parts.h",
"brave_web_main_parts.mm",
]
group("browser") {
deps = [
"api/ai_chat",
"api/bookmarks",
@@ -24,6 +17,7 @@ source_set("browser") {
"api/brave_shields",
"api/brave_wallet:wallet_mojom_wrappers",
"api/certificate",
"api/content_settings",
"api/credential_provider",
"api/developer_options_code",
"api/favicon",
@@ -46,40 +40,15 @@ source_set("browser") {
"api/version_info",
"api/web",
"api/web_image",
"api/web_view",
"brave_wallet",
"//base",
"//brave/browser/sync",
"//brave/components/ai_chat/core/browser",
"//brave/components/brave_component_updater/browser",
"//brave/components/brave_wallet/browser",
"//brave/components/constants",
"//brave/ios/browser/application_context",
"//brave/ios/browser/brave_wallet",
"//brave/ios/browser/profile/model",
"//brave/ios/browser/ui/webui",
"//components/component_updater/installer_policies",
"//components/flags_ui",
"//components/metrics",
"//components/metrics_services_manager",
"//components/variations",
"//components/variations/service",
"//ios/chrome/browser/application_context/model",
"//ios/chrome/browser/flags",
"//ios/chrome/browser/flags:client_side",
"//ios/chrome/browser/profile/model:keyed_service_factories",
"//ios/chrome/browser/providers/raccoon:chromium_raccoon",
"//ios/chrome/browser/shared/model/paths",
"//brave/ios/browser/web",
"//ios/chrome/browser/shared/model/prefs",
"//ios/chrome/browser/shared/model/profile",
"//ios/chrome/browser/shared/model/url:constants",
"//ios/chrome/browser/web/model:web_internal",
"//ios/components/webui:url_constants",
"//ios/public/provider/chrome/browser/url_rewriters:url_rewriters_api",
"//ios/web/public",
"//ios/web/public/init",
"//ios/web/public/navigation",
"//ios/web/public/thread",
"//ui/base",
"//url",
]
}
+1
View File
@@ -10,4 +10,5 @@ include_rules += [
"+brave/components/p3a",
"+ios/chrome/browser",
"+ios/web/web_state",
"+ios/web_view",
]
+16
View File
@@ -0,0 +1,16 @@
# Copyright (c) 2024 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/.
source_set("content_settings") {
sources = [
"default_host_content_settings.h",
"default_host_content_settings.mm",
"default_host_content_settings_internal.h",
]
deps = [
"//base",
"//components/content_settings/core/browser",
]
}
@@ -0,0 +1,30 @@
// Copyright (c) 2024 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_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_H_
#define BRAVE_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_H_
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
// The mode in which pages should be loaded.
typedef NS_ENUM(NSUInteger, DefaultPageMode) {
DefaultPageModeMobile,
DefaultPageModeDesktop,
};
/// A list of default website preferences.
OBJC_EXPORT
@interface DefaultHostContentSettings : NSObject
/// The default page mode in which pages should be loaded.
@property(nonatomic) DefaultPageMode defaultPageMode;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_H_
@@ -0,0 +1,36 @@
// Copyright (c) 2024 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/ios/browser/api/content_settings/default_host_content_settings.h"
#include "base/memory/scoped_refptr.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
@implementation DefaultHostContentSettings {
scoped_refptr<HostContentSettingsMap> _settingsMap;
}
- (instancetype)initWithSettingsMap:(HostContentSettingsMap*)settingsMap {
if ((self = [super init])) {
_settingsMap = settingsMap;
}
return self;
}
- (DefaultPageMode)defaultPageMode {
auto setting = _settingsMap->GetDefaultContentSetting(
ContentSettingsType::REQUEST_DESKTOP_SITE, nullptr);
return setting == CONTENT_SETTING_ALLOW ? DefaultPageModeDesktop
: DefaultPageModeMobile;
}
- (void)setDefaultPageMode:(DefaultPageMode)defaultPageMode {
_settingsMap->SetDefaultContentSetting(
ContentSettingsType::REQUEST_DESKTOP_SITE,
defaultPageMode == DefaultPageModeDesktop ? CONTENT_SETTING_ALLOW
: CONTENT_SETTING_BLOCK);
}
@end
@@ -0,0 +1,18 @@
// Copyright (c) 2024 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_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_INTERNAL_H_
#define BRAVE_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_INTERNAL_H_
#include "brave/ios/browser/api/content_settings/default_host_content_settings.h"
class HostContentSettingsMap;
@interface DefaultHostContentSettings ()
- (instancetype)initWithSettingsMap:(HostContentSettingsMap*)settingsMap
NS_DESIGNATED_INITIALIZER;
@end
#endif // BRAVE_IOS_BROWSER_API_CONTENT_SETTINGS_DEFAULT_HOST_CONTENT_SETTINGS_INTERNAL_H_
@@ -0,0 +1,8 @@
# Copyright (c) 2024 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/.
content_settings_public_headers = [
"//brave/ios/browser/api/content_settings/default_host_content_settings.h",
]
+23
View File
@@ -31,6 +31,26 @@ BraveURLSchemeDisplay const BraveURLSchemeDisplayOmitCryptographic =
// MARK: - Implementation
namespace {
constexpr char16_t kChromeSchema16[] = u"chrome://";
constexpr char16_t kBraveSchema16[] = u"brave://";
} // namespace
namespace brave_utils {
bool ReplaceChromeToBraveScheme(std::u16string& url_string) {
if (base::StartsWith(url_string, kChromeSchema16,
base::CompareCase::INSENSITIVE_ASCII)) {
base::ReplaceFirstSubstringAfterOffset(&url_string, 0, kChromeSchema16,
kBraveSchema16);
return true;
}
return false;
}
} // namespace brave_utils
@implementation BraveURLFormatter
+ (NSString*)formatURLOriginForSecurityDisplay:(NSString*)origin
schemeDisplay:
@@ -38,6 +58,7 @@ BraveURLSchemeDisplay const BraveURLSchemeDisplayOmitCryptographic =
std::u16string result = url_formatter::FormatUrlForSecurityDisplay(
GURL(base::SysNSStringToUTF8(origin)),
static_cast<url_formatter::SchemeDisplay>(schemeDisplay));
brave_utils::ReplaceChromeToBraveScheme(result);
return base::SysUTF16ToNSString(result) ?: @"";
}
@@ -46,6 +67,7 @@ BraveURLSchemeDisplay const BraveURLSchemeDisplayOmitCryptographic =
std::u16string result =
url_formatter::FormatUrlForDisplayOmitSchemePathAndTrivialSubdomains(
GURL(base::SysNSStringToUTF8(origin)));
brave_utils::ReplaceChromeToBraveScheme(result);
return base::SysUTF16ToNSString(result) ?: @"";
}
@@ -57,6 +79,7 @@ BraveURLSchemeDisplay const BraveURLSchemeDisplayOmitCryptographic =
static_cast<url_formatter::FormatUrlType>(formatTypes),
static_cast<base::UnescapeRule::Type>(unescapeOptions), nullptr, nullptr,
nullptr);
brave_utils::ReplaceChromeToBraveScheme(result);
return base::SysUTF16ToNSString(result) ?: @"";
}
@end
+24
View File
@@ -0,0 +1,24 @@
# Copyright (c) 2025 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/.
source_set("web_view") {
sources = [
"brave_web_view.h",
"brave_web_view.mm",
"crw_wk_navigation_handler_impl.mm",
]
deps = [
"//base",
"//brave/ios/web_view",
"//ios/chrome/browser/tabs/model",
"//ios/web/common",
"//ios/web/web_state",
"//ios/web_view:web_view_sources",
]
frameworks = [
"Foundation.framework",
"WebKit.framework",
]
}
+52
View File
@@ -0,0 +1,52 @@
// Copyright (c) 2025 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_IOS_BROWSER_API_WEB_VIEW_BRAVE_WEB_VIEW_H_
#define BRAVE_IOS_BROWSER_API_WEB_VIEW_BRAVE_WEB_VIEW_H_
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
#import "cwv_export.h" // NOLINT
#import "cwv_navigation_delegate.h" // NOLINT
#import "cwv_web_view.h" // NOLINT
NS_ASSUME_NONNULL_BEGIN
/// Additional navigation delegate methods that extend functionality of
/// CWVWebView
CWV_EXPORT
@protocol BraveWebViewNavigationDelegate <CWVNavigationDelegate>
@optional
/// Decides whether or not universal links should be blocked for a given request
- (BOOL)webView:(CWVWebView*)webView
shouldBlockUniversalLinksForRequest:(NSURLRequest*)request;
/// Decides whether or not JavaScript should be blocked on the resulting page
- (BOOL)webView:(CWVWebView*)webView
shouldBlockJavaScriptForRequest:(NSURLRequest*)request;
/// Notifies the delegate that basic authentication is required to access the
/// requested resource
- (void)webView:(CWVWebView*)webView
didRequestHTTPAuthForProtectionSpace:(NSURLProtectionSpace*)protectionSpace
proposedCredential:(NSURLCredential*)proposedCredential
completionHandler:
(void (^)(NSString* _Nullable username,
NSString* _Nullable password))handler;
@end
/// A CWVWebView with Chrome tab helpers attached and the ability to handle
/// some Brave specific features
CWV_EXPORT
@interface BraveWebView : CWVWebView
// This web view's navigation delegate.
@property(nonatomic, weak, nullable) id<BraveWebViewNavigationDelegate>
navigationDelegate;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_IOS_BROWSER_API_WEB_VIEW_BRAVE_WEB_VIEW_H_
@@ -0,0 +1,57 @@
// Copyright (c) 2025 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/ios/browser/api/web_view/brave_web_view.h"
#include "base/notreached.h"
#include "ios/chrome/browser/tabs/model/tab_helper_util.h"
#include "ios/web/public/web_state.h"
#include "ios/web_view/internal/cwv_web_view_internal.h"
@interface CWVWebView ()
- (void)attachSecurityInterstitialHelpersToWebStateIfNecessary;
@end
@implementation BraveWebView
// These are shadowed CWVWebView properties
@dynamic navigationDelegate;
- (void)attachSecurityInterstitialHelpersToWebStateIfNecessary {
[super attachSecurityInterstitialHelpersToWebStateIfNecessary];
AttachTabHelpers(self.webState);
}
- (CWVAutofillController*)autofillController {
NOTREACHED();
return nil;
}
- (CWVTranslationController*)translationController {
NOTREACHED();
return nil;
}
#pragma mark - CRWWebStateDelegate
- (void)webState:(web::WebState*)webState
didRequestHTTPAuthForProtectionSpace:(NSURLProtectionSpace*)protectionSpace
proposedCredential:(NSURLCredential*)proposedCredential
completionHandler:(void (^)(NSString* username,
NSString* password))handler {
SEL selector = @selector(webView:
didRequestHTTPAuthForProtectionSpace:proposedCredential:completionHandler
:);
if ([self.navigationDelegate respondsToSelector:selector]) {
[self.navigationDelegate webView:self
didRequestHTTPAuthForProtectionSpace:protectionSpace
proposedCredential:proposedCredential
completionHandler:handler];
} else {
handler(nil, nil);
}
}
@end
@@ -0,0 +1,52 @@
// Copyright (c) 2024 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 <Foundation/Foundation.h>
#import "brave/ios/browser/api/web_view/brave_web_view.h"
#include "ios/web/common/url_scheme_util.h"
#include "ios/web/public/web_state.h"
#import "ios/web_view/internal/cwv_web_view_internal.h"
namespace brave {
bool ShouldBlockJavaScript(web::WebState* webState, NSURLRequest* request) {
if (!web::UrlHasWebScheme(request.URL)) {
return false;
}
BraveWebView* webView =
static_cast<BraveWebView*>([BraveWebView webViewForWebState:webState]);
if (!webView) {
return false;
}
id<BraveWebViewNavigationDelegate> navigationDelegate =
webView.navigationDelegate;
if ([navigationDelegate respondsToSelector:@selector
(webView:shouldBlockJavaScriptForRequest:)]) {
return [navigationDelegate webView:webView
shouldBlockJavaScriptForRequest:request];
}
return false;
}
bool ShouldBlockUniversalLinks(web::WebState* webState, NSURLRequest* request) {
BraveWebView* webView =
static_cast<BraveWebView*>([BraveWebView webViewForWebState:webState]);
if (!webView) {
return false;
}
id<BraveWebViewNavigationDelegate> navigationDelegate =
webView.navigationDelegate;
if ([navigationDelegate respondsToSelector:@selector
(webView:shouldBlockUniversalLinksForRequest:)]) {
return [navigationDelegate webView:webView
shouldBlockUniversalLinksForRequest:request];
}
return false;
}
} // namespace brave
+7
View File
@@ -0,0 +1,7 @@
# Copyright (c) 2025 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/.
brave_web_view_public_headers =
[ "//brave/ios/browser/api/web_view/brave_web_view.h" ]
-73
View File
@@ -1,73 +0,0 @@
/* Copyright (c) 2020 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 http://mozilla.org/MPL/2.0/. */
#import "brave/ios/browser/brave_web_client.h"
#include "base/functional/bind.h"
#include "brave/components/constants/url_constants.h"
#include "brave/ios/browser/brave_web_main_parts.h"
#include "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
#include "ios/components/webui/web_ui_url_constants.h"
#import "ios/public/provider/chrome/browser/url_rewriters/url_rewriters_api.h"
#import "ios/web/public/navigation/browser_url_rewriter.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
BraveWebClient::BraveWebClient() {}
BraveWebClient::~BraveWebClient() {
}
std::unique_ptr<web::WebMainParts> BraveWebClient::CreateWebMainParts() {
return std::make_unique<BraveWebMainParts>(
*base::CommandLine::ForCurrentProcess());
}
void BraveWebClient::SetUserAgent(const std::string& user_agent) {
user_agent_ = user_agent;
}
std::string BraveWebClient::GetUserAgent(web::UserAgentType type) const {
if (user_agent_.empty()) {
return ChromeWebClient::GetUserAgent(type);
}
return user_agent_;
}
void BraveWebClient::AddAdditionalSchemes(Schemes* schemes) const {
ChromeWebClient::AddAdditionalSchemes(schemes);
schemes->standard_schemes.push_back(kBraveUIScheme);
schemes->secure_schemes.push_back(kBraveUIScheme);
}
bool BraveWebClient::IsAppSpecificURL(const GURL& url) const {
return ChromeWebClient::IsAppSpecificURL(url) || url.SchemeIs(kBraveUIScheme);
}
bool WillHandleBraveURLRedirect(GURL* url, web::BrowserState* browser_state) {
if (url->SchemeIs(kBraveUIScheme)) {
GURL::Replacements replacements;
replacements.SetSchemeStr(kChromeUIScheme);
*url = url->ReplaceComponents(replacements);
}
return false;
}
std::vector<web::JavaScriptFeature*> BraveWebClient::GetJavaScriptFeatures(
web::BrowserState* browser_state) const {
// We don't use Chromium web views for anything but WebUI at the moment, so
// we don't need any JS features added.
return {};
}
void BraveWebClient::PostBrowserURLRewriterCreation(
web::BrowserURLRewriter* rewriter) {
rewriter->AddURLRewriter(&WillHandleBraveURLRedirect);
ChromeWebClient::PostBrowserURLRewriterCreation(rewriter);
}
+37
View File
@@ -0,0 +1,37 @@
# Copyright (c) 2024 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/.
source_set("web") {
sources = [
"brave_web_client.h",
"brave_web_client.mm",
"brave_web_main_parts.h",
"brave_web_main_parts.mm",
]
deps = [
"//base",
"//brave/components/ai_chat/core/browser",
"//brave/components/brave_component_updater/browser",
"//brave/components/brave_wallet/browser",
"//brave/components/constants",
"//brave/ios/browser/application_context",
"//components/component_updater/installer_policies",
"//components/translate/ios/browser",
"//ios/chrome/browser/application_context/model",
"//ios/chrome/browser/providers/raccoon:chromium_raccoon",
"//ios/chrome/browser/shared/model/application_context",
"//ios/chrome/browser/shared/model/paths",
"//ios/chrome/browser/shared/model/url",
"//ios/chrome/browser/shared/model/url:constants",
"//ios/chrome/browser/web/model:web_internal",
"//ios/components/security_interstitials",
"//ios/components/security_interstitials/lookalikes",
"//ios/components/security_interstitials/safe_browsing",
"//ios/components/webui:url_constants",
"//ios/public/provider/chrome/browser/url_rewriters:url_rewriters_api",
"//ios/web_view:web_view_sources",
]
frameworks = [ "Foundation.framework" ]
}
@@ -1,10 +1,10 @@
/* Copyright (c) 2020 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 http://mozilla.org/MPL/2.0/. */
// Copyright (c) 2020 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_IOS_BROWSER_BRAVE_WEB_CLIENT_H_
#define BRAVE_IOS_BROWSER_BRAVE_WEB_CLIENT_H_
#ifndef BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_CLIENT_H_
#define BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_CLIENT_H_
#include <memory>
#include <string>
@@ -19,24 +19,26 @@ class BraveWebClient : public ChromeWebClient {
BraveWebClient& operator=(const BraveWebClient&) = delete;
~BraveWebClient() override;
void SetUserAgent(const std::string& user_agent);
void SetLegacyUserAgent(const std::string& user_agent);
// WebClient implementation.
std::unique_ptr<web::WebMainParts> CreateWebMainParts() override;
std::string GetUserAgent(web::UserAgentType type) const override;
void AddAdditionalSchemes(Schemes* schemes) const override;
bool IsAppSpecificURL(const GURL& url) const override;
std::vector<web::JavaScriptFeature*> GetJavaScriptFeatures(
web::BrowserState* browser_state) const override;
bool EnableLongPressUIContextMenu() const override;
bool EnableWebInspector(web::BrowserState* browser_state) const override;
void PostBrowserURLRewriterCreation(
web::BrowserURLRewriter* rewriter) override;
private:
std::string user_agent_;
std::string legacy_user_agent_;
};
#endif // BRAVE_IOS_BROWSER_BRAVE_WEB_CLIENT_H_
#endif // BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_CLIENT_H_
+95
View File
@@ -0,0 +1,95 @@
// Copyright (c) 2020 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/ios/browser/web/brave_web_client.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/ios/ns_error_util.h"
#include "base/strings/sys_string_conversions.h"
#include "brave/components/constants/url_constants.h"
#include "brave/ios/browser/web/brave_web_main_parts.h"
#import "components/translate/ios/browser/translate_java_script_feature.h"
#include "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
#include "ios/chrome/browser/web/model/chrome_web_client.h"
#import "ios/components/security_interstitials/ios_security_interstitial_java_script_feature.h"
#import "ios/components/security_interstitials/lookalikes/lookalike_url_error.h"
#import "ios/components/security_interstitials/safe_browsing/safe_browsing_error.h"
#include "ios/components/webui/web_ui_url_constants.h"
#import "ios/public/provider/chrome/browser/url_rewriters/url_rewriters_api.h"
#import "ios/web/public/navigation/browser_url_rewriter.h"
#import "ios/web_view/internal/cwv_ssl_error_handler_internal.h"
#import "ios/web_view/internal/cwv_web_view_internal.h"
#import "ios/web_view/public/cwv_navigation_delegate.h"
#import "net/base/apple/url_conversions.h"
#include "url/gurl.h"
BraveWebClient::BraveWebClient() {}
BraveWebClient::~BraveWebClient() {}
std::unique_ptr<web::WebMainParts> BraveWebClient::CreateWebMainParts() {
return std::make_unique<BraveWebMainParts>(
*base::CommandLine::ForCurrentProcess());
}
std::string BraveWebClient::GetUserAgent(web::UserAgentType type) const {
if (!legacy_user_agent_.empty()) {
return legacy_user_agent_;
}
return ChromeWebClient::GetUserAgent(type);
}
void BraveWebClient::AddAdditionalSchemes(Schemes* schemes) const {
ChromeWebClient::AddAdditionalSchemes(schemes);
schemes->standard_schemes.push_back(kBraveUIScheme);
schemes->secure_schemes.push_back(kBraveUIScheme);
}
bool BraveWebClient::IsAppSpecificURL(const GURL& url) const {
// temporarily add `internal://` scheme handling until those pages can be
// ported to WebUI
return ChromeWebClient::IsAppSpecificURL(url) ||
url.SchemeIs(kBraveUIScheme) || url.SchemeIs("internal");
}
bool WillHandleBraveURLRedirect(GURL* url, web::BrowserState* browser_state) {
if (url->SchemeIs(kBraveUIScheme)) {
GURL::Replacements replacements;
replacements.SetSchemeStr(kChromeUIScheme);
*url = url->ReplaceComponents(replacements);
}
return false;
}
std::vector<web::JavaScriptFeature*> BraveWebClient::GetJavaScriptFeatures(
web::BrowserState* browser_state) const {
// Add any JavaScriptFeature's from Chromium or Brave as needed
std::vector<web::JavaScriptFeature*> features;
features.push_back(
security_interstitials::IOSSecurityInterstitialJavaScriptFeature::
GetInstance());
return features;
}
void BraveWebClient::PostBrowserURLRewriterCreation(
web::BrowserURLRewriter* rewriter) {
rewriter->AddURLRewriter(&WillHandleBraveURLRedirect);
ChromeWebClient::PostBrowserURLRewriterCreation(rewriter);
}
bool BraveWebClient::EnableLongPressUIContextMenu() const {
return CWVWebView.chromeContextMenuEnabled;
}
bool BraveWebClient::EnableWebInspector(
web::BrowserState* browser_state) const {
return CWVWebView.webInspectorEnabled;
}
void BraveWebClient::SetLegacyUserAgent(const std::string& user_agent) {
legacy_user_agent_ = user_agent;
}
@@ -1,10 +1,10 @@
/* Copyright (c) 2019 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 http://mozilla.org/MPL/2.0/. */
// Copyright (c) 2019 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_IOS_BROWSER_BRAVE_WEB_MAIN_PARTS_H_
#define BRAVE_IOS_BROWSER_BRAVE_WEB_MAIN_PARTS_H_
#ifndef BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_MAIN_PARTS_H_
#define BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_MAIN_PARTS_H_
#include "ios/chrome/browser/web/model/chrome_main_parts.h"
@@ -21,4 +21,4 @@ class BraveWebMainParts : public IOSChromeMainParts {
void PreMainMessageLoopRun() override;
};
#endif // BRAVE_IOS_BROWSER_BRAVE_WEB_MAIN_PARTS_H_
#endif // BRAVE_IOS_BROWSER_WEB_BRAVE_WEB_MAIN_PARTS_H_
@@ -1,11 +1,11 @@
/* Copyright (c) 2020 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 http://mozilla.org/MPL/2.0/. */
// Copyright (c) 2019 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/ios/browser/brave_web_main_parts.h"
#include "brave/ios/browser/web/brave_web_main_parts.h"
#include "base/metrics/user_metrics.h"
#include "base/command_line.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
@@ -14,30 +14,12 @@
#include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h"
#include "brave/components/brave_wallet/browser/wallet_data_files_installer.h"
#include "brave/ios/browser/application_context/brave_application_context_impl.h"
#include "brave/ios/browser/profile/model/brave_keyed_service_factories.h"
#include "components/component_updater/installer_policies/safety_tips_component_installer.h"
#include "components/flags_ui/pref_service_flags_storage.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "components/variations/service/variations_service.h"
#include "components/variations/synthetic_trial_registry.h"
#include "components/variations/synthetic_trials_active_group_id_provider.h"
#include "components/variations/variations_ids_provider.h"
#include "components/variations/variations_switches.h"
#include "ios/chrome/browser/application_context/model/application_context_impl.h"
#include "ios/chrome/browser/flags/about_flags.h"
#include "ios/chrome/browser/profile/model/keyed_service_factories.h"
#include "ios/chrome/browser/shared/model/paths/paths.h"
#include "ios/chrome/browser/shared/model/profile/profile_manager_ios.h"
#include "ios/web/public/thread/web_task_traits.h"
#include "ios/web/public/thread/web_thread.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
void RegisterComponentsForUpdate(
component_updater::ComponentUpdateService* cus) {
@@ -59,8 +41,7 @@ void BraveWebMainParts::PreCreateMainMessageLoop() {
IOSChromeMainParts::PreCreateMainMessageLoop();
// Add Brave Resource Pack
base::FilePath brave_pack_path;
base::PathService::Get(base::DIR_ASSETS, &brave_pack_path);
auto brave_pack_path = base::PathService::CheckedGet(base::DIR_ASSETS);
brave_pack_path = brave_pack_path.AppendASCII("brave_resources.pak");
ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
brave_pack_path, ui::kScaleFactorNone);
+50
View File
@@ -0,0 +1,50 @@
# Copyright (c) 2024 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/ios/web_view/headers.gni")
config("config") {
# TODO(crbug.com/40120082): This will only guarantee ios/web_view source files
# are extension safe. We also need to pass this flag to all all dependencies.
common_flags = [ "-fapplication-extension" ]
cflags_objc = common_flags
cflags_objcc = common_flags
defines = [ "CWV_IMPLEMENTATION" ]
frameworks = [
"CoreGraphics.framework",
"Foundation.framework",
"MobileCoreServices.framework",
"UIKit.framework",
]
# For our own public headers to be able to import the official public headers
include_dirs = [ "//ios/web_view/public" ]
}
source_set("web_view") {
sources = [
"internal/cwv_ssl_status_extras.mm",
"internal/cwv_web_view_extras.mm",
"internal/cwv_x509_certificate_extras.mm",
"internal/web_view_global_state_util.mm",
"public/cwv_ssl_status_extras.h",
"public/cwv_web_view_extras.h",
"public/cwv_x509_certificate_extras.h",
]
deps = [
"//base",
"//components/ssl_errors",
"//ios/web/js_messaging",
"//ios/web/js_messaging:java_script_feature_manager_header",
"//ios/web/js_messaging:web_view_js_utils",
"//ios/web/web_state",
"//ios/web/web_state:web_state_impl_header",
"//ios/web/web_state/ui",
"//ios/web_view:web_view_sources",
"//net",
"//url",
]
public_configs = [ ":config" ]
}
+5
View File
@@ -0,0 +1,5 @@
include_rules = [
"+components/ssl_errors",
"+ios/web",
"+ios/web_view",
]
+69
View File
@@ -0,0 +1,69 @@
# Copyright (c) 2024 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/.
# This file exposes the //ios/web_view embedder as a regular source_set as well
# as any additions found in //brave/ios/web_view/public
ios_web_view_public_headers = [
"//brave/ios/web_view/public/cwv_ssl_status_extras.h",
"//brave/ios/web_view/public/cwv_x509_certificate_extras.h",
"//brave/ios/web_view/public/cwv_web_view_extras.h",
"//ios/web_view/public/cwv_autofill_controller.h",
"//ios/web_view/public/cwv_autofill_controller_delegate.h",
"//ios/web_view/public/cwv_autofill_data_manager.h",
"//ios/web_view/public/cwv_autofill_data_manager_observer.h",
"//ios/web_view/public/cwv_autofill_form.h",
"//ios/web_view/public/cwv_autofill_profile.h",
"//ios/web_view/public/cwv_autofill_suggestion.h",
"//ios/web_view/public/cwv_back_forward_list.h",
"//ios/web_view/public/cwv_back_forward_list_item.h",
"//ios/web_view/public/cwv_cert_status.h",
"//ios/web_view/public/cwv_credential_provider_extension_utils.h",
"//ios/web_view/public/cwv_credit_card.h",
"//ios/web_view/public/cwv_credit_card_saver.h",
"//ios/web_view/public/cwv_credit_card_verifier.h",
"//ios/web_view/public/cwv_defines.h",
"//ios/web_view/public/cwv_download_task.h",
"//ios/web_view/public/cwv_export.h",
"//ios/web_view/public/cwv_favicon.h",
"//ios/web_view/public/cwv_find_in_page_controller.h",
"//ios/web_view/public/cwv_html_element.h",
"//ios/web_view/public/cwv_identity.h",
"//ios/web_view/public/cwv_leak_check_credential.h",
"//ios/web_view/public/cwv_leak_check_service.h",
"//ios/web_view/public/cwv_leak_check_service_observer.h",
"//ios/web_view/public/cwv_lookalike_url_handler.h",
"//ios/web_view/public/cwv_navigation_action.h",
"//ios/web_view/public/cwv_navigation_delegate.h",
"//ios/web_view/public/cwv_navigation_response.h",
"//ios/web_view/public/cwv_navigation_type.h",
"//ios/web_view/public/cwv_password.h",
"//ios/web_view/public/cwv_preferences.h",
"//ios/web_view/public/cwv_preview_element_info.h",
"//ios/web_view/public/cwv_reuse_check_service.h",
"//ios/web_view/public/cwv_ssl_error_handler.h",
"//ios/web_view/public/cwv_ssl_status.h",
"//ios/web_view/public/cwv_suggestion_type.h",
"//ios/web_view/public/cwv_sync_controller.h",
"//ios/web_view/public/cwv_sync_controller_data_source.h",
"//ios/web_view/public/cwv_sync_controller_delegate.h",
"//ios/web_view/public/cwv_sync_errors.h",
"//ios/web_view/public/cwv_translation_controller.h",
"//ios/web_view/public/cwv_translation_controller_delegate.h",
"//ios/web_view/public/cwv_translation_language.h",
"//ios/web_view/public/cwv_translation_policy.h",
"//ios/web_view/public/cwv_trusted_vault_observer.h",
"//ios/web_view/public/cwv_trusted_vault_provider.h",
"//ios/web_view/public/cwv_trusted_vault_utils.h",
"//ios/web_view/public/cwv_ui_delegate.h",
"//ios/web_view/public/cwv_unsafe_url_handler.h",
"//ios/web_view/public/cwv_user_content_controller.h",
"//ios/web_view/public/cwv_user_script.h",
"//ios/web_view/public/cwv_weak_check_utils.h",
"//ios/web_view/public/cwv_web_view.h",
"//ios/web_view/public/cwv_web_view_configuration.h",
"//ios/web_view/public/cwv_x509_certificate.h",
]
@@ -0,0 +1,55 @@
// Copyright (c) 2024 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/ios/web_view/public/cwv_ssl_status_extras.h"
#include <Foundation/Foundation.h>
#include "base/strings/sys_string_conversions.h"
#include "components/ssl_errors/error_info.h"
#include "ios/web_view/internal/cwv_ssl_status_internal.h"
#include "net/base/apple/url_conversions.h"
#include "net/cert/cert_status_flags.h"
#include "url/gurl.h"
@interface CWVSSLErrorInformation ()
@property(nonatomic, copy) NSString* details;
@property(nonatomic, copy) NSString* shortDescription;
@end
@implementation CWVSSLErrorInformation
- (instancetype)initWithErrorInfo:(ssl_errors::ErrorInfo)errorInfo {
if ((self = [super init])) {
self.details = base::SysUTF16ToNSString(errorInfo.details());
self.shortDescription =
base::SysUTF16ToNSString(errorInfo.short_description());
}
return self;
}
@end
@implementation CWVSSLStatus (Extras)
- (BOOL)isCertStatusError {
return net::IsCertStatusError(self.internalStatus.cert_status);
}
- (NSArray<CWVSSLErrorInformation*>*)certStatusErrorsForURL:(NSURL*)url {
std::vector<ssl_errors::ErrorInfo> errors;
ssl_errors::ErrorInfo::GetErrorsForCertStatus(
self.internalStatus.certificate, self.internalStatus.cert_status,
net::GURLWithNSURL(url), &errors);
NSMutableArray<CWVSSLErrorInformation*>* bridgedErrors =
[[NSMutableArray alloc] init];
for (size_t i = 0; i < errors.size(); ++i) {
[bridgedErrors
addObject:[[CWVSSLErrorInformation alloc] initWithErrorInfo:errors[i]]];
}
return [bridgedErrors copy];
}
@end
@@ -0,0 +1,131 @@
/* Copyright (c) 2024 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/ios/web_view/public/cwv_web_view_extras.h"
#include "base/apple/foundation_util.h"
#include "base/json/json_writer.h"
#include "base/strings/sys_string_conversions.h"
#include "ios/web/common/user_agent.h"
#include "ios/web/js_messaging/java_script_feature_manager.h"
#include "ios/web/js_messaging/web_frame_internal.h"
#include "ios/web/js_messaging/web_view_js_utils.h"
#include "ios/web/public/js_messaging/web_frames_manager.h"
#include "ios/web/web_state/ui/crw_web_controller.h"
#include "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
#include "ios/web/web_state/web_state_impl.h"
#include "ios/web_view/internal/cwv_web_view_configuration_internal.h"
#include "ios/web_view/internal/cwv_web_view_internal.h"
#include "ios/web_view/internal/web_view_browser_state.h"
#include "ios/web_view/public/cwv_navigation_delegate.h"
const CWVUserAgentType CWVUserAgentTypeNone =
static_cast<CWVUserAgentType>(web::UserAgentType::NONE);
const CWVUserAgentType CWVUserAgentTypeAutomatic =
static_cast<CWVUserAgentType>(web::UserAgentType::AUTOMATIC);
const CWVUserAgentType CWVUserAgentTypeMobile =
static_cast<CWVUserAgentType>(web::UserAgentType::MOBILE);
const CWVUserAgentType CWVUserAgentTypeDesktop =
static_cast<CWVUserAgentType>(web::UserAgentType::DESKTOP);
@implementation CWVWebView (Extras)
+ (BOOL)isRestoreDataValid:(NSData*)data {
return [self _isRestoreDataValid:data];
}
- (void)updateScripts {
// This runs `UpdateScripts` on the configuration provider which we will need
// to call in-place of `-[WKUserContentController removeAllUserScripts]` until
// all Brave JavaScript features are ported over to actual Chromium
// JavascriptFeature types and added to BraveWebClient
web::WKWebViewConfigurationProvider& config_provider =
web::WKWebViewConfigurationProvider::FromBrowserState(
self.webState->GetBrowserState());
config_provider.UpdateScripts();
}
- (void)createFullPagePDF:(void (^)(NSData* _Nullable))completionHandler {
self.webState->CreateFullPagePdf(base::BindOnce(completionHandler));
}
- (BOOL)canTakeSnapshot {
return self.webState->CanTakeSnapshot();
}
- (void)takeSnapshotWithRect:(CGRect)rect
completionHandler:(void (^)(UIImage* _Nullable))completionHandler {
self.webState->TakeSnapshot(rect, base::BindRepeating(completionHandler));
}
- (CWVUserAgentType)currentItemUserAgentType {
return static_cast<CWVUserAgentType>(self.webState->GetNavigationManager()
->GetVisibleItem()
->GetUserAgentType());
}
- (void)reloadWithUserAgentType:(CWVUserAgentType)userAgentType {
self.webState->GetNavigationManager()->ReloadWithUserAgentType(
static_cast<web::UserAgentType>(userAgentType));
}
- (void)evaluateJavaScript:(NSString*)javaScriptString
contentWorld:(WKContentWorld*)contentWorld
completionHandler:(void (^)(id result, NSError* error))completion {
web::WebFrame* mainFrame =
self.webState->GetPageWorldWebFramesManager()->GetMainWebFrame();
if (!mainFrame) {
if (completion) {
completion(nil, [NSError errorWithDomain:@"org.chromium.chromewebview"
code:0
userInfo:nil]);
}
return;
}
web::WebFrameInternal* webFrame = mainFrame->GetWebFrameInternal();
auto worlds = web::JavaScriptFeatureManager::FromBrowserState(
self.configuration.browserState)
->GetAllContentWorlds();
auto jsContentWorld =
std::find_if(worlds.begin(), worlds.end(), [&contentWorld](auto world) {
return world->GetWKContentWorld() == contentWorld;
});
if (jsContentWorld == worlds.end()) {
if (completion) {
completion(nil, [NSError errorWithDomain:@"org.chromium.chromewebview"
code:0
userInfo:nil]);
}
return;
}
webFrame->ExecuteJavaScriptInContentWorld(
base::SysNSStringToUTF16(javaScriptString), *jsContentWorld,
base::BindOnce(^(const base::Value* result, NSError* error) {
if (completion) {
id jsResult = nil;
if (!error && result) {
jsResult = [CWVWebView objectFromValue:result];
}
completion(jsResult, error);
}
}));
}
- (WKWebView*)internalWebView {
CRWWebController* web_controller =
web::WebStateImpl::FromWebState(self.webState)->GetWebController();
return web_controller.webView;
}
- (WKWebViewConfiguration*)WKConfiguration {
web::WKWebViewConfigurationProvider& config_provider =
web::WKWebViewConfigurationProvider::FromBrowserState(
self.webState->GetBrowserState());
return config_provider.GetWebViewConfiguration();
}
@end
@@ -0,0 +1,17 @@
// Copyright (c) 2024 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 "ios/web_view/internal/cwv_x509_certificate_internal.h"
#include "net/cert/x509_util_apple.h"
@implementation CWVX509Certificate (Extras)
- (SecCertificateRef)certificateRef {
return net::x509_util::CreateSecCertificateFromX509Certificate(
self.internalCertificate.get())
.release(); // Swift bridging should handle the lifetime
}
@end
@@ -0,0 +1,26 @@
// Copyright (c) 2024 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 "ios/web_view/internal/web_view_global_state_util.h"
namespace ios_web_view {
void InitializeGlobalState() {
// We already provide global initialization with -[BraveCoreMain init] so this
// is a stub of a required function.
//
// This function when implemented by the main `//ios/web_view` target would
// typically setup the required Chromium web infrastructure required to
// support CWVWebView: `WebMain`, `WebMainDelegate` and `WebClient`
//
// We already set this up in a similar fashion to Chrome iOS however so there
// is no need to do it here.
//
// Note: This method is removed in M135 and replaced with a new type that
// handles things similarily: `CWVGlobalState`. This new type will need a
// chromium_src override to remove said initialization
}
} // namespace ios_web_view
@@ -0,0 +1,48 @@
// Copyright (c) 2024 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_IOS_WEB_VIEW_PUBLIC_CWV_SSL_STATUS_EXTRAS_H_
#define BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_SSL_STATUS_EXTRAS_H_
#import <Foundation/Foundation.h>
#import "cwv_ssl_status.h"
NS_ASSUME_NONNULL_BEGIN
/// Describes an error that happened while showing a page over SSL.
OBJC_EXPORT
@interface CWVSSLErrorInformation : NSObject
/// A description of the error.
@property(readonly) NSString* details;
/// A short message describing the error (1 line).
@property(readonly) NSString* shortDescription;
@end
/// Adds additional functionality to CWVSSLStatus that is not be supported out
/// of the box but can be implemented using the underlying web::SSLStatus
OBJC_EXPORT
@interface CWVSSLStatus (Extras)
/// Whether or not `certStatus` is an error
///
/// It is possible to have `securityStyle` be `authenticationBroken` and
/// non-error `certStatus` for WKWebView because `securityStyle` and
/// `certStatus` are calculated using different API, which may lead to different
/// cert verification results. Check this before using error information from
/// `certStatusErrorsForURL`
@property(readonly) BOOL isCertStatusError;
/// A list of error details for a given URL using this SSL certificate
- (NSArray<CWVSSLErrorInformation*>*)certStatusErrorsForURL:(NSURL*)url;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_SSL_STATUS_EXTRAS_H_
+88
View File
@@ -0,0 +1,88 @@
/* Copyright (c) 2024 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_IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_EXTRAS_H_
#define BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_EXTRAS_H_
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import "cwv_export.h"
#import "cwv_web_view.h"
typedef NSInteger CWVUserAgentType NS_TYPED_ENUM;
OBJC_EXPORT const CWVUserAgentType CWVUserAgentTypeNone;
OBJC_EXPORT const CWVUserAgentType CWVUserAgentTypeAutomatic;
OBJC_EXPORT const CWVUserAgentType CWVUserAgentTypeMobile;
OBJC_EXPORT const CWVUserAgentType CWVUserAgentTypeDesktop;
NS_ASSUME_NONNULL_BEGIN
/// Adds additional functionality to CWVWebView that is not be supported out
/// of the box but can be implemented using the underlying WebState
CWV_EXPORT
@interface CWVWebView (Extras)
/// The user agent type currently used on the page (e.g. mobile/desktop)
- (CWVUserAgentType)currentItemUserAgentType;
/// Reloads the page with a specific user agent type
- (void)reloadWithUserAgentType:(CWVUserAgentType)userAgentType;
#pragma mark -
/// Creates a PDF of the current page
///
/// Equivalent of -[WKWebView createPDFWithConfiguration:completionHandler:]
- (void)createFullPagePDF:(void (^)(NSData* _Nullable))completionHandler;
/// Whether or not you can create a snapshot using `takeSnapshotWithRect`
- (BOOL)canTakeSnapshot;
/// Creates an image from the current rendered page for a given CGRect
///
/// Equivalent of -[WKWebView takeSnapshotWithConfiguration:completionHandler:]
- (void)takeSnapshotWithRect:(CGRect)rect
completionHandler:(void (^)(UIImage* _Nullable))completionHandler;
/// Evaluates JavaScript on the page on a given WebKit content world
///
/// Equivalent of -[WKWebView
/// evaluateJavaScript:contentWorld:completionHandler:]
- (void)evaluateJavaScript:(NSString*)javaScriptString
contentWorld:(WKContentWorld*)contentWorld
completionHandler:
(nullable void (^)(id _Nullable result,
NSError* _Nullable error))completion;
#pragma mark -
/// Determines if the data used to restore a CWVWebView is a WebState cache and
/// is valid.
///
/// Used for migration purposes, can be removed in the future
+ (BOOL)isRestoreDataValid:(NSData*)data;
/// Resets & reinjects all JavaScript features
- (void)updateScripts;
/// The underlying WKWebView if one has been created already.
///
/// This is only available for `use_blink=false` builds and be used for WebKit
/// specific paths.
@property(readonly, nullable) WKWebView* internalWebView;
/// The underlying WKWebViewConfiguration for this CWVWebView
///
/// This is only available for `use_blink=false` builds and be used for WebKit
/// specific paths.
@property(readonly) WKWebViewConfiguration* WKConfiguration;
@end
NS_ASSUME_NONNULL_END
#endif // BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_EXTRAS_H_
@@ -0,0 +1,19 @@
// Copyright (c) 2024 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_IOS_WEB_VIEW_PUBLIC_CWV_X509_CERTIFICATE_EXTRAS_H_
#define BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_X509_CERTIFICATE_EXTRAS_H_
#include "cwv_x509_certificate.h" // NOLINT
/// Adds additional functionality to CWVX509Certificate that is not be supported
/// out of the box but can be implemented using the underlying
/// net::X509Certificate
@interface CWVX509Certificate (Extras)
/// The underlying security reference
@property(readonly, nullable) SecCertificateRef certificateRef;
@end
#endif // BRAVE_IOS_WEB_VIEW_PUBLIC_CWV_X509_CERTIFICATE_EXTRAS_H_
+22
View File
@@ -0,0 +1,22 @@
# Copyright (c) 2024 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/.
# Source exclusions for //ios/web_view
# - Excludes custom WebUI implementations as we use //ios/chrome's
# - Excludes the custom WebClient & WebMainParts as we don't use the
# //ios/web_view global state setup
brave_ios_web_view_excluded_sources = [
"internal/web_view_web_client.h",
"internal/web_view_web_client.mm",
"internal/web_view_web_main_parts.h",
"internal/web_view_web_main_parts.mm",
"internal/webui/web_view_web_ui_ios_controller_factory.h",
"internal/webui/web_view_web_ui_ios_controller_factory.mm",
"internal/webui/web_view_web_ui_provider.mm",
]
# Dep exclusions for //ios/web_view
# - Excludes the bundled resources since these are already bundled
brave_ios_web_view_excluded_public_deps = [ ":web_view_resources" ]
+12
View File
@@ -0,0 +1,12 @@
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 87d7a08bd5ef7c081169d2f56b0dc0b8416580b7..38f2fd8b0a65a927c97eddd4a4a1ce142f3ee2cd 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -438,6 +438,7 @@ source_set("web_view_sources") {
"//components/version_info:channel",
]
configs += [ ":config" ]
+ import("//brave/ios/web_view/sources.gni") sources -= brave_ios_web_view_excluded_sources public_deps -= brave_ios_web_view_excluded_public_deps
}
action("web_view_umbrella_header") {
@@ -0,0 +1,13 @@
diff --git a/ios/web_view/public/cwv_web_view.h b/ios/web_view/public/cwv_web_view.h
index c17c6eb810f3122705cc0124e68e1b4a32cd10b8..c76bc2193fb3230585e719e35db730d24eee60e1 100644
--- a/ios/web_view/public/cwv_web_view.h
+++ b/ios/web_view/public/cwv_web_view.h
@@ -71,7 +71,7 @@ CWV_EXPORT
// (not implemented for CWVWebView)
// |visibleURL| is the bad cert page URL. |lastCommittedURL| is the previous
// page URL.
-@property(nonatomic, readonly) NSURL* visibleURL;
+@property(nonatomic, readonly, nullable) NSURL* visibleURL;
// A human-friendly string which represents the location of the document
// currently being loaded. KVO compliant.