1// Copyright 2014 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/apps/drive/drive_app_mapping.h"
6
7#include "base/prefs/pref_service.h"
8#include "base/prefs/scoped_user_pref_update.h"
9#include "base/values.h"
10#include "chrome/common/pref_names.h"
11#include "components/pref_registry/pref_registry_syncable.h"
12
13namespace {
14
15// Key for a string value that holds the mapped chrome app id.
16const char kKeyChromeApp[] = "chrome_app";
17
18// Key for a boolean value of whether the mapped chrome app is auto generated.
19// Default is false.
20const char kKeyGenerated[] = "generated";
21
22scoped_ptr<base::DictionaryValue> CreateInfoDict(
23    const std::string& chrome_app_id,
24    bool generated) {
25  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
26  dict->SetStringWithoutPathExpansion(kKeyChromeApp, chrome_app_id);
27
28  // Only writes non-default value.
29  if (generated)
30    dict->SetBooleanWithoutPathExpansion(kKeyGenerated, true);
31  return dict.Pass();
32}
33
34}  // namespace
35
36DriveAppMapping::DriveAppMapping(PrefService* prefs) : prefs_(prefs) {
37}
38
39DriveAppMapping::~DriveAppMapping() {
40}
41
42// static
43void DriveAppMapping::RegisterProfilePrefs(
44    user_prefs::PrefRegistrySyncable* registry) {
45  registry->RegisterDictionaryPref(
46      prefs::kAppLauncherDriveAppMapping,
47      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
48}
49
50void DriveAppMapping::Add(const std::string& drive_app_id,
51                          const std::string& chrome_app_id,
52                          bool generated) {
53  DictionaryPrefUpdate update(prefs_, prefs::kAppLauncherDriveAppMapping);
54  update->SetWithoutPathExpansion(
55      drive_app_id, CreateInfoDict(chrome_app_id, generated).release());
56}
57
58void DriveAppMapping::Remove(const std::string& drive_app_id) {
59  DictionaryPrefUpdate update(prefs_, prefs::kAppLauncherDriveAppMapping);
60  update->RemoveWithoutPathExpansion(drive_app_id, NULL);
61}
62
63std::string DriveAppMapping::GetChromeApp(
64    const std::string& drive_app_id) const {
65  const base::DictionaryValue* mapping =
66      prefs_->GetDictionary(prefs::kAppLauncherDriveAppMapping);
67  const base::DictionaryValue* info_dict;
68  std::string chrome_app_id;
69  if (mapping->GetDictionaryWithoutPathExpansion(drive_app_id, &info_dict) &&
70      info_dict->GetStringWithoutPathExpansion(kKeyChromeApp, &chrome_app_id)) {
71    return chrome_app_id;
72  }
73
74  return std::string();
75}
76
77std::string DriveAppMapping::GetDriveApp(
78    const std::string& chrome_app_id) const {
79  const base::DictionaryValue* mapping =
80      prefs_->GetDictionary(prefs::kAppLauncherDriveAppMapping);
81  for (base::DictionaryValue::Iterator it(*mapping); !it.IsAtEnd();
82       it.Advance()) {
83    const base::DictionaryValue* info_dict;
84    std::string value_string;
85    DCHECK(it.value().IsType(base::Value::TYPE_DICTIONARY));
86    if (it.value().GetAsDictionary(&info_dict) &&
87        info_dict->GetStringWithoutPathExpansion(kKeyChromeApp,
88                                                 &value_string) &&
89        value_string == chrome_app_id) {
90      return it.key();
91    }
92  }
93  return std::string();
94}
95
96bool DriveAppMapping::IsChromeAppGenerated(
97    const std::string& chrome_app_id) const {
98  const base::DictionaryValue* mapping =
99      prefs_->GetDictionary(prefs::kAppLauncherDriveAppMapping);
100  for (base::DictionaryValue::Iterator it(*mapping); !it.IsAtEnd();
101       it.Advance()) {
102    const base::DictionaryValue* info_dict;
103    std::string value_string;
104    bool generated = false;
105    DCHECK(it.value().IsType(base::Value::TYPE_DICTIONARY));
106    if (it.value().GetAsDictionary(&info_dict) &&
107        info_dict->GetStringWithoutPathExpansion(kKeyChromeApp,
108                                                 &value_string) &&
109        value_string == chrome_app_id &&
110        info_dict->GetBooleanWithoutPathExpansion(kKeyGenerated, &generated)) {
111      return generated;
112    }
113  }
114
115  return false;
116}
117
118std::set<std::string> DriveAppMapping::GetDriveAppIds() const {
119  const base::DictionaryValue* mapping =
120      prefs_->GetDictionary(prefs::kAppLauncherDriveAppMapping);
121  std::set<std::string> keys;
122  for (base::DictionaryValue::Iterator it(*mapping); !it.IsAtEnd();
123       it.Advance()) {
124    keys.insert(it.key());
125  }
126  return keys;
127}
128