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_CHROMEOS_DRIVE_DRIVE_INTEGRATION_SERVICE_H_ 6 #define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_INTEGRATION_SERVICE_H_ 7 8 #include "base/callback.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/singleton.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/observer_list.h" 13 #include "chrome/browser/chromeos/drive/file_errors.h" 14 #include "chrome/browser/chromeos/drive/file_system_util.h" 15 #include "chrome/browser/chromeos/drive/job_scheduler.h" 16 #include "chrome/browser/drive/drive_notification_observer.h" 17 #include "components/keyed_service/content/browser_context_keyed_service_factory.h" 18 #include "components/keyed_service/core/keyed_service.h" 19 #include "content/public/browser/notification_observer.h" 20 #include "content/public/browser/notification_registrar.h" 21 22 namespace base { 23 class FilePath; 24 class SequencedTaskRunner; 25 } 26 27 namespace drive { 28 29 class DebugInfoCollector; 30 class DownloadHandler; 31 class DriveAppRegistry; 32 class DriveServiceInterface; 33 class EventLogger; 34 class FileSystemInterface; 35 class JobListInterface; 36 37 namespace internal { 38 class FileCache; 39 class ResourceMetadata; 40 class ResourceMetadataStorage; 41 } // namespace internal 42 43 // Interface for classes that need to observe events from 44 // DriveIntegrationService. All events are notified on UI thread. 45 class DriveIntegrationServiceObserver { 46 public: 47 // Triggered when the file system is mounted. OnFileSystemMounted()48 virtual void OnFileSystemMounted() { 49 } 50 51 // Triggered when the file system is being unmounted. OnFileSystemBeingUnmounted()52 virtual void OnFileSystemBeingUnmounted() { 53 } 54 55 protected: ~DriveIntegrationServiceObserver()56 virtual ~DriveIntegrationServiceObserver() {} 57 }; 58 59 // DriveIntegrationService is used to integrate Drive to Chrome. This class 60 // exposes the file system representation built on top of Drive and some 61 // other Drive related objects to the file manager, and some other sub 62 // systems. 63 // 64 // The class is essentially a container that manages lifetime of the objects 65 // that are used to integrate Drive to Chrome. The object of this class is 66 // created per-profile. 67 class DriveIntegrationService : public KeyedService, 68 public DriveNotificationObserver, 69 public content::NotificationObserver { 70 public: 71 class PreferenceWatcher; 72 73 // test_drive_service, test_mount_point_name, test_cache_root and 74 // test_file_system are used by tests to inject customized instances. 75 // Pass NULL or the empty value when not interested. 76 // |preference_watcher| observes the drive enable preference, and sets the 77 // enable state when changed. It can be NULL. The ownership is taken by 78 // the DriveIntegrationService. 79 DriveIntegrationService( 80 Profile* profile, 81 PreferenceWatcher* preference_watcher, 82 DriveServiceInterface* test_drive_service, 83 const std::string& test_mount_point_name, 84 const base::FilePath& test_cache_root, 85 FileSystemInterface* test_file_system); 86 virtual ~DriveIntegrationService(); 87 88 // KeyedService override: 89 virtual void Shutdown() OVERRIDE; 90 91 void SetEnabled(bool enabled); is_enabled()92 bool is_enabled() const { return enabled_; } 93 94 bool IsMounted() const; 95 96 // Adds and removes the observer. 97 void AddObserver(DriveIntegrationServiceObserver* observer); 98 void RemoveObserver(DriveIntegrationServiceObserver* observer); 99 100 // DriveNotificationObserver implementation. 101 virtual void OnNotificationReceived() OVERRIDE; 102 virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE; 103 event_logger()104 EventLogger* event_logger() { return logger_.get(); } drive_service()105 DriveServiceInterface* drive_service() { return drive_service_.get(); } debug_info_collector()106 DebugInfoCollector* debug_info_collector() { 107 return debug_info_collector_.get(); 108 } file_system()109 FileSystemInterface* file_system() { return file_system_.get(); } download_handler()110 DownloadHandler* download_handler() { return download_handler_.get(); } drive_app_registry()111 DriveAppRegistry* drive_app_registry() { return drive_app_registry_.get(); } job_list()112 JobListInterface* job_list() { return scheduler_.get(); } 113 114 // Clears all the local cache file, the local resource metadata, and 115 // in-memory Drive app registry, and remounts the file system. |callback| 116 // is called with true when this operation is done successfully. Otherwise, 117 // |callback| is called with false. |callback| must not be null. 118 void ClearCacheAndRemountFileSystem( 119 const base::Callback<void(bool)>& callback); 120 121 private: 122 enum State { 123 NOT_INITIALIZED, 124 INITIALIZING, 125 INITIALIZED, 126 REMOUNTING, 127 }; 128 129 // Returns true if Drive is enabled. 130 // Must be called on UI thread. 131 bool IsDriveEnabled(); 132 133 // Registers remote file system for drive mount point. 134 void AddDriveMountPoint(); 135 // Unregisters drive mount point from File API. 136 void RemoveDriveMountPoint(); 137 138 // Adds back the drive mount point. 139 // Used to implement ClearCacheAndRemountFileSystem(). 140 void AddBackDriveMountPoint(const base::Callback<void(bool)>& callback, 141 FileError error); 142 143 // Initializes the object. This function should be called before any 144 // other functions. 145 void Initialize(); 146 147 // Called when metadata initialization is done. Continues initialization if 148 // the metadata initialization is successful. 149 void InitializeAfterMetadataInitialized(FileError error); 150 151 // Change the download directory to the local "Downloads" if the download 152 // destination is set under Drive. This must be called when disabling Drive. 153 void AvoidDriveAsDownloadDirecotryPreference(); 154 155 // content::NotificationObserver overrides. 156 virtual void Observe(int type, 157 const content::NotificationSource& source, 158 const content::NotificationDetails& details) OVERRIDE; 159 160 friend class DriveIntegrationServiceFactory; 161 162 Profile* profile_; 163 State state_; 164 bool enabled_; 165 // Custom mount point name that can be injected for testing in constructor. 166 std::string mount_point_name_; 167 168 base::FilePath cache_root_directory_; 169 scoped_ptr<EventLogger> logger_; 170 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 171 scoped_ptr<internal::ResourceMetadataStorage, 172 util::DestroyHelper> metadata_storage_; 173 scoped_ptr<internal::FileCache, util::DestroyHelper> cache_; 174 scoped_ptr<DriveServiceInterface> drive_service_; 175 scoped_ptr<JobScheduler> scheduler_; 176 scoped_ptr<DriveAppRegistry> drive_app_registry_; 177 scoped_ptr<internal::ResourceMetadata, 178 util::DestroyHelper> resource_metadata_; 179 scoped_ptr<FileSystemInterface> file_system_; 180 scoped_ptr<DownloadHandler> download_handler_; 181 scoped_ptr<DebugInfoCollector> debug_info_collector_; 182 183 ObserverList<DriveIntegrationServiceObserver> observers_; 184 scoped_ptr<PreferenceWatcher> preference_watcher_; 185 scoped_ptr<content::NotificationRegistrar> profile_notification_registrar_; 186 187 // Note: This should remain the last member so it'll be destroyed and 188 // invalidate its weak pointers before any other members are destroyed. 189 base::WeakPtrFactory<DriveIntegrationService> weak_ptr_factory_; 190 DISALLOW_COPY_AND_ASSIGN(DriveIntegrationService); 191 }; 192 193 // Singleton that owns all instances of DriveIntegrationService and 194 // associates them with Profiles. 195 class DriveIntegrationServiceFactory 196 : public BrowserContextKeyedServiceFactory { 197 public: 198 // Factory function used by tests. 199 typedef base::Callback<DriveIntegrationService*(Profile* profile)> 200 FactoryCallback; 201 202 // Sets and resets a factory function for tests. See below for why we can't 203 // use BrowserContextKeyedServiceFactory::SetTestingFactory(). 204 class ScopedFactoryForTest { 205 public: 206 explicit ScopedFactoryForTest(FactoryCallback* factory_for_test); 207 ~ScopedFactoryForTest(); 208 }; 209 210 // Returns the DriveIntegrationService for |profile|, creating it if it is 211 // not yet created. 212 static DriveIntegrationService* GetForProfile(Profile* profile); 213 214 // Returns the DriveIntegrationService that is already associated with 215 // |profile|, if it is not yet created it will return NULL. 216 static DriveIntegrationService* FindForProfile(Profile* profile); 217 218 // Returns the DriveIntegrationServiceFactory instance. 219 static DriveIntegrationServiceFactory* GetInstance(); 220 221 private: 222 friend struct DefaultSingletonTraits<DriveIntegrationServiceFactory>; 223 224 DriveIntegrationServiceFactory(); 225 virtual ~DriveIntegrationServiceFactory(); 226 227 // BrowserContextKeyedServiceFactory overrides. 228 virtual content::BrowserContext* GetBrowserContextToUse( 229 content::BrowserContext* context) const OVERRIDE; 230 virtual KeyedService* BuildServiceInstanceFor( 231 content::BrowserContext* context) const OVERRIDE; 232 233 // This is static so it can be set without instantiating the factory. This 234 // allows factory creation to be delayed until it normally happens (on profile 235 // creation) rather than when tests are set up. DriveIntegrationServiceFactory 236 // transitively depends on ExtensionSystemFactory which crashes if created too 237 // soon (i.e. before the BrowserProcess exists). 238 static FactoryCallback* factory_for_test_; 239 }; 240 241 } // namespace drive 242 243 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_INTEGRATION_SERVICE_H_ 244