1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/api/signedin_devices/signedin_devices_api.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/scoped_vector.h"
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/values.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/api/signedin_devices/id_mapping_helper.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/glue/device_info.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using base::DictionaryValue;
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using browser_sync::DeviceInfo;
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace extensions {
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const char kPrefStringForIdMapping[] = "id_mapping_dictioanry";
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Gets the dictionary that stores the id mapping. The dictionary is stored
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// in the |ExtensionPrefs|.
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const base::DictionaryValue* GetIdMappingDictionary(
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ExtensionPrefs* extension_prefs,
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& extension_id) {
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const base::DictionaryValue* out_value = NULL;
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!extension_prefs->ReadPrefAsDictionary(
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          extension_id,
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          kPrefStringForIdMapping,
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          &out_value) || out_value == NULL) {
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Looks like this is the first call to get the dictionary. Let us create
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // a dictionary and set it in to |extension_prefs|.
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<DictionaryValue> dictionary(new DictionaryValue());
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    out_value = dictionary.get();
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extension_prefs->UpdateExtensionPref(
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        extension_id,
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        kPrefStringForIdMapping,
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        dictionary.release());
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return out_value;
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Helper routine to get all signed in devices. The helper takes in
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// the pointers for |ProfileSyncService| and |Extensionprefs|. This
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// makes it easier to test by passing mock values for these pointers.
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ScopedVector<DeviceInfo> GetAllSignedInDevices(
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& extension_id,
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ProfileSyncService* pss,
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ExtensionPrefs* extension_prefs) {
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ScopedVector<DeviceInfo> devices = pss->GetAllSignedInDevices();
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const DictionaryValue* mapping_dictionary = GetIdMappingDictionary(
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      extension_prefs,
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      extension_id);
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CHECK(mapping_dictionary);
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // |mapping_dictionary| is const. So make an editable copy.
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<DictionaryValue> editable_mapping_dictionary(
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      mapping_dictionary->DeepCopy());
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CreateMappingForUnmappedDevices(&(devices.get()),
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  editable_mapping_dictionary.get());
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Write into |ExtensionPrefs| which will get persisted in disk.
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  extension_prefs->UpdateExtensionPref(extension_id,
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       kPrefStringForIdMapping,
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       editable_mapping_dictionary.release());
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return devices.Pass();
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ScopedVector<DeviceInfo> GetAllSignedInDevices(
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& extension_id,
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile) {
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Get the profile sync service and extension prefs pointers
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // and call the helper.
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(profile);
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile);
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return GetAllSignedInDevices(extension_id,
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               pss,
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               extension_prefs);
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace extensions
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
90