Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / sessions / notification_service_sessions_router.cc
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.
4
5 #include "chrome/browser/sync/sessions/notification_service_sessions_router.h"
6
7 #include "base/logging.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/history/history_service.h"
10 #include "chrome/browser/history/history_service_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/sync/glue/sync_start_util.h"
13 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
14 #include "chrome/browser/sync/sessions/sessions_util.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/notification_details.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/web_contents.h"
22
23 #if defined(ENABLE_MANAGED_USERS)
24 #include "chrome/browser/supervised_user/supervised_user_service.h"
25 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
26 #endif
27
28 #if defined(ENABLE_EXTENSIONS)
29 #include "chrome/browser/extensions/tab_helper.h"
30 #endif
31
32 using content::NavigationController;
33 using content::WebContents;
34
35 namespace browser_sync {
36
37 NotificationServiceSessionsRouter::NotificationServiceSessionsRouter(
38     Profile* profile, const syncer::SyncableService::StartSyncFlare& flare)
39         : handler_(NULL),
40           profile_(profile),
41           flare_(flare),
42           weak_ptr_factory_(this) {
43   registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
44       content::NotificationService::AllSources());
45   registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
46       content::NotificationService::AllSources());
47   registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED,
48       content::NotificationService::AllSources());
49   registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED,
50       content::NotificationService::AllSources());
51   registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
52       content::NotificationService::AllSources());
53 #if defined(ENABLE_EXTENSIONS)
54   registrar_.Add(this,
55       chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
56       content::NotificationService::AllSources());
57 #endif
58   registrar_.Add(this,
59       content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
60       content::NotificationService::AllBrowserContextsAndSources());
61   HistoryService* history_service =
62       HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS);
63   if (history_service) {
64     favicon_changed_subscription_ = history_service->AddFaviconChangedCallback(
65         base::Bind(&NotificationServiceSessionsRouter::OnFaviconChanged,
66                    base::Unretained(this)));
67   }
68 #if defined(ENABLE_MANAGED_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()));
75   }
76 #endif
77 }
78
79 NotificationServiceSessionsRouter::~NotificationServiceSessionsRouter() {}
80
81 void NotificationServiceSessionsRouter::Observe(
82     int type,
83     const content::NotificationSource& source,
84     const content::NotificationDetails& details) {
85   switch (type) {
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_)
94         return;
95       if (handler_)
96         handler_->OnLocalTabModified(tab);
97       if (!sessions_util::ShouldSyncTab(*tab))
98         return;
99       break;
100     }
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()->
107               GetWebContents());
108       if (!tab || tab->profile() != profile_)
109         return;
110       if (handler_)
111         handler_->OnLocalTabModified(tab);
112       if (!sessions_util::ShouldSyncTab(*tab))
113         return;
114       break;
115     }
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() !=
121               profile_) {
122         return;
123       }
124       if (extension_tab_helper->extension_app()) {
125         SyncedTabDelegate* tab = SyncedTabDelegate::ImplFromWebContents(
126             extension_tab_helper->web_contents());
127         if (!tab || tab->profile() != profile_)
128           return;
129         if (handler_)
130           handler_->OnLocalTabModified(tab);
131         break;
132       }
133       return;
134     }
135 #endif
136     default:
137       LOG(ERROR) << "Received unexpected notification of type " << type;
138       return;
139   }
140
141   if (!flare_.is_null()) {
142     flare_.Run(syncer::SESSIONS);
143     flare_.Reset();
144   }
145 }
146
147 void NotificationServiceSessionsRouter::OnNavigationBlocked(
148     content::WebContents* web_contents) {
149   SyncedTabDelegate* tab =
150       SyncedTabDelegate::ImplFromWebContents(web_contents);
151   if (!tab || !handler_)
152     return;
153
154   DCHECK(tab->profile() == profile_);
155   handler_->OnLocalTabModified(tab);
156 }
157
158 void NotificationServiceSessionsRouter::OnFaviconChanged(
159     const std::set<GURL>& changed_favicons) {
160   if (handler_)
161     handler_->OnFaviconPageUrlsUpdated(changed_favicons);
162 }
163
164 void NotificationServiceSessionsRouter::StartRoutingTo(
165     LocalSessionEventHandler* handler) {
166   DCHECK(!handler_);
167   handler_ = handler;
168 }
169
170 void NotificationServiceSessionsRouter::Stop() {
171   weak_ptr_factory_.InvalidateWeakPtrs();
172   handler_ = NULL;
173 }
174
175 }  // namespace browser_sync