Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / signed_in_devices / signed_in_devices_manager.cc
blob39160c2a5770fc9b1daf7ab9e6eb2a70e69dfb65
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.
5 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h"
7 #include <string>
8 #include <vector>
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/extensions/api/signed_in_devices/signed_in_devices_api.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/sync/profile_sync_service.h"
19 #include "chrome/browser/sync/profile_sync_service_factory.h"
20 #include "chrome/common/extensions/api/signed_in_devices.h"
21 #include "components/sync_driver/device_info.h"
22 #include "extensions/browser/event_router.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/common/extension.h"
26 using sync_driver::DeviceInfo;
27 namespace extensions {
29 namespace {
30 void FillDeviceInfo(const DeviceInfo& device_info,
31 api::signed_in_devices::DeviceInfo* api_device_info) {
32 api_device_info->id = device_info.public_id();
33 api_device_info->name = device_info.client_name();
34 api_device_info->os = api::signed_in_devices::ParseOS(
35 device_info.GetOSString());
36 api_device_info->type = api::signed_in_devices::ParseDeviceType(
37 device_info.GetDeviceTypeString());
38 api_device_info->chrome_version = device_info.chrome_version();
40 } // namespace
42 SignedInDevicesChangeObserver::SignedInDevicesChangeObserver(
43 const std::string& extension_id,
44 Profile* profile) : extension_id_(extension_id),
45 profile_(profile) {
46 ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile_);
47 if (pss) {
48 DCHECK(pss->GetDeviceInfoTracker());
49 pss->GetDeviceInfoTracker()->AddObserver(this);
53 SignedInDevicesChangeObserver::~SignedInDevicesChangeObserver() {
54 ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile_);
55 if (pss) {
56 DCHECK(pss->GetDeviceInfoTracker());
57 pss->GetDeviceInfoTracker()->RemoveObserver(this);
61 void SignedInDevicesChangeObserver::OnDeviceInfoChange() {
62 // There is a change in the list of devices. Get all devices and send them to
63 // the listener.
64 ScopedVector<DeviceInfo> devices = GetAllSignedInDevices(extension_id_,
65 profile_);
67 std::vector<linked_ptr<api::signed_in_devices::DeviceInfo> > args;
69 for (ScopedVector<DeviceInfo>::const_iterator it = devices.begin();
70 it != devices.end();
71 ++it) {
72 linked_ptr<api::signed_in_devices::DeviceInfo> api_device =
73 make_linked_ptr(new api::signed_in_devices::DeviceInfo);
74 FillDeviceInfo(*(*it), api_device.get());
75 args.push_back(api_device);
78 scoped_ptr<base::ListValue> result =
79 api::signed_in_devices::OnDeviceInfoChange::Create(args);
80 scoped_ptr<Event> event(new Event(
81 events::SIGNED_IN_DEVICES_ON_DEVICE_INFO_CHANGE,
82 api::signed_in_devices::OnDeviceInfoChange::kEventName, result.Pass()));
84 event->restrict_to_browser_context = profile_;
86 EventRouter::Get(profile_)->DispatchEventToExtension(
87 extension_id_, event.Pass());
90 static base::LazyInstance<
91 BrowserContextKeyedAPIFactory<SignedInDevicesManager> > g_factory =
92 LAZY_INSTANCE_INITIALIZER;
94 // static
95 BrowserContextKeyedAPIFactory<SignedInDevicesManager>*
96 SignedInDevicesManager::GetFactoryInstance() {
97 return g_factory.Pointer();
100 SignedInDevicesManager::SignedInDevicesManager()
101 : profile_(NULL), extension_registry_observer_(this) {
104 SignedInDevicesManager::SignedInDevicesManager(content::BrowserContext* context)
105 : profile_(Profile::FromBrowserContext(context)),
106 extension_registry_observer_(this) {
107 EventRouter* router = EventRouter::Get(profile_);
108 if (router) {
109 router->RegisterObserver(
110 this, api::signed_in_devices::OnDeviceInfoChange::kEventName);
113 // Register for unload event so we could clear all our listeners when
114 // extensions have unloaded.
115 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
118 SignedInDevicesManager::~SignedInDevicesManager() {
119 if (profile_) {
120 EventRouter* router = EventRouter::Get(profile_);
121 if (router)
122 router->UnregisterObserver(this);
126 void SignedInDevicesManager::OnListenerAdded(
127 const EventListenerInfo& details) {
128 for (ScopedVector<SignedInDevicesChangeObserver>::const_iterator it =
129 change_observers_.begin();
130 it != change_observers_.end();
131 ++it) {
132 if ((*it)->extension_id() == details.extension_id) {
133 DCHECK(false) <<"OnListenerAded fired twice for same extension";
134 return;
138 change_observers_.push_back(new SignedInDevicesChangeObserver(
139 details.extension_id,
140 profile_));
143 void SignedInDevicesManager::OnListenerRemoved(
144 const EventListenerInfo& details) {
145 RemoveChangeObserverForExtension(details.extension_id);
148 void SignedInDevicesManager::RemoveChangeObserverForExtension(
149 const std::string& extension_id) {
150 for (ScopedVector<SignedInDevicesChangeObserver>::iterator it =
151 change_observers_.begin();
152 it != change_observers_.end();
153 ++it) {
154 if ((*it)->extension_id() == extension_id) {
155 change_observers_.erase(it);
156 return;
161 void SignedInDevicesManager::OnExtensionUnloaded(
162 content::BrowserContext* browser_context,
163 const Extension* extension,
164 UnloadedExtensionInfo::Reason reason) {
165 RemoveChangeObserverForExtension(extension->id());
168 } // namespace extensions