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/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/extensions/extension_system.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/sync/glue/device_info.h"
21 #include "chrome/browser/sync/profile_sync_service.h"
22 #include "chrome/browser/sync/profile_sync_service_factory.h"
23 #include "chrome/common/extensions/api/signed_in_devices.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_source.h"
29 #include "extensions/browser/event_router.h"
30 #include "extensions/common/extension.h"
32 using browser_sync::DeviceInfo
;
33 namespace extensions
{
36 void FillDeviceInfo(const DeviceInfo
& device_info
,
37 api::signed_in_devices::DeviceInfo
* api_device_info
) {
38 api_device_info
->id
= device_info
.public_id();
39 api_device_info
->name
= device_info
.client_name();
40 api_device_info
->os
= api::signed_in_devices::ParseOS(
41 device_info
.GetOSString());
42 api_device_info
->type
= api::signed_in_devices::ParseDeviceType(
43 device_info
.GetDeviceTypeString());
44 api_device_info
->chrome_version
= device_info
.chrome_version();
48 SignedInDevicesChangeObserver::SignedInDevicesChangeObserver(
49 const std::string
& extension_id
,
50 Profile
* profile
) : extension_id_(extension_id
),
52 ProfileSyncService
* pss
= ProfileSyncServiceFactory::GetForProfile(profile_
);
54 pss
->AddObserverForDeviceInfoChange(this);
58 SignedInDevicesChangeObserver::~SignedInDevicesChangeObserver() {
59 ProfileSyncService
* pss
= ProfileSyncServiceFactory::GetForProfile(profile_
);
61 pss
->RemoveObserverForDeviceInfoChange(this);
66 void SignedInDevicesChangeObserver::OnDeviceInfoChange() {
67 // There is a change in the list of devices. Get all devices and send them to
69 ScopedVector
<DeviceInfo
> devices
= GetAllSignedInDevices(extension_id_
,
72 std::vector
<linked_ptr
<api::signed_in_devices::DeviceInfo
> > args
;
74 for (ScopedVector
<DeviceInfo
>::const_iterator it
= devices
.begin();
77 linked_ptr
<api::signed_in_devices::DeviceInfo
> api_device
=
78 make_linked_ptr(new api::signed_in_devices::DeviceInfo
);
79 FillDeviceInfo(*(*it
), api_device
.get());
80 args
.push_back(api_device
);
83 scoped_ptr
<base::ListValue
> result
=
84 api::signed_in_devices::OnDeviceInfoChange::Create(args
);
85 scoped_ptr
<Event
> event(new Event(
86 api::signed_in_devices::OnDeviceInfoChange::kEventName
,
89 event
->restrict_to_browser_context
= profile_
;
91 ExtensionSystem::Get(profile_
)->event_router()->DispatchEventToExtension(
92 extension_id_
, event
.Pass());
95 static base::LazyInstance
<ProfileKeyedAPIFactory
<SignedInDevicesManager
> >
96 g_factory
= LAZY_INSTANCE_INITIALIZER
;
99 ProfileKeyedAPIFactory
<SignedInDevicesManager
>*
100 SignedInDevicesManager::GetFactoryInstance() {
101 return &g_factory
.Get();
104 SignedInDevicesManager::SignedInDevicesManager()
107 SignedInDevicesManager::SignedInDevicesManager(Profile
* profile
)
108 : profile_(profile
) {
109 extensions::EventRouter
* router
= extensions::ExtensionSystem::Get(
110 profile_
)->event_router();
113 router
->RegisterObserver(
114 this, api::signed_in_devices::OnDeviceInfoChange::kEventName
);
117 // Register for unload event so we could clear all our listeners when
118 // extensions have unloaded.
119 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED
,
120 content::Source
<Profile
>(profile_
->GetOriginalProfile()));
123 SignedInDevicesManager::~SignedInDevicesManager() {}
125 void SignedInDevicesManager::OnListenerAdded(
126 const EventListenerInfo
& details
) {
127 for (ScopedVector
<SignedInDevicesChangeObserver
>::const_iterator it
=
128 change_observers_
.begin();
129 it
!= change_observers_
.end();
131 if ((*it
)->extension_id() == details
.extension_id
) {
132 DCHECK(false) <<"OnListenerAded fired twice for same extension";
137 change_observers_
.push_back(new SignedInDevicesChangeObserver(
138 details
.extension_id
,
142 void SignedInDevicesManager::OnListenerRemoved(
143 const EventListenerInfo
& details
) {
144 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::Observe(
163 const content::NotificationSource
& source
,
164 const content::NotificationDetails
& details
) {
165 DCHECK_EQ(type
, chrome::NOTIFICATION_EXTENSION_UNLOADED
);
166 UnloadedExtensionInfo
* reason
=
167 content::Details
<UnloadedExtensionInfo
>(details
).ptr();
168 RemoveChangeObserverForExtension(reason
->extension
->id());
171 } // namespace extensions