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