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"
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
{
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();
42 SignedInDevicesChangeObserver::SignedInDevicesChangeObserver(
43 const std::string
& extension_id
,
44 Profile
* profile
) : extension_id_(extension_id
),
46 ProfileSyncService
* pss
= ProfileSyncServiceFactory::GetForProfile(profile_
);
48 DCHECK(pss
->GetDeviceInfoTracker());
49 pss
->GetDeviceInfoTracker()->AddObserver(this);
53 SignedInDevicesChangeObserver::~SignedInDevicesChangeObserver() {
54 ProfileSyncService
* pss
= ProfileSyncServiceFactory::GetForProfile(profile_
);
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
64 ScopedVector
<DeviceInfo
> devices
= GetAllSignedInDevices(extension_id_
,
67 std::vector
<linked_ptr
<api::signed_in_devices::DeviceInfo
> > args
;
69 for (ScopedVector
<DeviceInfo
>::const_iterator it
= devices
.begin();
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
;
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_
);
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() {
120 EventRouter
* router
= EventRouter::Get(profile_
);
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();
132 if ((*it
)->extension_id() == details
.extension_id
) {
133 DCHECK(false) <<"OnListenerAded fired twice for same extension";
138 change_observers_
.push_back(new SignedInDevicesChangeObserver(
139 details
.extension_id
,
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();
154 if ((*it
)->extension_id() == extension_id
) {
155 change_observers_
.erase(it
);
161 void SignedInDevicesManager::OnExtensionUnloaded(
162 content::BrowserContext
* browser_context
,
163 const Extension
* extension
,
164 UnloadedExtensionInfo::Reason reason
) {
165 RemoveChangeObserverForExtension(extension
->id());
168 } // namespace extensions