Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / signed_in_devices / signed_in_devices_manager.cc
1 // Copyright 2013 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/extensions/api/signed_in_devices/signed_in_devices_manager.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/lazy_instance.h"
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/values.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/sync/glue/device_info.h"
20 #include "chrome/browser/sync/profile_sync_service.h"
21 #include "chrome/browser/sync/profile_sync_service_factory.h"
22 #include "chrome/common/extensions/api/signed_in_devices.h"
23 #include "content/public/browser/notification_details.h"
24 #include "content/public/browser/notification_observer.h"
25 #include "content/public/browser/notification_registrar.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_source.h"
28 #include "extensions/browser/event_router.h"
29 #include "extensions/common/extension.h"
30
31 using browser_sync::DeviceInfo;
32 namespace extensions {
33
34 namespace {
35 void FillDeviceInfo(const DeviceInfo& device_info,
36                     api::signed_in_devices::DeviceInfo* api_device_info) {
37   api_device_info->id = device_info.public_id();
38   api_device_info->name = device_info.client_name();
39   api_device_info->os = api::signed_in_devices::ParseOS(
40       device_info.GetOSString());
41   api_device_info->type = api::signed_in_devices::ParseDeviceType(
42       device_info.GetDeviceTypeString());
43   api_device_info->chrome_version = device_info.chrome_version();
44 }
45 }  // namespace
46
47 SignedInDevicesChangeObserver::SignedInDevicesChangeObserver(
48     const std::string& extension_id,
49     Profile* profile) : extension_id_(extension_id),
50                         profile_(profile) {
51   ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile_);
52   if (pss) {
53     pss->AddObserverForDeviceInfoChange(this);
54   }
55 }
56
57 SignedInDevicesChangeObserver::~SignedInDevicesChangeObserver() {
58   ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile_);
59   if (pss) {
60     pss->RemoveObserverForDeviceInfoChange(this);
61   }
62
63 }
64
65 void SignedInDevicesChangeObserver::OnDeviceInfoChange() {
66   // There is a change in the list of devices. Get all devices and send them to
67   // the listener.
68   ScopedVector<DeviceInfo> devices = GetAllSignedInDevices(extension_id_,
69                                                            profile_);
70
71   std::vector<linked_ptr<api::signed_in_devices::DeviceInfo> > args;
72
73   for (ScopedVector<DeviceInfo>::const_iterator it = devices.begin();
74        it != devices.end();
75        ++it) {
76     linked_ptr<api::signed_in_devices::DeviceInfo> api_device =
77         make_linked_ptr(new api::signed_in_devices::DeviceInfo);
78     FillDeviceInfo(*(*it), api_device.get());
79     args.push_back(api_device);
80   }
81
82   scoped_ptr<base::ListValue> result =
83       api::signed_in_devices::OnDeviceInfoChange::Create(args);
84   scoped_ptr<Event> event(new Event(
85       api::signed_in_devices::OnDeviceInfoChange::kEventName,
86       result.Pass()));
87
88   event->restrict_to_browser_context = profile_;
89
90   EventRouter::Get(profile_)->DispatchEventToExtension(
91       extension_id_, event.Pass());
92 }
93
94 static base::LazyInstance<
95     BrowserContextKeyedAPIFactory<SignedInDevicesManager> > g_factory =
96     LAZY_INSTANCE_INITIALIZER;
97
98 // static
99 BrowserContextKeyedAPIFactory<SignedInDevicesManager>*
100 SignedInDevicesManager::GetFactoryInstance() {
101   return g_factory.Pointer();
102 }
103
104 SignedInDevicesManager::SignedInDevicesManager()
105     : profile_(NULL) {}
106
107 SignedInDevicesManager::SignedInDevicesManager(content::BrowserContext* context)
108     : profile_(Profile::FromBrowserContext(context)) {
109   extensions::EventRouter* router = extensions::EventRouter::Get(profile_);
110   if (router) {
111     router->RegisterObserver(
112         this, api::signed_in_devices::OnDeviceInfoChange::kEventName);
113   }
114
115   // Register for unload event so we could clear all our listeners when
116   // extensions have unloaded.
117   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
118                  content::Source<Profile>(profile_->GetOriginalProfile()));
119 }
120
121 SignedInDevicesManager::~SignedInDevicesManager() {}
122
123 void SignedInDevicesManager::OnListenerAdded(
124     const EventListenerInfo& details) {
125   for (ScopedVector<SignedInDevicesChangeObserver>::const_iterator it =
126            change_observers_.begin();
127            it != change_observers_.end();
128            ++it) {
129     if ((*it)->extension_id() == details.extension_id) {
130       DCHECK(false) <<"OnListenerAded fired twice for same extension";
131       return;
132     }
133   }
134
135   change_observers_.push_back(new SignedInDevicesChangeObserver(
136       details.extension_id,
137       profile_));
138 }
139
140 void SignedInDevicesManager::OnListenerRemoved(
141     const EventListenerInfo& details) {
142   RemoveChangeObserverForExtension(details.extension_id);
143 }
144
145
146 void SignedInDevicesManager::RemoveChangeObserverForExtension(
147     const std::string& extension_id) {
148   for (ScopedVector<SignedInDevicesChangeObserver>::iterator it =
149            change_observers_.begin();
150            it != change_observers_.end();
151            ++it) {
152     if ((*it)->extension_id() == extension_id) {
153       change_observers_.erase(it);
154       return;
155     }
156   }
157 }
158
159 void SignedInDevicesManager::Observe(
160     int type,
161     const content::NotificationSource& source,
162     const content::NotificationDetails& details) {
163   DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED);
164   UnloadedExtensionInfo* reason =
165       content::Details<UnloadedExtensionInfo>(details).ptr();
166   RemoveChangeObserverForExtension(reason->extension->id());
167 }
168
169 }  // namespace extensions