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