1 // Copyright (c) 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_api.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/sync/profile_sync_service.h"
13 #include "chrome/browser/sync/profile_sync_service_factory.h"
14 #include "chrome/common/extensions/api/signed_in_devices.h"
15 #include "components/sync_driver/device_info_tracker.h"
16 #include "components/sync_driver/local_device_info_provider.h"
17 #include "extensions/browser/extension_prefs.h"
19 using base::DictionaryValue
;
20 using sync_driver::DeviceInfo
;
21 using sync_driver::DeviceInfoTracker
;
22 using sync_driver::LocalDeviceInfoProvider
;
24 namespace extensions
{
26 static const char kPrefStringForIdMapping
[] = "id_mapping_dictioanry";
28 // Gets the dictionary that stores the id mapping. The dictionary is stored
29 // in the |ExtensionPrefs|.
30 const base::DictionaryValue
* GetIdMappingDictionary(
31 ExtensionPrefs
* extension_prefs
,
32 const std::string
& extension_id
) {
33 const base::DictionaryValue
* out_value
= NULL
;
34 if (!extension_prefs
->ReadPrefAsDictionary(
36 kPrefStringForIdMapping
,
37 &out_value
) || out_value
== NULL
) {
38 // Looks like this is the first call to get the dictionary. Let us create
39 // a dictionary and set it in to |extension_prefs|.
40 scoped_ptr
<base::DictionaryValue
> dictionary(new base::DictionaryValue());
41 out_value
= dictionary
.get();
42 extension_prefs
->UpdateExtensionPref(
44 kPrefStringForIdMapping
,
45 dictionary
.release());
51 // Helper routine to get all signed in devices. The helper takes in
52 // the pointers for |DeviceInfoTracker| and |Extensionprefs|. This
53 // makes it easier to test by passing mock values for these pointers.
54 ScopedVector
<DeviceInfo
> GetAllSignedInDevices(
55 const std::string
& extension_id
,
56 DeviceInfoTracker
* device_tracker
,
57 ExtensionPrefs
* extension_prefs
) {
58 DCHECK(device_tracker
);
59 ScopedVector
<DeviceInfo
> devices
= device_tracker
->GetAllDeviceInfo();
60 const base::DictionaryValue
* mapping_dictionary
= GetIdMappingDictionary(
64 CHECK(mapping_dictionary
);
66 // |mapping_dictionary| is const. So make an editable copy.
67 scoped_ptr
<base::DictionaryValue
> editable_mapping_dictionary(
68 mapping_dictionary
->DeepCopy());
70 CreateMappingForUnmappedDevices(&(devices
.get()),
71 editable_mapping_dictionary
.get());
73 // Write into |ExtensionPrefs| which will get persisted in disk.
74 extension_prefs
->UpdateExtensionPref(extension_id
,
75 kPrefStringForIdMapping
,
76 editable_mapping_dictionary
.release());
77 return devices
.Pass();
80 ScopedVector
<DeviceInfo
> GetAllSignedInDevices(
81 const std::string
& extension_id
,
83 // Get the device tracker and extension prefs pointers
84 // and call the helper.
85 DeviceInfoTracker
* device_tracker
=
86 ProfileSyncServiceFactory::GetForProfile(profile
)->GetDeviceInfoTracker();
87 DCHECK(device_tracker
);
88 if (!device_tracker
->IsSyncing()) {
89 // Devices are not sync'ing.
90 return ScopedVector
<DeviceInfo
>().Pass();
93 ExtensionPrefs
* extension_prefs
= ExtensionPrefs::Get(profile
);
95 return GetAllSignedInDevices(extension_id
, device_tracker
, extension_prefs
);
98 scoped_ptr
<DeviceInfo
> GetLocalDeviceInfo(const std::string
& extension_id
,
100 ProfileSyncService
* pss
= ProfileSyncServiceFactory::GetForProfile(profile
);
102 return scoped_ptr
<DeviceInfo
>();
105 LocalDeviceInfoProvider
* local_device
= pss
->GetLocalDeviceInfoProvider();
106 DCHECK(local_device
);
107 std::string guid
= local_device
->GetLocalSyncCacheGUID();
108 scoped_ptr
<DeviceInfo
> device
= GetDeviceInfoForClientId(guid
,
111 return device
.Pass();
114 bool SignedInDevicesGetFunction::RunSync() {
115 scoped_ptr
<api::signed_in_devices::Get::Params
> params(
116 api::signed_in_devices::Get::Params::Create(*args_
));
117 EXTENSION_FUNCTION_VALIDATE(params
.get());
119 bool is_local
= params
->is_local
.get() ? *params
->is_local
: false;
122 scoped_ptr
<DeviceInfo
> device
=
123 GetLocalDeviceInfo(extension_id(), GetProfile());
124 base::ListValue
* result
= new base::ListValue();
126 result
->Append(device
->ToValue());
132 ScopedVector
<DeviceInfo
> devices
=
133 GetAllSignedInDevices(extension_id(), GetProfile());
135 scoped_ptr
<base::ListValue
> result(new base::ListValue());
137 for (ScopedVector
<DeviceInfo
>::const_iterator it
= devices
.begin();
140 result
->Append((*it
)->ToValue());
143 SetResult(result
.release());
147 } // namespace extensions