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/extensions/tab_helper.h"
10 #include "chrome/browser/history/history_service.h"
11 #include "chrome/browser/history/history_service_factory.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sync/glue/sync_start_util.h"
14 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
15 #include "chrome/browser/sync/sessions/sessions_util.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "content/public/browser/navigation_controller.h"
18 #include "content/public/browser/navigation_entry.h"
19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_service.h"
21 #include "content/public/browser/notification_source.h"
22 #include "content/public/browser/web_contents.h"
24 #if defined(ENABLE_MANAGED_USERS)
25 #include "chrome/browser/supervised_user/supervised_user_service.h"
26 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
29 using content::NavigationController
;
30 using content::WebContents
;
32 namespace browser_sync
{
34 NotificationServiceSessionsRouter::NotificationServiceSessionsRouter(
35 Profile
* profile
, const syncer::SyncableService::StartSyncFlare
& flare
)
39 weak_ptr_factory_(this) {
41 registrar_
.Add(this, chrome::NOTIFICATION_TAB_PARENTED
,
42 content::NotificationService::AllSources());
43 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
44 content::NotificationService::AllSources());
45 registrar_
.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED
,
46 content::NotificationService::AllSources());
47 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED
,
48 content::NotificationService::AllSources());
49 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
50 content::NotificationService::AllSources());
52 chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED
,
53 content::NotificationService::AllSources());
55 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
56 content::NotificationService::AllBrowserContextsAndSources());
57 HistoryService
* history_service
=
58 HistoryServiceFactory::GetForProfile(profile
, Profile::EXPLICIT_ACCESS
);
59 if (history_service
) {
60 favicon_changed_subscription_
= history_service
->AddFaviconChangedCallback(
61 base::Bind(&NotificationServiceSessionsRouter::OnFaviconChanged
,
62 base::Unretained(this)));
64 #if defined(ENABLE_MANAGED_USERS)
65 if (profile_
->IsSupervised()) {
66 SupervisedUserService
* supervised_user_service
=
67 SupervisedUserServiceFactory::GetForProfile(profile_
);
68 supervised_user_service
->AddNavigationBlockedCallback(
69 base::Bind(&NotificationServiceSessionsRouter::OnNavigationBlocked
,
70 weak_ptr_factory_
.GetWeakPtr()));
75 NotificationServiceSessionsRouter::~NotificationServiceSessionsRouter() {}
77 void NotificationServiceSessionsRouter::Observe(
79 const content::NotificationSource
& source
,
80 const content::NotificationDetails
& details
) {
82 // Source<WebContents>.
83 case chrome::NOTIFICATION_TAB_PARENTED
:
84 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
:
85 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED
: {
86 WebContents
* web_contents
= content::Source
<WebContents
>(source
).ptr();
87 SyncedTabDelegate
* tab
=
88 SyncedTabDelegate::ImplFromWebContents(web_contents
);
89 if (!tab
|| tab
->profile() != profile_
)
92 handler_
->OnLocalTabModified(tab
);
93 if (!sessions_util::ShouldSyncTab(*tab
))
97 // Source<NavigationController>.
98 case content::NOTIFICATION_NAV_LIST_PRUNED
:
99 case content::NOTIFICATION_NAV_ENTRY_CHANGED
:
100 case content::NOTIFICATION_NAV_ENTRY_COMMITTED
: {
101 SyncedTabDelegate
* tab
= SyncedTabDelegate::ImplFromWebContents(
102 content::Source
<NavigationController
>(source
).ptr()->
104 if (!tab
|| tab
->profile() != profile_
)
107 handler_
->OnLocalTabModified(tab
);
108 if (!sessions_util::ShouldSyncTab(*tab
))
112 case chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED
: {
113 extensions::TabHelper
* extension_tab_helper
=
114 content::Source
<extensions::TabHelper
>(source
).ptr();
115 if (extension_tab_helper
->web_contents()->GetBrowserContext() !=
119 if (extension_tab_helper
->extension_app()) {
120 SyncedTabDelegate
* tab
= SyncedTabDelegate::ImplFromWebContents(
121 extension_tab_helper
->web_contents());
122 if (!tab
|| tab
->profile() != profile_
)
125 handler_
->OnLocalTabModified(tab
);
131 LOG(ERROR
) << "Received unexpected notification of type " << type
;
135 if (!flare_
.is_null()) {
136 flare_
.Run(syncer::SESSIONS
);
141 void NotificationServiceSessionsRouter::OnNavigationBlocked(
142 content::WebContents
* web_contents
) {
143 SyncedTabDelegate
* tab
=
144 SyncedTabDelegate::ImplFromWebContents(web_contents
);
145 if (!tab
|| !handler_
)
148 DCHECK(tab
->profile() == profile_
);
149 handler_
->OnLocalTabModified(tab
);
152 void NotificationServiceSessionsRouter::OnFaviconChanged(
153 const std::set
<GURL
>& changed_favicons
) {
155 handler_
->OnFaviconPageUrlsUpdated(changed_favicons
);
158 void NotificationServiceSessionsRouter::StartRoutingTo(
159 LocalSessionEventHandler
* handler
) {
164 void NotificationServiceSessionsRouter::Stop() {
165 weak_ptr_factory_
.InvalidateWeakPtrs();
169 } // namespace browser_sync