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 #include "chrome/browser/chromeos/drive/drive_integration_service.h" 6 7 #include "base/bind.h" 8 #include "base/file_util.h" 9 #include "base/prefs/pref_change_registrar.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/strings/stringprintf.h" 12 #include "base/threading/sequenced_worker_pool.h" 13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/chrome_notification_types.h" 15 #include "chrome/browser/chromeos/drive/debug_info_collector.h" 16 #include "chrome/browser/chromeos/drive/download_handler.h" 17 #include "chrome/browser/chromeos/drive/file_cache.h" 18 #include "chrome/browser/chromeos/drive/file_system.h" 19 #include "chrome/browser/chromeos/drive/file_system_util.h" 20 #include "chrome/browser/chromeos/drive/job_scheduler.h" 21 #include "chrome/browser/chromeos/drive/resource_metadata.h" 22 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" 23 #include "chrome/browser/chromeos/file_manager/path_util.h" 24 #include "chrome/browser/chromeos/profiles/profile_util.h" 25 #include "chrome/browser/download/download_prefs.h" 26 #include "chrome/browser/download/download_service.h" 27 #include "chrome/browser/download/download_service_factory.h" 28 #include "chrome/browser/drive/drive_api_service.h" 29 #include "chrome/browser/drive/drive_api_util.h" 30 #include "chrome/browser/drive/drive_app_registry.h" 31 #include "chrome/browser/drive/drive_notification_manager.h" 32 #include "chrome/browser/drive/drive_notification_manager_factory.h" 33 #include "chrome/browser/drive/event_logger.h" 34 #include "chrome/browser/profiles/incognito_helpers.h" 35 #include "chrome/browser/profiles/profile.h" 36 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 37 #include "chrome/browser/signin/signin_manager_factory.h" 38 #include "chrome/common/chrome_version_info.h" 39 #include "chrome/common/pref_names.h" 40 #include "components/keyed_service/content/browser_context_dependency_manager.h" 41 #include "components/signin/core/browser/profile_oauth2_token_service.h" 42 #include "components/signin/core/browser/signin_manager.h" 43 #include "content/public/browser/browser_context.h" 44 #include "content/public/browser/browser_thread.h" 45 #include "content/public/browser/notification_service.h" 46 #include "content/public/common/user_agent.h" 47 #include "google_apis/drive/auth_service.h" 48 #include "google_apis/drive/gdata_wapi_url_generator.h" 49 #include "grit/generated_resources.h" 50 #include "ui/base/l10n/l10n_util.h" 51 #include "webkit/browser/fileapi/external_mount_points.h" 52 53 using content::BrowserContext; 54 using content::BrowserThread; 55 56 namespace drive { 57 namespace { 58 59 // Name of the directory used to store metadata. 60 const base::FilePath::CharType kMetadataDirectory[] = FILE_PATH_LITERAL("meta"); 61 62 // Name of the directory used to store cached files. 63 const base::FilePath::CharType kCacheFileDirectory[] = 64 FILE_PATH_LITERAL("files"); 65 66 // Name of the directory used to store temporary files. 67 const base::FilePath::CharType kTemporaryFileDirectory[] = 68 FILE_PATH_LITERAL("tmp"); 69 70 // Returns a user agent string used for communicating with the Drive backend, 71 // both WAPI and Drive API. The user agent looks like: 72 // 73 // chromedrive-<VERSION> chrome-cc/none (<OS_CPU_INFO>) 74 // chromedrive-24.0.1274.0 chrome-cc/none (CrOS x86_64 0.4.0) 75 // 76 // TODO(satorux): Move this function to somewhere else: crbug.com/151605 77 std::string GetDriveUserAgent() { 78 const char kDriveClientName[] = "chromedrive"; 79 80 chrome::VersionInfo version_info; 81 const std::string version = (version_info.is_valid() ? 82 version_info.Version() : 83 std::string("unknown")); 84 85 // This part is <client_name>/<version>. 86 const char kLibraryInfo[] = "chrome-cc/none"; 87 88 const std::string os_cpu_info = content::BuildOSCpuInfo(); 89 90 // Add "gzip" to receive compressed data from the server. 91 // (see https://developers.google.com/drive/performance) 92 return base::StringPrintf("%s-%s %s (%s) (gzip)", 93 kDriveClientName, 94 version.c_str(), 95 kLibraryInfo, 96 os_cpu_info.c_str()); 97 } 98 99 // Initializes FileCache and ResourceMetadata. 100 // Must be run on the same task runner used by |cache| and |resource_metadata|. 101 FileError InitializeMetadata( 102 const base::FilePath& cache_root_directory, 103 internal::ResourceMetadataStorage* metadata_storage, 104 internal::FileCache* cache, 105 internal::ResourceMetadata* resource_metadata, 106 const ResourceIdCanonicalizer& id_canonicalizer, 107 const base::FilePath& downloads_directory) { 108 // Files in temporary directory need not persist across sessions. Clean up 109 // the directory content while initialization. 110 base::DeleteFile(cache_root_directory.Append(kTemporaryFileDirectory), 111 true); // recursive 112 if (!base::CreateDirectory(cache_root_directory.Append( 113 kMetadataDirectory)) || 114 !base::CreateDirectory(cache_root_directory.Append( 115 kCacheFileDirectory)) || 116 !base::CreateDirectory(cache_root_directory.Append( 117 kTemporaryFileDirectory))) { 118 LOG(WARNING) << "Failed to create directories."; 119 return FILE_ERROR_FAILED; 120 } 121 122 // Change permissions of cache file directory to u+rwx,og+x (711) in order to 123 // allow archive files in that directory to be mounted by cros-disks. 124 base::SetPosixFilePermissions( 125 cache_root_directory.Append(kCacheFileDirectory), 126 base::FILE_PERMISSION_USER_MASK | 127 base::FILE_PERMISSION_EXECUTE_BY_GROUP | 128 base::FILE_PERMISSION_EXECUTE_BY_OTHERS); 129 130 internal::ResourceMetadataStorage::UpgradeOldDB( 131 metadata_storage->directory_path(), id_canonicalizer); 132 133 if (!metadata_storage->Initialize()) { 134 LOG(WARNING) << "Failed to initialize the metadata storage."; 135 return FILE_ERROR_FAILED; 136 } 137 138 if (!cache->Initialize()) { 139 LOG(WARNING) << "Failed to initialize the cache."; 140 return FILE_ERROR_FAILED; 141 } 142 143 if (metadata_storage->cache_file_scan_is_needed()) { 144 // Generate unique directory name. 145 const std::string& dest_directory_name = l10n_util::GetStringUTF8( 146 IDS_FILE_BROWSER_RECOVERED_FILES_FROM_GOOGLE_DRIVE_DIRECTORY_NAME); 147 base::FilePath dest_directory = downloads_directory.Append( 148 base::FilePath::FromUTF8Unsafe(dest_directory_name)); 149 for (int uniquifier = 1; base::PathExists(dest_directory); ++uniquifier) { 150 dest_directory = downloads_directory.Append( 151 base::FilePath::FromUTF8Unsafe(dest_directory_name)) 152 .InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)); 153 } 154 155 internal::ResourceMetadataStorage::RecoveredCacheInfoMap 156 recovered_cache_info; 157 metadata_storage->RecoverCacheInfoFromTrashedResourceMap( 158 &recovered_cache_info); 159 160 LOG_IF(WARNING, !recovered_cache_info.empty()) 161 << "DB could not be opened for some reasons. " 162 << "Recovering cache files to " << dest_directory.value(); 163 if (!cache->RecoverFilesFromCacheDirectory(dest_directory, 164 recovered_cache_info)) { 165 LOG(WARNING) << "Failed to recover cache files."; 166 return FILE_ERROR_FAILED; 167 } 168 } 169 170 FileError error = resource_metadata->Initialize(); 171 LOG_IF(WARNING, error != FILE_ERROR_OK) 172 << "Failed to initialize resource metadata. " << FileErrorToString(error); 173 return error; 174 } 175 176 } // namespace 177 178 // Observes drive disable Preference's change. 179 class DriveIntegrationService::PreferenceWatcher { 180 public: 181 explicit PreferenceWatcher(PrefService* pref_service) 182 : pref_service_(pref_service), 183 integration_service_(NULL), 184 weak_ptr_factory_(this) { 185 DCHECK(pref_service); 186 pref_change_registrar_.Init(pref_service); 187 pref_change_registrar_.Add( 188 prefs::kDisableDrive, 189 base::Bind(&PreferenceWatcher::OnPreferenceChanged, 190 weak_ptr_factory_.GetWeakPtr())); 191 } 192 193 void set_integration_service(DriveIntegrationService* integration_service) { 194 integration_service_ = integration_service; 195 } 196 197 private: 198 void OnPreferenceChanged() { 199 DCHECK(integration_service_); 200 integration_service_->SetEnabled( 201 !pref_service_->GetBoolean(prefs::kDisableDrive)); 202 } 203 204 PrefService* pref_service_; 205 PrefChangeRegistrar pref_change_registrar_; 206 DriveIntegrationService* integration_service_; 207 208 base::WeakPtrFactory<PreferenceWatcher> weak_ptr_factory_; 209 DISALLOW_COPY_AND_ASSIGN(PreferenceWatcher); 210 }; 211 212 DriveIntegrationService::DriveIntegrationService( 213 Profile* profile, 214 PreferenceWatcher* preference_watcher, 215 DriveServiceInterface* test_drive_service, 216 const std::string& test_mount_point_name, 217 const base::FilePath& test_cache_root, 218 FileSystemInterface* test_file_system) 219 : profile_(profile), 220 state_(NOT_INITIALIZED), 221 enabled_(false), 222 mount_point_name_(test_mount_point_name), 223 cache_root_directory_(!test_cache_root.empty() ? 224 test_cache_root : util::GetCacheRootPath(profile)), 225 weak_ptr_factory_(this) { 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 227 DCHECK(profile && !profile->IsOffTheRecord()); 228 229 logger_.reset(new EventLogger); 230 base::SequencedWorkerPool* blocking_pool = BrowserThread::GetBlockingPool(); 231 blocking_task_runner_ = blocking_pool->GetSequencedTaskRunner( 232 blocking_pool->GetSequenceToken()); 233 234 ProfileOAuth2TokenService* oauth_service = 235 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 236 237 if (test_drive_service) { 238 drive_service_.reset(test_drive_service); 239 } else { 240 drive_service_.reset(new DriveAPIService( 241 oauth_service, 242 g_browser_process->system_request_context(), 243 blocking_task_runner_.get(), 244 GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction), 245 GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction), 246 GURL(google_apis::GDataWapiUrlGenerator::kBaseUrlForProduction), 247 GetDriveUserAgent())); 248 } 249 scheduler_.reset(new JobScheduler( 250 profile_->GetPrefs(), 251 logger_.get(), 252 drive_service_.get(), 253 blocking_task_runner_.get())); 254 metadata_storage_.reset(new internal::ResourceMetadataStorage( 255 cache_root_directory_.Append(kMetadataDirectory), 256 blocking_task_runner_.get())); 257 cache_.reset(new internal::FileCache( 258 metadata_storage_.get(), 259 cache_root_directory_.Append(kCacheFileDirectory), 260 blocking_task_runner_.get(), 261 NULL /* free_disk_space_getter */)); 262 drive_app_registry_.reset(new DriveAppRegistry(drive_service_.get())); 263 264 resource_metadata_.reset(new internal::ResourceMetadata( 265 metadata_storage_.get(), cache_.get(), blocking_task_runner_)); 266 267 file_system_.reset( 268 test_file_system ? test_file_system : new FileSystem( 269 profile_->GetPrefs(), 270 logger_.get(), 271 cache_.get(), 272 drive_service_.get(), 273 scheduler_.get(), 274 resource_metadata_.get(), 275 blocking_task_runner_.get(), 276 cache_root_directory_.Append(kTemporaryFileDirectory))); 277 download_handler_.reset(new DownloadHandler(file_system())); 278 debug_info_collector_.reset(new DebugInfoCollector( 279 resource_metadata_.get(), file_system(), blocking_task_runner_.get())); 280 281 if (preference_watcher) { 282 preference_watcher_.reset(preference_watcher); 283 preference_watcher->set_integration_service(this); 284 } 285 286 SetEnabled(drive::util::IsDriveEnabledForProfile(profile)); 287 } 288 289 DriveIntegrationService::~DriveIntegrationService() { 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 291 } 292 293 void DriveIntegrationService::Shutdown() { 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 295 296 weak_ptr_factory_.InvalidateWeakPtrs(); 297 298 DriveNotificationManager* drive_notification_manager = 299 DriveNotificationManagerFactory::FindForBrowserContext(profile_); 300 if (drive_notification_manager) 301 drive_notification_manager->RemoveObserver(this); 302 303 RemoveDriveMountPoint(); 304 debug_info_collector_.reset(); 305 download_handler_.reset(); 306 file_system_.reset(); 307 drive_app_registry_.reset(); 308 scheduler_.reset(); 309 drive_service_.reset(); 310 } 311 312 void DriveIntegrationService::SetEnabled(bool enabled) { 313 // If Drive is being disabled, ensure the download destination preference to 314 // be out of Drive. Do this before "Do nothing if not changed." because we 315 // want to run the check for the first SetEnabled() called in the constructor, 316 // which may be a change from false to false. 317 if (!enabled) 318 AvoidDriveAsDownloadDirecotryPreference(); 319 320 // Do nothing if not changed. 321 if (enabled_ == enabled) 322 return; 323 324 if (enabled) { 325 enabled_ = true; 326 switch (state_) { 327 case NOT_INITIALIZED: 328 // If the initialization is not yet done, trigger it. 329 Initialize(); 330 return; 331 332 case INITIALIZING: 333 case REMOUNTING: 334 // If the state is INITIALIZING or REMOUNTING, at the end of the 335 // process, it tries to mounting (with re-checking enabled state). 336 // Do nothing for now. 337 return; 338 339 case INITIALIZED: 340 // The integration service is already initialized. Add the mount point. 341 AddDriveMountPoint(); 342 return; 343 } 344 NOTREACHED(); 345 } else { 346 RemoveDriveMountPoint(); 347 enabled_ = false; 348 } 349 } 350 351 bool DriveIntegrationService::IsMounted() const { 352 if (mount_point_name_.empty()) 353 return false; 354 355 // Look up the registered path, and just discard it. 356 // GetRegisteredPath() returns true if the path is available. 357 base::FilePath unused; 358 fileapi::ExternalMountPoints* const mount_points = 359 fileapi::ExternalMountPoints::GetSystemInstance(); 360 DCHECK(mount_points); 361 return mount_points->GetRegisteredPath(mount_point_name_, &unused); 362 } 363 364 void DriveIntegrationService::AddObserver( 365 DriveIntegrationServiceObserver* observer) { 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 367 observers_.AddObserver(observer); 368 } 369 370 void DriveIntegrationService::RemoveObserver( 371 DriveIntegrationServiceObserver* observer) { 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373 observers_.RemoveObserver(observer); 374 } 375 376 void DriveIntegrationService::OnNotificationReceived() { 377 file_system_->CheckForUpdates(); 378 drive_app_registry_->Update(); 379 } 380 381 void DriveIntegrationService::OnPushNotificationEnabled(bool enabled) { 382 if (enabled) 383 drive_app_registry_->Update(); 384 385 const char* status = (enabled ? "enabled" : "disabled"); 386 logger_->Log(logging::LOG_INFO, "Push notification is %s", status); 387 } 388 389 void DriveIntegrationService::ClearCacheAndRemountFileSystem( 390 const base::Callback<void(bool)>& callback) { 391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 392 DCHECK(!callback.is_null()); 393 394 if (state_ != INITIALIZED) { 395 callback.Run(false); 396 return; 397 } 398 399 RemoveDriveMountPoint(); 400 401 state_ = REMOUNTING; 402 // Reloads the Drive app registry. 403 drive_app_registry_->Update(); 404 // Resetting the file system clears resource metadata and cache. 405 file_system_->Reset(base::Bind( 406 &DriveIntegrationService::AddBackDriveMountPoint, 407 weak_ptr_factory_.GetWeakPtr(), 408 callback)); 409 } 410 411 void DriveIntegrationService::AddBackDriveMountPoint( 412 const base::Callback<void(bool)>& callback, 413 FileError error) { 414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 415 DCHECK(!callback.is_null()); 416 417 state_ = error == FILE_ERROR_OK ? INITIALIZED : NOT_INITIALIZED; 418 419 if (error != FILE_ERROR_OK || !enabled_) { 420 // Failed to reset, or Drive was disabled during the reset. 421 callback.Run(false); 422 return; 423 } 424 425 AddDriveMountPoint(); 426 callback.Run(true); 427 } 428 429 void DriveIntegrationService::AddDriveMountPoint() { 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 431 DCHECK_EQ(INITIALIZED, state_); 432 DCHECK(enabled_); 433 434 const base::FilePath& drive_mount_point = 435 util::GetDriveMountPointPath(profile_); 436 if (mount_point_name_.empty()) 437 mount_point_name_ = drive_mount_point.BaseName().AsUTF8Unsafe(); 438 fileapi::ExternalMountPoints* const mount_points = 439 fileapi::ExternalMountPoints::GetSystemInstance(); 440 DCHECK(mount_points); 441 442 bool success = mount_points->RegisterFileSystem( 443 mount_point_name_, 444 fileapi::kFileSystemTypeDrive, 445 fileapi::FileSystemMountOption(), 446 drive_mount_point); 447 448 if (success) { 449 logger_->Log(logging::LOG_INFO, "Drive mount point is added"); 450 FOR_EACH_OBSERVER(DriveIntegrationServiceObserver, observers_, 451 OnFileSystemMounted()); 452 } 453 } 454 455 void DriveIntegrationService::RemoveDriveMountPoint() { 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 457 458 if (!mount_point_name_.empty()) { 459 job_list()->CancelAllJobs(); 460 461 FOR_EACH_OBSERVER(DriveIntegrationServiceObserver, observers_, 462 OnFileSystemBeingUnmounted()); 463 464 fileapi::ExternalMountPoints* const mount_points = 465 fileapi::ExternalMountPoints::GetSystemInstance(); 466 DCHECK(mount_points); 467 468 mount_points->RevokeFileSystem(mount_point_name_); 469 logger_->Log(logging::LOG_INFO, "Drive mount point is removed"); 470 } 471 } 472 473 void DriveIntegrationService::Initialize() { 474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 475 DCHECK_EQ(NOT_INITIALIZED, state_); 476 DCHECK(enabled_); 477 478 state_ = INITIALIZING; 479 480 base::PostTaskAndReplyWithResult( 481 blocking_task_runner_.get(), 482 FROM_HERE, 483 base::Bind(&InitializeMetadata, 484 cache_root_directory_, 485 metadata_storage_.get(), 486 cache_.get(), 487 resource_metadata_.get(), 488 drive_service_->GetResourceIdCanonicalizer(), 489 file_manager::util::GetDownloadsFolderForProfile(profile_)), 490 base::Bind(&DriveIntegrationService::InitializeAfterMetadataInitialized, 491 weak_ptr_factory_.GetWeakPtr())); 492 } 493 494 void DriveIntegrationService::InitializeAfterMetadataInitialized( 495 FileError error) { 496 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 497 DCHECK_EQ(INITIALIZING, state_); 498 499 SigninManagerBase* signin_manager = 500 SigninManagerFactory::GetForProfile(profile_); 501 drive_service_->Initialize(signin_manager->GetAuthenticatedAccountId()); 502 503 if (error != FILE_ERROR_OK) { 504 LOG(WARNING) << "Failed to initialize: " << FileErrorToString(error); 505 506 // Cannot used Drive. Set the download destination preference out of Drive. 507 AvoidDriveAsDownloadDirecotryPreference(); 508 509 // Back to NOT_INITIALIZED state. Then, re-running Initialize() should 510 // work if the error is recoverable manually (such as out of disk space). 511 state_ = NOT_INITIALIZED; 512 return; 513 } 514 515 // Initialize Download Handler for hooking downloads to the Drive folder. 516 content::DownloadManager* download_manager = 517 g_browser_process->download_status_updater() ? 518 BrowserContext::GetDownloadManager(profile_) : NULL; 519 download_handler_->Initialize( 520 download_manager, 521 cache_root_directory_.Append(kTemporaryFileDirectory)); 522 523 // Install the handler also to incognito profile. 524 if (g_browser_process->download_status_updater()) { 525 if (profile_->HasOffTheRecordProfile()) { 526 download_handler_->ObserveIncognitoDownloadManager( 527 BrowserContext::GetDownloadManager( 528 profile_->GetOffTheRecordProfile())); 529 } 530 profile_notification_registrar_.reset(new content::NotificationRegistrar); 531 profile_notification_registrar_->Add( 532 this, 533 chrome::NOTIFICATION_PROFILE_CREATED, 534 content::NotificationService::AllSources()); 535 } 536 537 // Register for Google Drive invalidation notifications. 538 DriveNotificationManager* drive_notification_manager = 539 DriveNotificationManagerFactory::GetForBrowserContext(profile_); 540 if (drive_notification_manager) { 541 drive_notification_manager->AddObserver(this); 542 const bool registered = 543 drive_notification_manager->push_notification_registered(); 544 const char* status = (registered ? "registered" : "not registered"); 545 logger_->Log(logging::LOG_INFO, "Push notification is %s", status); 546 547 if (drive_notification_manager->push_notification_enabled()) 548 drive_app_registry_->Update(); 549 } 550 551 state_ = INITIALIZED; 552 553 // Mount only when the drive is enabled. Initialize is triggered by 554 // SetEnabled(true), but there is a change to disable it again during 555 // the metadata initialization, so we need to look this up again here. 556 if (enabled_) 557 AddDriveMountPoint(); 558 } 559 560 void DriveIntegrationService::AvoidDriveAsDownloadDirecotryPreference() { 561 PrefService* pref_service = profile_->GetPrefs(); 562 if (util::IsUnderDriveMountPoint( 563 pref_service->GetFilePath(prefs::kDownloadDefaultDirectory))) { 564 pref_service->SetFilePath( 565 prefs::kDownloadDefaultDirectory, 566 file_manager::util::GetDownloadsFolderForProfile(profile_)); 567 } 568 } 569 570 void DriveIntegrationService::Observe( 571 int type, 572 const content::NotificationSource& source, 573 const content::NotificationDetails& details) { 574 if (type == chrome::NOTIFICATION_PROFILE_CREATED) { 575 Profile* created_profile = content::Source<Profile>(source).ptr(); 576 if (created_profile->IsOffTheRecord() && 577 created_profile->IsSameProfile(profile_)) { 578 download_handler_->ObserveIncognitoDownloadManager( 579 BrowserContext::GetDownloadManager(created_profile)); 580 } 581 } 582 } 583 584 //===================== DriveIntegrationServiceFactory ======================= 585 586 DriveIntegrationServiceFactory::FactoryCallback* 587 DriveIntegrationServiceFactory::factory_for_test_ = NULL; 588 589 DriveIntegrationServiceFactory::ScopedFactoryForTest::ScopedFactoryForTest( 590 FactoryCallback* factory_for_test) { 591 factory_for_test_ = factory_for_test; 592 } 593 594 DriveIntegrationServiceFactory::ScopedFactoryForTest::~ScopedFactoryForTest() { 595 factory_for_test_ = NULL; 596 } 597 598 // static 599 DriveIntegrationService* DriveIntegrationServiceFactory::GetForProfile( 600 Profile* profile) { 601 return GetForProfileRegardlessOfStates(profile); 602 } 603 604 // static 605 DriveIntegrationService* 606 DriveIntegrationServiceFactory::GetForProfileRegardlessOfStates( 607 Profile* profile) { 608 return static_cast<DriveIntegrationService*>( 609 GetInstance()->GetServiceForBrowserContext(profile, true)); 610 } 611 612 // static 613 DriveIntegrationService* DriveIntegrationServiceFactory::FindForProfile( 614 Profile* profile) { 615 return FindForProfileRegardlessOfStates(profile); 616 } 617 618 // static 619 DriveIntegrationService* 620 DriveIntegrationServiceFactory::FindForProfileRegardlessOfStates( 621 Profile* profile) { 622 return static_cast<DriveIntegrationService*>( 623 GetInstance()->GetServiceForBrowserContext(profile, false)); 624 } 625 626 // static 627 DriveIntegrationServiceFactory* DriveIntegrationServiceFactory::GetInstance() { 628 return Singleton<DriveIntegrationServiceFactory>::get(); 629 } 630 631 DriveIntegrationServiceFactory::DriveIntegrationServiceFactory() 632 : BrowserContextKeyedServiceFactory( 633 "DriveIntegrationService", 634 BrowserContextDependencyManager::GetInstance()) { 635 DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); 636 DependsOn(DriveNotificationManagerFactory::GetInstance()); 637 DependsOn(DownloadServiceFactory::GetInstance()); 638 } 639 640 DriveIntegrationServiceFactory::~DriveIntegrationServiceFactory() { 641 } 642 643 content::BrowserContext* DriveIntegrationServiceFactory::GetBrowserContextToUse( 644 content::BrowserContext* context) const { 645 return chrome::GetBrowserContextRedirectedInIncognito(context); 646 } 647 648 KeyedService* DriveIntegrationServiceFactory::BuildServiceInstanceFor( 649 content::BrowserContext* context) const { 650 Profile* profile = Profile::FromBrowserContext(context); 651 652 DriveIntegrationService* service = NULL; 653 if (!factory_for_test_) { 654 DriveIntegrationService::PreferenceWatcher* preference_watcher = NULL; 655 if (chromeos::IsProfileAssociatedWithGaiaAccount(profile)) { 656 // Drive File System can be enabled. 657 preference_watcher = 658 new DriveIntegrationService::PreferenceWatcher(profile->GetPrefs()); 659 } 660 661 service = new DriveIntegrationService( 662 profile, preference_watcher, 663 NULL, std::string(), base::FilePath(), NULL); 664 } else { 665 service = factory_for_test_->Run(profile); 666 } 667 668 return service; 669 } 670 671 } // namespace drive 672