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