Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1365)

Side by Side Diff: ios/chrome/browser/tabs/tab.mm

Issue 2859663002: Revert of [ios] ARCMigrate ios/chrome/browser/tabs/tab.mm to ARC. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/chrome/browser/tabs/tab.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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/browser/tabs/tab.h" 5 #import "ios/chrome/browser/tabs/tab.h"
6 6
7 #import <CoreLocation/CoreLocation.h> 7 #import <CoreLocation/CoreLocation.h>
8 #import <UIKit/UIKit.h> 8 #import <UIKit/UIKit.h>
9 9
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/ios/block_types.h" 14 #include "base/ios/block_types.h"
15 #import "base/ios/weak_nsobject.h"
15 #include "base/json/string_escape.h" 16 #include "base/json/string_escape.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/mac/bind_objc_block.h" 18 #include "base/mac/bind_objc_block.h"
18 #include "base/mac/foundation_util.h" 19 #include "base/mac/foundation_util.h"
19 #include "base/memory/ptr_util.h" 20 #include "base/mac/objc_property_releaser.h"
21 #include "base/mac/scoped_nsobject.h"
20 #include "base/metrics/histogram_macros.h" 22 #include "base/metrics/histogram_macros.h"
21 #include "base/metrics/user_metrics.h" 23 #include "base/metrics/user_metrics.h"
22 #include "base/metrics/user_metrics_action.h" 24 #include "base/metrics/user_metrics_action.h"
23 #include "base/scoped_observer.h" 25 #include "base/scoped_observer.h"
24 #include "base/strings/string_split.h" 26 #include "base/strings/string_split.h"
25 #include "base/strings/sys_string_conversions.h" 27 #include "base/strings/sys_string_conversions.h"
26 #include "base/strings/utf_string_conversions.h" 28 #include "base/strings/utf_string_conversions.h"
27 #include "base/time/time.h" 29 #include "base/time/time.h"
28 #include "components/favicon/core/favicon_driver_observer.h" 30 #include "components/favicon/core/favicon_driver_observer.h"
29 #include "components/favicon/ios/web_favicon_driver.h" 31 #include "components/favicon/ios/web_favicon_driver.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 #import "net/base/mac/url_conversions.h" 131 #import "net/base/mac/url_conversions.h"
130 #include "net/base/net_errors.h" 132 #include "net/base/net_errors.h"
131 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 133 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
132 #include "net/cert/x509_certificate.h" 134 #include "net/cert/x509_certificate.h"
133 #include "net/http/http_response_headers.h" 135 #include "net/http/http_response_headers.h"
134 #include "net/url_request/url_fetcher.h" 136 #include "net/url_request/url_fetcher.h"
135 #include "ui/base/l10n/l10n_util.h" 137 #include "ui/base/l10n/l10n_util.h"
136 #include "ui/base/page_transition_types.h" 138 #include "ui/base/page_transition_types.h"
137 #include "url/origin.h" 139 #include "url/origin.h"
138 140
139 #if !defined(__has_feature) || !__has_feature(objc_arc) 141 using base::UserMetricsAction;
140 #error "This file requires ARC support." 142 using web::NavigationManagerImpl;
141 #endif 143 using net::RequestTracker;
142 144
143 NSString* const kTabUrlStartedLoadingNotificationForCrashReporting = 145 NSString* const kTabUrlStartedLoadingNotificationForCrashReporting =
144 @"kTabUrlStartedLoadingNotificationForCrashReporting"; 146 @"kTabUrlStartedLoadingNotificationForCrashReporting";
145 NSString* const kTabUrlMayStartLoadingNotificationForCrashReporting = 147 NSString* const kTabUrlMayStartLoadingNotificationForCrashReporting =
146 @"kTabUrlMayStartLoadingNotificationForCrashReporting"; 148 @"kTabUrlMayStartLoadingNotificationForCrashReporting";
147 NSString* const kTabIsShowingExportableNotificationForCrashReporting = 149 NSString* const kTabIsShowingExportableNotificationForCrashReporting =
148 @"kTabIsShowingExportableNotificationForCrashReporting"; 150 @"kTabIsShowingExportableNotificationForCrashReporting";
149 NSString* const kTabClosingCurrentDocumentNotificationForCrashReporting = 151 NSString* const kTabClosingCurrentDocumentNotificationForCrashReporting =
150 @"kTabClosingCurrentDocumentNotificationForCrashReporting"; 152 @"kTabClosingCurrentDocumentNotificationForCrashReporting";
151 153
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 191
190 // Returns true if |item| is the result of a HTTP redirect. 192 // Returns true if |item| is the result of a HTTP redirect.
191 // Returns false if |item| is nullptr; 193 // Returns false if |item| is nullptr;
192 bool IsItemRedirectItem(web::NavigationItem* item) { 194 bool IsItemRedirectItem(web::NavigationItem* item) {
193 if (!item) 195 if (!item)
194 return false; 196 return false;
195 197
196 return (ui::PageTransition::PAGE_TRANSITION_IS_REDIRECT_MASK & 198 return (ui::PageTransition::PAGE_TRANSITION_IS_REDIRECT_MASK &
197 item->GetTransitionType()) == 0; 199 item->GetTransitionType()) == 0;
198 } 200 }
201 } // namespace
199 202
203 @interface Tab ()<CRWWebStateObserver,
204 CRWWebControllerObserver,
205 FindInPageControllerDelegate,
206 ReaderModeControllerDelegate> {
207 TabModel* parentTabModel_; // weak
208 ios::ChromeBrowserState* browserState_; // weak
209
210 base::scoped_nsobject<OpenInController> openInController_;
211 base::WeakNSProtocol<id<PassKitDialogProvider>> passKitDialogProvider_;
212
213 // Whether or not this tab is currently being displayed.
214 BOOL visible_;
215
216 // Holds entries that need to be added to the history DB. Prerender tabs do
217 // not write navigation data to the history DB. Instead, they cache history
218 // data in this vector and add it to the DB when the prerender status is
219 // removed (when the Tab is swapped in as a real Tab).
220 std::vector<history::HistoryAddPageArgs> addPageVector_;
221
222 // YES if this Tab is being prerendered.
223 BOOL isPrerenderTab_;
224
225 // YES if this Tab was initiated from a voice search.
226 BOOL isVoiceSearchResultsTab_;
227
228 // YES if the Tab needs to be reloaded after the app becomes active.
229 BOOL requireReloadAfterBecomingActive_;
230
231 // Last visited timestamp.
232 double lastVisitedTimestamp_;
233
234 base::mac::ObjCPropertyReleaser propertyReleaser_Tab_;
235
236 id<TabDelegate> delegate_; // weak
237 base::WeakNSProtocol<id<TabDialogDelegate>> dialogDelegate_;
238 base::WeakNSProtocol<id<SnapshotOverlayProvider>> snapshotOverlayProvider_;
239
240 // Delegate used for snapshotting geometry.
241 id<TabSnapshottingDelegate> tabSnapshottingDelegate_; // weak
242
243 // The Full Screen Controller responsible for hiding/showing the toolbar.
244 base::scoped_nsobject<FullScreenController> fullScreenController_;
245
246 // The delegate responsible for headers over the tab.
247 id<TabHeadersDelegate> tabHeadersDelegate_; // weak
248
249 base::WeakNSProtocol<id<FullScreenControllerDelegate>>
250 fullScreenControllerDelegate_;
251
252 // The Overscroll controller responsible for displaying the
253 // overscrollActionsView above the toolbar.
254 base::scoped_nsobject<OverscrollActionsController>
255 overscrollActionsController_;
256 base::WeakNSProtocol<id<OverscrollActionsControllerDelegate>>
257 overscrollActionsControllerDelegate_;
258
259 base::scoped_nsobject<NSString> tabId_;
260
261 // Lightweight object dealing with various different UI behaviours when
262 // opening a URL in an external application.
263 base::scoped_nsobject<ExternalAppLauncher> externalAppLauncher_;
264
265 // Handles suggestions for form entry.
266 base::scoped_nsobject<FormSuggestionController> suggestionController_;
267
268 // Manages the input accessory view during form input.
269 base::scoped_nsobject<FormInputAccessoryViewController>
270 inputAccessoryViewController_;
271
272 // TODO(crbug.com/661665): move the WebContentsObservers into their own
273 // container.
274 // Handles saving and autofill of passwords.
275 base::scoped_nsobject<PasswordController> passwordController_;
276
277 // Handles autofill.
278 base::scoped_nsobject<AutofillController> autofillController_;
279
280 // Handles caching and retrieving of snapshots.
281 base::scoped_nsobject<SnapshotManager> snapshotManager_;
282
283 // Handles retrieving, generating and updating snapshots of CRWWebController's
284 // web page.
285 base::scoped_nsobject<WebControllerSnapshotHelper>
286 webControllerSnapshotHelper_;
287
288 // Handles support for window.print JavaScript calls.
289 std::unique_ptr<PrintObserver> printObserver_;
290
291 // AutoReloadBridge for this tab.
292 base::scoped_nsobject<AutoReloadBridge> autoReloadBridge_;
293
294 // WebStateImpl for this tab.
295 web::WebStateImpl* webStateImpl_;
296
297 // Allows Tab to conform CRWWebStateDelegate protocol.
298 std::unique_ptr<web::WebStateObserverBridge> webStateObserver_;
299
300 // Context used by history to scope the lifetime of navigation entry
301 // references to Tab.
302 std::unique_ptr<TabHistoryContext> tabHistoryContext_;
303
304 // The controller for everything related to reader mode.
305 base::scoped_nsobject<ReaderModeController> readerModeController_;
306
307 // C++ bridge that receives notifications from the FaviconDriver.
308 std::unique_ptr<FaviconDriverObserverBridge> faviconDriverObserverBridge_;
309
310 // U2F call controller object.
311 base::scoped_nsobject<U2FController> U2FController_;
312
313 // C++ observer used to trigger snapshots after the removal of InfoBars.
314 std::unique_ptr<TabInfoBarObserver> tabInfoBarObserver_;
315 }
316
317 // Returns the tab's reader mode controller. May contain nil if the feature is
318 // disabled.
319 @property(nonatomic, readonly) ReaderModeController* readerModeController;
320
321 // Returns a list of FormSuggestionProviders to be queried for suggestions
322 // in order of priority.
323 - (NSArray*)suggestionProviders;
324
325 // Returns a list of FormInputAccessoryViewProviders to be queried for an input
326 // accessory view in order of priority.
327 - (NSArray*)accessoryViewProviders;
328
329 // Sets the favicon on the current NavigationItem.
330 - (void)setFavicon:(const gfx::Image*)image;
331
332 // Saves the current title to the history database.
333 - (void)saveTitleToHistoryDB;
334
335 // Adds the current session entry to this history database.
336 - (void)addCurrentEntryToHistoryDB;
337
338 // Adds any cached entries from |addPageVector_| to the history DB.
339 - (void)commitCachedEntriesToHistoryDB;
340
341 // Returns the OpenInController for this tab.
342 - (OpenInController*)openInController;
343
344 // Handles exportable files if possible.
345 - (void)handleExportableFile:(net::HttpResponseHeaders*)headers;
346
347 // Called after the session history is replaced, useful for updating members
348 // with new sessionID.
349 - (void)didReplaceSessionHistory;
350
351 // Called when the UIApplication's state becomes active.
352 - (void)applicationDidBecomeActive;
353
354 @end
355
356 namespace {
200 // TabHistoryContext is used by history to scope the lifetime of navigation 357 // TabHistoryContext is used by history to scope the lifetime of navigation
201 // entry references to Tab. 358 // entry references to Tab.
202 class TabHistoryContext : public history::Context { 359 class TabHistoryContext : public history::Context {
203 public: 360 public:
204 TabHistoryContext() {} 361 TabHistoryContext() {}
205 ~TabHistoryContext() {} 362 ~TabHistoryContext() {}
206 363
207 private: 364 private:
208 DISALLOW_COPY_AND_ASSIGN(TabHistoryContext); 365 DISALLOW_COPY_AND_ASSIGN(TabHistoryContext);
209 }; 366 };
210 } // namespace
211 367
212 @interface Tab ()<CRWWebStateObserver,
213 CRWWebControllerObserver,
214 FindInPageControllerDelegate,
215 ReaderModeControllerDelegate> {
216 __weak TabModel* parentTabModel_;
217 ios::ChromeBrowserState* browserState_;
218
219 OpenInController* openInController_;
220
221 // Whether or not this tab is currently being displayed.
222 BOOL visible_;
223
224 // Holds entries that need to be added to the history DB. Prerender tabs do
225 // not write navigation data to the history DB. Instead, they cache history
226 // data in this vector and add it to the DB when the prerender status is
227 // removed (when the Tab is swapped in as a real Tab).
228 std::vector<history::HistoryAddPageArgs> addPageVector_;
229
230 // YES if this Tab is being prerendered.
231 BOOL isPrerenderTab_;
232
233 // YES if this Tab was initiated from a voice search.
234 BOOL isVoiceSearchResultsTab_;
235
236 // YES if the Tab needs to be reloaded after the app becomes active.
237 BOOL requireReloadAfterBecomingActive_;
238
239 // Last visited timestamp.
240 double lastVisitedTimestamp_;
241
242 // The Full Screen Controller responsible for hiding/showing the toolbar.
243 FullScreenController* fullScreenController_;
244
245 // The Overscroll controller responsible for displaying the
246 // overscrollActionsView above the toolbar.
247 OverscrollActionsController* overscrollActionsController_;
248
249 // Lightweight object dealing with various different UI behaviours when
250 // opening a URL in an external application.
251 ExternalAppLauncher* externalAppLauncher_;
252
253 // Handles suggestions for form entry.
254 FormSuggestionController* suggestionController_;
255
256 // Manages the input accessory view during form input.
257 FormInputAccessoryViewController* inputAccessoryViewController_;
258
259 // Handles autofill.
260 AutofillController* autofillController_;
261
262 // Handles caching and retrieving of snapshots.
263 SnapshotManager* snapshotManager_;
264
265 // Handles retrieving, generating and updating snapshots of CRWWebController's
266 // web page.
267 WebControllerSnapshotHelper* webControllerSnapshotHelper_;
268
269 // Handles support for window.print JavaScript calls.
270 std::unique_ptr<PrintObserver> printObserver_;
271
272 // AutoReloadBridge for this tab.
273 AutoReloadBridge* autoReloadBridge_;
274
275 // WebStateImpl for this tab.
276 web::WebStateImpl* webStateImpl_;
277
278 // Allows Tab to conform CRWWebStateDelegate protocol.
279 std::unique_ptr<web::WebStateObserverBridge> webStateObserver_;
280
281 // Context used by history to scope the lifetime of navigation entry
282 // references to Tab.
283 TabHistoryContext tabHistoryContext_;
284
285 // C++ bridge that receives notifications from the FaviconDriver.
286 std::unique_ptr<FaviconDriverObserverBridge> faviconDriverObserverBridge_;
287
288 // U2F call controller object.
289 U2FController* U2FController_;
290
291 // C++ observer used to trigger snapshots after the removal of InfoBars.
292 std::unique_ptr<TabInfoBarObserver> tabInfoBarObserver_;
293 }
294
295 // Returns the tab's reader mode controller. May contain nil if the feature is
296 // disabled.
297 @property(nonatomic, readonly) ReaderModeController* readerModeController;
298
299 // Returns a list of FormSuggestionProviders to be queried for suggestions
300 // in order of priority.
301 - (NSArray*)suggestionProviders;
302
303 // Returns a list of FormInputAccessoryViewProviders to be queried for an input
304 // accessory view in order of priority.
305 - (NSArray*)accessoryViewProviders;
306
307 // Sets the favicon on the current NavigationItem.
308 - (void)setFavicon:(const gfx::Image*)image;
309
310 // Saves the current title to the history database.
311 - (void)saveTitleToHistoryDB;
312
313 // Adds the current session entry to this history database.
314 - (void)addCurrentEntryToHistoryDB;
315
316 // Adds any cached entries from |addPageVector_| to the history DB.
317 - (void)commitCachedEntriesToHistoryDB;
318
319 // Returns the OpenInController for this tab.
320 - (OpenInController*)openInController;
321
322 // Handles exportable files if possible.
323 - (void)handleExportableFile:(net::HttpResponseHeaders*)headers;
324
325 // Called after the session history is replaced, useful for updating members
326 // with new sessionID.
327 - (void)didReplaceSessionHistory;
328
329 // Called when the UIApplication's state becomes active.
330 - (void)applicationDidBecomeActive;
331
332 @end
333
334 namespace {
335 class FaviconDriverObserverBridge : public favicon::FaviconDriverObserver { 368 class FaviconDriverObserverBridge : public favicon::FaviconDriverObserver {
336 public: 369 public:
337 FaviconDriverObserverBridge(Tab* owner, 370 FaviconDriverObserverBridge(Tab* owner,
338 favicon::FaviconDriver* favicon_driver); 371 favicon::FaviconDriver* favicon_driver);
339 ~FaviconDriverObserverBridge() override; 372 ~FaviconDriverObserverBridge() override;
340 373
341 // favicon::FaviconDriverObserver implementation. 374 // favicon::FaviconDriverObserver implementation.
342 void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, 375 void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
343 NotificationIconType notification_icon_type, 376 NotificationIconType notification_icon_type,
344 const GURL& icon_url, 377 const GURL& icon_url,
345 bool icon_url_changed, 378 bool icon_url_changed,
346 const gfx::Image& image) override; 379 const gfx::Image& image) override;
347 380
348 private: 381 private:
349 __weak Tab* owner_; 382 Tab* owner_; // Owns this instance.
350 ScopedObserver<favicon::FaviconDriver, favicon::FaviconDriverObserver> 383 ScopedObserver<favicon::FaviconDriver, favicon::FaviconDriverObserver>
351 scoped_observer_; 384 scoped_observer_;
352 DISALLOW_COPY_AND_ASSIGN(FaviconDriverObserverBridge); 385 DISALLOW_COPY_AND_ASSIGN(FaviconDriverObserverBridge);
353 }; 386 };
354 387
355 FaviconDriverObserverBridge::FaviconDriverObserverBridge( 388 FaviconDriverObserverBridge::FaviconDriverObserverBridge(
356 Tab* owner, 389 Tab* owner,
357 favicon::FaviconDriver* favicon_driver) 390 favicon::FaviconDriver* favicon_driver)
358 : owner_(owner), scoped_observer_(this) { 391 : owner_(owner), scoped_observer_(this) {
359 scoped_observer_.Add(favicon_driver); 392 scoped_observer_.Add(favicon_driver);
(...skipping 15 matching lines...) Expand all
375 public: 408 public:
376 explicit TabInfoBarObserver(Tab* owner); 409 explicit TabInfoBarObserver(Tab* owner);
377 ~TabInfoBarObserver() override; 410 ~TabInfoBarObserver() override;
378 void SetShouldObserveInfoBarManager(bool should_observe); 411 void SetShouldObserveInfoBarManager(bool should_observe);
379 void OnInfoBarAdded(infobars::InfoBar* infobar) override; 412 void OnInfoBarAdded(infobars::InfoBar* infobar) override;
380 void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override; 413 void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override;
381 void OnInfoBarReplaced(infobars::InfoBar* old_infobar, 414 void OnInfoBarReplaced(infobars::InfoBar* old_infobar,
382 infobars::InfoBar* new_infobar) override; 415 infobars::InfoBar* new_infobar) override;
383 416
384 private: 417 private:
385 __weak Tab* owner_; 418 Tab* owner_; // Owns this instance;
386 ScopedObserver<infobars::InfoBarManager, TabInfoBarObserver> scoped_observer_; 419 ScopedObserver<infobars::InfoBarManager, TabInfoBarObserver> scoped_observer_;
387 DISALLOW_COPY_AND_ASSIGN(TabInfoBarObserver); 420 DISALLOW_COPY_AND_ASSIGN(TabInfoBarObserver);
388 }; 421 };
389 422
390 TabInfoBarObserver::TabInfoBarObserver(Tab* owner) 423 TabInfoBarObserver::TabInfoBarObserver(Tab* owner)
391 : owner_(owner), scoped_observer_(this) {} 424 : owner_(owner), scoped_observer_(this) {}
392 425
393 TabInfoBarObserver::~TabInfoBarObserver() {} 426 TabInfoBarObserver::~TabInfoBarObserver() {}
394 427
395 void TabInfoBarObserver::SetShouldObserveInfoBarManager(bool should_observe) { 428 void TabInfoBarObserver::SetShouldObserveInfoBarManager(bool should_observe) {
(...skipping 24 matching lines...) Expand all
420 infobars::InfoBar* new_infobar) { 453 infobars::InfoBar* new_infobar) {
421 // Update snapshots after the infobar has been replaced. 454 // Update snapshots after the infobar has been replaced.
422 [owner_ updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; 455 [owner_ updateSnapshotWithOverlay:YES visibleFrameOnly:YES];
423 } 456 }
424 457
425 } // anonymous namespace 458 } // anonymous namespace
426 459
427 @implementation Tab 460 @implementation Tab
428 461
429 @synthesize browserState = browserState_; 462 @synthesize browserState = browserState_;
430 @synthesize tabId = tabId_;
431 @synthesize useGreyImageCache = useGreyImageCache_; 463 @synthesize useGreyImageCache = useGreyImageCache_;
432 @synthesize isPrerenderTab = isPrerenderTab_; 464 @synthesize isPrerenderTab = isPrerenderTab_;
433 @synthesize isLinkLoadingPrerenderTab = isLinkLoadingPrerenderTab_; 465 @synthesize isLinkLoadingPrerenderTab = isLinkLoadingPrerenderTab_;
434 @synthesize isVoiceSearchResultsTab = isVoiceSearchResultsTab_; 466 @synthesize isVoiceSearchResultsTab = isVoiceSearchResultsTab_;
435 @synthesize passwordController = passwordController_;
436 @synthesize overscrollActionsController = overscrollActionsController_;
437 @synthesize readerModeController = readerModeController_;
438 @synthesize overscrollActionsControllerDelegate =
439 overscrollActionsControllerDelegate_;
440 @synthesize passKitDialogProvider = passKitDialogProvider_;
441 @synthesize delegate = delegate_; 467 @synthesize delegate = delegate_;
442 @synthesize dialogDelegate = dialogDelegate_;
443 @synthesize snapshotOverlayProvider = snapshotOverlayProvider_;
444 @synthesize tabSnapshottingDelegate = tabSnapshottingDelegate_; 468 @synthesize tabSnapshottingDelegate = tabSnapshottingDelegate_;
445 @synthesize tabHeadersDelegate = tabHeadersDelegate_; 469 @synthesize tabHeadersDelegate = tabHeadersDelegate_;
446 @synthesize fullScreenControllerDelegate = fullScreenControllerDelegate_;
447 470
448 - (instancetype)initWithWebState:(web::WebState*)webState { 471 - (instancetype)initWithWebState:(web::WebState*)webState {
449 DCHECK(webState); 472 DCHECK(webState);
450 self = [super init]; 473 self = [super init];
451 if (self) { 474 if (self) {
475 propertyReleaser_Tab_.Init(self, [Tab class]);
476
452 // TODO(crbug.com/620465): Tab should only use public API of WebState. 477 // TODO(crbug.com/620465): Tab should only use public API of WebState.
453 // Remove this cast once this is the case. 478 // Remove this cast once this is the case.
454 webStateImpl_ = static_cast<web::WebStateImpl*>(webState); 479 webStateImpl_ = static_cast<web::WebStateImpl*>(webState);
455 browserState_ = 480 browserState_ =
456 ios::ChromeBrowserState::FromBrowserState(webState->GetBrowserState()); 481 ios::ChromeBrowserState::FromBrowserState(webState->GetBrowserState());
482
483 tabHistoryContext_ = base::MakeUnique<TabHistoryContext>();
457 webStateObserver_ = 484 webStateObserver_ =
458 base::MakeUnique<web::WebStateObserverBridge>(webState, self); 485 base::MakeUnique<web::WebStateObserverBridge>(webState, self);
459 486
460 [self updateLastVisitedTimestamp]; 487 [self updateLastVisitedTimestamp];
461 [[self webController] addObserver:self]; 488 [[self webController] addObserver:self];
462 [[self webController] setDelegate:self]; 489 [[self webController] setDelegate:self];
463 490
464 snapshotManager_ = [[SnapshotManager alloc] init]; 491 snapshotManager_.reset([[SnapshotManager alloc] init]);
465 webControllerSnapshotHelper_ = [[WebControllerSnapshotHelper alloc] 492 webControllerSnapshotHelper_.reset([[WebControllerSnapshotHelper alloc]
466 initWithSnapshotManager:snapshotManager_ 493 initWithSnapshotManager:snapshotManager_
467 tab:self]; 494 tab:self]);
468 495
469 [[NSNotificationCenter defaultCenter] 496 [[NSNotificationCenter defaultCenter]
470 addObserver:self 497 addObserver:self
471 selector:@selector(applicationDidBecomeActive) 498 selector:@selector(applicationDidBecomeActive)
472 name:UIApplicationDidBecomeActiveNotification 499 name:UIApplicationDidBecomeActiveNotification
473 object:nil]; 500 object:nil];
474 } 501 }
475 return self; 502 return self;
476 } 503 }
477 504
478 - (void)attachTabHelpers { 505 - (void)attachTabHelpers {
479 tabInfoBarObserver_ = base::MakeUnique<TabInfoBarObserver>(self); 506 tabInfoBarObserver_.reset(new TabInfoBarObserver(self));
480 tabInfoBarObserver_->SetShouldObserveInfoBarManager(true); 507 tabInfoBarObserver_->SetShouldObserveInfoBarManager(true);
481 508
482 if (experimental_flags::IsAutoReloadEnabled()) 509 if (experimental_flags::IsAutoReloadEnabled()) {
483 autoReloadBridge_ = [[AutoReloadBridge alloc] initWithTab:self]; 510 autoReloadBridge_.reset([[AutoReloadBridge alloc] initWithTab:self]);
511 }
484 printObserver_ = base::MakeUnique<PrintObserver>(self.webState); 512 printObserver_ = base::MakeUnique<PrintObserver>(self.webState);
485 513
486 id<PasswordsUiDelegate> passwordsUiDelegate = 514 base::scoped_nsprotocol<id<PasswordsUiDelegate>> passwordsUiDelegate(
487 [[PasswordsUiDelegateImpl alloc] init]; 515 [[PasswordsUiDelegateImpl alloc] init]);
488 passwordController_ = 516 passwordController_.reset([[PasswordController alloc]
489 [[PasswordController alloc] initWithWebState:self.webState 517 initWithWebState:self.webState
490 passwordsUiDelegate:passwordsUiDelegate]; 518 passwordsUiDelegate:passwordsUiDelegate]);
491 password_manager::PasswordGenerationManager* passwordGenerationManager = 519 password_manager::PasswordGenerationManager* passwordGenerationManager =
492 [passwordController_ passwordGenerationManager]; 520 [passwordController_ passwordGenerationManager];
493 autofillController_ = 521 autofillController_.reset([[AutofillController alloc]
494 [[AutofillController alloc] initWithBrowserState:browserState_ 522 initWithBrowserState:browserState_
495 passwordGenerationManager:passwordGenerationManager 523 passwordGenerationManager:passwordGenerationManager
496 webState:self.webState]; 524 webState:self.webState]);
497 suggestionController_ = [[FormSuggestionController alloc] 525 suggestionController_.reset([[FormSuggestionController alloc]
498 initWithWebState:self.webState 526 initWithWebState:self.webState
499 providers:[self suggestionProviders]]; 527 providers:[self suggestionProviders]]);
500 inputAccessoryViewController_ = [[FormInputAccessoryViewController alloc] 528 inputAccessoryViewController_.reset([[FormInputAccessoryViewController alloc]
501 initWithWebState:self.webState 529 initWithWebState:self.webState
502 providers:[self accessoryViewProviders]]; 530 providers:[self accessoryViewProviders]]);
503 531
504 [self setShouldObserveFaviconChanges:YES]; 532 [self setShouldObserveFaviconChanges:YES];
505 533
506 // Create the ReaderModeController immediately so it can register for 534 // Create the ReaderModeController immediately so it can register for
507 // WebState changes. 535 // WebState changes.
508 if (experimental_flags::IsReaderModeEnabled()) { 536 if (experimental_flags::IsReaderModeEnabled()) {
509 readerModeController_ = 537 readerModeController_.reset([[ReaderModeController alloc]
510 [[ReaderModeController alloc] initWithWebState:self.webState 538 initWithWebState:self.webState
511 delegate:self]; 539 delegate:self]);
512 } 540 }
513 } 541 }
514 542
515 - (NSArray*)accessoryViewProviders { 543 - (NSArray*)accessoryViewProviders {
516 NSMutableArray* providers = [NSMutableArray array]; 544 NSMutableArray* providers = [NSMutableArray array];
517 id<FormInputAccessoryViewProvider> provider = 545 id<FormInputAccessoryViewProvider> provider =
518 [passwordController_ accessoryViewProvider]; 546 [passwordController_ accessoryViewProvider];
519 if (provider) 547 if (provider)
520 [providers addObject:provider]; 548 [providers addObject:provider];
521 [providers addObject:[suggestionController_ accessoryViewProvider]]; 549 [providers addObject:[suggestionController_ accessoryViewProvider]];
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 } 581 }
554 582
555 - (id<TabDialogDelegate>)dialogDelegate { 583 - (id<TabDialogDelegate>)dialogDelegate {
556 return dialogDelegate_; 584 return dialogDelegate_;
557 } 585 }
558 586
559 - (BOOL)loadFinished { 587 - (BOOL)loadFinished {
560 return [self.webController loadPhase] == web::PAGE_LOADED; 588 return [self.webController loadPhase] == web::PAGE_LOADED;
561 } 589 }
562 590
591 - (void)setDialogDelegate:(id<TabDialogDelegate>)dialogDelegate {
592 dialogDelegate_.reset(dialogDelegate);
593 }
594
563 - (void)setIsVoiceSearchResultsTab:(BOOL)isVoiceSearchResultsTab { 595 - (void)setIsVoiceSearchResultsTab:(BOOL)isVoiceSearchResultsTab {
564 // There is intentionally no equality check in this setter, as we want the 596 // There is intentionally no equality check in this setter, as we want the
565 // notificaiton to be sent regardless of whether the value has changed. 597 // notificaiton to be sent regardless of whether the value has changed.
566 isVoiceSearchResultsTab_ = isVoiceSearchResultsTab; 598 isVoiceSearchResultsTab_ = isVoiceSearchResultsTab;
567 [parentTabModel_ notifyTabChanged:self]; 599 [parentTabModel_ notifyTabChanged:self];
568 } 600 }
569 601
602 - (PasswordController*)passwordController {
603 return passwordController_.get();
604 }
605
570 - (void)retrieveSnapshot:(void (^)(UIImage*))callback { 606 - (void)retrieveSnapshot:(void (^)(UIImage*))callback {
571 [webControllerSnapshotHelper_ 607 [webControllerSnapshotHelper_
572 retrieveSnapshotForWebController:self.webController 608 retrieveSnapshotForWebController:self.webController
573 sessionID:self.tabId 609 sessionID:self.tabId
574 withOverlays:[self snapshotOverlays] 610 withOverlays:[self snapshotOverlays]
575 callback:callback]; 611 callback:callback];
576 } 612 }
577 613
578 - (const GURL&)url { 614 - (const GURL&)url {
579 // See note in header; this method should be removed. 615 // See note in header; this method should be removed.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 648
613 - (NSString*)urlDisplayString { 649 - (NSString*)urlDisplayString {
614 base::string16 urlText = url_formatter::FormatUrl( 650 base::string16 urlText = url_formatter::FormatUrl(
615 self.url, url_formatter::kFormatUrlOmitNothing, net::UnescapeRule::SPACES, 651 self.url, url_formatter::kFormatUrlOmitNothing, net::UnescapeRule::SPACES,
616 nullptr, nullptr, nullptr); 652 nullptr, nullptr, nullptr);
617 return base::SysUTF16ToNSString(urlText); 653 return base::SysUTF16ToNSString(urlText);
618 } 654 }
619 655
620 - (NSString*)tabId { 656 - (NSString*)tabId {
621 if (tabId_) 657 if (tabId_)
622 return tabId_; 658 return tabId_.get();
623 659
624 DCHECK(self.webState); 660 DCHECK(self.webState);
625 web::SerializableUserDataManager* userDataManager = 661 web::SerializableUserDataManager* userDataManager =
626 web::SerializableUserDataManager::FromWebState(self.webState); 662 web::SerializableUserDataManager::FromWebState(self.webState);
627 NSString* tabId = base::mac::ObjCCast<NSString>( 663 NSString* tabId = base::mac::ObjCCast<NSString>(
628 userDataManager->GetValueForSerializationKey(kTabIDKey)); 664 userDataManager->GetValueForSerializationKey(kTabIDKey));
629 665
630 if (!tabId || ![tabId length]) { 666 if (!tabId || ![tabId length]) {
631 tabId = [[NSUUID UUID] UUIDString]; 667 tabId = [[NSUUID UUID] UUIDString];
632 userDataManager->AddSerializableData(tabId, kTabIDKey); 668 userDataManager->AddSerializableData(tabId, kTabIDKey);
633 } 669 }
634 670
635 tabId_ = [tabId copy]; 671 tabId_.reset([tabId copy]);
636 return tabId_; 672 return tabId_.get();
637 } 673 }
638 674
639 - (web::WebState*)webState { 675 - (web::WebState*)webState {
640 return webStateImpl_; 676 return webStateImpl_;
641 } 677 }
642 678
643 - (void)fetchFavicon { 679 - (void)fetchFavicon {
644 const GURL& url = self.url; 680 const GURL& url = self.url;
645 if (!url.is_valid()) 681 if (!url.is_valid())
646 return; 682 return;
647 683
648 favicon::FaviconDriver* faviconDriver = 684 favicon::FaviconDriver* faviconDriver =
649 favicon::WebFaviconDriver::FromWebState(self.webState); 685 favicon::WebFaviconDriver::FromWebState(self.webState);
650 if (faviconDriver) 686 if (faviconDriver) {
651 faviconDriver->FetchFavicon(url); 687 faviconDriver->FetchFavicon(url);
688 }
652 } 689 }
653 690
654 - (void)setFavicon:(const gfx::Image*)image { 691 - (void)setFavicon:(const gfx::Image*)image {
655 web::NavigationItem* item = [self navigationManager]->GetVisibleItem(); 692 web::NavigationItem* item = [self navigationManager]->GetVisibleItem();
656 if (!item) 693 if (!item)
657 return; 694 return;
658 if (image) { 695 if (image) {
659 item->GetFavicon().image = *image; 696 item->GetFavicon().image = *image;
660 item->GetFavicon().valid = true; 697 item->GetFavicon().valid = true;
661 } 698 }
662 [parentTabModel_ notifyTabChanged:self]; 699 [parentTabModel_ notifyTabChanged:self];
663 } 700 }
664 701
665 - (UIImage*)favicon { 702 - (UIImage*)favicon {
666 DCHECK([self navigationManager]); 703 DCHECK([self navigationManager]);
667 web::NavigationItem* item = [self navigationManager]->GetVisibleItem(); 704 web::NavigationItem* item = [self navigationManager]->GetVisibleItem();
668 if (!item) 705 if (!item)
669 return nil; 706 return nil;
670 const gfx::Image& image = item->GetFavicon().image; 707 const gfx::Image& image = item->GetFavicon().image;
671 if (image.IsEmpty()) 708 if (image.IsEmpty())
672 return nil; 709 return nil;
673 return image.ToUIImage(); 710 return image.ToUIImage();
674 } 711 }
675 712
676 - (UIView*)view { 713 - (UIView*)view {
677 // Record reload of previously-evicted tab. 714 // Record reload of previously-evicted tab.
678 if (![self.webController isViewAlive] && [parentTabModel_ tabUsageRecorder]) 715 if (![self.webController isViewAlive] && [parentTabModel_ tabUsageRecorder]) {
679 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); 716 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self);
717 }
680 return self.webState ? self.webState->GetView() : nil; 718 return self.webState ? self.webState->GetView() : nil;
681 } 719 }
682 720
683 - (UIView*)viewForPrinting { 721 - (UIView*)viewForPrinting {
684 return self.webController.viewForPrinting; 722 return self.webController.viewForPrinting;
685 } 723 }
686 724
687 - (web::NavigationManager*)navigationManager { 725 - (web::NavigationManager*)navigationManager {
688 return self.webState ? self.webState->GetNavigationManager() : nullptr; 726 return self.webState ? self.webState->GetNavigationManager() : nullptr;
689 } 727 }
(...skipping 19 matching lines...) Expand all
709 } 747 }
710 748
711 - (void)didReplaceSessionHistory { 749 - (void)didReplaceSessionHistory {
712 // Replace fullScreenController_ with a new sessionID when the navigation 750 // Replace fullScreenController_ with a new sessionID when the navigation
713 // manager changes. 751 // manager changes.
714 // TODO(crbug.com/661666): Consider just updating sessionID and not replacing 752 // TODO(crbug.com/661666): Consider just updating sessionID and not replacing
715 // |fullScreenController_|. 753 // |fullScreenController_|.
716 if (fullScreenController_) { 754 if (fullScreenController_) {
717 [fullScreenController_ invalidate]; 755 [fullScreenController_ invalidate];
718 [self.webController removeObserver:fullScreenController_]; 756 [self.webController removeObserver:fullScreenController_];
719 fullScreenController_ = [[FullScreenController alloc] 757 fullScreenController_.reset([[FullScreenController alloc]
720 initWithDelegate:fullScreenControllerDelegate_ 758 initWithDelegate:fullScreenControllerDelegate_
721 navigationManager:self.navigationManager 759 navigationManager:self.navigationManager
722 sessionID:self.tabId]; 760 sessionID:self.tabId]);
723 [self.webController addObserver:fullScreenController_]; 761 [self.webController addObserver:fullScreenController_];
724 // If the content of the page was loaded without knowledge of the 762 // If the content of the page was loaded without knowledge of the
725 // toolbar position it will be misplaced under the toolbar instead of 763 // toolbar position it will be misplaced under the toolbar instead of
726 // right below. This happens e.g. in the case of preloading. This is to make 764 // right below. This happens e.g. in the case of preloading. This is to make
727 // sure the content is moved to the right place. 765 // sure the content is moved to the right place.
728 [fullScreenController_ moveContentBelowHeader]; 766 [fullScreenController_ moveContentBelowHeader];
729 } 767 }
730 } 768 }
731 769
732 - (void)setIsLinkLoadingPrerenderTab:(BOOL)isLinkLoadingPrerenderTab { 770 - (void)setIsLinkLoadingPrerenderTab:(BOOL)isLinkLoadingPrerenderTab {
(...skipping 23 matching lines...) Expand all
756 BOOL loadingFinished = self.webController.loadPhase == web::PAGE_LOADED; 794 BOOL loadingFinished = self.webController.loadPhase == web::PAGE_LOADED;
757 if (loadingFinished) 795 if (loadingFinished)
758 [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; 796 [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES];
759 797
760 [[OmniboxGeolocationController sharedInstance] 798 [[OmniboxGeolocationController sharedInstance]
761 finishPageLoadForTab:self 799 finishPageLoadForTab:self
762 loadSuccess:loadingFinished]; 800 loadSuccess:loadingFinished];
763 [self countMainFrameLoad]; 801 [self countMainFrameLoad];
764 } 802 }
765 803
804 - (id<FullScreenControllerDelegate>)fullScreenControllerDelegate {
805 return fullScreenControllerDelegate_.get();
806 }
807
766 - (void)setFullScreenControllerDelegate: 808 - (void)setFullScreenControllerDelegate:
767 (id<FullScreenControllerDelegate>)fullScreenControllerDelegate { 809 (id<FullScreenControllerDelegate>)fullScreenControllerDelegate {
768 if (fullScreenControllerDelegate == fullScreenControllerDelegate_) 810 if (fullScreenControllerDelegate == fullScreenControllerDelegate_) {
769 return; 811 return;
812 }
770 // Lazily create a FullScreenController. 813 // Lazily create a FullScreenController.
771 // The check for fullScreenControllerDelegate is necessary to avoid recreating 814 // The check for fullScreenControllerDelegate is necessary to avoid recreating
772 // a FullScreenController during teardown. 815 // a FullScreenController during teardown.
773 if (!fullScreenController_ && fullScreenControllerDelegate) { 816 if (!fullScreenController_ && fullScreenControllerDelegate) {
774 fullScreenController_ = [[FullScreenController alloc] 817 fullScreenController_.reset([[FullScreenController alloc]
775 initWithDelegate:fullScreenControllerDelegate 818 initWithDelegate:fullScreenControllerDelegate
776 navigationManager:self.navigationManager 819 navigationManager:self.navigationManager
777 sessionID:self.tabId]; 820 sessionID:self.tabId]);
778 [self.webController addObserver:fullScreenController_]; 821 [self.webController addObserver:fullScreenController_];
779 // If the content of the page was loaded without knowledge of the 822 // If the content of the page was loaded without knowledge of the
780 // toolbar position it will be misplaced under the toolbar instead of 823 // toolbar position it will be misplaced under the toolbar instead of
781 // right below. This happens e.g. in the case of preloading. This is to make 824 // right below. This happens e.g. in the case of preloading. This is to make
782 // sure the content is moved to the right place. 825 // sure the content is moved to the right place.
783 [fullScreenController_ moveContentBelowHeader]; 826 [fullScreenController_ moveContentBelowHeader];
784 } 827 }
785 fullScreenControllerDelegate_ = fullScreenControllerDelegate; 828 fullScreenControllerDelegate_.reset(fullScreenControllerDelegate);
829 }
830
831 - (OverscrollActionsController*)overscrollActionsController {
832 return overscrollActionsController_.get();
833 }
834
835 - (id<OverscrollActionsControllerDelegate>)overscrollActionsControllerDelegate {
836 return overscrollActionsControllerDelegate_.get();
786 } 837 }
787 838
788 - (void)setOverscrollActionsControllerDelegate: 839 - (void)setOverscrollActionsControllerDelegate:
789 (id<OverscrollActionsControllerDelegate>) 840 (id<OverscrollActionsControllerDelegate>)
790 overscrollActionsControllerDelegate { 841 overscrollActionsControllerDelegate {
791 if (overscrollActionsControllerDelegate_ == 842 if (overscrollActionsControllerDelegate_ ==
792 overscrollActionsControllerDelegate) { 843 overscrollActionsControllerDelegate)
793 return; 844 return;
794 }
795 845
796 // Lazily create a OverscrollActionsController. 846 // Lazily create a OverscrollActionsController.
797 // The check for overscrollActionsControllerDelegate is necessary to avoid 847 // The check for overscrollActionsControllerDelegate is necessary to avoid
798 // recreating a OverscrollActionsController during teardown. 848 // recreating a OverscrollActionsController during teardown.
799 if (!overscrollActionsController_) { 849 if (!overscrollActionsController_) {
800 overscrollActionsController_ = [[OverscrollActionsController alloc] init]; 850 overscrollActionsController_.reset(
851 [[OverscrollActionsController alloc] init]);
801 [self.webController addObserver:overscrollActionsController_]; 852 [self.webController addObserver:overscrollActionsController_];
802 } 853 }
803 OverscrollStyle style = OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO; 854 OverscrollStyle style = OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO;
804 if (browserState_->IsOffTheRecord()) 855 if (browserState_->IsOffTheRecord()) {
805 style = OverscrollStyle::REGULAR_PAGE_INCOGNITO; 856 style = OverscrollStyle::REGULAR_PAGE_INCOGNITO;
857 }
806 [overscrollActionsController_ setStyle:style]; 858 [overscrollActionsController_ setStyle:style];
807 [overscrollActionsController_ 859 [overscrollActionsController_
808 setDelegate:overscrollActionsControllerDelegate]; 860 setDelegate:overscrollActionsControllerDelegate];
809 overscrollActionsControllerDelegate_ = overscrollActionsControllerDelegate; 861 overscrollActionsControllerDelegate_.reset(
862 overscrollActionsControllerDelegate);
810 } 863 }
811 864
812 - (void)saveTitleToHistoryDB { 865 - (void)saveTitleToHistoryDB {
813 // If incognito, don't update history. 866 // If incognito, don't update history.
814 if (browserState_->IsOffTheRecord()) 867 if (browserState_->IsOffTheRecord())
815 return; 868 return;
816 // Don't update the history if current entry has no title. 869 // Don't update the history if current entry has no title.
817 NSString* title = [self title]; 870 NSString* title = [self title];
818 if (![title length] || 871 if (![title length] ||
819 [title isEqualToString:l10n_util::GetNSString(IDS_DEFAULT_TAB_TITLE)]) { 872 [title isEqualToString:l10n_util::GetNSString(IDS_DEFAULT_TAB_TITLE)])
820 return; 873 return;
821 }
822 874
823 history::HistoryService* historyService = 875 history::HistoryService* historyService =
824 ios::HistoryServiceFactory::GetForBrowserState( 876 ios::HistoryServiceFactory::GetForBrowserState(
825 browserState_, ServiceAccessType::IMPLICIT_ACCESS); 877 browserState_, ServiceAccessType::IMPLICIT_ACCESS);
826 DCHECK(historyService); 878 DCHECK(historyService);
827 historyService->SetPageTitle(self.url, base::SysNSStringToUTF16(title)); 879 historyService->SetPageTitle(self.url, base::SysNSStringToUTF16(title));
828 } 880 }
829 881
830 - (void)addCurrentEntryToHistoryDB { 882 - (void)addCurrentEntryToHistoryDB {
831 DCHECK([self navigationManager]->GetVisibleItem()); 883 DCHECK([self navigationManager]->GetVisibleItem());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 } 929 }
878 930
879 DCHECK(item->GetTimestamp().ToInternalValue() > 0); 931 DCHECK(item->GetTimestamp().ToInternalValue() > 0);
880 if ([self isPrerenderTab]) { 932 if ([self isPrerenderTab]) {
881 // Clicks on content suggestions on the NTP should not contribute to the 933 // Clicks on content suggestions on the NTP should not contribute to the
882 // Most Visited tiles in the NTP. 934 // Most Visited tiles in the NTP.
883 const bool consider_for_ntp_most_visited = 935 const bool consider_for_ntp_most_visited =
884 referrer.url != GURL(kChromeContentSuggestionsReferrer); 936 referrer.url != GURL(kChromeContentSuggestionsReferrer);
885 937
886 history::HistoryAddPageArgs args( 938 history::HistoryAddPageArgs args(
887 url, item->GetTimestamp(), &tabHistoryContext_, item->GetUniqueID(), 939 url, item->GetTimestamp(), tabHistoryContext_.get(),
888 referrer.url, redirects, item->GetTransitionType(), 940 item->GetUniqueID(), referrer.url, redirects, item->GetTransitionType(),
889 history::SOURCE_BROWSED, false, consider_for_ntp_most_visited); 941 history::SOURCE_BROWSED, false, consider_for_ntp_most_visited);
890 addPageVector_.push_back(args); 942 addPageVector_.push_back(args);
891 } else { 943 } else {
892 historyService->AddPage(url, item->GetTimestamp(), &tabHistoryContext_, 944 historyService->AddPage(url, item->GetTimestamp(), tabHistoryContext_.get(),
893 item->GetUniqueID(), referrer.url, redirects, 945 item->GetUniqueID(), referrer.url, redirects,
894 item->GetTransitionType(), history::SOURCE_BROWSED, 946 item->GetTransitionType(), history::SOURCE_BROWSED,
895 false); 947 false);
896 [self saveTitleToHistoryDB]; 948 [self saveTitleToHistoryDB];
897 } 949 }
898 } 950 }
899 951
900 - (void)commitCachedEntriesToHistoryDB { 952 - (void)commitCachedEntriesToHistoryDB {
901 // If OTR, don't update history. 953 // If OTR, don't update history.
902 if (browserState_->IsOffTheRecord()) { 954 if (browserState_->IsOffTheRecord()) {
(...skipping 27 matching lines...) Expand all
930 } 982 }
931 } 983 }
932 984
933 ui::PageTransition transition = params.transition_type; 985 ui::PageTransition transition = params.transition_type;
934 986
935 // Record any explicit, non-redirect navigation as a clobber (as long as it's 987 // Record any explicit, non-redirect navigation as a clobber (as long as it's
936 // in a real tab). 988 // in a real tab).
937 if (!initialNavigation && !isPrerenderTab_ && 989 if (!initialNavigation && !isPrerenderTab_ &&
938 !PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) && 990 !PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) &&
939 (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0) { 991 (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0) {
940 base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); 992 base::RecordAction(UserMetricsAction("MobileTabClobbered"));
941 } 993 }
942 if ([parentTabModel_ tabUsageRecorder]) 994 if ([parentTabModel_ tabUsageRecorder])
943 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); 995 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self);
944 996
945 // Reset |isVoiceSearchResultsTab| since a new page is being navigated to. 997 // Reset |isVoiceSearchResultsTab| since a new page is being navigated to.
946 self.isVoiceSearchResultsTab = NO; 998 self.isVoiceSearchResultsTab = NO;
947 999
948 web::NavigationItem* navigationItem = 1000 web::NavigationItem* navigationItem =
949 [self navigationManager]->GetPendingItem(); 1001 [self navigationManager]->GetPendingItem();
950 1002
951 // TODO(crbug.com/676129): the pending item is not correctly set when the 1003 // TODO(crbug.com/676129): the pending item is not correctly set when the
952 // page is reloading, use the last committed item if pending item is null. 1004 // page is reloading, use the last committed item if pending item is null.
953 // Remove this once tracking bug is fixed. 1005 // Remove this once tracking bug is fixed.
954 if (!navigationItem) 1006 if (!navigationItem)
955 navigationItem = [self navigationManager]->GetLastCommittedItem(); 1007 navigationItem = [self navigationManager]->GetLastCommittedItem();
956 1008
957 [[OmniboxGeolocationController sharedInstance] 1009 [[OmniboxGeolocationController sharedInstance]
958 addLocationToNavigationItem:navigationItem 1010 addLocationToNavigationItem:navigationItem
959 browserState:browserState_]; 1011 browserState:browserState_];
960 } 1012 }
961 1013
962 - (void)loadSessionTab:(const sessions::SessionTab*)sessionTab { 1014 - (void)loadSessionTab:(const sessions::SessionTab*)sessionTab {
963 DCHECK(sessionTab); 1015 DCHECK(sessionTab);
964 [self replaceHistoryWithNavigations:sessionTab->navigations 1016 [self replaceHistoryWithNavigations:sessionTab->navigations
965 currentIndex:sessionTab->current_navigation_index]; 1017 currentIndex:sessionTab->current_navigation_index];
966 } 1018 }
967 1019
968 - (void)webWillReload { 1020 - (void)webWillReload {
969 if ([parentTabModel_ tabUsageRecorder]) 1021 if ([parentTabModel_ tabUsageRecorder]) {
970 [parentTabModel_ tabUsageRecorder]->RecordReload(self); 1022 [parentTabModel_ tabUsageRecorder]->RecordReload(self);
1023 }
971 } 1024 }
972 1025
973 // Halt the tab, which amounts to halting its webController. 1026 // Halt the tab, which amounts to halting its webController.
974 - (void)terminateNetworkActivity { 1027 - (void)terminateNetworkActivity {
975 [self.webController terminateNetworkActivity]; 1028 [self.webController terminateNetworkActivity];
976 } 1029 }
977 1030
978 - (void)webStateDestroyed:(web::WebState*)webState { 1031 - (void)webStateDestroyed:(web::WebState*)webState {
979 DCHECK_EQ(webStateImpl_, webState); 1032 DCHECK_EQ(webStateImpl_, webState);
980 self.fullScreenControllerDelegate = nil; 1033 self.fullScreenControllerDelegate = nil;
981 self.overscrollActionsControllerDelegate = nil; 1034 self.overscrollActionsControllerDelegate = nil;
982 self.passKitDialogProvider = nil; 1035 self.passKitDialogProvider = nil;
983 self.snapshotOverlayProvider = nil; 1036 self.snapshotOverlayProvider = nil;
984 1037
985 [[NSNotificationCenter defaultCenter] removeObserver:self]; 1038 [[NSNotificationCenter defaultCenter] removeObserver:self];
986 1039
987 [passwordController_ detach]; 1040 [passwordController_ detach];
988 passwordController_ = nil; 1041 passwordController_.reset();
989 tabInfoBarObserver_.reset(); 1042 tabInfoBarObserver_.reset();
990 1043
991 faviconDriverObserverBridge_.reset(); 1044 faviconDriverObserverBridge_.reset();
992 [openInController_ detachFromWebController]; 1045 [openInController_ detachFromWebController];
993 openInController_ = nil; 1046 openInController_.reset();
994 [autofillController_ detachFromWebState]; 1047 [autofillController_ detachFromWebState];
995 [suggestionController_ detachFromWebState]; 1048 [suggestionController_ detachFromWebState];
996 if (fullScreenController_) 1049 if (fullScreenController_)
997 [self.webController removeObserver:fullScreenController_]; 1050 [self.webController removeObserver:fullScreenController_];
998 [fullScreenController_ invalidate]; 1051 [fullScreenController_ invalidate];
999 fullScreenController_ = nil; 1052 fullScreenController_.reset();
1000 if (overscrollActionsController_) 1053 if (overscrollActionsController_)
1001 [self.webController removeObserver:overscrollActionsController_]; 1054 [self.webController removeObserver:overscrollActionsController_];
1002 [overscrollActionsController_ invalidate]; 1055 [overscrollActionsController_ invalidate];
1003 overscrollActionsController_ = nil; 1056 overscrollActionsController_.reset();
1004 [readerModeController_ detachFromWebState]; 1057 [readerModeController_ detachFromWebState];
1005 readerModeController_ = nil; 1058 readerModeController_.reset();
1006 1059
1007 // Invalidate any snapshot stored for this session. 1060 // Invalidate any snapshot stored for this session.
1008 DCHECK(self.tabId); 1061 DCHECK(self.tabId);
1009 [snapshotManager_ removeImageWithSessionID:self.tabId]; 1062 [snapshotManager_ removeImageWithSessionID:self.tabId];
1010 1063
1011 // Cancel any queued dialogs. 1064 // Cancel any queued dialogs.
1012 [self.dialogDelegate cancelDialogForTab:self]; 1065 [self.dialogDelegate cancelDialogForTab:self];
1013 1066
1014 webStateObserver_.reset(); 1067 webStateObserver_.reset();
1015 webStateImpl_ = nullptr; 1068 webStateImpl_ = nullptr;
1016 } 1069 }
1017 1070
1018 - (void)dismissModals { 1071 - (void)dismissModals {
1019 [openInController_ disable]; 1072 [openInController_ disable];
1020 [self.webController dismissModals]; 1073 [self.webController dismissModals];
1021 } 1074 }
1022 1075
1023 - (void)setShouldObserveInfoBarManager:(BOOL)shouldObserveInfoBarManager { 1076 - (void)setShouldObserveInfoBarManager:(BOOL)shouldObserveInfoBarManager {
1024 tabInfoBarObserver_->SetShouldObserveInfoBarManager( 1077 tabInfoBarObserver_->SetShouldObserveInfoBarManager(
1025 shouldObserveInfoBarManager); 1078 shouldObserveInfoBarManager);
1026 } 1079 }
1027 1080
1028 - (void)setShouldObserveFaviconChanges:(BOOL)shouldObserveFaviconChanges { 1081 - (void)setShouldObserveFaviconChanges:(BOOL)shouldObserveFaviconChanges {
1029 if (shouldObserveFaviconChanges) { 1082 if (shouldObserveFaviconChanges) {
1030 favicon::FaviconDriver* faviconDriver = 1083 favicon::FaviconDriver* faviconDriver =
1031 favicon::WebFaviconDriver::FromWebState(self.webState); 1084 favicon::WebFaviconDriver::FromWebState(self.webState);
1032 // Some MockWebContents used in tests do not support the FaviconDriver. 1085 // Some MockWebContents used in tests do not support the FaviconDriver.
1033 if (faviconDriver) { 1086 if (faviconDriver) {
1034 faviconDriverObserverBridge_ = 1087 faviconDriverObserverBridge_.reset(
1035 base::MakeUnique<FaviconDriverObserverBridge>(self, faviconDriver); 1088 new FaviconDriverObserverBridge(self, faviconDriver));
1036 } 1089 }
1037 } else { 1090 } else {
1038 faviconDriverObserverBridge_.reset(); 1091 faviconDriverObserverBridge_.reset();
1039 } 1092 }
1040 } 1093 }
1041 1094
1042 - (void)goBack { 1095 - (void)goBack {
1043 if (self.navigationManager) { 1096 if (self.navigationManager) {
1044 DCHECK(self.navigationManager->CanGoBack()); 1097 DCHECK(self.navigationManager->CanGoBack());
1045 base::RecordAction(base::UserMetricsAction("Back")); 1098 base::RecordAction(UserMetricsAction("Back"));
1046 self.navigationManager->GoBack(); 1099 self.navigationManager->GoBack();
1047 } 1100 }
1048 } 1101 }
1049 1102
1050 - (void)goForward { 1103 - (void)goForward {
1051 if (self.navigationManager) { 1104 if (self.navigationManager) {
1052 DCHECK(self.navigationManager->CanGoForward()); 1105 DCHECK(self.navigationManager->CanGoForward());
1053 base::RecordAction(base::UserMetricsAction("Forward")); 1106 base::RecordAction(UserMetricsAction("Forward"));
1054 self.navigationManager->GoForward(); 1107 self.navigationManager->GoForward();
1055 } 1108 }
1056 } 1109 }
1057 1110
1058 - (BOOL)canGoBack { 1111 - (BOOL)canGoBack {
1059 return self.navigationManager && self.navigationManager->CanGoBack(); 1112 return self.navigationManager && self.navigationManager->CanGoBack();
1060 } 1113 }
1061 1114
1062 - (BOOL)canGoForward { 1115 - (BOOL)canGoForward {
1063 return self.navigationManager && self.navigationManager->CanGoForward(); 1116 return self.navigationManager && self.navigationManager->CanGoForward();
1064 } 1117 }
1065 1118
1066 - (void)goToItem:(const web::NavigationItem*)item { 1119 - (void)goToItem:(const web::NavigationItem*)item {
1067 DCHECK(item); 1120 DCHECK(item);
1068 1121
1069 if (self.navigationManager) { 1122 if (self.navigationManager) {
1070 CRWSessionController* sessionController = 1123 CRWSessionController* sessionController =
1071 [self navigationManagerImpl]->GetSessionController(); 1124 [self navigationManagerImpl]->GetSessionController();
1072 NSInteger itemIndex = [sessionController indexOfItem:item]; 1125 NSInteger itemIndex = [sessionController indexOfItem:item];
1073 DCHECK_NE(itemIndex, NSNotFound); 1126 DCHECK_NE(itemIndex, NSNotFound);
1074 self.navigationManager->GoToIndex(itemIndex); 1127 self.navigationManager->GoToIndex(itemIndex);
1075 } 1128 }
1076 } 1129 }
1077 1130
1078 - (BOOL)openExternalURL:(const GURL&)url 1131 - (BOOL)openExternalURL:(const GURL&)url
1079 sourceURL:(const GURL&)sourceURL 1132 sourceURL:(const GURL&)sourceURL
1080 linkClicked:(BOOL)linkClicked { 1133 linkClicked:(BOOL)linkClicked {
1081 if (!externalAppLauncher_) 1134 if (!externalAppLauncher_.get())
1082 externalAppLauncher_ = [[ExternalAppLauncher alloc] init]; 1135 externalAppLauncher_.reset([[ExternalAppLauncher alloc] init]);
1136
1137 // This method may release CRWWebController which may cause a crash
1138 // (crbug.com/393949).
1139 [[self.webController retain] autorelease];
1083 1140
1084 // Make a local url copy for possible modification. 1141 // Make a local url copy for possible modification.
1085 GURL finalURL = url; 1142 GURL finalURL = url;
1086 1143
1087 // Check if it's a direct FIDO U2F x-callback call. If so, do not open it, to 1144 // Check if it's a direct FIDO U2F x-callback call. If so, do not open it, to
1088 // prevent pages from spoofing requests with different origins. 1145 // prevent pages from spoofing requests with different origins.
1089 if (finalURL.SchemeIs("u2f-x-callback")) 1146 if (finalURL.SchemeIs("u2f-x-callback")) {
1090 return NO; 1147 return NO;
1148 }
1091 1149
1092 // Check if it's a FIDO U2F call. 1150 // Check if it's a FIDO U2F call.
1093 if (finalURL.SchemeIs("u2f")) { 1151 if (finalURL.SchemeIs("u2f")) {
1094 // Create U2FController object lazily. 1152 // Create U2FController object lazily.
1095 if (!U2FController_) 1153 if (!U2FController_) {
1096 U2FController_ = [[U2FController alloc] init]; 1154 U2FController_.reset([[U2FController alloc] init]);
1155 }
1097 1156
1098 DCHECK([self navigationManager]); 1157 DCHECK([self navigationManager]);
1099 GURL origin = 1158 GURL origin =
1100 [self navigationManager]->GetLastCommittedItem()->GetURL().GetOrigin(); 1159 [self navigationManager]->GetLastCommittedItem()->GetURL().GetOrigin();
1101 1160
1102 // Compose u2f-x-callback URL and update urlToOpen. 1161 // Compose u2f-x-callback URL and update urlToOpen.
1103 finalURL = [U2FController_ XCallbackFromRequestURL:finalURL 1162 finalURL = [U2FController_ XCallbackFromRequestURL:finalURL
1104 originURL:origin 1163 originURL:origin
1105 tabURL:self.url 1164 tabURL:self.url
1106 tabID:self.tabId]; 1165 tabID:self.tabId];
1107 1166
1108 if (!finalURL.is_valid()) 1167 if (!finalURL.is_valid()) {
1109 return NO; 1168 return NO;
1169 }
1110 } 1170 }
1111 1171
1112 if ([externalAppLauncher_ openURL:finalURL linkClicked:linkClicked]) { 1172 if ([externalAppLauncher_ openURL:finalURL linkClicked:linkClicked]) {
1113 // Clears pending navigation history after successfully launching the 1173 // Clears pending navigation history after successfully launching the
1114 // external app. 1174 // external app.
1115 DCHECK([self navigationManager]); 1175 DCHECK([self navigationManager]);
1116 [self navigationManager]->DiscardNonCommittedItems(); 1176 [self navigationManager]->DiscardNonCommittedItems();
1117 // Ensure the UI reflects the current entry, not the just-discarded pending 1177 // Ensure the UI reflects the current entry, not the just-discarded pending
1118 // entry. 1178 // entry.
1119 [parentTabModel_ notifyTabChanged:self]; 1179 [parentTabModel_ notifyTabChanged:self];
1120 1180
1121 if (sourceURL.is_valid()) { 1181 if (sourceURL.is_valid()) {
1122 ReadingListModel* model = 1182 ReadingListModel* model =
1123 ReadingListModelFactory::GetForBrowserState(browserState_); 1183 ReadingListModelFactory::GetForBrowserState(browserState_);
1124 if (model && model->loaded()) 1184 if (model && model->loaded()) {
1125 model->SetReadStatus(sourceURL, true); 1185 model->SetReadStatus(sourceURL, true);
1186 }
1126 } 1187 }
1127 1188
1128 return YES; 1189 return YES;
1129 } 1190 }
1130 return NO; 1191 return NO;
1131 } 1192 }
1132 1193
1133 - (void)webState:(web::WebState*)webState 1194 - (void)webState:(web::WebState*)webState
1134 didFinishNavigation:(web::NavigationContext*)navigation { 1195 didFinishNavigation:(web::NavigationContext*)navigation {
1135 if (navigation->IsSameDocument()) { 1196 if (navigation->IsSameDocument()) {
1136 // Fetch the favicon for the new URL.
1137 auto* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState); 1197 auto* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState);
1138 if (faviconDriver) 1198 if (faviconDriver) {
1199 // Fetch the favicon for the new URL.
1139 faviconDriver->FetchFavicon(navigation->GetUrl()); 1200 faviconDriver->FetchFavicon(navigation->GetUrl());
1201 }
1140 } 1202 }
1141 1203
1142 if (!navigation->IsErrorPage()) { 1204 if (!navigation->IsErrorPage()) {
1143 [self addCurrentEntryToHistoryDB]; 1205 [self addCurrentEntryToHistoryDB];
1144 [self countMainFrameLoad]; 1206 [self countMainFrameLoad];
1145 } 1207 }
1146 1208
1147 [parentTabModel_ notifyTabChanged:self]; 1209 [parentTabModel_ notifyTabChanged:self];
1148 } 1210 }
1149 1211
(...skipping 10 matching lines...) Expand all
1160 break; 1222 break;
1161 case UIInterfaceOrientationUnknown: 1223 case UIInterfaceOrientationUnknown:
1162 // TODO(crbug.com/228832): Convert from a boolean histogram to an 1224 // TODO(crbug.com/228832): Convert from a boolean histogram to an
1163 // enumerated histogram and log this case as well. 1225 // enumerated histogram and log this case as well.
1164 break; 1226 break;
1165 } 1227 }
1166 } 1228 }
1167 1229
1168 - (OpenInController*)openInController { 1230 - (OpenInController*)openInController {
1169 if (!openInController_) { 1231 if (!openInController_) {
1170 openInController_ = [[OpenInController alloc] 1232 openInController_.reset([[OpenInController alloc]
1171 initWithRequestContext:browserState_->GetRequestContext() 1233 initWithRequestContext:browserState_->GetRequestContext()
1172 webController:self.webController]; 1234 webController:self.webController]);
1173 } 1235 }
1174 return openInController_; 1236 return openInController_.get();
1175 } 1237 }
1176 1238
1177 - (id<CRWNativeContent>)controllerForUnhandledContentAtURL:(const GURL&)url { 1239 - (id<CRWNativeContent>)controllerForUnhandledContentAtURL:(const GURL&)url {
1178 // Shows download manager UI for unhandled content. 1240 // Shows download manager UI for unhandled content.
1179 DownloadManagerController* downloadController = 1241 DownloadManagerController* downloadController =
1180 [[DownloadManagerController alloc] initWithWebState:self.webState 1242 [[[DownloadManagerController alloc] initWithWebState:self.webState
1181 downloadURL:url]; 1243 downloadURL:url] autorelease];
1182 [downloadController start]; 1244 [downloadController start];
1183 return downloadController; 1245 return downloadController;
1184 } 1246 }
1185 1247
1186 - (void)handleExportableFile:(net::HttpResponseHeaders*)headers { 1248 - (void)handleExportableFile:(net::HttpResponseHeaders*)headers {
1187 // Only "application/pdf" is supported for now. 1249 // Only "application/pdf" is supported for now.
1188 if (self.webState->GetContentsMimeType() != "application/pdf") 1250 if (self.webState->GetContentsMimeType() != "application/pdf")
1189 return; 1251 return;
1190 1252
1191 [[NSNotificationCenter defaultCenter] 1253 [[NSNotificationCenter defaultCenter]
(...skipping 12 matching lines...) Expand all
1204 "", // referrer-charset 1266 "", // referrer-charset
1205 "", // suggested-name 1267 "", // suggested-name
1206 "application/pdf", // mime-type 1268 "application/pdf", // mime-type
1207 defaultFilename); 1269 defaultFilename);
1208 [[self openInController] 1270 [[self openInController]
1209 enableWithDocumentURL:self.url 1271 enableWithDocumentURL:self.url
1210 suggestedFilename:base::SysUTF16ToNSString(filename)]; 1272 suggestedFilename:base::SysUTF16ToNSString(filename)];
1211 } 1273 }
1212 1274
1213 - (void)countMainFrameLoad { 1275 - (void)countMainFrameLoad {
1214 if ([self isPrerenderTab] || [self url].SchemeIs(kChromeUIScheme)) 1276 if ([self isPrerenderTab] || [self url].SchemeIs(kChromeUIScheme)) {
1215 return; 1277 return;
1216 base::RecordAction(base::UserMetricsAction("MobilePageLoaded")); 1278 }
1279 base::RecordAction(UserMetricsAction("MobilePageLoaded"));
1217 } 1280 }
1218 1281
1219 - (void)applicationDidBecomeActive { 1282 - (void)applicationDidBecomeActive {
1220 if (!requireReloadAfterBecomingActive_) 1283 if (requireReloadAfterBecomingActive_) {
1221 return; 1284 if (visible_) {
1222 if (visible_) { 1285 self.navigationManager->Reload(web::ReloadType::NORMAL,
1223 self.navigationManager->Reload(web::ReloadType::NORMAL, 1286 false /* check_for_repost */);
1224 false /* check_for_repost */); 1287 } else {
1225 } else { 1288 [self.webController requirePageReload];
1226 [self.webController requirePageReload]; 1289 }
1290 requireReloadAfterBecomingActive_ = NO;
1227 } 1291 }
1228 requireReloadAfterBecomingActive_ = NO;
1229 } 1292 }
1230 1293
1231 #pragma mark - 1294 #pragma mark -
1232 #pragma mark FindInPageControllerDelegate 1295 #pragma mark FindInPageControllerDelegate
1233 1296
1234 - (void)willAdjustScrollPosition { 1297 - (void)willAdjustScrollPosition {
1235 // Skip the next attempt to correct the scroll offset for the toolbar height. 1298 // Skip the next attempt to correct the scroll offset for the toolbar height.
1236 // Used when programatically scrolling down the y offset. 1299 // Used when programatically scrolling down the y offset.
1237 [fullScreenController_ shouldSkipNextScrollOffsetForHeader]; 1300 [fullScreenController_ shouldSkipNextScrollOffsetForHeader];
1238 } 1301 }
1239 1302
1240 #pragma mark - 1303 #pragma mark -
1241 #pragma mark FullScreen 1304 #pragma mark FullScreen
1242 1305
1243 - (void)updateFullscreenWithToolbarVisible:(BOOL)visible { 1306 - (void)updateFullscreenWithToolbarVisible:(BOOL)visible {
1244 [fullScreenController_ moveHeaderToRestingPosition:visible]; 1307 [fullScreenController_ moveHeaderToRestingPosition:visible];
1245 } 1308 }
1246 1309
1247 #pragma mark - 1310 #pragma mark -
1248 #pragma mark Reader mode 1311 #pragma mark Reader mode
1249 1312
1250 - (UIView*)superviewForReaderModePanel { 1313 - (UIView*)superviewForReaderModePanel {
1251 return self.view; 1314 return self.view;
1252 } 1315 }
1253 1316
1317 - (ReaderModeController*)readerModeController {
1318 return readerModeController_.get();
1319 }
1320
1254 - (BOOL)canSwitchToReaderMode { 1321 - (BOOL)canSwitchToReaderMode {
1255 // Only if the page is loaded and the page passes suitability checks. 1322 // Only if the page is loaded and the page passes suitability checks.
1256 ReaderModeController* controller = self.readerModeController; 1323 ReaderModeController* controller = self.readerModeController;
1257 return controller && controller.checker->CanSwitchToReaderMode(); 1324 return controller && controller.checker->CanSwitchToReaderMode();
1258 } 1325 }
1259 1326
1260 - (void)switchToReaderMode { 1327 - (void)switchToReaderMode {
1261 DCHECK(self.view); 1328 DCHECK(self.view);
1262 [self.readerModeController switchToReaderMode]; 1329 [self.readerModeController switchToReaderMode];
1263 } 1330 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 params.user_agent_override_option = 1388 params.user_agent_override_option =
1322 web::NavigationManager::UserAgentOverrideOption::MOBILE; 1389 web::NavigationManager::UserAgentOverrideOption::MOBILE;
1323 break; 1390 break;
1324 case web::UserAgentType::NONE: 1391 case web::UserAgentType::NONE:
1325 NOTREACHED(); 1392 NOTREACHED();
1326 } 1393 }
1327 1394
1328 navigationManager->LoadURLWithParams(params); 1395 navigationManager->LoadURLWithParams(params);
1329 } 1396 }
1330 1397
1398 - (id<SnapshotOverlayProvider>)snapshotOverlayProvider {
1399 return snapshotOverlayProvider_.get();
1400 }
1401
1402 - (void)setSnapshotOverlayProvider:
1403 (id<SnapshotOverlayProvider>)snapshotOverlayProvider {
1404 snapshotOverlayProvider_.reset(snapshotOverlayProvider);
1405 }
1406
1331 - (void)evaluateU2FResultFromURL:(const GURL&)URL { 1407 - (void)evaluateU2FResultFromURL:(const GURL&)URL {
1332 DCHECK(U2FController_); 1408 DCHECK(U2FController_);
1333 [U2FController_ evaluateU2FResultFromU2FURL:URL webState:self.webState]; 1409 [U2FController_ evaluateU2FResultFromU2FURL:URL webState:self.webState];
1334 } 1410 }
1335 1411
1336 #pragma mark - CRWWebControllerObserver protocol methods. 1412 #pragma mark - CRWWebControllerObserver protocol methods.
1337 1413
1338 - (void)webControllerWillClose:(CRWWebController*)webController { 1414 - (void)webControllerWillClose:(CRWWebController*)webController {
1339 DCHECK_EQ(webController, [self webController]); 1415 DCHECK_EQ(webController, [self webController]);
1340 [[self webController] removeObserver:self]; 1416 [[self webController] removeObserver:self];
(...skipping 20 matching lines...) Expand all
1361 BOOL isUserNavigationEvent = 1437 BOOL isUserNavigationEvent =
1362 (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0; 1438 (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0;
1363 // Check for link-follow clobbers. These are changes where there is no 1439 // Check for link-follow clobbers. These are changes where there is no
1364 // pending entry (since that means the change wasn't caused by this class), 1440 // pending entry (since that means the change wasn't caused by this class),
1365 // and where the URL changes (to avoid counting page resurrection). 1441 // and where the URL changes (to avoid counting page resurrection).
1366 // TODO(crbug.com/546401): Consider moving this into NavigationManager, or 1442 // TODO(crbug.com/546401): Consider moving this into NavigationManager, or
1367 // into a NavigationManager observer callback, so it doesn't need to be 1443 // into a NavigationManager observer callback, so it doesn't need to be
1368 // checked in several places. 1444 // checked in several places.
1369 if (isUserNavigationEvent && !isPrerenderTab_ && 1445 if (isUserNavigationEvent && !isPrerenderTab_ &&
1370 ![self navigationManager]->GetPendingItem() && url != self.url) { 1446 ![self navigationManager]->GetPendingItem() && url != self.url) {
1371 base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); 1447 base::RecordAction(UserMetricsAction("MobileTabClobbered"));
1372 if ([parentTabModel_ tabUsageRecorder]) 1448 if ([parentTabModel_ tabUsageRecorder])
1373 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); 1449 [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self);
1374 } 1450 }
1375 if (![self navigationManager]->GetPendingItem()) { 1451 if (![self navigationManager]->GetPendingItem()) {
1376 // Reset |isVoiceSearchResultsTab| since a new page is being navigated to. 1452 // Reset |isVoiceSearchResultsTab| since a new page is being navigated to.
1377 self.isVoiceSearchResultsTab = NO; 1453 self.isVoiceSearchResultsTab = NO;
1378 } 1454 }
1379 } 1455 }
1380 1456
1381 - (void)webState:(web::WebState*)webState 1457 - (void)webState:(web::WebState*)webState
(...skipping 18 matching lines...) Expand all
1400 [autoReloadBridge_ loadStartedForURL:lastCommittedURL]; 1476 [autoReloadBridge_ loadStartedForURL:lastCommittedURL];
1401 1477
1402 if (parentTabModel_) { 1478 if (parentTabModel_) {
1403 [[NSNotificationCenter defaultCenter] 1479 [[NSNotificationCenter defaultCenter]
1404 postNotificationName:kTabModelTabWillStartLoadingNotification 1480 postNotificationName:kTabModelTabWillStartLoadingNotification
1405 object:parentTabModel_ 1481 object:parentTabModel_
1406 userInfo:@{kTabModelTabKey : self}]; 1482 userInfo:@{kTabModelTabKey : self}];
1407 } 1483 }
1408 favicon::FaviconDriver* faviconDriver = 1484 favicon::FaviconDriver* faviconDriver =
1409 favicon::WebFaviconDriver::FromWebState(webState); 1485 favicon::WebFaviconDriver::FromWebState(webState);
1410 if (faviconDriver) 1486 if (faviconDriver) {
1411 faviconDriver->FetchFavicon(lastCommittedURL); 1487 faviconDriver->FetchFavicon(lastCommittedURL);
1488 }
1412 [parentTabModel_ notifyTabChanged:self]; 1489 [parentTabModel_ notifyTabChanged:self];
1413 if (parentTabModel_) { 1490 if (parentTabModel_) {
1414 [[NSNotificationCenter defaultCenter] 1491 [[NSNotificationCenter defaultCenter]
1415 postNotificationName:kTabModelTabDidStartLoadingNotification 1492 postNotificationName:kTabModelTabDidStartLoadingNotification
1416 object:parentTabModel_ 1493 object:parentTabModel_
1417 userInfo:@{kTabModelTabKey : self}]; 1494 userInfo:@{kTabModelTabKey : self}];
1418 } 1495 }
1419 1496
1420 web::NavigationItem* previousItem = nullptr; 1497 web::NavigationItem* previousItem = nullptr;
1421 if (details.previous_item_index >= 0) { 1498 if (details.previous_item_index >= 0) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1454 [self navigationManager]->GetLastCommittedItem(); 1531 [self navigationManager]->GetLastCommittedItem();
1455 if (lastCommittedItem) { 1532 if (lastCommittedItem) {
1456 wasPost = lastCommittedItem->HasPostData(); 1533 wasPost = lastCommittedItem->HasPostData();
1457 lastCommittedURL = lastCommittedItem->GetVirtualURL(); 1534 lastCommittedURL = lastCommittedItem->GetVirtualURL();
1458 } 1535 }
1459 if (loadSuccess) 1536 if (loadSuccess)
1460 [autoReloadBridge_ loadFinishedForURL:lastCommittedURL wasPost:wasPost]; 1537 [autoReloadBridge_ loadFinishedForURL:lastCommittedURL wasPost:wasPost];
1461 else 1538 else
1462 [autoReloadBridge_ loadFailedForURL:lastCommittedURL wasPost:wasPost]; 1539 [autoReloadBridge_ loadFailedForURL:lastCommittedURL wasPost:wasPost];
1463 [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:YES]; 1540 [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:YES];
1464 if (!loadSuccess) 1541 if (!loadSuccess) {
1465 [fullScreenController_ disableFullScreen]; 1542 [fullScreenController_ disableFullScreen];
1543 }
1466 [self recordInterfaceOrientation]; 1544 [self recordInterfaceOrientation];
1467 navigation_metrics::RecordMainFrameNavigation( 1545 navigation_metrics::RecordMainFrameNavigation(
1468 lastCommittedURL, true, self.browserState->IsOffTheRecord()); 1546 lastCommittedURL, true, self.browserState->IsOffTheRecord());
1469 1547
1470 if (loadSuccess) { 1548 if (loadSuccess) {
1471 scoped_refptr<net::HttpResponseHeaders> headers = 1549 scoped_refptr<net::HttpResponseHeaders> headers =
1472 webStateImpl_->GetHttpResponseHeaders(); 1550 webStateImpl_->GetHttpResponseHeaders();
1473 [self handleExportableFile:headers.get()]; 1551 [self handleExportableFile:headers.get()];
1474 } 1552 }
1475 1553
1476 [parentTabModel_ notifyTabChanged:self]; 1554 [parentTabModel_ notifyTabChanged:self];
1477 1555
1478 if (parentTabModel_) { 1556 if (parentTabModel_) {
1479 if ([parentTabModel_ tabUsageRecorder]) 1557 if ([parentTabModel_ tabUsageRecorder])
1480 [parentTabModel_ tabUsageRecorder]->RecordPageLoadDone(self, loadSuccess); 1558 [parentTabModel_ tabUsageRecorder]->RecordPageLoadDone(self, loadSuccess);
1481 [[NSNotificationCenter defaultCenter] 1559 [[NSNotificationCenter defaultCenter]
1482 postNotificationName:kTabModelTabDidFinishLoadingNotification 1560 postNotificationName:kTabModelTabDidFinishLoadingNotification
1483 object:parentTabModel_ 1561 object:parentTabModel_
1484 userInfo:[NSDictionary 1562 userInfo:[NSDictionary
1485 dictionaryWithObjectsAndKeys: 1563 dictionaryWithObjectsAndKeys:
1486 self, kTabModelTabKey, 1564 self, kTabModelTabKey,
1487 [NSNumber numberWithBool:loadSuccess], 1565 [NSNumber numberWithBool:loadSuccess],
1488 kTabModelPageLoadSuccess, nil]]; 1566 kTabModelPageLoadSuccess, nil]];
1489 } 1567 }
1490 [[OmniboxGeolocationController sharedInstance] 1568 [[OmniboxGeolocationController sharedInstance]
1491 finishPageLoadForTab:self 1569 finishPageLoadForTab:self
1492 loadSuccess:loadSuccess]; 1570 loadSuccess:loadSuccess];
1493 1571
1494 if (loadSuccess) 1572 if (loadSuccess) {
1495 [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; 1573 [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES];
1574 }
1496 [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:NO]; 1575 [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:NO];
1497 } 1576 }
1498 1577
1499 - (void)webState:(web::WebState*)webState 1578 - (void)webState:(web::WebState*)webState
1500 didChangeLoadingProgress:(double)progress { 1579 didChangeLoadingProgress:(double)progress {
1501 // TODO(crbug.com/546406): It is probably possible to do something smarter, 1580 // TODO(crbug.com/546406): It is probably possible to do something smarter,
1502 // but the fact that this is not always sent will have to be taken into 1581 // but the fact that this is not always sent will have to be taken into
1503 // account. 1582 // account.
1504 [parentTabModel_ notifyTabChanged:self]; 1583 [parentTabModel_ notifyTabChanged:self];
1505 } 1584 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 linkClicked:(BOOL)linkClicked { 1643 linkClicked:(BOOL)linkClicked {
1565 // chrome:// URLs are only allowed if the mainDocumentURL is also a chrome:// 1644 // chrome:// URLs are only allowed if the mainDocumentURL is also a chrome://
1566 // URL. 1645 // URL.
1567 if (url.SchemeIs(kChromeUIScheme) && 1646 if (url.SchemeIs(kChromeUIScheme) &&
1568 !mainDocumentURL.SchemeIs(kChromeUIScheme)) { 1647 !mainDocumentURL.SchemeIs(kChromeUIScheme)) {
1569 return NO; 1648 return NO;
1570 } 1649 }
1571 1650
1572 // Always allow frame loads. 1651 // Always allow frame loads.
1573 BOOL isFrameLoad = (url != mainDocumentURL); 1652 BOOL isFrameLoad = (url != mainDocumentURL);
1574 if (isFrameLoad) 1653 if (isFrameLoad) {
1575 return YES; 1654 return YES;
1655 }
1576 1656
1577 // TODO(crbug.com/546402): If this turns out to be useful, find a less hacky 1657 // TODO(crbug.com/546402): If this turns out to be useful, find a less hacky
1578 // hook point to send this from. 1658 // hook point to send this from.
1579 NSString* urlString = base::SysUTF8ToNSString(url.spec()); 1659 NSString* urlString = base::SysUTF8ToNSString(url.spec());
1580 if ([urlString length]) { 1660 if ([urlString length]) {
1581 [[NSNotificationCenter defaultCenter] 1661 [[NSNotificationCenter defaultCenter]
1582 postNotificationName:kTabUrlMayStartLoadingNotificationForCrashReporting 1662 postNotificationName:kTabUrlMayStartLoadingNotificationForCrashReporting
1583 object:self 1663 object:self
1584 userInfo:[NSDictionary dictionaryWithObject:urlString 1664 userInfo:[NSDictionary dictionaryWithObject:urlString
1585 forKey:kTabUrlKey]]; 1665 forKey:kTabUrlKey]];
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 } 1774 }
1695 UMA_HISTOGRAM_ENUMERATION( 1775 UMA_HISTOGRAM_ENUMERATION(
1696 kRendererTerminationStateHistogram, static_cast<int>(tab_state), 1776 kRendererTerminationStateHistogram, static_cast<int>(tab_state),
1697 static_cast<int>( 1777 static_cast<int>(
1698 RendererTerminationTabState::TERMINATION_TAB_STATE_COUNT)); 1778 RendererTerminationTabState::TERMINATION_TAB_STATE_COUNT));
1699 if ([parentTabModel_ tabUsageRecorder]) 1779 if ([parentTabModel_ tabUsageRecorder])
1700 [parentTabModel_ tabUsageRecorder]->RendererTerminated(self, visible_); 1780 [parentTabModel_ tabUsageRecorder]->RendererTerminated(self, visible_);
1701 } 1781 }
1702 1782
1703 if (visible_) { 1783 if (visible_) {
1704 if (!applicationIsNotActive) 1784 if (!applicationIsNotActive) {
1705 [fullScreenController_ disableFullScreen]; 1785 [fullScreenController_ disableFullScreen];
1786 }
1706 } else { 1787 } else {
1707 [self.webController requirePageReload]; 1788 [self.webController requirePageReload];
1708 } 1789 }
1709 // Returning to the app (after the renderer crashed in the background) and 1790 // Returning to the app (after the renderer crashed in the background) and
1710 // having the page reload is much less confusing for the user. 1791 // having the page reload is much less confusing for the user.
1711 // Note: Given that the tab is visible, calling |requirePageReload| will not 1792 // Note: Given that the tab is visible, calling |requirePageReload| will not
1712 // work when the app becomes active because there is nothing to trigger 1793 // work when the app becomes active because there is nothing to trigger
1713 // a view redisplay in that scenario. 1794 // a view redisplay in that scenario.
1714 requireReloadAfterBecomingActive_ = visible_ && applicationIsNotActive; 1795 requireReloadAfterBecomingActive_ = visible_ && applicationIsNotActive;
1715 [self.dialogDelegate cancelDialogForTab:self]; 1796 [self.dialogDelegate cancelDialogForTab:self];
(...skipping 21 matching lines...) Expand all
1737 if (isPrerenderTab_) { 1818 if (isPrerenderTab_) {
1738 [delegate_ discardPrerender]; 1819 [delegate_ discardPrerender];
1739 return; 1820 return;
1740 } 1821 }
1741 if (self != [parentTabModel_ currentTab]) 1822 if (self != [parentTabModel_ currentTab])
1742 return; 1823 return;
1743 1824
1744 signin_metrics::LogAccountReconcilorStateOnGaiaResponse( 1825 signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
1745 ios::AccountReconcilorFactory::GetForBrowserState(browserState_) 1826 ios::AccountReconcilorFactory::GetForBrowserState(browserState_)
1746 ->GetState()); 1827 ->GetState());
1747 GenericChromeCommand* command = 1828 base::scoped_nsobject<GenericChromeCommand> command(
1748 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ACCOUNTS_SETTINGS]; 1829 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ACCOUNTS_SETTINGS]);
1749 [self.view chromeExecuteCommand:command]; 1830 [self.view chromeExecuteCommand:command];
1750 } 1831 }
1751 1832
1752 - (void)onAddAccount { 1833 - (void)onAddAccount {
1753 if (isPrerenderTab_) { 1834 if (isPrerenderTab_) {
1754 [delegate_ discardPrerender]; 1835 [delegate_ discardPrerender];
1755 return; 1836 return;
1756 } 1837 }
1757 if (self != [parentTabModel_ currentTab]) 1838 if (self != [parentTabModel_ currentTab])
1758 return; 1839 return;
1759 1840
1760 signin_metrics::LogAccountReconcilorStateOnGaiaResponse( 1841 signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
1761 ios::AccountReconcilorFactory::GetForBrowserState(browserState_) 1842 ios::AccountReconcilorFactory::GetForBrowserState(browserState_)
1762 ->GetState()); 1843 ->GetState());
1763 GenericChromeCommand* command = 1844 base::scoped_nsobject<GenericChromeCommand> command(
1764 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ADD_ACCOUNT]; 1845 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ADD_ACCOUNT]);
1765 [self.view chromeExecuteCommand:command]; 1846 [self.view chromeExecuteCommand:command];
1766 } 1847 }
1767 1848
1768 - (void)onGoIncognito:(const GURL&)url { 1849 - (void)onGoIncognito:(const GURL&)url {
1769 if (isPrerenderTab_) { 1850 if (isPrerenderTab_) {
1770 [delegate_ discardPrerender]; 1851 [delegate_ discardPrerender];
1771 return; 1852 return;
1772 } 1853 }
1773 if (self != [parentTabModel_ currentTab]) 1854 if (self != [parentTabModel_ currentTab])
1774 return; 1855 return;
1775 1856
1776 // The user taps on go incognito from the mobile U-turn webpage (the web page 1857 // The user taps on go incognito from the mobile U-turn webpage (the web page
1777 // that displays all users accounts available in the content area). As the 1858 // that displays all users accounts available in the content area). As the
1778 // user chooses to go to incognito, the mobile U-turn page is no longer 1859 // user chooses to go to incognito, the mobile U-turn page is no longer
1779 // neeeded. The current solution is to go back in history. This has the 1860 // neeeded. The current solution is to go back in history. This has the
1780 // advantage of keeping the current browsing session and give a good user 1861 // advantage of keeping the current browsing session and give a good user
1781 // experience when the user comes back from incognito. 1862 // experience when the user comes back from incognito.
1782 [self goBack]; 1863 [self goBack];
1783 1864
1784 if (url.is_valid()) { 1865 if (url.is_valid()) {
1785 OpenUrlCommand* command = [[OpenUrlCommand alloc] 1866 base::scoped_nsobject<OpenUrlCommand> command([[OpenUrlCommand alloc]
1786 initWithURL:url 1867 initWithURL:url
1787 referrer:web::Referrer() // Strip referrer when switching modes. 1868 referrer:web::Referrer() // Strip referrer when switching modes.
1788 inIncognito:YES 1869 inIncognito:YES
1789 inBackground:NO 1870 inBackground:NO
1790 appendTo:kLastTab]; 1871 appendTo:kLastTab]);
1791 [self.view chromeExecuteCommand:command]; 1872 [self.view chromeExecuteCommand:command];
1792 } else { 1873 } else {
1793 GenericChromeCommand* command = 1874 base::scoped_nsobject<GenericChromeCommand> chromeCommand(
1794 [[GenericChromeCommand alloc] initWithTag:IDC_NEW_INCOGNITO_TAB]; 1875 [[GenericChromeCommand alloc] initWithTag:IDC_NEW_INCOGNITO_TAB]);
1795 [self.view chromeExecuteCommand:command]; 1876 [self.view chromeExecuteCommand:chromeCommand];
1796 } 1877 }
1797 } 1878 }
1798 1879
1799 - (NativeAppNavigationController*)nativeAppNavigationController { 1880 - (NativeAppNavigationController*)nativeAppNavigationController {
1800 // TODO(crbug.com/711511): This call should eventually be eliminated. 1881 // TODO(crbug.com/711511): This call should eventually be eliminated.
1801 return nil; 1882 return nil;
1802 } 1883 }
1803 1884
1885 - (id<PassKitDialogProvider>)passKitDialogProvider {
1886 return passKitDialogProvider_.get();
1887 }
1888
1889 - (void)setPassKitDialogProvider:(id<PassKitDialogProvider>)provider {
1890 passKitDialogProvider_.reset(provider);
1891 }
1892
1804 - (void)wasShown { 1893 - (void)wasShown {
1805 visible_ = YES; 1894 visible_ = YES;
1806 [self updateFullscreenWithToolbarVisible:YES]; 1895 [self updateFullscreenWithToolbarVisible:YES];
1807 [self.webController wasShown]; 1896 [self.webController wasShown];
1808 [inputAccessoryViewController_ wasShown]; 1897 [inputAccessoryViewController_ wasShown];
1809 } 1898 }
1810 1899
1811 - (void)wasHidden { 1900 - (void)wasHidden {
1812 visible_ = NO; 1901 visible_ = NO;
1813 [self updateFullscreenWithToolbarVisible:YES]; 1902 [self updateFullscreenWithToolbarVisible:YES];
1814 [self.webController wasHidden]; 1903 [self.webController wasHidden];
1815 [inputAccessoryViewController_ wasHidden]; 1904 [inputAccessoryViewController_ wasHidden];
1816 } 1905 }
1817 1906
1818 #pragma mark - SadTabTabHelperDelegate 1907 #pragma mark - SadTabTabHelperDelegate
1819 1908
1820 - (BOOL)isTabVisibleForTabHelper:(SadTabTabHelper*)tabHelper { 1909 - (BOOL)isTabVisibleForTabHelper:(SadTabTabHelper*)tabHelper {
1821 UIApplicationState state = UIApplication.sharedApplication.applicationState; 1910 UIApplicationState state = UIApplication.sharedApplication.applicationState;
1822 return visible_ && !IsApplicationStateNotActive(state); 1911 return visible_ && !IsApplicationStateNotActive(state);
1823 } 1912 }
1824 1913
1825 @end 1914 @end
1826 1915
1827 #pragma mark - TestingSupport 1916 #pragma mark - TestingSupport
1828 1917
1829 @implementation Tab (TestingSupport) 1918 @implementation Tab (TestingSupport)
1830 1919
1831 - (void)replaceExternalAppLauncher:(id)externalAppLauncher { 1920 - (void)replaceExternalAppLauncher:(id)externalAppLauncher {
1832 externalAppLauncher_ = externalAppLauncher; 1921 externalAppLauncher_.reset([externalAppLauncher retain]);
1833 } 1922 }
1834 1923
1835 - (TabModel*)parentTabModel { 1924 - (TabModel*)parentTabModel {
1836 return parentTabModel_; 1925 return parentTabModel_;
1837 } 1926 }
1838 1927
1839 - (FormInputAccessoryViewController*)inputAccessoryViewController { 1928 - (FormInputAccessoryViewController*)inputAccessoryViewController {
1840 return inputAccessoryViewController_; 1929 return inputAccessoryViewController_.get();
1841 } 1930 }
1842 1931
1843 @end 1932 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/tabs/tab.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698