default_app_order.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/common/extensions/extension_constants.h"
15#include "chromeos/chromeos_paths.h"
16#include "content/public/browser/browser_thread.h"
17
18namespace chromeos {
19namespace default_app_order {
20
21namespace {
22
23// The single ExternalLoader instance.
24ExternalLoader* loader_instance = NULL;
25
26// Reads external ordinal json file and returned the parsed value. Returns NULL
27// if the file does not exist or could not be parsed properly. Caller takes
28// ownership of the returned value.
29base::ListValue* ReadExternalOrdinalFile(const base::FilePath& path) {
30  if (!base::PathExists(path))
31    return NULL;
32
33  JSONFileValueSerializer serializer(path);
34  std::string error_msg;
35  base::Value* value = serializer.Deserialize(NULL, &error_msg);
36  if (!value) {
37    LOG(WARNING) << "Unable to deserialize default app ordinals json data:"
38        << error_msg << ", file=" << path.value();
39    return NULL;
40  }
41
42  base::ListValue* ordinal_list_value = NULL;
43  if (value->GetAsList(&ordinal_list_value))
44    return ordinal_list_value;
45
46  LOG(WARNING) << "Expect a JSON list in file " << path.value();
47  return NULL;
48}
49
50// Gets built-in default app order.
51void GetDefault(std::vector<std::string>* app_ids) {
52  DCHECK(app_ids && app_ids->empty());
53
54  const char* kDefaultAppOrder[] = {
55    extension_misc::kChromeAppId,
56    extension_misc::kWebStoreAppId,
57    extension_misc::kGoogleSearchAppId,
58    extension_misc::kYoutubeAppId,
59    extension_misc::kGmailAppId,
60    "ejjicmeblgpmajnghnpcppodonldlgfn",  // Calendar
61    "kjebfhglflhjjjiceimfkgicifkhjlnm",  // Scratchpad
62    "lneaknkopdijkpnocmklfnjbeapigfbh",  // Google Maps
63    "apdfllckaahabafndbhieahigkjlhalf",  // Drive
64    extension_misc::kGoogleDocAppId,
65    extension_misc::kGoogleSheetsAppId,
66    extension_misc::kGoogleSlidesAppId,
67    "dlppkpafhbajpcmmoheippocdidnckmm",  // Google+
68    "kbpgddbgniojgndnhlkjbkpknjhppkbk",  // Google+ Hangouts
69    "hhaomjibdihmijegdhdafkllkbggdgoj",  // Files
70    "hkhhlkdconhgemhegnplaldnmnmkaemd",  // Tips & Tricks
71    extension_misc::kGooglePlayMusicAppId,
72    "mmimngoggfoobjdlefbcabngfnmieonb",  // Play Books
73    "fppdphmgcddhjeddoeghpjefkdlccljb",  // Play Movies
74    "fobcpibfeplaikcclojfdhfdmbbeofai",  // Games
75    "joodangkbfjnajiiifokapkpmhfnpleo",  // Calculator
76    "hfhhnacclhffhdffklopdkcgdhifgngh",  // Camera
77    "gbchcmhmhahfdphkhkmpfmihenigjmpp",  // Chrome Remote Desktop
78  };
79
80  for (size_t i = 0; i < arraysize(kDefaultAppOrder); ++i)
81    app_ids->push_back(std::string(kDefaultAppOrder[i]));
82}
83
84}  // namespace
85
86ExternalLoader::ExternalLoader(bool async)
87    : loaded_(true /* manual_rest */, false /* initially_signaled */) {
88  DCHECK(!loader_instance);
89  loader_instance = this;
90
91  if (async) {
92    content::BrowserThread::PostBlockingPoolTask(FROM_HERE,
93        base::Bind(&ExternalLoader::Load, base::Unretained(this)));
94  } else {
95    Load();
96  }
97}
98
99ExternalLoader::~ExternalLoader() {
100  DCHECK(loaded_.IsSignaled());
101  DCHECK_EQ(loader_instance, this);
102  loader_instance = NULL;
103}
104
105const std::vector<std::string>& ExternalLoader::GetAppIds() {
106  if (!loaded_.IsSignaled())
107    LOG(ERROR) << "GetAppIds() called before loaded.";
108  return app_ids_;
109}
110
111void ExternalLoader::Load() {
112  base::FilePath ordinals_file;
113  CHECK(PathService::Get(chromeos::FILE_DEFAULT_APP_ORDER, &ordinals_file));
114
115  scoped_ptr<base::ListValue> ordinals_value(
116      ReadExternalOrdinalFile(ordinals_file));
117  if (ordinals_value) {
118    for (size_t i = 0; i < ordinals_value->GetSize(); ++i) {
119      std::string app_id;
120      CHECK(ordinals_value->GetString(i, &app_id));
121      app_ids_.push_back(app_id);
122    }
123  } else {
124    GetDefault(&app_ids_);
125  }
126
127  loaded_.Signal();
128}
129
130void Get(std::vector<std::string>* app_ids) {
131  // |loader_instance| could be NULL for test.
132  if (!loader_instance) {
133    GetDefault(app_ids);
134    return;
135  }
136
137  *app_ids = loader_instance->GetAppIds();
138}
139
140}  // namespace default_app_order
141}  // namespace chromeos
142