1 // Copyright (c) 2011 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/extensions/external_pref_extension_loader.h"
6
7 #include "app/app_paths.h"
8 #include "base/file_path.h"
9 #include "base/file_util.h"
10 #include "base/logging.h"
11 #include "base/path_service.h"
12 #include "content/browser/browser_thread.h"
13 #include "content/common/json_value_serializer.h"
14
15 namespace {
16
17 // Caller takes ownership of the returned dictionary.
ExtractPrefs(const FilePath & path,ValueSerializer * serializer)18 DictionaryValue* ExtractPrefs(const FilePath& path,
19 ValueSerializer* serializer) {
20 std::string error_msg;
21 Value* extensions = serializer->Deserialize(NULL, &error_msg);
22 if (!extensions) {
23 LOG(WARNING) << "Unable to deserialize json data: " << error_msg
24 << " In file " << path.value() << " .";
25 } else {
26 if (!extensions->IsType(Value::TYPE_DICTIONARY)) {
27 LOG(WARNING) << "Expected a JSON dictionary in file "
28 << path.value() << " .";
29 } else {
30 return static_cast<DictionaryValue*>(extensions);
31 }
32 }
33 return new DictionaryValue;
34 }
35
36 } // namespace
37
ExternalPrefExtensionLoader(int base_path_key)38 ExternalPrefExtensionLoader::ExternalPrefExtensionLoader(int base_path_key)
39 : base_path_key_(base_path_key) {
40 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
41 }
42
GetBaseCrxFilePath()43 const FilePath ExternalPrefExtensionLoader::GetBaseCrxFilePath() {
44 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
45
46 // |base_path_| was set in LoadOnFileThread().
47 return base_path_;
48 }
49
StartLoading()50 void ExternalPrefExtensionLoader::StartLoading() {
51 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 BrowserThread::PostTask(
53 BrowserThread::FILE, FROM_HERE,
54 NewRunnableMethod(
55 this,
56 &ExternalPrefExtensionLoader::LoadOnFileThread));
57 }
58
LoadOnFileThread()59 void ExternalPrefExtensionLoader::LoadOnFileThread() {
60 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
61
62 // TODO(skerner): Some values of base_path_key_ will cause
63 // PathService::Get() to return false, because the path does
64 // not exist. Find and fix the build/install scripts so that
65 // this can become a CHECK(). Known examples include chrome
66 // OS developer builds and linux install packages.
67 // Tracked as crbug.com/70402 .
68
69 scoped_ptr<DictionaryValue> prefs;
70 if (PathService::Get(base_path_key_, &base_path_)) {
71 FilePath json_file;
72 json_file =
73 base_path_.Append(FILE_PATH_LITERAL("external_extensions.json"));
74
75 if (file_util::PathExists(json_file)) {
76 JSONFileValueSerializer serializer(json_file);
77 prefs.reset(ExtractPrefs(json_file, &serializer));
78 }
79 }
80
81 if (!prefs.get())
82 prefs.reset(new DictionaryValue());
83
84 prefs_.reset(prefs.release());
85
86 // If we have any records to process, then we must have
87 // read the .json file. If we read the .json file, then
88 // we were should have set |base_path_|.
89 if (!prefs_->empty())
90 CHECK(!base_path_.empty());
91
92 BrowserThread::PostTask(
93 BrowserThread::UI, FROM_HERE,
94 NewRunnableMethod(
95 this,
96 &ExternalPrefExtensionLoader::LoadFinished));
97 }
98
ExternalTestingExtensionLoader(const std::string & json_data,const FilePath & fake_base_path)99 ExternalTestingExtensionLoader::ExternalTestingExtensionLoader(
100 const std::string& json_data,
101 const FilePath& fake_base_path)
102 : fake_base_path_(fake_base_path) {
103 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
104 JSONStringValueSerializer serializer(json_data);
105 FilePath fake_json_path = fake_base_path.AppendASCII("fake.json");
106 testing_prefs_.reset(ExtractPrefs(fake_json_path, &serializer));
107 }
108
StartLoading()109 void ExternalTestingExtensionLoader::StartLoading() {
110 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 prefs_.reset(testing_prefs_->DeepCopy());
112 LoadFinished();
113 }
114
~ExternalTestingExtensionLoader()115 ExternalTestingExtensionLoader::~ExternalTestingExtensionLoader() {}
116
GetBaseCrxFilePath()117 const FilePath ExternalTestingExtensionLoader::GetBaseCrxFilePath() {
118 return fake_base_path_;
119 }
120