Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / extensions / default_app_order.cc
1 // Copyright (c) 2012 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/chromeos/extensions/default_app_order.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/json/json_file_value_serializer.h"
12 #include "base/path_service.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/common/extensions/extension_constants.h"
16 #include "chromeos/chromeos_paths.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "extensions/common/constants.h"
19
20 namespace chromeos {
21 namespace default_app_order {
22 namespace {
23
24 // The single ExternalLoader instance.
25 ExternalLoader* loader_instance = NULL;
26
27 // Names used in JSON file.
28 const char kOemAppsFolderAttr[] = "oem_apps_folder";
29 const char kLocalizedContentAttr[] = "localized_content";
30 const char kDefaultAttr[] = "default";
31 const char kNameAttr[] = "name";
32 const char kImportDefaultOrderAttr[] = "import_default_order";
33
34 const char* kDefaultAppOrder[] = {
35     extension_misc::kChromeAppId,
36     extensions::kWebStoreAppId,
37     extension_misc::kGoogleSearchAppId,
38     extension_misc::kYoutubeAppId,
39     extension_misc::kGmailAppId,
40     "ejjicmeblgpmajnghnpcppodonldlgfn",  // Calendar
41     "kjebfhglflhjjjiceimfkgicifkhjlnm",  // Scratchpad
42     "lneaknkopdijkpnocmklfnjbeapigfbh",  // Google Maps
43     "apdfllckaahabafndbhieahigkjlhalf",  // Drive
44     extension_misc::kGoogleDocAppId,
45     extension_misc::kGoogleSheetsAppId,
46     extension_misc::kGoogleSlidesAppId,
47     "dlppkpafhbajpcmmoheippocdidnckmm",  // Google+
48     "kbpgddbgniojgndnhlkjbkpknjhppkbk",  // Google+ Hangouts
49     "hhaomjibdihmijegdhdafkllkbggdgoj",  // Files
50     extension_misc::kGooglePlayMusicAppId,
51     "mmimngoggfoobjdlefbcabngfnmieonb",  // Play Books
52     "gdijeikdkaembjbdobgfkoidjkpbmlkd",  // Play Movies & TV
53     "fobcpibfeplaikcclojfdhfdmbbeofai",  // Games
54     "joodangkbfjnajiiifokapkpmhfnpleo",  // Calculator
55     "hfhhnacclhffhdffklopdkcgdhifgngh",  // Camera
56     "gbchcmhmhahfdphkhkmpfmihenigjmpp",  // Chrome Remote Desktop
57 };
58
59 // Reads external ordinal json file and returned the parsed value. Returns NULL
60 // if the file does not exist or could not be parsed properly. Caller takes
61 // ownership of the returned value.
62 base::ListValue* ReadExternalOrdinalFile(const base::FilePath& path) {
63   if (!base::PathExists(path))
64     return NULL;
65
66   JSONFileValueSerializer serializer(path);
67   std::string error_msg;
68   base::Value* value = serializer.Deserialize(NULL, &error_msg);
69   if (!value) {
70     LOG(WARNING) << "Unable to deserialize default app ordinals json data:"
71         << error_msg << ", file=" << path.value();
72     return NULL;
73   }
74
75   base::ListValue* ordinal_list_value = NULL;
76   if (value->GetAsList(&ordinal_list_value))
77     return ordinal_list_value;
78
79   LOG(WARNING) << "Expect a JSON list in file " << path.value();
80   return NULL;
81 }
82
83 std::string GetLocaleSpecificStringImpl(
84     const base::DictionaryValue* root,
85     const std::string& locale,
86     const std::string& dictionary_name,
87     const std::string& entry_name) {
88   const base::DictionaryValue* dictionary_content = NULL;
89   if (!root || !root->GetDictionary(dictionary_name, &dictionary_content))
90     return std::string();
91
92   const base::DictionaryValue* locale_dictionary = NULL;
93   if (dictionary_content->GetDictionary(locale, &locale_dictionary)) {
94     std::string result;
95     if (locale_dictionary->GetString(entry_name, &result))
96       return result;
97   }
98
99   const base::DictionaryValue* default_dictionary = NULL;
100   if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) {
101     std::string result;
102     if (default_dictionary->GetString(entry_name, &result))
103       return result;
104   }
105
106   return std::string();
107 }
108
109 // Gets built-in default app order.
110 void GetDefault(std::vector<std::string>* app_ids) {
111   for (size_t i = 0; i < arraysize(kDefaultAppOrder); ++i)
112     app_ids->push_back(std::string(kDefaultAppOrder[i]));
113 }
114
115 }  // namespace
116
117 const size_t kDefaultAppOrderCount = arraysize(kDefaultAppOrder);
118
119 ExternalLoader::ExternalLoader(bool async)
120     : loaded_(true /* manual_rest */, false /* initially_signaled */) {
121   DCHECK(!loader_instance);
122   loader_instance = this;
123
124   if (async) {
125     content::BrowserThread::PostBlockingPoolTask(FROM_HERE,
126         base::Bind(&ExternalLoader::Load, base::Unretained(this)));
127   } else {
128     Load();
129   }
130 }
131
132 ExternalLoader::~ExternalLoader() {
133   DCHECK(loaded_.IsSignaled());
134   DCHECK_EQ(loader_instance, this);
135   loader_instance = NULL;
136 }
137
138 const std::vector<std::string>& ExternalLoader::GetAppIds() {
139   if (!loaded_.IsSignaled())
140     LOG(ERROR) << "GetAppIds() called before loaded.";
141   return app_ids_;
142 }
143
144 const std::string& ExternalLoader::GetOemAppsFolderName() {
145   if (!loaded_.IsSignaled())
146     LOG(ERROR) << "GetOemAppsFolderName() called before loaded.";
147   return oem_apps_folder_name_;
148 }
149
150 void ExternalLoader::Load() {
151   base::FilePath ordinals_file;
152   CHECK(PathService::Get(chromeos::FILE_DEFAULT_APP_ORDER, &ordinals_file));
153
154   scoped_ptr<base::ListValue> ordinals_value(
155       ReadExternalOrdinalFile(ordinals_file));
156   if (ordinals_value) {
157     std::string locale = g_browser_process->GetApplicationLocale();
158     for (size_t i = 0; i < ordinals_value->GetSize(); ++i) {
159       std::string app_id;
160       base::DictionaryValue* dict = NULL;
161       if (ordinals_value->GetString(i, &app_id)) {
162         app_ids_.push_back(app_id);
163       } else if (ordinals_value->GetDictionary(i, &dict)) {
164         bool flag = false;
165         if (dict->GetBoolean(kOemAppsFolderAttr, &flag) && flag) {
166           oem_apps_folder_name_ = GetLocaleSpecificStringImpl(
167               dict, locale, kLocalizedContentAttr, kNameAttr);
168         } else if (dict->GetBoolean(kImportDefaultOrderAttr, &flag) && flag) {
169           GetDefault(&app_ids_);
170         } else {
171           LOG(ERROR) << "Invalid syntax in default_app_order.json";
172         }
173       } else {
174         LOG(ERROR) << "Invalid entry in default_app_order.json";
175       }
176     }
177   } else {
178     GetDefault(&app_ids_);
179   }
180
181   loaded_.Signal();
182 }
183
184 void Get(std::vector<std::string>* app_ids) {
185   // |loader_instance| could be NULL for test.
186   if (!loader_instance) {
187     GetDefault(app_ids);
188     return;
189   }
190
191   *app_ids = loader_instance->GetAppIds();
192 }
193
194 std::string GetOemAppsFolderName() {
195   // |loader_instance| could be NULL for test.
196   if (!loader_instance)
197     return std::string();
198   else
199     return loader_instance->GetOemAppsFolderName();
200 }
201
202 }  // namespace default_app_order
203 }  // namespace chromeos