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. 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 38 ExternalPrefExtensionLoader::ExternalPrefExtensionLoader(int base_path_key) 39 : base_path_key_(base_path_key) { 40 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 41 } 42 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 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 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 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 109 void ExternalTestingExtensionLoader::StartLoading() { 110 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 prefs_.reset(testing_prefs_->DeepCopy()); 112 LoadFinished(); 113 } 114 115 ExternalTestingExtensionLoader::~ExternalTestingExtensionLoader() {} 116 117 const FilePath ExternalTestingExtensionLoader::GetBaseCrxFilePath() { 118 return fake_base_path_; 119 } 120