• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h"
6 
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/glue/device_info.h"
13 #include "chrome/browser/sync/profile_sync_service.h"
14 #include "chrome/browser/sync/profile_sync_service_factory.h"
15 #include "chrome/common/extensions/api/signed_in_devices.h"
16 #include "extensions/browser/extension_prefs.h"
17 
18 using base::DictionaryValue;
19 using browser_sync::DeviceInfo;
20 
21 namespace extensions {
22 
23 static const char kPrefStringForIdMapping[] = "id_mapping_dictioanry";
24 
25 // Gets the dictionary that stores the id mapping. The dictionary is stored
26 // in the |ExtensionPrefs|.
GetIdMappingDictionary(ExtensionPrefs * extension_prefs,const std::string & extension_id)27 const base::DictionaryValue* GetIdMappingDictionary(
28     ExtensionPrefs* extension_prefs,
29     const std::string& extension_id) {
30   const base::DictionaryValue* out_value = NULL;
31   if (!extension_prefs->ReadPrefAsDictionary(
32           extension_id,
33           kPrefStringForIdMapping,
34           &out_value) || out_value == NULL) {
35     // Looks like this is the first call to get the dictionary. Let us create
36     // a dictionary and set it in to |extension_prefs|.
37     scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
38     out_value = dictionary.get();
39     extension_prefs->UpdateExtensionPref(
40         extension_id,
41         kPrefStringForIdMapping,
42         dictionary.release());
43   }
44 
45   return out_value;
46 }
47 
48 // Helper routine to get all signed in devices. The helper takes in
49 // the pointers for |ProfileSyncService| and |Extensionprefs|. This
50 // makes it easier to test by passing mock values for these pointers.
GetAllSignedInDevices(const std::string & extension_id,ProfileSyncService * pss,ExtensionPrefs * extension_prefs)51 ScopedVector<DeviceInfo> GetAllSignedInDevices(
52     const std::string& extension_id,
53     ProfileSyncService* pss,
54     ExtensionPrefs* extension_prefs) {
55   ScopedVector<DeviceInfo> devices = pss->GetAllSignedInDevices();
56   const base::DictionaryValue* mapping_dictionary = GetIdMappingDictionary(
57       extension_prefs,
58       extension_id);
59 
60   CHECK(mapping_dictionary);
61 
62   // |mapping_dictionary| is const. So make an editable copy.
63   scoped_ptr<base::DictionaryValue> editable_mapping_dictionary(
64       mapping_dictionary->DeepCopy());
65 
66   CreateMappingForUnmappedDevices(&(devices.get()),
67                                   editable_mapping_dictionary.get());
68 
69   // Write into |ExtensionPrefs| which will get persisted in disk.
70   extension_prefs->UpdateExtensionPref(extension_id,
71                                        kPrefStringForIdMapping,
72                                        editable_mapping_dictionary.release());
73   return devices.Pass();
74 }
75 
GetAllSignedInDevices(const std::string & extension_id,Profile * profile)76 ScopedVector<DeviceInfo> GetAllSignedInDevices(
77     const std::string& extension_id,
78     Profile* profile) {
79   // Get the profile sync service and extension prefs pointers
80   // and call the helper.
81   ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile);
82   ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile);
83 
84   return GetAllSignedInDevices(extension_id,
85                                pss,
86                                extension_prefs);
87 }
88 
GetLocalDeviceInfo(const std::string & extension_id,Profile * profile)89 scoped_ptr<DeviceInfo> GetLocalDeviceInfo(const std::string& extension_id,
90                                           Profile* profile) {
91   ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile);
92   if (!pss) {
93     return scoped_ptr<DeviceInfo>();
94   }
95   std::string guid = pss->GetLocalSyncCacheGUID();
96   scoped_ptr<DeviceInfo> device = GetDeviceInfoForClientId(guid,
97                                                            extension_id,
98                                                            profile);
99   return device.Pass();
100 }
101 
RunSync()102 bool SignedInDevicesGetFunction::RunSync() {
103   scoped_ptr<api::signed_in_devices::Get::Params> params(
104       api::signed_in_devices::Get::Params::Create(*args_));
105   EXTENSION_FUNCTION_VALIDATE(params.get());
106 
107   bool is_local = params->is_local.get() ? *params->is_local : false;
108 
109   if (is_local) {
110     scoped_ptr<DeviceInfo> device =
111         GetLocalDeviceInfo(extension_id(), GetProfile());
112     base::ListValue* result = new base::ListValue();
113     if (device.get()) {
114       result->Append(device->ToValue());
115     }
116     SetResult(result);
117     return true;
118   }
119 
120   ScopedVector<DeviceInfo> devices =
121       GetAllSignedInDevices(extension_id(), GetProfile());
122 
123   scoped_ptr<base::ListValue> result(new base::ListValue());
124 
125   for (ScopedVector<DeviceInfo>::const_iterator it = devices.begin();
126        it != devices.end();
127        ++it) {
128     result->Append((*it)->ToValue());
129   }
130 
131   SetResult(result.release());
132   return true;
133 }
134 
135 }  // namespace extensions
136 
137