Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: chrome/browser/extensions/external_pref_extension_loader.cc

Issue 7718021: Add external extensions json source in proper mac location. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: p Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/external_pref_extension_loader.h" 5 #include "chrome/browser/extensions/external_pref_extension_loader.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
10 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "chrome/common/chrome_paths.h"
11 #include "content/browser/browser_thread.h" 13 #include "content/browser/browser_thread.h"
12 #include "content/common/json_value_serializer.h" 14 #include "content/common/json_value_serializer.h"
13 15
14 namespace { 16 namespace {
15 17
16 // Caller takes ownership of the returned dictionary. 18 // Caller takes ownership of the returned dictionary.
17 DictionaryValue* ExtractPrefs(const FilePath& path, 19 DictionaryValue* ExtractPrefs(const FilePath& path,
18 base::ValueSerializer* serializer) { 20 base::ValueSerializer* serializer) {
19 std::string error_msg; 21 std::string error_msg;
20 Value* extensions = serializer->Deserialize(NULL, &error_msg); 22 Value* extensions = serializer->Deserialize(NULL, &error_msg);
21 if (!extensions) { 23 if (!extensions) {
22 LOG(WARNING) << "Unable to deserialize json data: " << error_msg 24 LOG(WARNING) << "Unable to deserialize json data: " << error_msg
23 << " In file " << path.value() << " ."; 25 << " In file " << path.value() << " .";
24 } else { 26 } else {
25 if (!extensions->IsType(Value::TYPE_DICTIONARY)) { 27 if (!extensions->IsType(Value::TYPE_DICTIONARY)) {
26 LOG(WARNING) << "Expected a JSON dictionary in file " 28 LOG(WARNING) << "Expected a JSON dictionary in file "
27 << path.value() << " ."; 29 << path.value() << " .";
28 } else { 30 } else {
29 return static_cast<DictionaryValue*>(extensions); 31 return static_cast<DictionaryValue*>(extensions);
30 } 32 }
31 } 33 }
32 return new DictionaryValue; 34 return new DictionaryValue;
33 } 35 }
34 36
35 } // namespace 37 } // namespace
36 38
37 ExternalPrefExtensionLoader::ExternalPrefExtensionLoader(int base_path_key) 39 ExternalPrefExtensionLoader::ExternalPrefExtensionLoader(int base_path_key,
38 : base_path_key_(base_path_key) { 40 Options options)
41 : base_path_key_(base_path_key),
42 options_(options){
39 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 43 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40 } 44 }
41 45
42 const FilePath ExternalPrefExtensionLoader::GetBaseCrxFilePath() { 46 const FilePath ExternalPrefExtensionLoader::GetBaseCrxFilePath() {
43 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 47 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
44 48
45 // |base_path_| was set in LoadOnFileThread(). 49 // |base_path_| was set in LoadOnFileThread().
46 return base_path_; 50 return base_path_;
47 } 51 }
48 52
49 void ExternalPrefExtensionLoader::StartLoading() { 53 void ExternalPrefExtensionLoader::StartLoading() {
50 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 54 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 BrowserThread::PostTask( 55 BrowserThread::PostTask(
52 BrowserThread::FILE, FROM_HERE, 56 BrowserThread::FILE, FROM_HERE,
53 NewRunnableMethod( 57 NewRunnableMethod(
54 this, 58 this,
55 &ExternalPrefExtensionLoader::LoadOnFileThread)); 59 &ExternalPrefExtensionLoader::LoadOnFileThread));
56 } 60 }
57 61
58 void ExternalPrefExtensionLoader::LoadOnFileThread() { 62 DictionaryValue* ExternalPrefExtensionLoader::ReadJsonPrefsFile() {
59 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
60
61 // TODO(skerner): Some values of base_path_key_ will cause 63 // TODO(skerner): Some values of base_path_key_ will cause
62 // PathService::Get() to return false, because the path does 64 // PathService::Get() to return false, because the path does
63 // not exist. Find and fix the build/install scripts so that 65 // not exist. Find and fix the build/install scripts so that
64 // this can become a CHECK(). Known examples include chrome 66 // this can become a CHECK(). Known examples include chrome
65 // OS developer builds and linux install packages. 67 // OS developer builds and linux install packages.
66 // Tracked as crbug.com/70402 . 68 // Tracked as crbug.com/70402 .
67 69 if (!PathService::Get(base_path_key_, &base_path_)) {
68 scoped_ptr<DictionaryValue> prefs; 70 return NULL;
69 if (PathService::Get(base_path_key_, &base_path_)) {
70 FilePath json_file;
71 json_file =
72 base_path_.Append(FILE_PATH_LITERAL("external_extensions.json"));
73
74 if (file_util::PathExists(json_file)) {
75 JSONFileValueSerializer serializer(json_file);
76 prefs.reset(ExtractPrefs(json_file, &serializer));
77 }
78 } 71 }
79 72
80 if (!prefs.get()) 73 FilePath json_file = base_path_.Append(
81 prefs.reset(new DictionaryValue()); 74 FILE_PATH_LITERAL("external_extensions.json"));
82 75
83 prefs_.reset(prefs.release()); 76 if (!file_util::PathExists(json_file)) {
77 // This is not an error. The file does not exist by default.
78 return NULL;
79 }
80
81 if (IsOptionSet(ENSURE_PATH_CONTROLLED_BY_ADMIN)) {
82 #if defined(OS_MACOSX)
83 if (!file_util::VerifyPathControlledByAdmin(json_file)) {
84 LOG(ERROR) << "Can not read external extensions source. The file "
85 << json_file.value() << " and every directory in its path, "
86 << "must be owned by root, have group \"admin\", and not be "
87 << "writable by all users. These restrictions prevent "
88 << "unprivleged users from making chrome install extensions "
89 << "on other users' accounts.";
90 return NULL;
91 }
92 #else
93 // The only platform that uses this check is Mac OS. If you add one,
94 // you need to implement file_util::VerifyPathControlledByAdmin() for
95 // that platform.
96 NOTREACHED();
97 #endif // defined(OS_MACOSX)
98 }
99
100 JSONFileValueSerializer serializer(json_file);
101 return ExtractPrefs(json_file, &serializer);
102 }
103
104 void ExternalPrefExtensionLoader::LoadOnFileThread() {
105 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
106
107 prefs_.reset(ReadJsonPrefsFile());
108 if (!prefs_.get())
109 prefs_.reset(new DictionaryValue());
110
111 // We want to deprecate the external extensions file inside the app
112 // bundle on mac os. Use a histogram to see how many extensions
113 // are installed using the deprecated path, and how many are installed
114 // from the supported path. We can use this data to measure the
115 // effectiveness of asking developers to use the new path, or any
116 // automatic migration methods we implement.
117 #if defined(OS_MACOSX)
118 // The deprecated path only exists on mac for now.
119 if (base_path_key_ == chrome::DIR_DEPRICATED_EXTERNAL_EXTENSIONS) {
120 UMA_HISTOGRAM_COUNTS_100("Extensions.DepricatedExternalJsonCount",
121 prefs_->size());
122 }
123 #endif // defined(OS_MACOSX)
124 if (base_path_key_ == chrome::DIR_EXTERNAL_EXTENSIONS) {
125 UMA_HISTOGRAM_COUNTS_100("Extensions.ExternalJsonCount",
126 prefs_->size());
127 }
84 128
85 // If we have any records to process, then we must have 129 // If we have any records to process, then we must have
86 // read the .json file. If we read the .json file, then 130 // read the .json file. If we read the .json file, then
87 // we were should have set |base_path_|. 131 // we were should have set |base_path_|.
88 if (!prefs_->empty()) 132 if (!prefs_->empty())
89 CHECK(!base_path_.empty()); 133 CHECK(!base_path_.empty());
90 134
91 BrowserThread::PostTask( 135 BrowserThread::PostTask(
92 BrowserThread::UI, FROM_HERE, 136 BrowserThread::UI, FROM_HERE,
93 NewRunnableMethod( 137 NewRunnableMethod(
(...skipping 15 matching lines...) Expand all
109 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110 prefs_.reset(testing_prefs_->DeepCopy()); 154 prefs_.reset(testing_prefs_->DeepCopy());
111 LoadFinished(); 155 LoadFinished();
112 } 156 }
113 157
114 ExternalTestingExtensionLoader::~ExternalTestingExtensionLoader() {} 158 ExternalTestingExtensionLoader::~ExternalTestingExtensionLoader() {}
115 159
116 const FilePath ExternalTestingExtensionLoader::GetBaseCrxFilePath() { 160 const FilePath ExternalTestingExtensionLoader::GetBaseCrxFilePath() {
117 return fake_base_path_; 161 return fake_base_path_;
118 } 162 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/external_pref_extension_loader.h ('k') | chrome/common/chrome_paths.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698