• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
7 
8 #include <set>
9 
10 #include "base/files/file.h"
11 #include "base/scoped_observer.h"
12 #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
13 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
14 #include "chrome/browser/extensions/chrome_extension_function.h"
15 #include "chrome/browser/extensions/error_console/error_console.h"
16 #include "chrome/browser/extensions/extension_install_prompt.h"
17 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
18 #include "chrome/browser/extensions/pack_extension_job.h"
19 #include "chrome/browser/extensions/requirements_checker.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "extensions/browser/browser_context_keyed_api_factory.h"
24 #include "extensions/browser/event_router.h"
25 #include "extensions/browser/extension_registry_observer.h"
26 #include "ui/shell_dialogs/select_file_dialog.h"
27 #include "webkit/browser/fileapi/file_system_context.h"
28 #include "webkit/browser/fileapi/file_system_operation.h"
29 
30 class Profile;
31 
32 namespace extensions {
33 
34 class ExtensionError;
35 class ExtensionRegistry;
36 class ExtensionSystem;
37 class ManagementPolicy;
38 
39 namespace api {
40 
41 class EntryPicker;
42 class EntryPickerClient;
43 
44 namespace developer_private {
45 
46 struct ItemInfo;
47 struct ItemInspectView;
48 struct ProjectInfo;
49 
50 }  // namespace developer_private
51 
52 }  // namespace api
53 
54 namespace developer = api::developer_private;
55 
56 typedef std::vector<linked_ptr<developer::ItemInfo> > ItemInfoList;
57 typedef std::vector<linked_ptr<developer::ProjectInfo> > ProjectInfoList;
58 typedef std::vector<linked_ptr<developer::ItemInspectView> >
59     ItemInspectViewList;
60 
61 class DeveloperPrivateEventRouter : public content::NotificationObserver,
62                                     public ExtensionRegistryObserver,
63                                     public ErrorConsole::Observer {
64  public:
65   explicit DeveloperPrivateEventRouter(Profile* profile);
66   virtual ~DeveloperPrivateEventRouter();
67 
68   // Add or remove an ID to the list of extensions subscribed to events.
69   void AddExtensionId(const std::string& extension_id);
70   void RemoveExtensionId(const std::string& extension_id);
71 
72  private:
73   // content::NotificationObserver implementation.
74   virtual void Observe(int type,
75                        const content::NotificationSource& source,
76                        const content::NotificationDetails& details) OVERRIDE;
77 
78   // ExtensionRegistryObserver implementation.
79   virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
80                                  const Extension* extension) OVERRIDE;
81   virtual void OnExtensionUnloaded(
82       content::BrowserContext* browser_context,
83       const Extension* extension,
84       UnloadedExtensionInfo::Reason reason) OVERRIDE;
85   virtual void OnExtensionWillBeInstalled(
86       content::BrowserContext* browser_context,
87       const Extension* extension,
88       bool is_update,
89       bool from_ephemeral,
90       const std::string& old_name) OVERRIDE;
91   virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
92                                       const Extension* extension) OVERRIDE;
93 
94   // ErrorConsole::Observer implementation.
95   virtual void OnErrorAdded(const ExtensionError* error) OVERRIDE;
96 
97   content::NotificationRegistrar registrar_;
98 
99   ScopedObserver<extensions::ExtensionRegistry,
100                  extensions::ExtensionRegistryObserver>
101       extension_registry_observer_;
102 
103   Profile* profile_;
104 
105   // The set of IDs of the Extensions that have subscribed to DeveloperPrivate
106   // events. Since the only consumer of the DeveloperPrivate API is currently
107   // the Apps Developer Tool (which replaces the chrome://extensions page), we
108   // don't want to send information about the subscribing extension in an
109   // update. In particular, we want to avoid entering a loop, which could happen
110   // when, e.g., the Apps Developer Tool throws an error.
111   std::set<std::string> extension_ids_;
112 
113   DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateEventRouter);
114 };
115 
116 // The profile-keyed service that manages the DeveloperPrivate API.
117 class DeveloperPrivateAPI : public BrowserContextKeyedAPI,
118                             public EventRouter::Observer {
119  public:
120   static BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>*
121       GetFactoryInstance();
122 
123   // Convenience method to get the DeveloperPrivateAPI for a profile.
124   static DeveloperPrivateAPI* Get(content::BrowserContext* context);
125 
126   explicit DeveloperPrivateAPI(content::BrowserContext* context);
127   virtual ~DeveloperPrivateAPI();
128 
129   void SetLastUnpackedDirectory(const base::FilePath& path);
130 
GetLastUnpackedDirectory()131   base::FilePath& GetLastUnpackedDirectory() {
132     return last_unpacked_directory_;
133   }
134 
135   // KeyedService implementation
136   virtual void Shutdown() OVERRIDE;
137 
138   // EventRouter::Observer implementation.
139   virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
140   virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
141 
142  private:
143   friend class BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>;
144 
145   // BrowserContextKeyedAPI implementation.
service_name()146   static const char* service_name() { return "DeveloperPrivateAPI"; }
147   static const bool kServiceRedirectedInIncognito = true;
148   static const bool kServiceIsNULLWhileTesting = true;
149 
150   void RegisterNotifications();
151 
152   Profile* profile_;
153 
154   // Used to start the load |load_extension_dialog_| in the last directory that
155   // was loaded.
156   base::FilePath last_unpacked_directory_;
157 
158   // Created lazily upon OnListenerAdded.
159   scoped_ptr<DeveloperPrivateEventRouter> developer_private_event_router_;
160 
161   DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateAPI);
162 };
163 
164 namespace api {
165 
166 class DeveloperPrivateAutoUpdateFunction : public ChromeSyncExtensionFunction {
167  public:
168   DECLARE_EXTENSION_FUNCTION("developerPrivate.autoUpdate",
169                              DEVELOPERPRIVATE_AUTOUPDATE)
170 
171  protected:
172   virtual ~DeveloperPrivateAutoUpdateFunction();
173 
174   // ExtensionFunction:
175   virtual bool RunSync() OVERRIDE;
176 };
177 
178 class DeveloperPrivateGetItemsInfoFunction
179     : public ChromeAsyncExtensionFunction {
180  public:
181   DECLARE_EXTENSION_FUNCTION("developerPrivate.getItemsInfo",
182                              DEVELOPERPRIVATE_GETITEMSINFO)
183 
184  protected:
185   virtual ~DeveloperPrivateGetItemsInfoFunction();
186 
187   // ExtensionFunction:
188   virtual bool RunAsync() OVERRIDE;
189 
190  private:
191   scoped_ptr<developer::ItemInfo> CreateItemInfo(const Extension& item,
192                                                  bool item_is_enabled);
193 
194   void GetIconsOnFileThread(
195       ItemInfoList item_list,
196       std::map<std::string, ExtensionResource> itemIdToIconResourceMap);
197 
198   // Helper that lists the current inspectable html pages for the extension.
199   void GetInspectablePagesForExtensionProcess(
200       const Extension* extension,
201       const std::set<content::RenderViewHost*>& views,
202       ItemInspectViewList* result);
203 
204   ItemInspectViewList GetInspectablePagesForExtension(
205       const Extension* extension,
206       bool extension_is_enabled);
207 
208   void GetAppWindowPagesForExtensionProfile(const Extension* extension,
209                                             ItemInspectViewList* result);
210 
211   linked_ptr<developer::ItemInspectView> constructInspectView(
212       const GURL& url,
213       int render_process_id,
214       int render_view_id,
215       bool incognito,
216       bool generated_background_page);
217 };
218 
219 class DeveloperPrivateInspectFunction : public ChromeSyncExtensionFunction {
220  public:
221   DECLARE_EXTENSION_FUNCTION("developerPrivate.inspect",
222                              DEVELOPERPRIVATE_INSPECT)
223 
224  protected:
225   virtual ~DeveloperPrivateInspectFunction();
226 
227   // ExtensionFunction:
228   virtual bool RunSync() OVERRIDE;
229 };
230 
231 class DeveloperPrivateAllowFileAccessFunction
232     : public ChromeSyncExtensionFunction {
233  public:
234   DECLARE_EXTENSION_FUNCTION("developerPrivate.allowFileAccess",
235                              DEVELOPERPRIVATE_ALLOWFILEACCESS);
236 
237  protected:
238   virtual ~DeveloperPrivateAllowFileAccessFunction();
239 
240   // ExtensionFunction:
241   virtual bool RunSync() OVERRIDE;
242 };
243 
244 class DeveloperPrivateAllowIncognitoFunction
245     : public ChromeSyncExtensionFunction {
246  public:
247   DECLARE_EXTENSION_FUNCTION("developerPrivate.allowIncognito",
248                              DEVELOPERPRIVATE_ALLOWINCOGNITO);
249 
250  protected:
251   virtual ~DeveloperPrivateAllowIncognitoFunction();
252 
253   // ExtensionFunction:
254   virtual bool RunSync() OVERRIDE;
255 };
256 
257 class DeveloperPrivateReloadFunction : public ChromeSyncExtensionFunction {
258  public:
259   DECLARE_EXTENSION_FUNCTION("developerPrivate.reload",
260                              DEVELOPERPRIVATE_RELOAD);
261 
262  protected:
263   virtual ~DeveloperPrivateReloadFunction();
264 
265   // ExtensionFunction:
266   virtual bool RunSync() OVERRIDE;
267 };
268 
269 class DeveloperPrivateShowPermissionsDialogFunction
270     : public ChromeSyncExtensionFunction,
271       public ExtensionInstallPrompt::Delegate {
272  public:
273   DECLARE_EXTENSION_FUNCTION("developerPrivate.showPermissionsDialog",
274                              DEVELOPERPRIVATE_PERMISSIONS);
275 
276   DeveloperPrivateShowPermissionsDialogFunction();
277  protected:
278   virtual ~DeveloperPrivateShowPermissionsDialogFunction();
279 
280   // ExtensionFunction:
281   virtual bool RunSync() OVERRIDE;
282 
283   // Overridden from ExtensionInstallPrompt::Delegate
284   virtual void InstallUIProceed() OVERRIDE;
285   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
286 
287   scoped_ptr<ExtensionInstallPrompt> prompt_;
288   std::string extension_id_;
289 };
290 
291 class DeveloperPrivateEnableFunction
292     : public ChromeSyncExtensionFunction,
293       public base::SupportsWeakPtr<DeveloperPrivateEnableFunction> {
294  public:
295   DECLARE_EXTENSION_FUNCTION("developerPrivate.enable",
296                              DEVELOPERPRIVATE_ENABLE);
297 
298   DeveloperPrivateEnableFunction();
299 
300  protected:
301   virtual ~DeveloperPrivateEnableFunction();
302 
303   // Callback for requirements checker.
304   void OnRequirementsChecked(const std::string& extension_id,
305                              std::vector<std::string> requirements_errors);
306   // ExtensionFunction:
307   virtual bool RunSync() OVERRIDE;
308 
309  private:
310   scoped_ptr<RequirementsChecker> requirements_checker_;
311 };
312 
313 class DeveloperPrivateChooseEntryFunction : public ChromeAsyncExtensionFunction,
314                                             public EntryPickerClient {
315  protected:
316   virtual ~DeveloperPrivateChooseEntryFunction();
317   virtual bool RunAsync() OVERRIDE;
318   bool ShowPicker(ui::SelectFileDialog::Type picker_type,
319                   const base::FilePath& last_directory,
320                   const base::string16& select_title,
321                   const ui::SelectFileDialog::FileTypeInfo& info,
322                   int file_type_index);
323 
324   // EntryPickerClient functions.
325   virtual void FileSelected(const base::FilePath& path) = 0;
326   virtual void FileSelectionCanceled() = 0;
327 };
328 
329 
330 class DeveloperPrivateLoadUnpackedFunction
331     : public DeveloperPrivateChooseEntryFunction {
332  public:
333   DECLARE_EXTENSION_FUNCTION("developerPrivate.loadUnpacked",
334                              DEVELOPERPRIVATE_LOADUNPACKED);
335 
336  protected:
337   virtual ~DeveloperPrivateLoadUnpackedFunction();
338   virtual bool RunAsync() OVERRIDE;
339 
340   // EntryPickerCLient implementation.
341   virtual void FileSelected(const base::FilePath& path) OVERRIDE;
342   virtual void FileSelectionCanceled() OVERRIDE;
343 };
344 
345 class DeveloperPrivateChoosePathFunction
346     : public DeveloperPrivateChooseEntryFunction {
347  public:
348   DECLARE_EXTENSION_FUNCTION("developerPrivate.choosePath",
349                              DEVELOPERPRIVATE_CHOOSEPATH);
350 
351  protected:
352   virtual ~DeveloperPrivateChoosePathFunction();
353   virtual bool RunAsync() OVERRIDE;
354 
355   // EntryPickerClient functions.
356   virtual void FileSelected(const base::FilePath& path) OVERRIDE;
357   virtual void FileSelectionCanceled() OVERRIDE;
358 };
359 
360 class DeveloperPrivatePackDirectoryFunction
361     : public ChromeAsyncExtensionFunction,
362       public PackExtensionJob::Client {
363 
364  public:
365   DECLARE_EXTENSION_FUNCTION("developerPrivate.packDirectory",
366                              DEVELOPERPRIVATE_PACKDIRECTORY);
367 
368   DeveloperPrivatePackDirectoryFunction();
369 
370   // ExtensionPackJob::Client implementation.
371   virtual void OnPackSuccess(const base::FilePath& crx_file,
372                              const base::FilePath& key_file) OVERRIDE;
373   virtual void OnPackFailure(const std::string& error,
374                              ExtensionCreator::ErrorType error_type) OVERRIDE;
375 
376  protected:
377   virtual ~DeveloperPrivatePackDirectoryFunction();
378   virtual bool RunAsync() OVERRIDE;
379 
380  private:
381   scoped_refptr<PackExtensionJob> pack_job_;
382   std::string item_path_str_;
383   std::string key_path_str_;
384 };
385 
386 class DeveloperPrivateIsProfileManagedFunction
387     : public ChromeSyncExtensionFunction {
388  public:
389   DECLARE_EXTENSION_FUNCTION("developerPrivate.isProfileManaged",
390                              DEVELOPERPRIVATE_ISPROFILEMANAGED);
391 
392  protected:
393   virtual ~DeveloperPrivateIsProfileManagedFunction();
394 
395   // ExtensionFunction:
396   virtual bool RunSync() OVERRIDE;
397 };
398 
399 class DeveloperPrivateLoadDirectoryFunction
400     : public ChromeAsyncExtensionFunction {
401  public:
402   DECLARE_EXTENSION_FUNCTION("developerPrivate.loadDirectory",
403                              DEVELOPERPRIVATE_LOADUNPACKEDCROS);
404 
405   DeveloperPrivateLoadDirectoryFunction();
406 
407  protected:
408   virtual ~DeveloperPrivateLoadDirectoryFunction();
409 
410   // ExtensionFunction:
411   virtual bool RunAsync() OVERRIDE;
412 
413   void ClearExistingDirectoryContent(const base::FilePath& project_path);
414 
415   void ReadSyncFileSystemDirectory(const base::FilePath& project_path,
416                                    const base::FilePath& destination_path);
417 
418   void ReadSyncFileSystemDirectoryCb(
419       const base::FilePath& project_path,
420       const base::FilePath& destination_path,
421       base::File::Error result,
422       const fileapi::FileSystemOperation::FileEntryList& file_list,
423       bool has_more);
424 
425   void SnapshotFileCallback(
426       const base::FilePath& target_path,
427       base::File::Error result,
428       const base::File::Info& file_info,
429       const base::FilePath& platform_path,
430       const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
431 
432   void CopyFile(const base::FilePath& src_path,
433                 const base::FilePath& dest_path);
434 
435   void Load();
436 
437   scoped_refptr<fileapi::FileSystemContext> context_;
438 
439   // syncfs url representing the root of the folder to be copied.
440   std::string project_base_url_;
441 
442   // physical path on disc of the folder to be copied.
443   base::FilePath project_base_path_;
444 
445   // Path of the current folder to be copied.
446   base::FilePath current_path_;
447 
448  private:
449   int pending_copy_operations_count_;
450 
451   // This is set to false if any of the copyFile operations fail on
452   // call of the API. It is returned as a response of the API call.
453   bool success_;
454 };
455 
456 class DeveloperPrivateRequestFileSourceFunction
457     : public ChromeAsyncExtensionFunction {
458  public:
459   DECLARE_EXTENSION_FUNCTION("developerPrivate.requestFileSource",
460                              DEVELOPERPRIVATE_REQUESTFILESOURCE);
461 
462   DeveloperPrivateRequestFileSourceFunction();
463 
464  protected:
465   virtual ~DeveloperPrivateRequestFileSourceFunction();
466 
467   // ExtensionFunction:
468   virtual bool RunAsync() OVERRIDE;
469 
470  private:
471   void LaunchCallback(const base::DictionaryValue& results);
472 };
473 
474 class DeveloperPrivateOpenDevToolsFunction
475     : public ChromeAsyncExtensionFunction {
476  public:
477   DECLARE_EXTENSION_FUNCTION("developerPrivate.openDevTools",
478                              DEVELOPERPRIVATE_OPENDEVTOOLS);
479 
480   DeveloperPrivateOpenDevToolsFunction();
481 
482  protected:
483   virtual ~DeveloperPrivateOpenDevToolsFunction();
484 
485   // ExtensionFunction:
486   virtual bool RunAsync() OVERRIDE;
487 };
488 
489 }  // namespace api
490 
491 }  // namespace extensions
492 
493 #endif  // CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
494