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 #include "chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h"
6
7 #include "base/feature_list.h"
8 #include "base/memory/ptr_util.h"
9 #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router.h"
10 #include "components/favicon/content/content_favicon_driver.h"
11 #include "components/language/core/common/language_experiments.h"
12 #include "components/sessions/content/session_tab_helper.h"
13 #include "components/sync_sessions/synced_tab_delegate.h"
14 #include "content/public/browser/navigation_entry.h"
15 #include "content/public/browser/navigation_handle.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "ui/gfx/image/image_skia.h"
18
19 namespace sync_sessions {
20
21 // static
CreateForWebContents(content::WebContents * web_contents,SyncSessionsWebContentsRouter * router)22 void SyncSessionsRouterTabHelper::CreateForWebContents(
23 content::WebContents* web_contents,
24 SyncSessionsWebContentsRouter* router) {
25 DCHECK(web_contents);
26 if (!FromWebContents(web_contents)) {
27 web_contents->SetUserData(UserDataKey(),
28 base::WrapUnique(new SyncSessionsRouterTabHelper(
29 web_contents, router)));
30 }
31 }
32
SyncSessionsRouterTabHelper(content::WebContents * web_contents,SyncSessionsWebContentsRouter * router)33 SyncSessionsRouterTabHelper::SyncSessionsRouterTabHelper(
34 content::WebContents* web_contents,
35 SyncSessionsWebContentsRouter* router)
36 : content::WebContentsObserver(web_contents), router_(router) {
37 chrome_translate_client_ =
38 ChromeTranslateClient::FromWebContents(web_contents);
39 // A translate client is not always attached to web contents (e.g. tests).
40 if (chrome_translate_client_)
41 chrome_translate_client_->translate_driver()->AddObserver(this);
42
43 favicon_driver_ =
44 favicon::ContentFaviconDriver::FromWebContents(web_contents);
45 if (favicon_driver_)
46 favicon_driver_->AddObserver(this);
47 }
48
~SyncSessionsRouterTabHelper()49 SyncSessionsRouterTabHelper::~SyncSessionsRouterTabHelper() {}
50
DidFinishNavigation(content::NavigationHandle * navigation_handle)51 void SyncSessionsRouterTabHelper::DidFinishNavigation(
52 content::NavigationHandle* navigation_handle) {
53 if (navigation_handle && navigation_handle->IsInMainFrame())
54 NotifyRouter();
55 }
56
TitleWasSet(content::NavigationEntry * entry)57 void SyncSessionsRouterTabHelper::TitleWasSet(content::NavigationEntry* entry) {
58 NotifyRouter();
59 }
60
WebContentsDestroyed()61 void SyncSessionsRouterTabHelper::WebContentsDestroyed() {
62 NotifyRouter();
63 if (chrome_translate_client_)
64 chrome_translate_client_->translate_driver()->RemoveObserver(this);
65 if (favicon_driver_)
66 favicon_driver_->RemoveObserver(this);
67 }
68
DidFinishLoad(content::RenderFrameHost * render_frame_host,const GURL & validated_url)69 void SyncSessionsRouterTabHelper::DidFinishLoad(
70 content::RenderFrameHost* render_frame_host,
71 const GURL& validated_url) {
72 // Only notify when the main frame finishes loading; only the main frame
73 // doesn't have a parent.
74 if (render_frame_host && !render_frame_host->GetParent())
75 NotifyRouter(true);
76 }
77
DidOpenRequestedURL(content::WebContents * new_contents,content::RenderFrameHost * source_render_frame_host,const GURL & url,const content::Referrer & referrer,WindowOpenDisposition disposition,ui::PageTransition transition,bool started_from_context_menu,bool renderer_initiated)78 void SyncSessionsRouterTabHelper::DidOpenRequestedURL(
79 content::WebContents* new_contents,
80 content::RenderFrameHost* source_render_frame_host,
81 const GURL& url,
82 const content::Referrer& referrer,
83 WindowOpenDisposition disposition,
84 ui::PageTransition transition,
85 bool started_from_context_menu,
86 bool renderer_initiated) {
87 // TODO(crbug.com/1007969): This is a relic from when we actually did change
88 // something about the tab here. It should be safe to remove now.
89 NotifyRouter();
90 }
91
OnLanguageDetermined(const translate::LanguageDetectionDetails & details)92 void SyncSessionsRouterTabHelper::OnLanguageDetermined(
93 const translate::LanguageDetectionDetails& details) {
94 if (base::FeatureList::IsEnabled(language::kNotifySyncOnLanguageDetermined))
95 NotifyRouter();
96 }
97
NotifyRouter(bool page_load_completed)98 void SyncSessionsRouterTabHelper::NotifyRouter(bool page_load_completed) {
99 if (router_)
100 router_->NotifyTabModified(web_contents(), page_load_completed);
101 }
102
OnFaviconUpdated(favicon::FaviconDriver * favicon_driver,FaviconDriverObserver::NotificationIconType notification_icon_type,const GURL & icon_url,bool icon_url_changed,const gfx::Image & image)103 void SyncSessionsRouterTabHelper::OnFaviconUpdated(
104 favicon::FaviconDriver* favicon_driver,
105 FaviconDriverObserver::NotificationIconType notification_icon_type,
106 const GURL& icon_url,
107 bool icon_url_changed,
108 const gfx::Image& image) {
109 if (icon_url_changed) {
110 NotifyRouter();
111 }
112 }
113
114 WEB_CONTENTS_USER_DATA_KEY_IMPL(SyncSessionsRouterTabHelper)
115
116 } // namespace sync_sessions
117