Skip to content

Commit add2a72

Browse files
committed
Fix restoration of session after a crash.
Disable sending kTabModelNewTabWillOpenNotification notification when the TabModel is restoring a session as this breaks the BVC state that does not expect the notification to be sent when a tab is added due to session restoration. This is a reland of http://crrev.com/c/664557 that fixes EG tests by correctly initialising TabModelNotificationObserver (should not be disabled except during the restoration of the session). This CL also improves on the original CL by using a scoped closure runner to re-enable TabModelNotificationObserver to protect against early returns in -restoreSessionWindow:persistState:. Bug: 763964 Change-Id: Ie950ac3f35b13566abcc1ca6eae774512ed7a16a Reviewed-on: https://chromium-review.googlesource.com/665238 Reviewed-by: Rohit Rao (ping after 24h) <[email protected]> Commit-Queue: Sylvain Defresne <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#501944}(cherry picked from commit e8ae6ad) Reviewed-on: https://chromium-review.googlesource.com/674983 Reviewed-by: Sylvain Defresne <[email protected]> Cr-Commit-Position: refs/branch-heads/3202@{crosswalk-project#353} Cr-Branched-From: fa6a5d8-refs/heads/master@{#499098}
1 parent 6d1155a commit add2a72

6 files changed

+116
-26
lines changed

ios/chrome/browser/tabs/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ source_set("tabs_internal") {
5858
"tab_model_synced_window_delegate_getter.mm",
5959
"tab_model_web_state_list_delegate.h",
6060
"tab_model_web_state_list_delegate.mm",
61+
"tab_model_web_usage_enabled_observer.h",
62+
"tab_model_web_usage_enabled_observer.mm",
6163
"tab_parenting_observer.h",
6264
"tab_parenting_observer.mm",
6365
]

ios/chrome/browser/tabs/tab_model.mm

+24-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <vector>
1010

1111
#include "base/bind.h"
12+
#include "base/callback_helpers.h"
1213
#include "base/logging.h"
1314
#import "base/mac/foundation_util.h"
1415
#include "base/metrics/histogram_macros.h"
@@ -42,6 +43,7 @@
4243
#import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h"
4344
#import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
4445
#import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h"
46+
#import "ios/chrome/browser/tabs/tab_model_web_usage_enabled_observer.h"
4547
#import "ios/chrome/browser/tabs/tab_parenting_observer.h"
4648
#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
4749
#import "ios/chrome/browser/web_state_list/web_state_list.h"
@@ -156,6 +158,9 @@ @interface TabModel () {
156158
// The delegate for sync.
157159
std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
158160

161+
// The observer that sends kTabModelNewTabWillOpenNotification notifications.
162+
TabModelNotificationObserver* _tabModelNotificationObserver;
163+
159164
// Counters for metrics.
160165
WebStateListMetricsObserver* _webStateListMetricsObserver;
161166

@@ -313,7 +318,12 @@ - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
313318
_webStateListObservers.push_back(std::move(webStateListMetricsObserver));
314319

315320
_webStateListObservers.push_back(
316-
base::MakeUnique<TabModelNotificationObserver>(self));
321+
base::MakeUnique<TabModelWebUsageEnabledObserver>(self));
322+
323+
auto tabModelNotificationObserver =
324+
base::MakeUnique<TabModelNotificationObserver>(self);
325+
_tabModelNotificationObserver = tabModelNotificationObserver.get();
326+
_webStateListObservers.push_back(std::move(tabModelNotificationObserver));
317327

318328
for (const auto& webStateListObserver : _webStateListObservers)
319329
_webStateList->AddObserver(webStateListObserver.get());
@@ -569,7 +579,8 @@ - (void)browserStateDestroyed {
569579
UnregisterTabModelFromChromeBrowserState(_browserState, self);
570580
_browserState = nullptr;
571581

572-
// Clear weak pointer to WebStateListMetricsObserver before destroying it.
582+
// Clear weak pointer to observers before destroying them.
583+
_tabModelNotificationObserver = nullptr;
573584
_webStateListMetricsObserver = nullptr;
574585

575586
// Close all tabs. Do this in an @autoreleasepool as WebStateList observers
@@ -643,6 +654,16 @@ - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
643654
DCHECK(_browserState);
644655
DCHECK(window);
645656

657+
// Disable sending the kTabModelNewTabWillOpenNotification notification
658+
// while restoring a session as it breaks the BVC (see crbug.com/763964).
659+
base::ScopedClosureRunner enableTabModelNotificationObserver;
660+
if (_tabModelNotificationObserver) {
661+
_tabModelNotificationObserver->SetDisabled(true);
662+
enableTabModelNotificationObserver.ReplaceClosure(
663+
base::BindOnce(&TabModelNotificationObserver::SetDisabled,
664+
base::Unretained(_tabModelNotificationObserver), false));
665+
}
666+
646667
if (!window.sessions.count)
647668
return NO;
648669

@@ -695,6 +716,7 @@ - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
695716
_tabUsageRecorder->InitialRestoredTabs(self.currentTab.webState,
696717
restoredWebStates);
697718
}
719+
698720
return closedNTPTab;
699721
}
700722

ios/chrome/browser/tabs/tab_model_notification_observer.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ class TabModelNotificationObserver : public WebStateListObserver {
1515
explicit TabModelNotificationObserver(TabModel* tab_model);
1616
~TabModelNotificationObserver() override;
1717

18+
// Controls whether sending notification is enabled or not.
19+
void SetDisabled(bool disabled);
20+
1821
// WebStateListObserver implementation.
1922
void WebStateInsertedAt(WebStateList* web_state_list,
2023
web::WebState* web_state,
2124
int index,
2225
bool activating) override;
23-
void WebStateReplacedAt(WebStateList* web_state_list,
24-
web::WebState* old_web_state,
25-
web::WebState* new_web_state,
26-
int index) override;
2726

2827
private:
2928
__weak TabModel* tab_model_;
29+
bool disabled_ = false;
3030

3131
DISALLOW_COPY_AND_ASSIGN(TabModelNotificationObserver);
3232
};

ios/chrome/browser/tabs/tab_model_notification_observer.mm

+6-20
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,22 @@
1212
#error "This file requires ARC support."
1313
#endif
1414

15-
namespace {
16-
17-
// Sets |web_state| web usage enabled property and starts loading the content
18-
// if necessary.
19-
void SetWebUsageEnabled(web::WebState* web_state, bool web_usage_enabled) {
20-
web_state->SetWebUsageEnabled(web_usage_enabled);
21-
if (web_usage_enabled)
22-
web_state->GetNavigationManager()->LoadIfNecessary();
23-
}
24-
25-
} // namespace
26-
2715
TabModelNotificationObserver::TabModelNotificationObserver(TabModel* tab_model)
2816
: tab_model_(tab_model) {}
2917

3018
TabModelNotificationObserver::~TabModelNotificationObserver() = default;
3119

20+
void TabModelNotificationObserver::SetDisabled(bool disabled) {
21+
disabled_ = disabled;
22+
}
23+
3224
void TabModelNotificationObserver::WebStateInsertedAt(
3325
WebStateList* web_state_list,
3426
web::WebState* web_state,
3527
int index,
3628
bool activating) {
37-
SetWebUsageEnabled(web_state, tab_model_.webUsageEnabled);
29+
if (disabled_)
30+
return;
3831

3932
Tab* tab = LegacyTabHelper::GetTabForWebState(web_state);
4033
[[NSNotificationCenter defaultCenter]
@@ -46,10 +39,3 @@ void SetWebUsageEnabled(web::WebState* web_state, bool web_usage_enabled) {
4639
}];
4740
}
4841

49-
void TabModelNotificationObserver::WebStateReplacedAt(
50-
WebStateList* web_state_list,
51-
web::WebState* old_web_state,
52-
web::WebState* new_web_state,
53-
int index) {
54-
SetWebUsageEnabled(new_web_state, tab_model_.webUsageEnabled);
55-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_USAGE_ENABLED_OBSERVER_H_
6+
#define IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_USAGE_ENABLED_OBSERVER_H_
7+
8+
#include "base/macros.h"
9+
#import "ios/chrome/browser/web_state_list/web_state_list_observer.h"
10+
11+
@class TabModel;
12+
13+
class TabModelWebUsageEnabledObserver : public WebStateListObserver {
14+
public:
15+
explicit TabModelWebUsageEnabledObserver(TabModel* tab_model);
16+
~TabModelWebUsageEnabledObserver() override;
17+
18+
// WebStateListObserver implementation.
19+
void WebStateInsertedAt(WebStateList* web_state_list,
20+
web::WebState* web_state,
21+
int index,
22+
bool activating) override;
23+
void WebStateReplacedAt(WebStateList* web_state_list,
24+
web::WebState* old_web_state,
25+
web::WebState* new_web_state,
26+
int index) override;
27+
28+
private:
29+
__weak TabModel* tab_model_;
30+
31+
DISALLOW_COPY_AND_ASSIGN(TabModelWebUsageEnabledObserver);
32+
};
33+
34+
#endif // IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_USAGE_ENABLED_OBSERVER_H_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#import "ios/chrome/browser/tabs/tab_model_web_usage_enabled_observer.h"
6+
7+
#import "ios/chrome/browser/tabs/tab_model.h"
8+
#import "ios/web/public/web_state/web_state.h"
9+
10+
#if !defined(__has_feature) || !__has_feature(objc_arc)
11+
#error "This file requires ARC support."
12+
#endif
13+
14+
namespace {
15+
16+
// Sets |web_state| web usage enabled property and starts loading the content
17+
// if necessary.
18+
void SetWebUsageEnabled(web::WebState* web_state, bool web_usage_enabled) {
19+
web_state->SetWebUsageEnabled(web_usage_enabled);
20+
if (web_usage_enabled)
21+
web_state->GetNavigationManager()->LoadIfNecessary();
22+
}
23+
24+
} // namespace
25+
26+
TabModelWebUsageEnabledObserver::TabModelWebUsageEnabledObserver(
27+
TabModel* tab_model)
28+
: tab_model_(tab_model) {}
29+
30+
TabModelWebUsageEnabledObserver::~TabModelWebUsageEnabledObserver() = default;
31+
32+
void TabModelWebUsageEnabledObserver::WebStateInsertedAt(
33+
WebStateList* web_state_list,
34+
web::WebState* web_state,
35+
int index,
36+
bool activating) {
37+
SetWebUsageEnabled(web_state, tab_model_.webUsageEnabled);
38+
}
39+
40+
void TabModelWebUsageEnabledObserver::WebStateReplacedAt(
41+
WebStateList* web_state_list,
42+
web::WebState* old_web_state,
43+
web::WebState* new_web_state,
44+
int index) {
45+
SetWebUsageEnabled(new_web_state, tab_model_.webUsageEnabled);
46+
}

0 commit comments

Comments
 (0)