Add build flag to disable hotwording.
[chromium-blink-merge.git] / ios / web / web_state / web_view_creation_utils.mm
blobff5c9264dd646ba26f433e6eae1614984ce4d759
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/web_state/web_view_creation_utils.h"
7 #import <objc/runtime.h>
8 #import <WebKit/WebKit.h>
10 #include "base/logging.h"
11 #include "base/mac/scoped_nsobject.h"
12 #import "ios/web/alloc_with_zone_interceptor.h"
13 #import "ios/web/public/browsing_data_partition.h"
14 #include "ios/web/public/browser_state.h"
15 #include "ios/web/public/web_client.h"
16 #include "ios/web/ui_web_view_util.h"
17 #import "ios/web/weak_nsobject_counter.h"
18 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
19 #import "ios/web/web_state/ui/crw_ui_simple_web_view_controller.h"
20 #import "ios/web/web_state/ui/crw_wk_simple_web_view_controller.h"
21 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
23 #if !defined(NDEBUG)
24 #import "ios/web/web_state/ui/crw_debug_web_view.h"
25 #endif
27 #if !defined(NDEBUG)
29 namespace {
30 // Returns the counter of all the active WKWebViews.
31 web::WeakNSObjectCounter& GetActiveWKWebViewCounter() {
32   static web::WeakNSObjectCounter active_wk_web_view_counter;
33   return active_wk_web_view_counter;
35 // Decides if WKWebView can be created.
36 BOOL gAllowWKWebViewCreation = NO;
37 }  // namespace
39 @interface WKWebView(CRWAdditions)
40 @end
42 @implementation WKWebView(CRWAdditions)
44 + (void)load {
45   id (^allocator)(Class klass, NSZone* zone) = ^id(Class klass, NSZone* zone) {
46     if (gAllowWKWebViewCreation) {
47       return NSAllocateObject(klass, 0, zone);
48     }
49     // You have hit this because you are trying to create a WKWebView directly.
50     // Please use one of the web::CreateWKWKWebView methods that vend a
51     // WKWebView instead.
52     NOTREACHED();
53     return nil;
54   };
55   web::AddAllocWithZoneMethod([WKWebView class], allocator);
58 @end
60 #endif  // !defined(NDEBUG)
62 namespace {
63 // Returns a new WKWebView for displaying regular web content.
64 // Note: Callers are responsible for releasing the returned WKWebView.
65 WKWebView* CreateWKWebViewWithConfiguration(
66     CGRect frame,
67     WKWebViewConfiguration* configuration) {
68   DCHECK(configuration);
69   DCHECK(web::GetWebClient());
70   web::GetWebClient()->PreWebViewCreation();
71 #if !defined(NDEBUG)
72   gAllowWKWebViewCreation = YES;
73 #endif
75   WKWebView* result =
76       [[WKWebView alloc] initWithFrame:frame configuration:configuration];
77 #if !defined(NDEBUG)
78   GetActiveWKWebViewCounter().Insert(result);
79   gAllowWKWebViewCreation = NO;
80 #endif
82   // TODO(stuartmorgan): Figure out how to make this work; two different client
83   // methods for the two web view types?
84   // web::GetWebClient()->PostWebViewCreation(result);
86   return result;
90 namespace web {
92 UIWebView* CreateWebView(CGRect frame,
93                          NSString* request_group_id,
94                          BOOL use_desktop_user_agent) {
95   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
96                                              use_desktop_user_agent);
97   return web::CreateWebView(frame);
100 UIWebView* CreateWebView(CGRect frame) {
101   DCHECK(web::GetWebClient());
102   web::GetWebClient()->PreWebViewCreation();
104   UIWebView* result = nil;
105 #if defined(NDEBUG)
106   result = [[UIWebView alloc] initWithFrame:frame];
107 #else
108   // TODO(eugenebut): create constant for @"LogJavascript" (crbug.com/391807).
109   if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LogJavascript"])
110     result = [[CRWDebugWebView alloc] initWithFrame:frame];
111   else
112     result = [[UIWebView alloc] initWithFrame:frame];
113 #endif  // defined(NDEBUG)
115   // Disable data detector types. Safari does the same.
116   [result setDataDetectorTypes:UIDataDetectorTypeNone];
117   [result setScalesPageToFit:YES];
119   // By default UIWebView uses a very sluggish scroll speed. Set it to a more
120   // reasonable value.
121   result.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
123   web::GetWebClient()->PostWebViewCreation(result);
125   return result;
128 WKWebView* CreateWKWebView(CGRect frame,
129                            WKWebViewConfiguration* configuration,
130                            BrowserState* browser_state,
131                            NSString* request_group_id,
132                            BOOL use_desktop_user_agent) {
133   DCHECK(browser_state);
134   DCHECK(web::BrowsingDataPartition::IsSynchronized());
136   WKWebViewConfigurationProvider& config_provider =
137       WKWebViewConfigurationProvider::FromBrowserState(browser_state);
138   DCHECK_EQ([config_provider.GetWebViewConfiguration() processPool],
139             [configuration processPool]);
140   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
141                                              use_desktop_user_agent);
142   return CreateWKWebViewWithConfiguration(frame, configuration);
145 WKWebView* CreateWKWebView(CGRect frame, BrowserState* browser_state) {
146   DCHECK(browser_state);
147   DCHECK(web::BrowsingDataPartition::IsSynchronized());
149   WKWebViewConfigurationProvider& config_provider =
150       WKWebViewConfigurationProvider::FromBrowserState(browser_state);
151   return CreateWKWebViewWithConfiguration(
152       frame, config_provider.GetWebViewConfiguration());
155 NSUInteger GetActiveWKWebViewsCount() {
156 #if defined(NDEBUG)
157   // This should not be used in release builds.
158   CHECK(0);
159   return 0;
160 #else
161   return GetActiveWKWebViewCounter().Size();
162 #endif
165 id<CRWSimpleWebViewController> CreateSimpleWebViewController(
166     CGRect frame,
167     BrowserState* browser_state,
168     WebViewType web_view_type) {
169   DCHECK(web::BrowsingDataPartition::IsSynchronized());
171   // Transparently return the correct subclass.
172   if (web_view_type == WK_WEB_VIEW_TYPE) {
173     base::scoped_nsobject<WKWebView> web_view(
174         web::CreateWKWebView(frame, browser_state));
175     return [[CRWWKSimpleWebViewController alloc] initWithWKWebView:web_view];
176   }
177   base::scoped_nsobject<UIWebView> web_view(web::CreateWebView(frame));
178   return [[CRWUISimpleWebViewController alloc] initWithUIWebView:web_view];
181 id<CRWSimpleWebViewController> CreateStaticFileSimpleWebViewController(
182     CGRect frame,
183     BrowserState* browser_state,
184     WebViewType web_view_type) {
185   DCHECK(web::BrowsingDataPartition::IsSynchronized());
187   // Transparently return the correct subclass.
188   if (web_view_type == WK_WEB_VIEW_TYPE) {
189     // TOOD(shreyasv): Create a new util function vending a WKWebView, wrap that
190     // now return the UIWebView version. crbug.com/403634.
191   }
192   base::scoped_nsobject<UIWebView> staticFileWebView(
193       CreateStaticFileWebView(frame, browser_state));
194   return [[CRWUISimpleWebViewController alloc]
195       initWithUIWebView:staticFileWebView];
198 UIWebView* CreateStaticFileWebView(CGRect frame, BrowserState* browser_state) {
199   DCHECK(web::GetWebClient());
200   web::GetWebClient()->PreWebViewCreation();
202   UIWebView* result =
203       [[CRWStaticFileWebView alloc] initWithFrame:frame
204                                      browserState:browser_state];
206   web::GetWebClient()->PostWebViewCreation(result);
207   return result;
210 UIWebView* CreateStaticFileWebView() {
211   return CreateStaticFileWebView(CGRectZero, nullptr);
214 }  // namespace web