Commit c647b2ae authored by sangwoo.ko's avatar sangwoo.ko Committed by Commit Bot

Use TabStripModelObserver's new API in Browser

Replace old API with new API. This CL is a refactor
and has no intended behavior change.

The new API callbacks are only invoked when the internal
state of TabStripModel is consistent. The old API callbacks
would be invoked while the internal state of
TabStripModel was inconsistent.

FullscreenController's implementation was relying on
an inconsistent state for TabStripModel. So FullscreenController
is modified too. FullscreenController::IsFullscreenForTabOrPending()
checks if |web_contents| is same with the active tab. But when it's
handling tab deactivation, the active tab is already changed to the
newly activated tab. Therefore we shouldn't assert in that case.

Change-Id: I10a9f055ae111d43ba20ad6b9155196abe638e5b
Bug: 842194
Reviewed-on: https://chromium-review.googlesource.com/c/1196287Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Commit-Queue: Sang Woo Ko <sangwoo108@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601831}
parent 17f4e7d2
...@@ -710,8 +710,16 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, MAYBE_AbortClose) { ...@@ -710,8 +710,16 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, MAYBE_AbortClose) {
manager.WaitForNavigationFinished(); manager.WaitForNavigationFinished();
// TODO(sangwoo.ko) We are refacoring TabStripModelObserver's API.
// Expected histogram should be internal::kHistogramAbortCloseBeforeCommit
// regardless of platform. After applying new API to BrowserView, restore this.
#if defined(OS_MACOSX)
histogram_tester_.ExpectTotalCount(internal::kHistogramAbortCloseBeforeCommit, histogram_tester_.ExpectTotalCount(internal::kHistogramAbortCloseBeforeCommit,
1); 1);
#else
histogram_tester_.ExpectTotalCount(
internal::kHistogramAbortBackgroundBeforeCommit, 1);
#endif
} }
IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, AbortMultiple) { IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, AbortMultiple) {
......
...@@ -987,208 +987,51 @@ WebContents* Browser::OpenURL(const OpenURLParams& params) { ...@@ -987,208 +987,51 @@ WebContents* Browser::OpenURL(const OpenURLParams& params) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Browser, TabStripModelObserver implementation: // Browser, TabStripModelObserver implementation:
void Browser::TabInsertedAt(TabStripModel* tab_strip_model, void Browser::OnTabStripModelChanged(TabStripModel* tab_strip_model,
WebContents* contents, const TabStripModelChange& change,
int index, const TabStripSelectionChange& selection) {
bool foreground) { switch (change.type()) {
SetAsDelegate(contents, true); case TabStripModelChange::kInserted: {
for (const auto& delta : change.deltas())
SessionTabHelper::FromWebContents(contents)->SetWindowID(session_id()); OnTabInsertedAt(delta.insert.contents, delta.insert.index);
break;
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_PARENTED,
content::Source<content::WebContents>(contents),
content::NotificationService::NoDetails());
SyncHistoryWithTabs(index);
// Make sure the loading state is updated correctly, otherwise the throbber
// won't start if the page is loading. Note that we don't want to
// ScheduleUIUpdate() because the tab may not have been inserted in the UI
// yet if this function is called before TabStripModel::TabInsertedAt().
UpdateWindowForLoadingStateChanged(contents, true);
interstitial_observers_.push_back(new InterstitialObserver(this, contents));
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service) {
session_service->TabInserted(contents);
int new_active_index = tab_strip_model_->active_index();
if (index < new_active_index)
session_service->SetSelectedTabInWindow(session_id(),
new_active_index);
}
}
void Browser::TabClosingAt(TabStripModel* tab_strip_model,
WebContents* contents,
int index) {
// Typically, ModalDialogs are closed when the WebContents is destroyed.
// However, when the tab is being closed, we must first close the dialogs [to
// give them an opportunity to clean up after themselves] while the state
// associated with their tab is still valid.
WebContentsModalDialogManager::FromWebContents(contents)->CloseAllDialogs();
// Page load metrics need to be informed that the WebContents will soon be
// destroyed, so that upcoming visiblity changes can be ignored.
page_load_metrics::MetricsWebContentsObserver* metrics_observer =
page_load_metrics::MetricsWebContentsObserver::FromWebContents(contents);
metrics_observer->WebContentsWillSoonBeDestroyed();
exclusive_access_manager_->OnTabClosing(contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
session_service->TabClosing(contents);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_CLOSING,
content::Source<NavigationController>(&contents->GetController()),
content::NotificationService::NoDetails());
}
void Browser::TabDetachedAt(WebContents* contents, int index, bool was_active) {
if (!tab_strip_model_->closing_all()) {
SessionService* session_service =
SessionServiceFactory::GetForProfileIfExisting(profile_);
if (session_service) {
session_service->SetSelectedTabInWindow(session_id(),
tab_strip_model_->active_index());
} }
} case TabStripModelChange::kRemoved: {
for (const auto& delta : change.deltas()) {
TabDetachedAtImpl(contents, was_active, DETACH_TYPE_DETACH); if (delta.remove.will_be_deleted)
} OnTabClosing(delta.remove.contents);
void Browser::TabDeactivated(WebContents* contents) {
exclusive_access_manager_->OnTabDeactivated(contents);
SearchTabHelper::FromWebContents(contents)->OnTabDeactivated();
// Save what the user's currently typing, so it can be restored when we
// switch back to this tab.
window_->GetLocationBar()->SaveStateToContents(contents);
}
void Browser::ActiveTabChanged(WebContents* old_contents, OnTabDetached(delta.remove.contents,
WebContents* new_contents, delta.remove.contents == selection.old_contents);
int index, }
int reason) { break;
// Mac correctly sets the initial background color of new tabs to the theme }
// background color, so it does not need this block of code. Aura should case TabStripModelChange::kMoved: {
// implement this as well. for (const auto& delta : change.deltas())
// https://crbug.com/719230 OnTabMoved(delta.move.from_index, delta.move.to_index);
#if !defined(OS_MACOSX) break;
// Copies the background color from an old WebContents to a new one that }
// replaces it on the screen. This allows the new WebContents to use the case TabStripModelChange::kReplaced: {
// old one's background color as the starting background color, before having for (const auto& delta : change.deltas())
// loaded any contents. As a result, we avoid flashing white when moving to OnTabReplacedAt(delta.replace.old_contents, delta.replace.new_contents,
// a new tab. (There is also code in RenderFrameHostManager to do something delta.replace.index);
// similar for intra-tab navigations.) break;
if (old_contents && new_contents) { }
// While GetMainFrame() is guaranteed to return non-null, GetView() is not, case TabStripModelChange::kSelectionOnly:
// e.g. between WebContents creation and creation of the break;
// RenderWidgetHostView.
RenderWidgetHostView* old_view = old_contents->GetMainFrame()->GetView();
RenderWidgetHostView* new_view = new_contents->GetMainFrame()->GetView();
if (old_view && new_view && old_view->GetBackgroundColor())
new_view->SetBackgroundColor(*old_view->GetBackgroundColor());
}
#endif
base::RecordAction(UserMetricsAction("ActiveTabChanged"));
// Update the bookmark state, since the BrowserWindow may query it during
// OnActiveTabChanged() below.
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
// Let the BrowserWindow do its handling. On e.g. views this changes the
// focused object, which should happen before we update the toolbar below,
// since the omnibox expects the correct element to already be focused when it
// is updated.
window_->OnActiveTabChanged(old_contents, new_contents, index, reason);
exclusive_access_manager_->OnTabDetachedFromView(old_contents);
// If we have any update pending, do it now.
if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
ProcessPendingUIUpdates();
// Propagate the profile to the location bar.
UpdateToolbar((reason & CHANGE_REASON_REPLACED) == 0);
// Update reload/stop state.
command_controller_->LoadingStateChanged(new_contents->IsLoading(), true);
// Update commands to reflect current state.
command_controller_->TabStateChanged();
// Reset the status bubble.
StatusBubble* status_bubble = GetStatusBubble();
if (status_bubble) {
status_bubble->Hide();
// Show the loading state (if any).
status_bubble->SetStatus(CoreTabHelper::FromWebContents(
tab_strip_model_->GetActiveWebContents())->GetStatusText());
} }
if (HasFindBarController()) { if (!selection.active_tab_changed())
find_bar_controller_->ChangeWebContents(new_contents); return;
find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect());
}
// Update sessions (selected tab index and last active time). Don't force if (selection.old_contents)
// creation of sessions. If sessions doesn't exist, the change will be picked OnTabDeactivated(selection.old_contents);
// up by sessions when created.
SessionService* session_service =
SessionServiceFactory::GetForProfileIfExisting(profile_);
if (session_service && !tab_strip_model_->closing_all()) {
session_service->SetSelectedTabInWindow(session_id(),
tab_strip_model_->active_index());
SessionTabHelper* session_tab_helper =
SessionTabHelper::FromWebContents(new_contents);
session_service->SetLastActiveTime(session_id(),
session_tab_helper->session_id(),
base::TimeTicks::Now());
}
SearchTabHelper::FromWebContents(new_contents)->OnTabActivated(); if (tab_strip_model_->empty())
} return;
void Browser::TabMoved(WebContents* contents, OnActiveTabChanged(selection.old_contents, selection.new_contents,
int from_index, selection.new_model.active(), selection.reason);
int to_index) {
DCHECK(from_index >= 0 && to_index >= 0);
// Notify the history service.
SyncHistoryWithTabs(std::min(from_index, to_index));
}
void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
WebContents* old_contents,
WebContents* new_contents,
int index) {
bool was_active = index == tab_strip_model_->active_index();
TabDetachedAtImpl(old_contents, was_active, DETACH_TYPE_REPLACE);
exclusive_access_manager_->OnTabClosing(old_contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
session_service->TabClosing(old_contents);
TabInsertedAt(tab_strip_model, new_contents, index, was_active);
if (!new_contents->GetController().IsInitialBlankNavigation()) {
// Send out notification so that observers are updated appropriately.
int entry_count = new_contents->GetController().GetEntryCount();
new_contents->GetController().NotifyEntryChanged(
new_contents->GetController().GetEntryAtIndex(entry_count - 1));
}
if (session_service) {
// The new_contents may end up with a different navigation stack. Force
// the session service to update itself.
session_service->TabRestored(new_contents,
tab_strip_model_->IsTabPinned(index));
}
} }
void Browser::TabPinnedStateChanged(TabStripModel* tab_strip_model, void Browser::TabPinnedStateChanged(TabStripModel* tab_strip_model,
...@@ -2231,6 +2074,201 @@ void Browser::OnTranslateEnabledChanged(content::WebContents* source) { ...@@ -2231,6 +2074,201 @@ void Browser::OnTranslateEnabledChanged(content::WebContents* source) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Browser, Command and state updating (private): // Browser, Command and state updating (private):
void Browser::OnTabInsertedAt(WebContents* contents, int index) {
SetAsDelegate(contents, true);
SessionTabHelper::FromWebContents(contents)->SetWindowID(session_id());
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_PARENTED,
content::Source<content::WebContents>(contents),
content::NotificationService::NoDetails());
SyncHistoryWithTabs(index);
// Make sure the loading state is updated correctly, otherwise the throbber
// won't start if the page is loading. Note that we don't want to
// ScheduleUIUpdate() because the tab may not have been inserted in the UI
// yet if this function is called before TabStripModel::TabInsertedAt().
UpdateWindowForLoadingStateChanged(contents, true);
interstitial_observers_.push_back(new InterstitialObserver(this, contents));
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service) {
session_service->TabInserted(contents);
int new_active_index = tab_strip_model_->active_index();
if (index < new_active_index)
session_service->SetSelectedTabInWindow(session_id(), new_active_index);
}
}
void Browser::OnTabClosing(WebContents* contents) {
// Typically, ModalDialogs are closed when the WebContents is destroyed.
// However, when the tab is being closed, we must first close the dialogs [to
// give them an opportunity to clean up after themselves] while the state
// associated with their tab is still valid.
WebContentsModalDialogManager::FromWebContents(contents)->CloseAllDialogs();
// Page load metrics need to be informed that the WebContents will soon be
// destroyed, so that upcoming visibility changes can be ignored.
page_load_metrics::MetricsWebContentsObserver* metrics_observer =
page_load_metrics::MetricsWebContentsObserver::FromWebContents(contents);
metrics_observer->WebContentsWillSoonBeDestroyed();
exclusive_access_manager_->OnTabClosing(contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
session_service->TabClosing(contents);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_CLOSING,
content::Source<NavigationController>(&contents->GetController()),
content::NotificationService::NoDetails());
}
void Browser::OnTabDetached(WebContents* contents, bool was_active) {
if (!tab_strip_model_->closing_all()) {
SessionService* session_service =
SessionServiceFactory::GetForProfileIfExisting(profile_);
if (session_service) {
session_service->SetSelectedTabInWindow(session_id(),
tab_strip_model_->active_index());
}
}
TabDetachedAtImpl(contents, was_active, DETACH_TYPE_DETACH);
}
void Browser::OnTabDeactivated(WebContents* contents) {
exclusive_access_manager_->OnTabDeactivated(contents);
SearchTabHelper::FromWebContents(contents)->OnTabDeactivated();
// Save what the user's currently typing, so it can be restored when we
// switch back to this tab.
window_->GetLocationBar()->SaveStateToContents(contents);
}
void Browser::OnActiveTabChanged(WebContents* old_contents,
WebContents* new_contents,
int index,
int reason) {
// Mac correctly sets the initial background color of new tabs to the theme
// background color, so it does not need this block of code. Aura should
// implement this as well.
// https://crbug.com/719230
#if !defined(OS_MACOSX)
// Copies the background color from an old WebContents to a new one that
// replaces it on the screen. This allows the new WebContents to use the
// old one's background color as the starting background color, before having
// loaded any contents. As a result, we avoid flashing white when moving to
// a new tab. (There is also code in RenderFrameHostManager to do something
// similar for intra-tab navigations.)
if (old_contents && new_contents) {
// While GetMainFrame() is guaranteed to return non-null, GetView() is not,
// e.g. between WebContents creation and creation of the
// RenderWidgetHostView.
RenderWidgetHostView* old_view = old_contents->GetMainFrame()->GetView();
RenderWidgetHostView* new_view = new_contents->GetMainFrame()->GetView();
if (old_view && new_view && old_view->GetBackgroundColor())
new_view->SetBackgroundColor(*old_view->GetBackgroundColor());
}
#endif
base::RecordAction(UserMetricsAction("ActiveTabChanged"));
// Update the bookmark state, since the BrowserWindow may query it during
// OnActiveTabChanged() below.
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
// Let the BrowserWindow do its handling. On e.g. views this changes the
// focused object, which should happen before we update the toolbar below,
// since the omnibox expects the correct element to already be focused when it
// is updated.
window_->OnActiveTabChanged(old_contents, new_contents, index, reason);
exclusive_access_manager_->OnTabDetachedFromView(old_contents);
// If we have any update pending, do it now.
if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
ProcessPendingUIUpdates();
// Propagate the profile to the location bar.
UpdateToolbar((reason & CHANGE_REASON_REPLACED) == 0);
// Update reload/stop state.
command_controller_->LoadingStateChanged(new_contents->IsLoading(), true);
// Update commands to reflect current state.
command_controller_->TabStateChanged();
// Reset the status bubble.
StatusBubble* status_bubble = GetStatusBubble();
if (status_bubble) {
status_bubble->Hide();
// Show the loading state (if any).
status_bubble->SetStatus(
CoreTabHelper::FromWebContents(tab_strip_model_->GetActiveWebContents())
->GetStatusText());
}
if (HasFindBarController()) {
find_bar_controller_->ChangeWebContents(new_contents);
find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect());
}
// Update sessions (selected tab index and last active time). Don't force
// creation of sessions. If sessions doesn't exist, the change will be picked
// up by sessions when created.
SessionService* session_service =
SessionServiceFactory::GetForProfileIfExisting(profile_);
if (session_service && !tab_strip_model_->closing_all()) {
session_service->SetSelectedTabInWindow(session_id(),
tab_strip_model_->active_index());
SessionTabHelper* session_tab_helper =
SessionTabHelper::FromWebContents(new_contents);
session_service->SetLastActiveTime(
session_id(), session_tab_helper->session_id(), base::TimeTicks::Now());
}
SearchTabHelper::FromWebContents(new_contents)->OnTabActivated();
}
void Browser::OnTabMoved(int from_index, int to_index) {
DCHECK(from_index >= 0 && to_index >= 0);
// Notify the history service.
SyncHistoryWithTabs(std::min(from_index, to_index));
}
void Browser::OnTabReplacedAt(WebContents* old_contents,
WebContents* new_contents,
int index) {
bool was_active = index == tab_strip_model_->active_index();
TabDetachedAtImpl(old_contents, was_active, DETACH_TYPE_REPLACE);
exclusive_access_manager_->OnTabClosing(old_contents);
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile_);
if (session_service)
session_service->TabClosing(old_contents);
OnTabInsertedAt(new_contents, index);
if (!new_contents->GetController().IsInitialBlankNavigation()) {
// Send out notification so that observers are updated appropriately.
int entry_count = new_contents->GetController().GetEntryCount();
new_contents->GetController().NotifyEntryChanged(
new_contents->GetController().GetEntryAtIndex(entry_count - 1));
}
if (session_service) {
// The new_contents may end up with a different navigation stack. Force
// the session service to update itself.
session_service->TabRestored(new_contents,
tab_strip_model_->IsTabPinned(index));
}
}
void Browser::OnDevToolsAvailabilityChanged() { void Browser::OnDevToolsAvailabilityChanged() {
using DTPH = policy::DeveloperToolsPolicyHandler; using DTPH = policy::DeveloperToolsPolicyHandler;
// We close all windows as a safety measure, even for // We close all windows as a safety measure, even for
......
...@@ -442,28 +442,10 @@ class Browser : public TabStripModelObserver, ...@@ -442,28 +442,10 @@ class Browser : public TabStripModelObserver,
content::WebContents* OpenURL(const content::OpenURLParams& params) override; content::WebContents* OpenURL(const content::OpenURLParams& params) override;
// Overridden from TabStripModelObserver: // Overridden from TabStripModelObserver:
void TabInsertedAt(TabStripModel* tab_strip_model, void OnTabStripModelChanged(
content::WebContents* contents, TabStripModel* tab_strip_model,
int index, const TabStripModelChange& change,
bool foreground) override; const TabStripSelectionChange& selection) override;
void TabClosingAt(TabStripModel* tab_strip_model,
content::WebContents* contents,
int index) override;
void TabDetachedAt(content::WebContents* contents,
int index,
bool was_active) override;
void TabDeactivated(content::WebContents* contents) override;
void ActiveTabChanged(content::WebContents* old_contents,
content::WebContents* new_contents,
int index,
int reason) override;
void TabMoved(content::WebContents* contents,
int from_index,
int to_index) override;
void TabReplacedAt(TabStripModel* tab_strip_model,
content::WebContents* old_contents,
content::WebContents* new_contents,
int index) override;
void TabPinnedStateChanged(TabStripModel* tab_strip_model, void TabPinnedStateChanged(TabStripModel* tab_strip_model,
content::WebContents* contents, content::WebContents* contents,
int index) override; int index) override;
...@@ -771,6 +753,20 @@ class Browser : public TabStripModelObserver, ...@@ -771,6 +753,20 @@ class Browser : public TabStripModelObserver,
// Command and state updating /////////////////////////////////////////////// // Command and state updating ///////////////////////////////////////////////
// Handle changes to tab strip model.
void OnTabInsertedAt(content::WebContents* contents, int index);
void OnTabClosing(content::WebContents* contents);
void OnTabDetached(content::WebContents* contents, bool was_active);
void OnTabDeactivated(content::WebContents* contents);
void OnActiveTabChanged(content::WebContents* old_contents,
content::WebContents* new_contents,
int index,
int reason);
void OnTabMoved(int from_index, int to_index);
void OnTabReplacedAt(content::WebContents* old_contents,
content::WebContents* new_contents,
int index);
// Handle changes to kDevToolsAvailability preference. // Handle changes to kDevToolsAvailability preference.
void OnDevToolsAvailabilityChanged(); void OnDevToolsAvailabilityChanged();
......
...@@ -56,6 +56,7 @@ FullscreenController::FullscreenController(ExclusiveAccessManager* manager) ...@@ -56,6 +56,7 @@ FullscreenController::FullscreenController(ExclusiveAccessManager* manager)
state_prior_to_tab_fullscreen_(STATE_INVALID), state_prior_to_tab_fullscreen_(STATE_INVALID),
tab_fullscreen_(false), tab_fullscreen_(false),
toggled_into_fullscreen_(false), toggled_into_fullscreen_(false),
deactivated_contents_(nullptr),
is_privileged_fullscreen_for_testing_(false), is_privileged_fullscreen_for_testing_(false),
is_tab_fullscreen_for_testing_(false), is_tab_fullscreen_for_testing_(false),
ptr_factory_(this) {} ptr_factory_(this) {}
...@@ -102,8 +103,14 @@ bool FullscreenController::IsFullscreenForTabOrPending( ...@@ -102,8 +103,14 @@ bool FullscreenController::IsFullscreenForTabOrPending(
if (IsFullscreenWithinTab(web_contents)) if (IsFullscreenWithinTab(web_contents))
return true; return true;
if (web_contents == exclusive_access_tab()) { if (web_contents == exclusive_access_tab()) {
// If we're handling OnTabDeactivated(), |web_contents| is the
// deactivated contents. On the other hand,
// exclusive_access_manager()->context()->GetActiveWebContents() returns
// newly activated contents. That's because deactivation of tab is notified
// after TabStripModel's internal state is consistent.
DCHECK(web_contents == DCHECK(web_contents ==
exclusive_access_manager()->context()->GetActiveWebContents()); exclusive_access_manager()->context()->GetActiveWebContents() ||
web_contents == deactivated_contents_);
return true; return true;
} }
return false; return false;
...@@ -207,6 +214,13 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) { ...@@ -207,6 +214,13 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
PostFullscreenChangeNotification(true); PostFullscreenChangeNotification(true);
} }
void FullscreenController::OnTabDeactivated(
content::WebContents* web_contents) {
base::AutoReset<content::WebContents*> auto_resetter(&deactivated_contents_,
web_contents);
ExclusiveAccessControllerBase::OnTabDeactivated(web_contents);
}
void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) { void FullscreenController::OnTabDetachedFromView(WebContents* old_contents) {
if (!IsFullscreenWithinTab(old_contents)) if (!IsFullscreenWithinTab(old_contents))
return; return;
......
...@@ -128,6 +128,7 @@ class FullscreenController : public ExclusiveAccessControllerBase { ...@@ -128,6 +128,7 @@ class FullscreenController : public ExclusiveAccessControllerBase {
// Platform Fullscreen /////////////////////////////////////////////////////// // Platform Fullscreen ///////////////////////////////////////////////////////
// Overrde from ExclusiveAccessControllerBase. // Overrde from ExclusiveAccessControllerBase.
void OnTabDeactivated(content::WebContents* web_contents) override;
void OnTabDetachedFromView(content::WebContents* web_contents) override; void OnTabDetachedFromView(content::WebContents* web_contents) override;
void OnTabClosing(content::WebContents* web_contents) override; void OnTabClosing(content::WebContents* web_contents) override;
bool HandleUserPressedEscape() override; bool HandleUserPressedEscape() override;
...@@ -204,6 +205,10 @@ class FullscreenController : public ExclusiveAccessControllerBase { ...@@ -204,6 +205,10 @@ class FullscreenController : public ExclusiveAccessControllerBase {
// True if this controller has toggled into tab OR browser fullscreen. // True if this controller has toggled into tab OR browser fullscreen.
bool toggled_into_fullscreen_; bool toggled_into_fullscreen_;
// Set in OnTabDeactivated(). Used to see if we're in the middle of
// deactivation of a tab.
content::WebContents* deactivated_contents_;
// Used in testing to confirm proper behavior for specific, privileged // Used in testing to confirm proper behavior for specific, privileged
// fullscreen cases. // fullscreen cases.
bool is_privileged_fullscreen_for_testing_; bool is_privileged_fullscreen_for_testing_;
......
...@@ -304,8 +304,13 @@ IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, ...@@ -304,8 +304,13 @@ IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
static_cast<base::HistogramBase::Sample>(DismissalCause::kDialogClosed)); static_cast<base::HistogramBase::Sample>(DismissalCause::kDialogClosed));
EXPECT_EQ(canceled_count + closed_count, 1); EXPECT_EQ(canceled_count + closed_count, 1);
#else #else
// TODO(sangwoo.ko) Now we are refactoring TabStripModelObserver's API.
// As Browser::OnTabStripModelChanged() is called later than
// BrowserView::OnTabDetached(), DismisslCause::kTabHidden is used. So I guess
// this can be restored to DismissalCause::kDialogClosed after BrowserView is
// refactored too.
histogram_tester.ExpectUniqueSample("JSDialogs.DismissalCause.Prompt", histogram_tester.ExpectUniqueSample("JSDialogs.DismissalCause.Prompt",
DismissalCause::kDialogClosed, 1); DismissalCause::kTabHidden, 1);
#endif #endif
} }
......
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