OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/app/application_delegate/app_state.h" | 5 #import "ios/chrome/app/application_delegate/app_state.h" |
6 | 6 |
7 #include "base/critical_closure.h" | 7 #include "base/critical_closure.h" |
8 #import "base/mac/bind_objc_block.h" | 8 #import "base/mac/bind_objc_block.h" |
9 #import "base/mac/scoped_nsobject.h" | |
10 #include "components/metrics/metrics_service.h" | 9 #include "components/metrics/metrics_service.h" |
| 10 #import "ios/chrome/app/main_application_delegate.h" |
11 #import "ios/chrome/app/application_delegate/app_navigation.h" | 11 #import "ios/chrome/app/application_delegate/app_navigation.h" |
12 #import "ios/chrome/app/application_delegate/browser_launcher.h" | 12 #import "ios/chrome/app/application_delegate/browser_launcher.h" |
13 #import "ios/chrome/app/application_delegate/memory_warning_helper.h" | 13 #import "ios/chrome/app/application_delegate/memory_warning_helper.h" |
14 #import "ios/chrome/app/application_delegate/metrics_mediator.h" | 14 #import "ios/chrome/app/application_delegate/metrics_mediator.h" |
15 #import "ios/chrome/app/application_delegate/startup_information.h" | 15 #import "ios/chrome/app/application_delegate/startup_information.h" |
16 #import "ios/chrome/app/application_delegate/tab_opening.h" | 16 #import "ios/chrome/app/application_delegate/tab_opening.h" |
17 #import "ios/chrome/app/application_delegate/tab_switching.h" | 17 #import "ios/chrome/app/application_delegate/tab_switching.h" |
18 #import "ios/chrome/app/application_delegate/user_activity_handler.h" | 18 #import "ios/chrome/app/application_delegate/user_activity_handler.h" |
19 #import "ios/chrome/app/deferred_initialization_runner.h" | 19 #import "ios/chrome/app/deferred_initialization_runner.h" |
20 #import "ios/chrome/app/safe_mode/safe_mode_coordinator.h" | 20 #import "ios/chrome/app/safe_mode/safe_mode_coordinator.h" |
(...skipping 12 matching lines...) Expand all Loading... |
33 #import "ios/chrome/browser/ui/browser_view_controller.h" | 33 #import "ios/chrome/browser/ui/browser_view_controller.h" |
34 #import "ios/chrome/browser/ui/main/browser_view_information.h" | 34 #import "ios/chrome/browser/ui/main/browser_view_information.h" |
35 #include "ios/net/cookies/cookie_store_ios.h" | 35 #include "ios/net/cookies/cookie_store_ios.h" |
36 #include "ios/net/cookies/system_cookie_util.h" | 36 #include "ios/net/cookies/system_cookie_util.h" |
37 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" | 37 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
38 #include "ios/public/provider/chrome/browser/distribution/app_distribution_provi
der.h" | 38 #include "ios/public/provider/chrome/browser/distribution/app_distribution_provi
der.h" |
39 #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider
.h" | 39 #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider
.h" |
40 #include "ios/web/net/request_tracker_impl.h" | 40 #include "ios/web/net/request_tracker_impl.h" |
41 #include "net/url_request/url_request_context.h" | 41 #include "net/url_request/url_request_context.h" |
42 | 42 |
| 43 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 44 #error "This file requires ARC support." |
| 45 #endif |
| 46 |
43 namespace { | 47 namespace { |
44 // Helper method to post |closure| on the UI thread. | 48 // Helper method to post |closure| on the UI thread. |
45 void PostTaskOnUIThread(const base::Closure& closure) { | 49 void PostTaskOnUIThread(const base::Closure& closure) { |
46 web::WebThread::PostTask(web::WebThread::UI, FROM_HERE, closure); | 50 web::WebThread::PostTask(web::WebThread::UI, FROM_HERE, closure); |
47 } | 51 } |
48 NSString* const kStartupAttemptReset = @"StartupAttempReset"; | 52 NSString* const kStartupAttemptReset = @"StartupAttempReset"; |
49 } // namespace | 53 } // namespace |
50 | 54 |
51 @interface AppState ()<SafeModeCoordinatorDelegate> { | 55 @interface AppState ()<SafeModeCoordinatorDelegate> { |
52 // Container for startup information. | 56 // Container for startup information. |
53 base::WeakNSProtocol<id<StartupInformation>> _startupInformation; | 57 __weak id<StartupInformation> _startupInformation; |
54 // Browser launcher to launch browser in different states. | 58 // Browser launcher to launch browser in different states. |
55 base::WeakNSProtocol<id<BrowserLauncher>> _browserLauncher; | 59 __weak id<BrowserLauncher> _browserLauncher; |
56 // UIApplicationDelegate for the application. | 60 // UIApplicationDelegate for the application. |
57 base::WeakNSObject<MainApplicationDelegate> _mainApplicationDelegate; | 61 __weak MainApplicationDelegate* _mainApplicationDelegate; |
58 // Window for the application. | 62 // Window for the application. |
59 base::WeakNSObject<UIWindow> _window; | 63 __weak UIWindow* _window; |
60 | 64 |
61 // Variables backing properties of same name. | 65 // Variables backing properties of same name. |
62 base::scoped_nsobject<SafeModeCoordinator> _safeModeCoordinator; | 66 SafeModeCoordinator* _safeModeCoordinator; |
63 | 67 |
64 // Start of the current session, used for UMA. | 68 // Start of the current session, used for UMA. |
65 base::TimeTicks _sessionStartTime; | 69 base::TimeTicks _sessionStartTime; |
66 // YES if the app is currently in the process of terminating. | 70 // YES if the app is currently in the process of terminating. |
67 BOOL _appIsTerminating; | 71 BOOL _appIsTerminating; |
68 // Indicates if an NTP tab should be opened once the application has become | 72 // Indicates if an NTP tab should be opened once the application has become |
69 // active. | 73 // active. |
70 BOOL _shouldOpenNTPTabOnActive; | 74 BOOL _shouldOpenNTPTabOnActive; |
71 // Interstitial view used to block any incognito tabs after backgrounding. | 75 // Interstitial view used to block any incognito tabs after backgrounding. |
72 base::scoped_nsobject<UIView> _incognitoBlocker; | 76 UIView* _incognitoBlocker; |
73 // Whether the application is currently in the background. | 77 // Whether the application is currently in the background. |
74 // This is a workaround for rdar://22392526 where | 78 // This is a workaround for rdar://22392526 where |
75 // -applicationDidEnterBackground: can be called twice. | 79 // -applicationDidEnterBackground: can be called twice. |
76 // TODO(crbug.com/546196): Remove this once rdar://22392526 is fixed. | 80 // TODO(crbug.com/546196): Remove this once rdar://22392526 is fixed. |
77 BOOL _applicationInBackground; | 81 BOOL _applicationInBackground; |
78 // YES if cookies are currently being flushed to disk. | 82 // YES if cookies are currently being flushed to disk. |
79 BOOL _savingCookies; | 83 BOOL _savingCookies; |
80 } | 84 } |
81 | 85 |
82 // Safe mode coordinator. If this is non-nil, the app is displaying the safe | 86 // Safe mode coordinator. If this is non-nil, the app is displaying the safe |
83 // mode UI. | 87 // mode UI. |
84 @property(nonatomic, retain) SafeModeCoordinator* safeModeCoordinator; | 88 @property(nonatomic, strong) SafeModeCoordinator* safeModeCoordinator; |
85 | 89 |
86 // Return value for -requiresHandlingAfterLaunchWithOptions that determines if | 90 // Return value for -requiresHandlingAfterLaunchWithOptions that determines if |
87 // UIKit should make followup delegate calls such as | 91 // UIKit should make followup delegate calls such as |
88 // -performActionForShortcutItem or -openURL. | 92 // -performActionForShortcutItem or -openURL. |
89 @property(nonatomic, assign) BOOL shouldPerformAdditionalDelegateHandling; | 93 @property(nonatomic, assign) BOOL shouldPerformAdditionalDelegateHandling; |
90 | 94 |
91 // This method is the first to be called when user launches the application. | 95 // This method is the first to be called when user launches the application. |
92 // Depending on the background tasks history, the state of the application is | 96 // Depending on the background tasks history, the state of the application is |
93 // either INITIALIZATION_STAGE_BASIC or INITIALIZATION_STAGE_BACKGROUND so this | 97 // either INITIALIZATION_STAGE_BASIC or INITIALIZATION_STAGE_BACKGROUND so this |
94 // step cannot be included in the |startUpBrowserToStage:| method. | 98 // step cannot be included in the |startUpBrowserToStage:| method. |
(...skipping 13 matching lines...) Expand all Loading... |
108 NOTREACHED(); | 112 NOTREACHED(); |
109 return nil; | 113 return nil; |
110 } | 114 } |
111 | 115 |
112 - (instancetype) | 116 - (instancetype) |
113 initWithBrowserLauncher:(id<BrowserLauncher>)browserLauncher | 117 initWithBrowserLauncher:(id<BrowserLauncher>)browserLauncher |
114 startupInformation:(id<StartupInformation>)startupInformation | 118 startupInformation:(id<StartupInformation>)startupInformation |
115 applicationDelegate:(MainApplicationDelegate*)applicationDelegate { | 119 applicationDelegate:(MainApplicationDelegate*)applicationDelegate { |
116 self = [super init]; | 120 self = [super init]; |
117 if (self) { | 121 if (self) { |
118 _startupInformation.reset(startupInformation); | 122 _startupInformation = startupInformation; |
119 _browserLauncher.reset(browserLauncher); | 123 _browserLauncher = browserLauncher; |
120 _mainApplicationDelegate.reset(applicationDelegate); | 124 _mainApplicationDelegate = applicationDelegate; |
121 } | 125 } |
122 return self; | 126 return self; |
123 } | 127 } |
124 | 128 |
125 #pragma mark - Properties implementation | 129 #pragma mark - Properties implementation |
126 | 130 |
127 - (SafeModeCoordinator*)safeModeCoordinator { | 131 - (SafeModeCoordinator*)safeModeCoordinator { |
128 return _safeModeCoordinator; | 132 return _safeModeCoordinator; |
129 } | 133 } |
130 | 134 |
131 - (void)setSafeModeCoordinator:(SafeModeCoordinator*)safeModeCoordinator { | 135 - (void)setSafeModeCoordinator:(SafeModeCoordinator*)safeModeCoordinator { |
132 _safeModeCoordinator.reset([safeModeCoordinator retain]); | 136 _safeModeCoordinator = safeModeCoordinator; |
133 } | 137 } |
134 | 138 |
135 - (void)setWindow:(UIWindow*)window { | 139 - (void)setWindow:(UIWindow*)window { |
136 _window.reset(window); | 140 _window = window; |
137 } | 141 } |
138 | 142 |
139 - (UIWindow*)window { | 143 - (UIWindow*)window { |
140 return _window; | 144 return _window; |
141 } | 145 } |
142 | 146 |
143 #pragma mark - Public methods. | 147 #pragma mark - Public methods. |
144 | 148 |
145 - (void)applicationDidEnterBackground:(UIApplication*)application | 149 - (void)applicationDidEnterBackground:(UIApplication*)application |
146 memoryHelper:(MemoryWarningHelper*)memoryHelper | 150 memoryHelper:(MemoryWarningHelper*)memoryHelper |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 if (([[_browserLauncher browserViewInformation] currentBrowserState] && | 189 if (([[_browserLauncher browserViewInformation] currentBrowserState] && |
186 [[_browserLauncher browserViewInformation] currentBrowserState] | 190 [[_browserLauncher browserViewInformation] currentBrowserState] |
187 ->IsOffTheRecord()) || | 191 ->IsOffTheRecord()) || |
188 (tabSwitcherIsActive && | 192 (tabSwitcherIsActive && |
189 ![[[_browserLauncher browserViewInformation] otrTabModel] isEmpty])) { | 193 ![[[_browserLauncher browserViewInformation] otrTabModel] isEmpty])) { |
190 // Cover the largest area potentially shown in the app switcher, in case the | 194 // Cover the largest area potentially shown in the app switcher, in case the |
191 // screenshot is reused in a different orientation or size class. | 195 // screenshot is reused in a different orientation or size class. |
192 CGRect screenBounds = [[UIScreen mainScreen] bounds]; | 196 CGRect screenBounds = [[UIScreen mainScreen] bounds]; |
193 CGFloat maxDimension = | 197 CGFloat maxDimension = |
194 std::max(CGRectGetWidth(screenBounds), CGRectGetHeight(screenBounds)); | 198 std::max(CGRectGetWidth(screenBounds), CGRectGetHeight(screenBounds)); |
195 _incognitoBlocker.reset([[UIView alloc] | 199 _incognitoBlocker = [[UIView alloc] |
196 initWithFrame:CGRectMake(0, 0, maxDimension, maxDimension)]); | 200 initWithFrame:CGRectMake(0, 0, maxDimension, maxDimension)]; |
197 InstallBackgroundInView(_incognitoBlocker); | 201 InstallBackgroundInView(_incognitoBlocker); |
198 [_window addSubview:_incognitoBlocker]; | 202 [_window addSubview:_incognitoBlocker]; |
199 } | 203 } |
200 | 204 |
201 // Do not save cookies if it is already in progress. | 205 // Do not save cookies if it is already in progress. |
202 if ([[_browserLauncher browserViewInformation] currentBVC].browserState && | 206 if ([[_browserLauncher browserViewInformation] currentBVC].browserState && |
203 !_savingCookies) { | 207 !_savingCookies) { |
204 // Save cookies to disk. The empty critical closure guarantees that the task | 208 // Save cookies to disk. The empty critical closure guarantees that the task |
205 // will be run before backgrounding. | 209 // will be run before backgrounding. |
206 scoped_refptr<net::URLRequestContextGetter> getter = | 210 scoped_refptr<net::URLRequestContextGetter> getter = |
207 [[_browserLauncher browserViewInformation] currentBVC] | 211 [[_browserLauncher browserViewInformation] currentBVC] |
208 .browserState->GetRequestContext(); | 212 .browserState->GetRequestContext(); |
209 _savingCookies = YES; | 213 _savingCookies = YES; |
210 base::Closure criticalClosure = base::MakeCriticalClosure(base::BindBlock(^{ | 214 base::Closure criticalClosure = |
211 DCHECK_CURRENTLY_ON(web::WebThread::UI); | 215 base::MakeCriticalClosure(base::BindBlockArc(^{ |
212 _savingCookies = NO; | 216 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
213 })); | 217 _savingCookies = NO; |
| 218 })); |
214 web::WebThread::PostTask( | 219 web::WebThread::PostTask( |
215 web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 220 web::WebThread::IO, FROM_HERE, base::BindBlockArc(^{ |
216 net::CookieStoreIOS* store = static_cast<net::CookieStoreIOS*>( | 221 net::CookieStoreIOS* store = static_cast<net::CookieStoreIOS*>( |
217 getter->GetURLRequestContext()->cookie_store()); | 222 getter->GetURLRequestContext()->cookie_store()); |
218 // FlushStore() runs its callback on any thread. Jump back to UI. | 223 // FlushStore() runs its callback on any thread. Jump back to UI. |
219 store->FlushStore(base::Bind(&PostTaskOnUIThread, criticalClosure)); | 224 store->FlushStore(base::Bind(&PostTaskOnUIThread, criticalClosure)); |
220 })); | 225 })); |
221 } | 226 } |
222 | 227 |
223 // Mark the startup as clean if it hasn't already been. | 228 // Mark the startup as clean if it hasn't already been. |
224 [[DeferredInitializationRunner sharedInstance] | 229 [[DeferredInitializationRunner sharedInstance] |
225 runBlockIfNecessary:kStartupAttemptReset]; | 230 runBlockIfNecessary:kStartupAttemptReset]; |
(...skipping 26 matching lines...) Expand all Loading... |
252 // is not complete. | 257 // is not complete. |
253 [self initializeUI]; | 258 [self initializeUI]; |
254 return; | 259 return; |
255 } | 260 } |
256 if ([self isInSafeMode]) | 261 if ([self isInSafeMode]) |
257 return; | 262 return; |
258 | 263 |
259 _applicationInBackground = NO; | 264 _applicationInBackground = NO; |
260 | 265 |
261 [_incognitoBlocker removeFromSuperview]; | 266 [_incognitoBlocker removeFromSuperview]; |
262 _incognitoBlocker.reset(); | 267 _incognitoBlocker = nil; |
263 | 268 |
264 breakpad_helper::SetCurrentlyInBackground(false); | 269 breakpad_helper::SetCurrentlyInBackground(false); |
265 | 270 |
266 // Update the state of metrics and crash reporting, as the method of | 271 // Update the state of metrics and crash reporting, as the method of |
267 // communication may have changed while the app was in the background. | 272 // communication may have changed while the app was in the background. |
268 [metricsMediator updateMetricsStateBasedOnPrefsUserTriggered:NO]; | 273 [metricsMediator updateMetricsStateBasedOnPrefsUserTriggered:NO]; |
269 | 274 |
270 // Send any feedback that might be still on temporary storage. | 275 // Send any feedback that might be still on temporary storage. |
271 ios::GetChromeBrowserProvider()->GetUserFeedbackProvider()->Synchronize(); | 276 ios::GetChromeBrowserProvider()->GetUserFeedbackProvider()->Synchronize(); |
272 | 277 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieCountOnForegrounding", | 313 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieCountOnForegrounding", |
309 cookie_count); | 314 cookie_count); |
310 net::CheckForCookieLoss(cookie_count, | 315 net::CheckForCookieLoss(cookie_count, |
311 net::COOKIES_APPLICATION_FOREGROUNDED); | 316 net::COOKIES_APPLICATION_FOREGROUNDED); |
312 } | 317 } |
313 } | 318 } |
314 | 319 |
315 - (void)resumeSessionWithTabOpener:(id<TabOpening>)tabOpener | 320 - (void)resumeSessionWithTabOpener:(id<TabOpening>)tabOpener |
316 tabSwitcher:(id<TabSwitching>)tabSwitcher { | 321 tabSwitcher:(id<TabSwitching>)tabSwitcher { |
317 [_incognitoBlocker removeFromSuperview]; | 322 [_incognitoBlocker removeFromSuperview]; |
318 _incognitoBlocker.reset(); | 323 _incognitoBlocker = nil; |
319 | 324 |
320 DCHECK([_browserLauncher browserInitializationStage] == | 325 DCHECK([_browserLauncher browserInitializationStage] == |
321 INITIALIZATION_STAGE_FOREGROUND); | 326 INITIALIZATION_STAGE_FOREGROUND); |
322 _sessionStartTime = base::TimeTicks::Now(); | 327 _sessionStartTime = base::TimeTicks::Now(); |
323 [[[_browserLauncher browserViewInformation] mainTabModel] | 328 [[[_browserLauncher browserViewInformation] mainTabModel] |
324 resetSessionMetrics]; | 329 resetSessionMetrics]; |
325 | 330 |
326 if ([_startupInformation startupParameters]) { | 331 if ([_startupInformation startupParameters]) { |
327 [UserActivityHandler | 332 [UserActivityHandler |
328 handleStartupParametersWithTabOpener:tabOpener | 333 handleStartupParametersWithTabOpener:tabOpener |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 441 |
437 #pragma mark - Internal methods. | 442 #pragma mark - Internal methods. |
438 | 443 |
439 - (void)initializeUI { | 444 - (void)initializeUI { |
440 _userInteracted = YES; | 445 _userInteracted = YES; |
441 [self saveLaunchDetailsToDefaults]; | 446 [self saveLaunchDetailsToDefaults]; |
442 | 447 |
443 DCHECK([_window rootViewController] == nil); | 448 DCHECK([_window rootViewController] == nil); |
444 if ([SafeModeCoordinator shouldStart]) { | 449 if ([SafeModeCoordinator shouldStart]) { |
445 SafeModeCoordinator* safeModeCoordinator = | 450 SafeModeCoordinator* safeModeCoordinator = |
446 [[[SafeModeCoordinator alloc] initWithWindow:_window] autorelease]; | 451 [[SafeModeCoordinator alloc] initWithWindow:_window]; |
447 | 452 |
448 self.safeModeCoordinator = safeModeCoordinator; | 453 self.safeModeCoordinator = safeModeCoordinator; |
449 [self.safeModeCoordinator setDelegate:self]; | 454 [self.safeModeCoordinator setDelegate:self]; |
450 | 455 |
451 // Activate the main window, which will prompt the views to load. | 456 // Activate the main window, which will prompt the views to load. |
452 [_window makeKeyAndVisible]; | 457 [_window makeKeyAndVisible]; |
453 | 458 |
454 [self.safeModeCoordinator start]; | 459 [self.safeModeCoordinator start]; |
455 return; | 460 return; |
456 } | 461 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 self = [self initWithBrowserLauncher:browserLauncher | 495 self = [self initWithBrowserLauncher:browserLauncher |
491 startupInformation:startupInformation | 496 startupInformation:startupInformation |
492 applicationDelegate:applicationDelegate]; | 497 applicationDelegate:applicationDelegate]; |
493 if (self) { | 498 if (self) { |
494 _shouldOpenNTPTabOnActive = shouldOpenNTP; | 499 _shouldOpenNTPTabOnActive = shouldOpenNTP; |
495 } | 500 } |
496 return self; | 501 return self; |
497 } | 502 } |
498 | 503 |
499 @end | 504 @end |
OLD | NEW |