1 // Copyright 2020 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 #include "chrome/browser/ui/ash/back_gesture_contextual_nudge_delegate.h" 6 7 #include "ash/public/cpp/back_gesture_contextual_nudge_controller.h" 8 #include "chrome/browser/ui/browser.h" 9 #include "chrome/browser/ui/tabs/tab_strip_model.h" 10 #include "chrome/browser/ui/views/frame/browser_view.h" 11 #include "content/public/browser/navigation_details.h" 12 #include "content/public/browser/navigation_handle.h" 13 #include "ui/aura/window.h" 14 BackGestureContextualNudgeDelegate(ash::BackGestureContextualNudgeController * controller)15BackGestureContextualNudgeDelegate::BackGestureContextualNudgeDelegate( 16 ash::BackGestureContextualNudgeController* controller) 17 : controller_(controller) {} 18 ~BackGestureContextualNudgeDelegate()19BackGestureContextualNudgeDelegate::~BackGestureContextualNudgeDelegate() { 20 StopTrackingNavigation(); 21 } 22 MaybeStartTrackingNavigation(aura::Window * window)23void BackGestureContextualNudgeDelegate::MaybeStartTrackingNavigation( 24 aura::Window* window) { 25 if (window == window_) 26 return; 27 28 // Stop tracking the previous window before tracking a new window. 29 StopTrackingNavigation(); 30 31 BrowserView* browser_view = 32 BrowserView::GetBrowserViewForNativeWindow(window); 33 if (!browser_view) 34 return; 35 36 window_ = window; 37 window_->AddObserver(this); 38 39 TabStripModel* tab_strip_model = browser_view->browser()->tab_strip_model(); 40 tab_strip_model->AddObserver(this); 41 42 content::WebContents* contents = tab_strip_model->GetActiveWebContents(); 43 Observe(contents); 44 } 45 DidFinishNavigation(content::NavigationHandle * navigation_handle)46void BackGestureContextualNudgeDelegate::DidFinishNavigation( 47 content::NavigationHandle* navigation_handle) { 48 DCHECK(window_); 49 // Make sure for one valid navigation, we only fire one status change 50 // notification. 51 if (navigation_handle->HasCommitted() && 52 (navigation_handle->IsInMainFrame() || 53 navigation_handle->HasSubframeNavigationEntryCommitted()) && 54 (navigation_handle->GetURL() != navigation_handle->GetPreviousURL())) { 55 controller_->NavigationEntryChanged(window_); 56 } 57 } 58 OnTabStripModelChanged(TabStripModel * tab_strip_model,const TabStripModelChange & change,const TabStripSelectionChange & selection)59void BackGestureContextualNudgeDelegate::OnTabStripModelChanged( 60 TabStripModel* tab_strip_model, 61 const TabStripModelChange& change, 62 const TabStripSelectionChange& selection) { 63 const bool active_tab_changed = selection.active_tab_changed(); 64 if (active_tab_changed) { 65 DCHECK(window_); 66 controller_->NavigationEntryChanged(window_); 67 content::WebContents* contents = tab_strip_model->GetActiveWebContents(); 68 Observe(contents); 69 } 70 } 71 OnWindowDestroying(aura::Window * window)72void BackGestureContextualNudgeDelegate::OnWindowDestroying( 73 aura::Window* window) { 74 DCHECK_EQ(window_, window); 75 StopTrackingNavigation(); 76 } 77 StopTrackingNavigation()78void BackGestureContextualNudgeDelegate::StopTrackingNavigation() { 79 if (window_) { 80 BrowserView* browser_view = 81 BrowserView::GetBrowserViewForNativeWindow(window_); 82 DCHECK(browser_view); 83 browser_view->browser()->tab_strip_model()->RemoveObserver(this); 84 85 window_->RemoveObserver(this); 86 window_ = nullptr; 87 } 88 Observe(nullptr); 89 } 90