Commit 2b583111 authored by edchin's avatar edchin Committed by Commit Bot

[ios] Add will/did CloseAllWebStates to WebStateListObserver

This CL adds |-willCloseAllWebStates()| and |-didCloseAllWebStates()|
to the WebStateListObserver. This allows observers to know when CloseAll
has been called. This gives observers ability to batch process operations
instead of processing each close individually.

This CL will be quickly followed up with the first use case -- RecentTabs.
In RecentTabs, the close all operation should be batched instead of being
processed one at a time, which causes a UI freeze.

Bug: 994229
Change-Id: I9dd47786c508409690e4a753593505d5da71d11b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1854463
Commit-Queue: edchin <edchin@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705571}
parent ea54537e
...@@ -333,8 +333,13 @@ void WebStateList::CloseWebStateAt(int index, int close_flags) { ...@@ -333,8 +333,13 @@ void WebStateList::CloseWebStateAt(int index, int close_flags) {
} }
void WebStateList::CloseAllWebStates(int close_flags) { void WebStateList::CloseAllWebStates(int close_flags) {
const bool user_action = IsClosingFlagSet(close_flags, CLOSE_USER_ACTION);
for (auto& observer : observers_)
observer.WillCloseAllWebStates(this, user_action);
while (!empty()) while (!empty())
CloseWebStateAt(count() - 1, close_flags); CloseWebStateAt(count() - 1, close_flags);
for (auto& observer : observers_)
observer.DidCloseAllWebStates(this, user_action);
} }
void WebStateList::ActivateWebStateAt(int index) { void WebStateList::ActivateWebStateAt(int index) {
......
...@@ -85,6 +85,16 @@ class WebStateListObserver { ...@@ -85,6 +85,16 @@ class WebStateListObserver {
int active_index, int active_index,
int reason); int reason);
// Invoked before all WebStates are closed in the WebStateList. If the
// WebState is closed due to user action, |user_action| will be true.
virtual void WillCloseAllWebStates(WebStateList* web_state_list,
bool user_action);
// Invoked after all WebStates are closed in the WebStateList. If the WebState
// is closed due to user action, |user_action| will be true.
virtual void DidCloseAllWebStates(WebStateList* web_state_list,
bool user_action);
private: private:
DISALLOW_COPY_AND_ASSIGN(WebStateListObserver); DISALLOW_COPY_AND_ASSIGN(WebStateListObserver);
}; };
......
...@@ -45,3 +45,9 @@ void WebStateListObserver::WebStateActivatedAt(WebStateList* web_state_list, ...@@ -45,3 +45,9 @@ void WebStateListObserver::WebStateActivatedAt(WebStateList* web_state_list,
web::WebState* new_web_state, web::WebState* new_web_state,
int active_index, int active_index,
int reason) {} int reason) {}
void WebStateListObserver::WillCloseAllWebStates(WebStateList* web_state_list,
bool user_action) {}
void WebStateListObserver::DidCloseAllWebStates(WebStateList* web_state_list,
bool user_action) {}
...@@ -68,6 +68,16 @@ ...@@ -68,6 +68,16 @@
atIndex:(int)atIndex atIndex:(int)atIndex
reason:(int)reason; reason:(int)reason;
// Invoked before all the WebStates are closed in the WebStateList. If the
// WebState is closed due to user action, |userAction| will be true.
- (void)webStateList:(WebStateList*)webStateList
willCloseAllWebStatesUserAction:(BOOL)userAction;
// Invoked after all the WebStates are closed in the WebStateList. If the
// WebState is closed due to user action, |userAction| will be true.
- (void)webStateList:(WebStateList*)webStateList
didCloseAllWebStatesUserAction:(BOOL)userAction;
@end @end
// Observer that bridges WebStateList events to an Objective-C observer that // Observer that bridges WebStateList events to an Objective-C observer that
...@@ -106,6 +116,10 @@ class WebStateListObserverBridge : public WebStateListObserver { ...@@ -106,6 +116,10 @@ class WebStateListObserverBridge : public WebStateListObserver {
web::WebState* new_web_state, web::WebState* new_web_state,
int active_index, int active_index,
int reason) override; int reason) override;
void WillCloseAllWebStates(WebStateList* web_state_list,
bool user_action) override;
void DidCloseAllWebStates(WebStateList* web_state_list,
bool user_action) override;
__weak id<WebStateListObserving> observer_ = nil; __weak id<WebStateListObserving> observer_ = nil;
......
...@@ -120,3 +120,25 @@ void WebStateListObserverBridge::WebStateActivatedAt( ...@@ -120,3 +120,25 @@ void WebStateListObserverBridge::WebStateActivatedAt(
atIndex:active_index atIndex:active_index
reason:reason]; reason:reason];
} }
void WebStateListObserverBridge::WillCloseAllWebStates(
WebStateList* web_state_list,
bool user_action) {
const SEL selector = @selector(webStateList:willCloseAllWebStatesUserAction:);
if (![observer_ respondsToSelector:selector])
return;
[observer_ webStateList:web_state_list
willCloseAllWebStatesUserAction:(user_action ? YES : NO)];
}
void WebStateListObserverBridge::DidCloseAllWebStates(
WebStateList* web_state_list,
bool user_action) {
const SEL selector = @selector(webStateList:didCloseAllWebStatesUserAction:);
if (![observer_ respondsToSelector:selector])
return;
[observer_ webStateList:web_state_list
didCloseAllWebStatesUserAction:(user_action ? YES : NO)];
}
...@@ -38,6 +38,8 @@ class WebStateListTestObserver : public WebStateListObserver { ...@@ -38,6 +38,8 @@ class WebStateListTestObserver : public WebStateListObserver {
web_state_replaced_called_ = false; web_state_replaced_called_ = false;
web_state_detached_called_ = false; web_state_detached_called_ = false;
web_state_activated_called_ = false; web_state_activated_called_ = false;
will_close_all_webstates_called_ = false;
did_close_all_webstates_called_ = false;
} }
// Returns whether WebStateInsertedAt was invoked. // Returns whether WebStateInsertedAt was invoked.
...@@ -57,6 +59,16 @@ class WebStateListTestObserver : public WebStateListObserver { ...@@ -57,6 +59,16 @@ class WebStateListTestObserver : public WebStateListObserver {
return web_state_activated_called_; return web_state_activated_called_;
} }
// Returns whether WillCloseAllWebStates was invoked.
bool will_close_all_webstates_called() const {
return will_close_all_webstates_called_;
}
// Returns whether DidCloseAllWebStates was invoked.
bool did_close_all_webstates_called() const {
return did_close_all_webstates_called_;
}
// WebStateListObserver implementation. // WebStateListObserver implementation.
void WebStateInsertedAt(WebStateList* web_state_list, void WebStateInsertedAt(WebStateList* web_state_list,
web::WebState* web_state, web::WebState* web_state,
...@@ -96,12 +108,24 @@ class WebStateListTestObserver : public WebStateListObserver { ...@@ -96,12 +108,24 @@ class WebStateListTestObserver : public WebStateListObserver {
web_state_activated_called_ = true; web_state_activated_called_ = true;
} }
void WillCloseAllWebStates(WebStateList* web_state_list,
bool user_action) override {
will_close_all_webstates_called_ = true;
}
void DidCloseAllWebStates(WebStateList* web_state_list,
bool user_action) override {
did_close_all_webstates_called_ = true;
}
private: private:
bool web_state_inserted_called_ = false; bool web_state_inserted_called_ = false;
bool web_state_moved_called_ = false; bool web_state_moved_called_ = false;
bool web_state_replaced_called_ = false; bool web_state_replaced_called_ = false;
bool web_state_detached_called_ = false; bool web_state_detached_called_ = false;
bool web_state_activated_called_ = false; bool web_state_activated_called_ = false;
bool will_close_all_webstates_called_ = false;
bool did_close_all_webstates_called_ = false;
DISALLOW_COPY_AND_ASSIGN(WebStateListTestObserver); DISALLOW_COPY_AND_ASSIGN(WebStateListTestObserver);
}; };
...@@ -693,3 +717,22 @@ TEST_F(WebStateListTest, OpenersChildsBeforeOpener) { ...@@ -693,3 +717,22 @@ TEST_F(WebStateListTest, OpenersChildsBeforeOpener) {
web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index, web_state_list_.GetIndexOfLastWebStateOpenedBy(opener, start_index,
true)); true));
} }
// Test closing all webstates.
TEST_F(WebStateListTest, CloseAllWebStates) {
AppendNewWebState(kURL0);
AppendNewWebState(kURL1);
AppendNewWebState(kURL2);
// Sanity check before closing WebStates.
EXPECT_EQ(3, web_state_list_.count());
observer_.ResetStatistics();
web_state_list_.CloseAllWebStates(WebStateList::CLOSE_USER_ACTION);
EXPECT_EQ(0, web_state_list_.count());
EXPECT_TRUE(observer_.web_state_detached_called());
EXPECT_TRUE(observer_.will_close_all_webstates_called());
EXPECT_TRUE(observer_.did_close_all_webstates_called());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment