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