Home | History | Annotate | Download | only in signed_in_devices
      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|.
     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.
     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 
     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 
     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 
    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