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