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.
5 #include "chrome/browser/chromeos/extensions/default_app_order.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"
21 namespace default_app_order
{
24 // The single ExternalLoader instance.
25 ExternalLoader
* loader_instance
= NULL
;
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";
34 const char* const 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
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
))
66 JSONFileValueDeserializer
deserializer(path
);
67 std::string error_msg
;
68 base::Value
* value
= deserializer
.Deserialize(NULL
, &error_msg
);
70 LOG(WARNING
) << "Unable to deserialize default app ordinals json data:"
71 << error_msg
<< ", file=" << path
.value();
75 base::ListValue
* ordinal_list_value
= NULL
;
76 if (value
->GetAsList(&ordinal_list_value
))
77 return ordinal_list_value
;
79 LOG(WARNING
) << "Expect a JSON list in file " << path
.value();
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
))
92 const base::DictionaryValue
* locale_dictionary
= NULL
;
93 if (dictionary_content
->GetDictionary(locale
, &locale_dictionary
)) {
95 if (locale_dictionary
->GetString(entry_name
, &result
))
99 const base::DictionaryValue
* default_dictionary
= NULL
;
100 if (dictionary_content
->GetDictionary(kDefaultAttr
, &default_dictionary
)) {
102 if (default_dictionary
->GetString(entry_name
, &result
))
106 return std::string();
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
]));
117 const size_t kDefaultAppOrderCount
= arraysize(kDefaultAppOrder
);
119 ExternalLoader::ExternalLoader(bool async
)
120 : loaded_(true /* manual_rest */, false /* initially_signaled */) {
121 DCHECK(!loader_instance
);
122 loader_instance
= this;
125 content::BrowserThread::PostBlockingPoolTask(FROM_HERE
,
126 base::Bind(&ExternalLoader::Load
, base::Unretained(this)));
132 ExternalLoader::~ExternalLoader() {
133 DCHECK(loaded_
.IsSignaled());
134 DCHECK_EQ(loader_instance
, this);
135 loader_instance
= NULL
;
138 const std::vector
<std::string
>& ExternalLoader::GetAppIds() {
139 if (!loaded_
.IsSignaled())
140 LOG(ERROR
) << "GetAppIds() called before loaded.";
144 const std::string
& ExternalLoader::GetOemAppsFolderName() {
145 if (!loaded_
.IsSignaled())
146 LOG(ERROR
) << "GetOemAppsFolderName() called before loaded.";
147 return oem_apps_folder_name_
;
150 void ExternalLoader::Load() {
151 base::FilePath ordinals_file
;
152 CHECK(PathService::Get(chromeos::FILE_DEFAULT_APP_ORDER
, &ordinals_file
));
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
) {
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
)) {
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_
);
171 LOG(ERROR
) << "Invalid syntax in default_app_order.json";
174 LOG(ERROR
) << "Invalid entry in default_app_order.json";
178 GetDefault(&app_ids_
);
184 void Get(std::vector
<std::string
>* app_ids
) {
185 // |loader_instance| could be NULL for test.
186 if (!loader_instance
) {
191 *app_ids
= loader_instance
->GetAppIds();
194 std::string
GetOemAppsFolderName() {
195 // |loader_instance| could be NULL for test.
196 if (!loader_instance
)
197 return std::string();
199 return loader_instance
->GetOemAppsFolderName();
202 } // namespace default_app_order
203 } // namespace chromeos