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/id_mapping_helper.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/memory/scoped_vector.h"
      9 #include "base/rand_util.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/values.h"
     12 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "components/crx_file/id_util.h"
     15 #include "components/sync_driver/device_info.h"
     16 
     17 using base::DictionaryValue;
     18 using base::Value;
     19 using sync_driver::DeviceInfo;
     20 
     21 namespace extensions {
     22 
     23 std::string GetPublicIdFromGUID(
     24     const base::DictionaryValue& id_mapping,
     25     const std::string& guid) {
     26   for (base::DictionaryValue::Iterator it(id_mapping);
     27        !it.IsAtEnd();
     28        it.Advance()) {
     29     const base::Value& value = it.value();
     30     std::string guid_in_value;
     31     if (!value.GetAsString(&guid_in_value)) {
     32       LOG(ERROR) << "Badly formatted dictionary";
     33       continue;
     34     }
     35     if (guid_in_value == guid) {
     36       return it.key();
     37     }
     38   }
     39 
     40   return std::string();
     41 }
     42 
     43 std::string GetGUIDFromPublicId(
     44     const base::DictionaryValue& id_mapping,
     45     const std::string& id) {
     46   std::string guid;
     47   id_mapping.GetString(id, &guid);
     48   return guid;
     49 }
     50 
     51 // Finds out a random unused id. First finds a random id.
     52 // If the id is in use, increments the id until it finds an unused id.
     53 std::string GetRandomId(
     54   const base::DictionaryValue& mapping,
     55   int device_count) {
     56   // Set the max value for rand to be twice the device count.
     57   int max = device_count * 2;
     58   int rand_value = base::RandInt(0, max);
     59   std::string string_value;
     60   const base::Value *out_value;
     61 
     62   do {
     63     string_value = base::IntToString(rand_value);
     64     rand_value++;
     65   } while (mapping.Get(string_value, &out_value));
     66 
     67   return string_value;
     68 }
     69 
     70 void CreateMappingForUnmappedDevices(
     71     std::vector<DeviceInfo*>* device_info,
     72     base::DictionaryValue* value) {
     73   for (unsigned int i = 0; i < device_info->size(); ++i) {
     74     DeviceInfo* device = (*device_info)[i];
     75     std::string local_id = GetPublicIdFromGUID(*value,
     76                                                device->guid());
     77 
     78     // If the device does not have a local id, set one.
     79     if (local_id.empty()) {
     80       local_id = GetRandomId(*value, device_info->size());
     81       value->SetString(local_id, device->guid());
     82     }
     83     device->set_public_id(local_id);
     84   }
     85 }
     86 
     87 scoped_ptr<DeviceInfo> GetDeviceInfoForClientId(
     88     const std::string& client_id,
     89     const std::string& extension_id,
     90     Profile* profile) {
     91   DCHECK(crx_file::id_util::IdIsValid(extension_id)) << extension_id
     92                                                      << " is not valid";
     93   ScopedVector<DeviceInfo> devices = GetAllSignedInDevices(extension_id,
     94                                                            profile);
     95   for (ScopedVector<DeviceInfo>::iterator it = devices.begin();
     96        it != devices.end();
     97        ++it) {
     98     if ((*it)->guid() == client_id) {
     99       scoped_ptr<DeviceInfo> device(*it);
    100       devices.weak_erase(it);
    101       return device.Pass();
    102     }
    103   }
    104   return scoped_ptr<DeviceInfo>();
    105 }
    106 
    107 }  // namespace  extensions
    108