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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/compiler_specific.h" 12 #include "base/macros.h" 13 #include "base/values.h" 14 #include "chrome/browser/extensions/external_loader.h" 15 16 class Profile; 17 18 namespace extensions { 19 20 // A specialization of the ExternalLoader that uses a json file to 21 // look up which external extensions are registered. 22 // Instances of this class are expected to be created and destroyed on the UI 23 // thread and they are expecting public method calls from the UI thread. 24 class ExternalPrefLoader : public ExternalLoader { 25 public: 26 enum Options { 27 NONE = 0, 28 29 // Ensure that only root can force an external install by checking 30 // that all components of the path to external extensions files are 31 // owned by root and not writable by any non-root user. 32 ENSURE_PATH_CONTROLLED_BY_ADMIN = 1 << 0, 33 34 #if defined(OS_CHROMEOS) 35 // Delay external preference load. It delays default apps installation 36 // to not overload the system on first time user login. 37 DELAY_LOAD_UNTIL_PRIORITY_SYNC = 1 << 1, 38 #endif 39 40 // Use profile user type filter to load extensions. 41 USE_USER_TYPE_PROFILE_FILTER = 1 << 2, 42 }; 43 44 // |base_path_id| is the directory containing the external_extensions.json 45 // file or the standalone extension manifest files. Relative file paths to 46 // extension files are resolved relative to this path. |profile| is used to 47 // wait priority sync if DELAY_LOAD_UNTIL_PRIORITY_SYNC set. 48 // |options| is combination of |Options|. 49 ExternalPrefLoader(int base_path_id, int options, Profile* profile); 50 51 const base::FilePath GetBaseCrxFilePath() override; 52 53 protected: 54 ~ExternalPrefLoader() override; 55 56 void StartLoading() override; IsOptionSet(Options option)57 bool IsOptionSet(Options option) { 58 return (options_ & option) != 0; 59 } 60 61 // The resource id of the base path with the information about the json 62 // file containing which extensions to load. 63 const int base_path_id_; 64 65 const int options_; 66 67 private: 68 friend class base::RefCountedThreadSafe<ExternalLoader>; 69 friend class ExternalTestingLoader; 70 friend class TestExternalPrefLoader; 71 72 #if defined(OS_CHROMEOS) 73 class PrioritySyncReadyWaiter; 74 #endif 75 76 // Extracts extension information from a json file serialized by |serializer|. 77 // |path| is only used for informational purposes (outputted when an error 78 // occurs). An empty dictionary is returned in case of failure (e.g. invalid 79 // path or json content). 80 static std::unique_ptr<base::DictionaryValue> ExtractExtensionPrefs( 81 base::ValueDeserializer* deserializer, 82 const base::FilePath& path); 83 84 // If priority sync ready posts LoadOnFileThread and return true. 85 bool PostLoadIfPrioritySyncReady(); 86 87 // Post LoadOnFileThread and stop observing for sync service states. 88 void PostLoadAndRemoveObservers(); 89 90 // Actually searches for and loads candidate standalone extension preference 91 // files in the path corresponding to |base_path_id|. 92 // Must be called on the file thread. 93 // Note: Overridden in tests. 94 virtual void LoadOnFileThread(); 95 96 // Extracts the information contained in an external_extension.json file 97 // regarding which extensions to install. |prefs| will be modified to 98 // receive the extracted extension information. 99 // Must be called from the File thread. 100 void ReadExternalExtensionPrefFile(base::DictionaryValue* prefs); 101 102 // Extracts the information contained in standalone external extension 103 // json files (<extension id>.json) regarding what external extensions 104 // to install. |prefs| will be modified to receive the extracted extension 105 // information. 106 // Must be called from the File thread. 107 void ReadStandaloneExtensionPrefFiles(base::DictionaryValue* prefs); 108 109 #if defined(OS_CHROMEOS) 110 void OnPrioritySyncReady(PrioritySyncReadyWaiter* waiter); 111 #endif 112 113 // The path (coresponding to |base_path_id_| containing the json files 114 // describing which extensions to load. 115 base::FilePath base_path_; 116 117 // Profile that loads these external prefs. 118 // Needed for waiting for waiting priority sync. 119 Profile* profile_; 120 121 // User type determined by |profile_|. Used to filter extensions. In some unit 122 // tests may not be set. 123 const std::string user_type_; 124 125 // Task runner for tasks that touch file. 126 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 127 128 #if defined(OS_CHROMEOS) 129 std::vector<std::unique_ptr<PrioritySyncReadyWaiter>> pending_waiter_list_; 130 #endif 131 132 DISALLOW_COPY_AND_ASSIGN(ExternalPrefLoader); 133 }; 134 135 } // namespace extensions 136 137 #endif // CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_ 138