1 // Copyright 2014 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.
5 #include "chrome/browser/sync/sessions/notification_service_sessions_router.h"
7 #include "base/logging.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/history/history_service_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/glue/sync_start_util.h"
12 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "components/history/core/browser/history_service.h"
15 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h"
20 #include "content/public/browser/web_contents.h"
22 #if defined(ENABLE_SUPERVISED_USERS)
23 #include "chrome/browser/supervised_user/supervised_user_service.h"
24 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
27 #if defined(ENABLE_EXTENSIONS)
28 #include "chrome/browser/extensions/tab_helper.h"
31 using content::NavigationController
;
32 using content::WebContents
;
34 namespace browser_sync
{
36 NotificationServiceSessionsRouter::NotificationServiceSessionsRouter(
37 Profile
* profile
, const syncer::SyncableService::StartSyncFlare
& flare
)
41 weak_ptr_factory_(this) {
42 registrar_
.Add(this, chrome::NOTIFICATION_TAB_PARENTED
,
43 content::NotificationService::AllSources());
44 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
45 content::NotificationService::AllSources());
46 registrar_
.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED
,
47 content::NotificationService::AllSources());
48 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED
,
49 content::NotificationService::AllSources());
50 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
51 content::NotificationService::AllSources());
52 #if defined(ENABLE_EXTENSIONS)
54 chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED
,
55 content::NotificationService::AllSources());
58 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
59 content::NotificationService::AllBrowserContextsAndSources());
60 history::HistoryService
* history_service
=
61 HistoryServiceFactory::GetForProfile(profile
,
62 ServiceAccessType::EXPLICIT_ACCESS
);
63 if (history_service
) {
64 favicon_changed_subscription_
= history_service
->AddFaviconsChangedCallback(
65 base::Bind(&NotificationServiceSessionsRouter::OnFaviconsChanged
,
66 base::Unretained(this)));
68 #if defined(ENABLE_SUPERVISED_USERS)
69 if (profile_
->IsSupervised()) {
70 SupervisedUserService
* supervised_user_service
=
71 SupervisedUserServiceFactory::GetForProfile(profile_
);
72 supervised_user_service
->AddNavigationBlockedCallback(
73 base::Bind(&NotificationServiceSessionsRouter::OnNavigationBlocked
,
74 weak_ptr_factory_
.GetWeakPtr()));
79 NotificationServiceSessionsRouter::~NotificationServiceSessionsRouter() {}
81 void NotificationServiceSessionsRouter::Observe(
83 const content::NotificationSource
& source
,
84 const content::NotificationDetails
& details
) {
86 // Source<WebContents>.
87 case chrome::NOTIFICATION_TAB_PARENTED
:
88 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
:
89 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED
: {
90 WebContents
* web_contents
= content::Source
<WebContents
>(source
).ptr();
91 SyncedTabDelegate
* tab
=
92 SyncedTabDelegate::ImplFromWebContents(web_contents
);
93 if (!tab
|| tab
->profile() != profile_
)
96 handler_
->OnLocalTabModified(tab
);
97 if (!tab
->ShouldSync())
101 // Source<NavigationController>.
102 case content::NOTIFICATION_NAV_LIST_PRUNED
:
103 case content::NOTIFICATION_NAV_ENTRY_CHANGED
:
104 case content::NOTIFICATION_NAV_ENTRY_COMMITTED
: {
105 SyncedTabDelegate
* tab
= SyncedTabDelegate::ImplFromWebContents(
106 content::Source
<NavigationController
>(source
).ptr()->
108 if (!tab
|| tab
->profile() != profile_
)
111 handler_
->OnLocalTabModified(tab
);
112 if (!tab
->ShouldSync())
116 #if defined(ENABLE_EXTENSIONS)
117 case chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED
: {
118 extensions::TabHelper
* extension_tab_helper
=
119 content::Source
<extensions::TabHelper
>(source
).ptr();
120 if (extension_tab_helper
->web_contents()->GetBrowserContext() !=
124 if (extension_tab_helper
->extension_app()) {
125 SyncedTabDelegate
* tab
= SyncedTabDelegate::ImplFromWebContents(
126 extension_tab_helper
->web_contents());
127 if (!tab
|| tab
->profile() != profile_
)
130 handler_
->OnLocalTabModified(tab
);
137 LOG(ERROR
) << "Received unexpected notification of type " << type
;
141 if (!flare_
.is_null()) {
142 flare_
.Run(syncer::SESSIONS
);
147 void NotificationServiceSessionsRouter::OnNavigationBlocked(
148 content::WebContents
* web_contents
) {
149 SyncedTabDelegate
* tab
=
150 SyncedTabDelegate::ImplFromWebContents(web_contents
);
151 if (!tab
|| !handler_
)
154 DCHECK(tab
->profile() == profile_
);
155 handler_
->OnLocalTabModified(tab
);
158 void NotificationServiceSessionsRouter::OnFaviconsChanged(
159 const std::set
<GURL
>& page_urls
,
160 const GURL
& icon_url
) {
162 handler_
->OnFaviconsChanged(page_urls
, icon_url
);
165 void NotificationServiceSessionsRouter::StartRoutingTo(
166 LocalSessionEventHandler
* handler
) {
171 void NotificationServiceSessionsRouter::Stop() {
172 weak_ptr_factory_
.InvalidateWeakPtrs();
176 } // namespace browser_sync