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_COMPONENT_LOADER_H_
6#define CHROME_BROWSER_EXTENSIONS_COMPONENT_LOADER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/callback_forward.h"
12#include "base/files/file_path.h"
13#include "base/gtest_prod_util.h"
14#include "base/memory/weak_ptr.h"
15#include "base/values.h"
16
17class ExtensionServiceInterface;
18class PrefService;
19
20namespace content {
21class BrowserContext;
22}
23
24namespace extensions {
25
26// For registering, loading, and unloading component extensions.
27class ComponentLoader {
28 public:
29  ComponentLoader(ExtensionServiceInterface* extension_service,
30                  PrefService* prefs,
31                  PrefService* local_state,
32                  content::BrowserContext* browser_context);
33  virtual ~ComponentLoader();
34
35  size_t registered_extensions_count() const {
36    return component_extensions_.size();
37  }
38
39  // Creates and loads all registered component extensions.
40  void LoadAll();
41
42  // Registers and possibly loads a component extension. If ExtensionService
43  // has been initialized, the extension is loaded; otherwise, the load is
44  // deferred until LoadAll is called. The ID of the added extension is
45  // returned.
46  //
47  // Component extension manifests must contain a "key" property with a unique
48  // public key, serialized in base64. You can create a suitable value with the
49  // following commands on a unixy system:
50  //
51  //   ssh-keygen -t rsa -b 1024 -N '' -f /tmp/key.pem
52  //   openssl rsa -pubout -outform DER < /tmp/key.pem 2>/dev/null | base64 -w 0
53  std::string Add(const std::string& manifest_contents,
54                  const base::FilePath& root_directory);
55
56  // Convenience method for registering a component extension by resource id.
57  std::string Add(int manifest_resource_id,
58                  const base::FilePath& root_directory);
59
60  // Loads a component extension from file system. Replaces previously added
61  // extension with the same ID.
62  std::string AddOrReplace(const base::FilePath& path);
63
64  // Returns the extension ID of a component extension specified by resource
65  // id of its manifest file.
66  std::string GetExtensionID(int manifest_resource_id,
67                             const base::FilePath& root_directory);
68
69  // Returns true if an extension with the specified id has been added.
70  bool Exists(const std::string& id) const;
71
72  // Unloads a component extension and removes it from the list of component
73  // extensions to be loaded.
74  void Remove(const base::FilePath& root_directory);
75  void Remove(const std::string& id);
76
77  // Call this during test setup to load component extensions that have
78  // background pages for testing, which could otherwise interfere with tests.
79  static void EnableBackgroundExtensionsForTesting();
80
81  // Adds the default component extensions. If |skip_session_components|
82  // the loader will skip loading component extensions that weren't supposed to
83  // be loaded unless we are in signed user session (ChromeOS). For all other
84  // platforms this |skip_session_components| is expected to be unset.
85  void AddDefaultComponentExtensions(bool skip_session_components);
86
87  // Similar to above but adds the default component extensions for kiosk mode.
88  void AddDefaultComponentExtensionsForKioskMode(bool skip_session_components);
89
90  // Parse the given JSON manifest. Returns NULL if it cannot be parsed, or if
91  // if the result is not a DictionaryValue.
92  base::DictionaryValue* ParseManifest(
93      const std::string& manifest_contents) const;
94
95  // Clear the list of registered extensions.
96  void ClearAllRegistered();
97
98  // Reloads a registered component extension.
99  void Reload(const std::string& extension_id);
100
101#if defined(OS_CHROMEOS)
102  // Calls |done_cb|, if not a null callback, on success.
103  // NOTE: |done_cb| is not called if the component loader is shut down
104  // during loading.
105  void AddChromeVoxExtension(const base::Closure& done_cb);
106  std::string AddChromeOsSpeechSynthesisExtension();
107#endif
108
109 private:
110  // Information about a registered component extension.
111  struct ComponentExtensionInfo {
112    ComponentExtensionInfo(const base::DictionaryValue* manifest,
113                           const base::FilePath& root_directory);
114
115    // The parsed contents of the extensions's manifest file.
116    const base::DictionaryValue* manifest;
117
118    // Directory where the extension is stored.
119    base::FilePath root_directory;
120
121    // The component extension's ID.
122    std::string extension_id;
123  };
124
125  std::string Add(const base::DictionaryValue* parsed_manifest,
126                  const base::FilePath& root_directory);
127
128  // Loads a registered component extension.
129  void Load(const ComponentExtensionInfo& info);
130
131  void AddDefaultComponentExtensionsWithBackgroundPages(
132      bool skip_session_components);
133  void AddFileManagerExtension();
134  void AddVideoPlayerExtension();
135  void AddGalleryExtension();
136  void AddHangoutServicesExtension();
137  void AddHotwordHelperExtension();
138  void AddImageLoaderExtension();
139  void AddNetworkSpeechSynthesisExtension();
140
141  void AddWithNameAndDescription(int manifest_resource_id,
142                                 const base::FilePath& root_directory,
143                                 int name_string_id,
144                                 int description_string_id);
145  void AddChromeApp();
146  void AddHotwordAudioVerificationApp();
147  void AddKeyboardApp();
148  void AddWebStoreApp();
149
150  // Unloads |component| from the memory.
151  void UnloadComponent(ComponentExtensionInfo* component);
152
153  // Enable HTML5 FileSystem for given component extension in Guest mode.
154  void EnableFileSystemInGuestMode(const std::string& id);
155
156#if defined(OS_CHROMEOS)
157  // Used as a reply callback when loading the ChromeVox extension.
158  // Called with a |chromevox_path| and parsed |manifest| and invokes
159  // |done_cb| after adding the extension.
160  void AddChromeVoxExtensionWithManifest(
161      const base::FilePath& chromevox_path,
162      const base::Closure& done_cb,
163      scoped_ptr<base::DictionaryValue> manifest);
164#endif
165
166  PrefService* profile_prefs_;
167  PrefService* local_state_;
168  content::BrowserContext* browser_context_;
169
170  ExtensionServiceInterface* extension_service_;
171
172  // List of registered component extensions (see Manifest::Location).
173  typedef std::vector<ComponentExtensionInfo> RegisteredComponentExtensions;
174  RegisteredComponentExtensions component_extensions_;
175
176  base::WeakPtrFactory<ComponentLoader> weak_factory_;
177
178  FRIEND_TEST_ALL_PREFIXES(TtsApiTest, NetworkSpeechEngine);
179  FRIEND_TEST_ALL_PREFIXES(TtsApiTest, NoNetworkSpeechEngineWhenOffline);
180
181  DISALLOW_COPY_AND_ASSIGN(ComponentLoader);
182};
183
184}  // namespace extensions
185
186#endif  // CHROME_BROWSER_EXTENSIONS_COMPONENT_LOADER_H_
187