Home | History | Annotate | Download | only in developer_private
      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 
    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.
    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