Home | History | Annotate | Download | only in file_manager
      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 "base/bind.h"
      6 #include "base/files/file_path.h"
      7 #include "base/files/file_util.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/path_service.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
     12 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
     13 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
     14 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     15 #include "chrome/browser/drive/fake_drive_service.h"
     16 #include "chrome/browser/extensions/extension_apitest.h"
     17 #include "chrome/browser/profiles/profile.h"
     18 #include "chrome/browser/profiles/profile_manager.h"
     19 #include "chrome/browser/ui/browser.h"
     20 #include "chrome/common/chrome_constants.h"
     21 #include "chrome/common/chrome_paths.h"
     22 #include "components/user_manager/user_manager.h"
     23 #include "content/public/browser/browser_context.h"
     24 #include "content/public/browser/notification_service.h"
     25 #include "content/public/test/test_utils.h"
     26 #include "extensions/browser/notification_types.h"
     27 #include "extensions/test/result_catcher.h"
     28 #include "google_apis/drive/drive_api_parser.h"
     29 #include "google_apis/drive/test_util.h"
     30 #include "google_apis/drive/time_util.h"
     31 #include "storage/browser/fileapi/external_mount_points.h"
     32 
     33 // Tests for access to external file systems (as defined in
     34 // storage/common/fileapi/file_system_types.h) from extensions with
     35 // fileManagerPrivate and fileBrowserHandler extension permissions.
     36 // The tests cover following external file system types:
     37 // - local (kFileSystemTypeLocalNative): a local file system on which files are
     38 //   accessed using native local path.
     39 // - restricted (kFileSystemTypeRestrictedLocalNative): a *read-only* local file
     40 //   system which can only be accessed by extensions that have full access to
     41 //   external file systems (i.e. extensions with fileManagerPrivate permission).
     42 // - drive (kFileSystemTypeDrive): a file system that provides access to Google
     43 //   Drive.
     44 //
     45 // The tests cover following scenarios:
     46 // - Performing file system operations on external file systems from an
     47 //   app with fileManagerPrivate permission (i.e. Files.app).
     48 // - Performing read/write operations from file handler extensions. These
     49 //   extensions need a file browser extension to give them permissions to access
     50 //   files. This also includes file handler extensions in filesystem API.
     51 // - Observing directory changes from a file browser extension (using
     52 //   fileManagerPrivate API).
     53 // - Doing searches on drive file system from file browser extension (using
     54 //   fileManagerPrivate API).
     55 
     56 using drive::DriveIntegrationServiceFactory;
     57 using extensions::Extension;
     58 
     59 namespace file_manager {
     60 namespace {
     61 
     62 // Root dirs for file systems expected by the test extensions.
     63 // NOTE: Root dir for drive file system is set by Chrome's drive implementation,
     64 // but the test will have to make sure the mount point is added before
     65 // starting a test extension using WaitUntilDriveMountPointIsAdded().
     66 const char kLocalMountPointName[] = "local";
     67 const char kRestrictedMountPointName[] = "restricted";
     68 
     69 // Default file content for the test files.
     70 const char kTestFileContent[] = "This is some test content.";
     71 
     72 // User account email and directory hash for secondary account for multi-profile
     73 // sensitive test cases.
     74 const char kSecondProfileAccount[] = "profile2 (at) test.com";
     75 const char kSecondProfileHash[] = "fileBrowserApiTestProfile2";
     76 
     77 // Sets up the initial file system state for native local and restricted native
     78 // local file systems. The hierarchy is the same as for the drive file system.
     79 // The directory is created at unique_temp_dir/|mount_point_name| path.
     80 bool InitializeLocalFileSystem(std::string mount_point_name,
     81                                base::ScopedTempDir* tmp_dir,
     82                                base::FilePath* mount_point_dir) {
     83   if (!tmp_dir->CreateUniqueTempDir())
     84     return false;
     85 
     86   *mount_point_dir = tmp_dir->path().AppendASCII(mount_point_name);
     87   // Create the mount point.
     88   if (!base::CreateDirectory(*mount_point_dir))
     89     return false;
     90 
     91   base::FilePath test_dir = mount_point_dir->AppendASCII("test_dir");
     92   if (!base::CreateDirectory(test_dir))
     93     return false;
     94 
     95   base::FilePath test_subdir = test_dir.AppendASCII("empty_test_dir");
     96   if (!base::CreateDirectory(test_subdir))
     97     return false;
     98 
     99   test_subdir = test_dir.AppendASCII("subdir");
    100   if (!base::CreateDirectory(test_subdir))
    101     return false;
    102 
    103   base::FilePath test_file = test_dir.AppendASCII("test_file.xul");
    104   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
    105     return false;
    106 
    107   test_file = test_dir.AppendASCII("test_file.xul.foo");
    108   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
    109     return false;
    110 
    111   test_file = test_dir.AppendASCII("test_file.tiff");
    112   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
    113     return false;
    114 
    115   test_file = test_dir.AppendASCII("test_file.tiff.foo");
    116   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
    117     return false;
    118 
    119   test_file = test_dir.AppendASCII("empty_test_file.foo");
    120   if (!google_apis::test_util::WriteStringToFile(test_file, ""))
    121     return false;
    122 
    123   return true;
    124 }
    125 
    126 scoped_ptr<google_apis::FileResource> UpdateDriveEntryTime(
    127     drive::FakeDriveService* fake_drive_service,
    128     const std::string& resource_id,
    129     const std::string& last_modified,
    130     const std::string& last_viewed_by_me) {
    131   base::Time last_modified_time, last_viewed_by_me_time;
    132   if (!google_apis::util::GetTimeFromString(last_modified,
    133                                             &last_modified_time) ||
    134       !google_apis::util::GetTimeFromString(last_viewed_by_me,
    135                                             &last_viewed_by_me_time))
    136     return scoped_ptr<google_apis::FileResource>();
    137 
    138   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    139   scoped_ptr<google_apis::FileResource> entry;
    140   fake_drive_service->UpdateResource(
    141       resource_id,
    142       std::string(),  // parent_resource_id
    143       std::string(),  // title
    144       last_modified_time,
    145       last_viewed_by_me_time,
    146       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    147   base::RunLoop().RunUntilIdle();
    148   if (error != google_apis::HTTP_SUCCESS)
    149     return scoped_ptr<google_apis::FileResource>();
    150 
    151   return entry.Pass();
    152 }
    153 
    154 scoped_ptr<google_apis::FileResource> AddFileToDriveService(
    155     drive::FakeDriveService* fake_drive_service,
    156     const std::string& mime_type,
    157     const std::string& content,
    158     const std::string& parent_resource_id,
    159     const std::string& title,
    160     const std::string& last_modified,
    161     const std::string& last_viewed_by_me) {
    162   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    163   scoped_ptr<google_apis::FileResource> entry;
    164   fake_drive_service->AddNewFile(
    165       mime_type,
    166       content,
    167       parent_resource_id,
    168       title,
    169       false,  // shared_with_me
    170       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    171   base::RunLoop().RunUntilIdle();
    172   if (error != google_apis::HTTP_CREATED)
    173     return scoped_ptr<google_apis::FileResource>();
    174 
    175   return UpdateDriveEntryTime(fake_drive_service, entry->file_id(),
    176                               last_modified, last_viewed_by_me);
    177 }
    178 
    179 scoped_ptr<google_apis::FileResource> AddDirectoryToDriveService(
    180     drive::FakeDriveService* fake_drive_service,
    181     const std::string& parent_resource_id,
    182     const std::string& title,
    183     const std::string& last_modified,
    184     const std::string& last_viewed_by_me) {
    185   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    186   scoped_ptr<google_apis::FileResource> entry;
    187   fake_drive_service->AddNewDirectory(
    188       parent_resource_id,
    189       title,
    190       drive::DriveServiceInterface::AddNewDirectoryOptions(),
    191       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    192   base::RunLoop().RunUntilIdle();
    193   if (error != google_apis::HTTP_CREATED)
    194     return scoped_ptr<google_apis::FileResource>();
    195 
    196   return UpdateDriveEntryTime(fake_drive_service, entry->file_id(),
    197                               last_modified, last_viewed_by_me);
    198 }
    199 
    200 // Sets up the drive service state.
    201 // The hierarchy is the same as for the local file system.
    202 bool InitializeDriveService(
    203     drive::FakeDriveService* fake_drive_service,
    204     std::map<std::string, std::string>* out_resource_ids) {
    205   scoped_ptr<google_apis::FileResource> entry;
    206 
    207   entry = AddDirectoryToDriveService(fake_drive_service,
    208                                      fake_drive_service->GetRootResourceId(),
    209                                      "test_dir",
    210                                      "2012-01-02T00:00:00.000Z",
    211                                      "2012-01-02T00:00:01.000Z");
    212   if (!entry)
    213     return false;
    214   (*out_resource_ids)[entry->title()] = entry->file_id();
    215 
    216   entry = AddDirectoryToDriveService(fake_drive_service,
    217                                      (*out_resource_ids)["test_dir"],
    218                                      "empty_test_dir",
    219                                      "2011-11-02T04:00:00.000Z",
    220                                      "2011-11-02T04:00:00.000Z");
    221   if (!entry)
    222     return false;
    223   (*out_resource_ids)[entry->title()] = entry->file_id();
    224 
    225   entry = AddDirectoryToDriveService(fake_drive_service,
    226                                      (*out_resource_ids)["test_dir"],
    227                                      "subdir",
    228                                      "2011-04-01T18:34:08.234Z",
    229                                      "2012-01-02T00:00:01.000Z");
    230   if (!entry)
    231     return false;
    232   (*out_resource_ids)[entry->title()] = entry->file_id();
    233 
    234   entry = AddFileToDriveService(fake_drive_service,
    235                                 "application/vnd.mozilla.xul+xml",
    236                                 kTestFileContent,
    237                                 (*out_resource_ids)["test_dir"],
    238                                 "test_file.xul",
    239                                 "2011-12-14T00:40:47.330Z",
    240                                 "2012-01-02T00:00:00.000Z");
    241   if (!entry)
    242     return false;
    243   (*out_resource_ids)[entry->title()] = entry->file_id();
    244 
    245   entry = AddFileToDriveService(fake_drive_service,
    246                                 "test/ro",
    247                                 kTestFileContent,
    248                                 (*out_resource_ids)["test_dir"],
    249                                 "test_file.xul.foo",
    250                                 "2012-01-01T10:00:30.000Z",
    251                                 "2012-01-01T00:00:00.000Z");
    252   if (!entry)
    253     return false;
    254   (*out_resource_ids)[entry->title()] = entry->file_id();
    255 
    256   entry = AddFileToDriveService(fake_drive_service,
    257                                 "image/tiff",
    258                                 kTestFileContent,
    259                                 (*out_resource_ids)["test_dir"],
    260                                 "test_file.tiff",
    261                                 "2011-04-03T11:11:10.000Z",
    262                                 "2012-01-02T00:00:00.000Z");
    263   if (!entry)
    264     return false;
    265   (*out_resource_ids)[entry->title()] = entry->file_id();
    266 
    267   entry = AddFileToDriveService(fake_drive_service,
    268                                 "test/rw",
    269                                 kTestFileContent,
    270                                 (*out_resource_ids)["test_dir"],
    271                                 "test_file.tiff.foo",
    272                                 "2011-12-14T00:40:47.330Z",
    273                                 "2010-01-02T00:00:00.000Z");
    274   if (!entry)
    275     return false;
    276   (*out_resource_ids)[entry->title()] = entry->file_id();
    277 
    278   entry = AddFileToDriveService(fake_drive_service,
    279                                 "test/rw",
    280                                 "",
    281                                 (*out_resource_ids)["test_dir"],
    282                                 "empty_test_file.foo",
    283                                 "2011-12-14T00:40:47.330Z",
    284                                 "2011-12-14T00:40:47.330Z");
    285   if (!entry)
    286     return false;
    287   (*out_resource_ids)[entry->title()] = entry->file_id();
    288 
    289   return true;
    290 }
    291 
    292 // Helper class to wait for a background page to load or close again.
    293 class BackgroundObserver {
    294  public:
    295   BackgroundObserver()
    296       : page_created_(extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
    297                       content::NotificationService::AllSources()),
    298         page_closed_(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
    299                      content::NotificationService::AllSources()) {}
    300 
    301   void WaitUntilLoaded() {
    302     page_created_.Wait();
    303   }
    304 
    305   void WaitUntilClosed() {
    306     page_closed_.Wait();
    307   }
    308 
    309  private:
    310   content::WindowedNotificationObserver page_created_;
    311   content::WindowedNotificationObserver page_closed_;
    312 };
    313 
    314 // Base class for FileSystemExtensionApi tests.
    315 class FileSystemExtensionApiTestBase : public ExtensionApiTest {
    316  public:
    317   enum Flags {
    318     FLAGS_NONE = 0,
    319     FLAGS_USE_FILE_HANDLER = 1 << 1,
    320     FLAGS_LAZY_FILE_HANDLER = 1 << 2
    321   };
    322 
    323   FileSystemExtensionApiTestBase() {}
    324   virtual ~FileSystemExtensionApiTestBase() {}
    325 
    326   virtual void SetUp() OVERRIDE {
    327     InitTestFileSystem();
    328     ExtensionApiTest::SetUp();
    329   }
    330 
    331   virtual void SetUpOnMainThread() OVERRIDE {
    332     AddTestMountPoint();
    333     ExtensionApiTest::SetUpOnMainThread();
    334   }
    335 
    336   // Runs a file system extension API test.
    337   // It loads test component extension at |filebrowser_path| with manifest
    338   // at |filebrowser_manifest|. The |filebrowser_manifest| should be a path
    339   // relative to |filebrowser_path|. The method waits until the test extension
    340   // sends test succeed or fail message. It returns true if the test succeeds.
    341   // If |FLAGS_USE_FILE_HANDLER| flag is set, the file handler extension at path
    342   // |filehandler_path| will be loaded before the file browser extension.
    343   // If the flag FLAGS_LAZY_FILE_HANDLER is set, the file handler extension must
    344   // not have persistent background page. The test will wait until the file
    345   // handler's background page is closed after initial load before the file
    346   // browser extension is loaded.
    347   // If |RunFileSystemExtensionApiTest| fails, |message_| will contain a failure
    348   // message.
    349   bool RunFileSystemExtensionApiTest(
    350       const std::string& filebrowser_path,
    351       const base::FilePath::CharType* filebrowser_manifest,
    352       const std::string& filehandler_path,
    353       int flags) {
    354     if (flags & FLAGS_USE_FILE_HANDLER) {
    355       if (filehandler_path.empty()) {
    356         message_ = "Missing file handler path.";
    357         return false;
    358       }
    359 
    360       BackgroundObserver page_complete;
    361       const Extension* file_handler =
    362           LoadExtension(test_data_dir_.AppendASCII(filehandler_path));
    363       if (!file_handler)
    364         return false;
    365 
    366       if (flags & FLAGS_LAZY_FILE_HANDLER) {
    367         page_complete.WaitUntilClosed();
    368       } else {
    369         page_complete.WaitUntilLoaded();
    370       }
    371     }
    372 
    373     extensions::ResultCatcher catcher;
    374 
    375     const Extension* file_browser = LoadExtensionAsComponentWithManifest(
    376         test_data_dir_.AppendASCII(filebrowser_path),
    377         filebrowser_manifest);
    378     if (!file_browser)
    379       return false;
    380 
    381     if (!catcher.GetNextResult()) {
    382       message_ = catcher.message();
    383       return false;
    384     }
    385 
    386     return true;
    387   }
    388 
    389  protected:
    390   // Sets up initial test file system hierarchy.
    391   virtual void InitTestFileSystem() = 0;
    392   // Registers mount point used in the test.
    393   virtual void AddTestMountPoint() = 0;
    394 };
    395 
    396 // Tests for a native local file system.
    397 class LocalFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
    398  public:
    399   LocalFileSystemExtensionApiTest() {}
    400   virtual ~LocalFileSystemExtensionApiTest() {}
    401 
    402   // FileSystemExtensionApiTestBase OVERRIDE.
    403   virtual void InitTestFileSystem() OVERRIDE {
    404     ASSERT_TRUE(InitializeLocalFileSystem(
    405         kLocalMountPointName, &tmp_dir_, &mount_point_dir_))
    406         << "Failed to initialize file system.";
    407   }
    408 
    409   // FileSystemExtensionApiTestBase OVERRIDE.
    410   virtual void AddTestMountPoint() OVERRIDE {
    411     EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())
    412                     ->RegisterFileSystem(kLocalMountPointName,
    413                                          storage::kFileSystemTypeNativeLocal,
    414                                          storage::FileSystemMountOption(),
    415                                          mount_point_dir_));
    416     VolumeManager::Get(browser()->profile())->AddVolumeInfoForTesting(
    417         mount_point_dir_, VOLUME_TYPE_TESTING, chromeos::DEVICE_TYPE_UNKNOWN);
    418   }
    419 
    420  private:
    421   base::ScopedTempDir tmp_dir_;
    422   base::FilePath mount_point_dir_;
    423 };
    424 
    425 // Tests for restricted native local file systems.
    426 class RestrictedFileSystemExtensionApiTest
    427     : public FileSystemExtensionApiTestBase {
    428  public:
    429   RestrictedFileSystemExtensionApiTest() {}
    430   virtual ~RestrictedFileSystemExtensionApiTest() {}
    431 
    432   // FileSystemExtensionApiTestBase OVERRIDE.
    433   virtual void InitTestFileSystem() OVERRIDE {
    434     ASSERT_TRUE(InitializeLocalFileSystem(
    435         kRestrictedMountPointName, &tmp_dir_, &mount_point_dir_))
    436         << "Failed to initialize file system.";
    437   }
    438 
    439   // FileSystemExtensionApiTestBase OVERRIDE.
    440   virtual void AddTestMountPoint() OVERRIDE {
    441     EXPECT_TRUE(
    442         content::BrowserContext::GetMountPoints(browser()->profile())
    443             ->RegisterFileSystem(kRestrictedMountPointName,
    444                                  storage::kFileSystemTypeRestrictedNativeLocal,
    445                                  storage::FileSystemMountOption(),
    446                                  mount_point_dir_));
    447     VolumeManager::Get(browser()->profile())->AddVolumeInfoForTesting(
    448         mount_point_dir_, VOLUME_TYPE_TESTING, chromeos::DEVICE_TYPE_UNKNOWN);
    449   }
    450 
    451  private:
    452   base::ScopedTempDir tmp_dir_;
    453   base::FilePath mount_point_dir_;
    454 };
    455 
    456 // Tests for a drive file system.
    457 class DriveFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
    458  public:
    459   DriveFileSystemExtensionApiTest() : fake_drive_service_(NULL) {}
    460   virtual ~DriveFileSystemExtensionApiTest() {}
    461 
    462   // FileSystemExtensionApiTestBase OVERRIDE.
    463   virtual void InitTestFileSystem() OVERRIDE {
    464     // Set up cache root to be used by DriveIntegrationService. This has to be
    465     // done before the browser is created because the service instance is
    466     // initialized by EventRouter.
    467     ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
    468 
    469     // This callback will get called during Profile creation.
    470     create_drive_integration_service_ = base::Bind(
    471         &DriveFileSystemExtensionApiTest::CreateDriveIntegrationService,
    472         base::Unretained(this));
    473     service_factory_for_test_.reset(
    474         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
    475             &create_drive_integration_service_));
    476   }
    477 
    478   // FileSystemExtensionApiTestBase OVERRIDE.
    479   virtual void AddTestMountPoint() OVERRIDE {
    480     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
    481   }
    482 
    483  protected:
    484   // DriveIntegrationService factory function for this test.
    485   drive::DriveIntegrationService* CreateDriveIntegrationService(
    486       Profile* profile) {
    487     fake_drive_service_ = new drive::FakeDriveService;
    488     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
    489 
    490     std::map<std::string, std::string> resource_ids;
    491     EXPECT_TRUE(InitializeDriveService(fake_drive_service_, &resource_ids));
    492 
    493     return new drive::DriveIntegrationService(
    494         profile, NULL,
    495         fake_drive_service_, "drive", test_cache_root_.path(), NULL);
    496   }
    497 
    498   base::ScopedTempDir test_cache_root_;
    499   drive::FakeDriveService* fake_drive_service_;
    500   DriveIntegrationServiceFactory::FactoryCallback
    501       create_drive_integration_service_;
    502   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
    503       service_factory_for_test_;
    504 };
    505 
    506 // Tests for Drive file systems in multi-profile setting.
    507 class MultiProfileDriveFileSystemExtensionApiTest :
    508     public FileSystemExtensionApiTestBase {
    509  public:
    510   MultiProfileDriveFileSystemExtensionApiTest() : second_profile(NULL) {}
    511 
    512   virtual void SetUpOnMainThread() OVERRIDE {
    513     base::FilePath user_data_directory;
    514     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
    515     user_manager::UserManager::Get()->UserLoggedIn(
    516         kSecondProfileAccount, kSecondProfileHash, false);
    517     // Set up the secondary profile.
    518     base::FilePath profile_dir =
    519         user_data_directory.Append(
    520             chromeos::ProfileHelper::GetUserProfileDir(
    521                 kSecondProfileHash).BaseName());
    522     second_profile =
    523         g_browser_process->profile_manager()->GetProfile(profile_dir);
    524 
    525     FileSystemExtensionApiTestBase::SetUpOnMainThread();
    526   }
    527 
    528   virtual void InitTestFileSystem() OVERRIDE {
    529     // This callback will get called during Profile creation.
    530     create_drive_integration_service_ = base::Bind(
    531         &MultiProfileDriveFileSystemExtensionApiTest::
    532             CreateDriveIntegrationService,
    533         base::Unretained(this));
    534     service_factory_for_test_.reset(
    535         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
    536             &create_drive_integration_service_));
    537   }
    538 
    539   virtual void AddTestMountPoint() OVERRIDE {
    540     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
    541     test_util::WaitUntilDriveMountPointIsAdded(second_profile);
    542   }
    543 
    544  protected:
    545   // DriveIntegrationService factory function for this test.
    546   drive::DriveIntegrationService* CreateDriveIntegrationService(
    547       Profile* profile) {
    548     base::FilePath cache_dir;
    549     base::CreateNewTempDirectory(base::FilePath::StringType(), &cache_dir);
    550 
    551     drive::FakeDriveService* const fake_drive_service =
    552         new drive::FakeDriveService;
    553     fake_drive_service->LoadAppListForDriveApi("drive/applist.json");
    554     EXPECT_TRUE(InitializeDriveService(fake_drive_service, &resource_ids_));
    555 
    556     return new drive::DriveIntegrationService(
    557         profile, NULL, fake_drive_service, std::string(), cache_dir, NULL);
    558   }
    559 
    560   bool AddTestHostedDocuments() {
    561     const char kResourceId[] = "unique-id-for-multiprofile-copy-test";
    562     drive::FakeDriveService* const main_service =
    563         static_cast<drive::FakeDriveService*>(
    564             drive::util::GetDriveServiceByProfile(browser()->profile()));
    565     drive::FakeDriveService* const sub_service =
    566         static_cast<drive::FakeDriveService*>(
    567             drive::util::GetDriveServiceByProfile(second_profile));
    568 
    569     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    570     scoped_ptr<google_apis::FileResource> entry;
    571 
    572     // Place a hosted document under root/test_dir of the sub profile.
    573     sub_service->AddNewFileWithResourceId(
    574         kResourceId,
    575         "application/vnd.google-apps.document", "",
    576         resource_ids_["test_dir"], "hosted_doc", true,
    577         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    578     content::RunAllBlockingPoolTasksUntilIdle();
    579     if (error != google_apis::HTTP_CREATED)
    580       return false;
    581 
    582     // Place the hosted document with no parent in the main profile, for
    583     // simulating the situation that the document is shared to the main profile.
    584     error = google_apis::GDATA_OTHER_ERROR;
    585     main_service->AddNewFileWithResourceId(
    586         kResourceId,
    587         "application/vnd.google-apps.document", "", "", "hosted_doc", true,
    588         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    589     content::RunAllBlockingPoolTasksUntilIdle();
    590     return (error == google_apis::HTTP_CREATED);
    591   }
    592 
    593   DriveIntegrationServiceFactory::FactoryCallback
    594       create_drive_integration_service_;
    595   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
    596       service_factory_for_test_;
    597   Profile* second_profile;
    598   std::map<std::string, std::string> resource_ids_;
    599 };
    600 
    601 class LocalAndDriveFileSystemExtensionApiTest
    602     : public FileSystemExtensionApiTestBase {
    603  public:
    604   LocalAndDriveFileSystemExtensionApiTest() {}
    605   virtual ~LocalAndDriveFileSystemExtensionApiTest() {}
    606 
    607   // FileSystemExtensionApiTestBase OVERRIDE.
    608   virtual void InitTestFileSystem() OVERRIDE {
    609     ASSERT_TRUE(InitializeLocalFileSystem(
    610         kLocalMountPointName, &local_tmp_dir_, &local_mount_point_dir_))
    611         << "Failed to initialize file system.";
    612 
    613     // Set up cache root to be used by DriveIntegrationService. This has to be
    614     // done before the browser is created because the service instance is
    615     // initialized by EventRouter.
    616     ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
    617 
    618     // This callback will get called during Profile creation.
    619     create_drive_integration_service_ = base::Bind(
    620         &LocalAndDriveFileSystemExtensionApiTest::CreateDriveIntegrationService,
    621         base::Unretained(this));
    622     service_factory_for_test_.reset(
    623         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
    624             &create_drive_integration_service_));
    625   }
    626 
    627   // FileSystemExtensionApiTestBase OVERRIDE.
    628   virtual void AddTestMountPoint() OVERRIDE {
    629     EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())
    630                     ->RegisterFileSystem(kLocalMountPointName,
    631                                          storage::kFileSystemTypeNativeLocal,
    632                                          storage::FileSystemMountOption(),
    633                                          local_mount_point_dir_));
    634     VolumeManager::Get(browser()->profile())
    635         ->AddVolumeInfoForTesting(local_mount_point_dir_,
    636                                   VOLUME_TYPE_TESTING,
    637                                   chromeos::DEVICE_TYPE_UNKNOWN);
    638     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
    639   }
    640 
    641  protected:
    642   // DriveIntegrationService factory function for this test.
    643   drive::DriveIntegrationService* CreateDriveIntegrationService(
    644       Profile* profile) {
    645     fake_drive_service_ = new drive::FakeDriveService;
    646     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
    647 
    648     std::map<std::string, std::string> resource_ids;
    649     EXPECT_TRUE(InitializeDriveService(fake_drive_service_, &resource_ids));
    650 
    651     return new drive::DriveIntegrationService(profile,
    652                                               NULL,
    653                                               fake_drive_service_,
    654                                               "drive",
    655                                               test_cache_root_.path(),
    656                                               NULL);
    657   }
    658 
    659  private:
    660   // For local volume.
    661   base::ScopedTempDir local_tmp_dir_;
    662   base::FilePath local_mount_point_dir_;
    663 
    664   // For drive volume.
    665   base::ScopedTempDir test_cache_root_;
    666   drive::FakeDriveService* fake_drive_service_;
    667   DriveIntegrationServiceFactory::FactoryCallback
    668       create_drive_integration_service_;
    669   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
    670       service_factory_for_test_;
    671 };
    672 
    673 //
    674 // LocalFileSystemExtensionApiTests.
    675 //
    676 
    677 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileSystemOperations) {
    678   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    679       "file_browser/filesystem_operations_test",
    680       FILE_PATH_LITERAL("manifest.json"),
    681       "",
    682       FLAGS_NONE)) << message_;
    683 }
    684 
    685 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileWatch) {
    686   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    687       "file_browser/file_watcher_test",
    688       FILE_PATH_LITERAL("manifest.json"),
    689       "",
    690       FLAGS_NONE)) << message_;
    691 }
    692 
    693 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileBrowserHandlers) {
    694   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    695       "file_browser/handler_test_runner",
    696       FILE_PATH_LITERAL("manifest.json"),
    697       "file_browser/file_browser_handler",
    698       FLAGS_USE_FILE_HANDLER)) << message_;
    699 }
    700 
    701 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest,
    702                        FileBrowserHandlersLazy) {
    703   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    704       "file_browser/handler_test_runner",
    705       FILE_PATH_LITERAL("manifest.json"),
    706       "file_browser/file_browser_handler_lazy",
    707       FLAGS_USE_FILE_HANDLER | FLAGS_LAZY_FILE_HANDLER)) << message_;
    708 }
    709 
    710 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, AppFileHandler) {
    711   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    712       "file_browser/handler_test_runner",
    713       FILE_PATH_LITERAL("manifest.json"),
    714       "file_browser/app_file_handler",
    715       FLAGS_USE_FILE_HANDLER)) << message_;
    716 }
    717 
    718 //
    719 // RestrictedFileSystemExtensionApiTests.
    720 //
    721 IN_PROC_BROWSER_TEST_F(RestrictedFileSystemExtensionApiTest,
    722                        FileSystemOperations) {
    723   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    724       "file_browser/filesystem_operations_test",
    725       FILE_PATH_LITERAL("manifest.json"),
    726       "",
    727       FLAGS_NONE)) << message_;
    728 }
    729 
    730 //
    731 // DriveFileSystemExtensionApiTests.
    732 //
    733 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileSystemOperations) {
    734   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    735       "file_browser/filesystem_operations_test",
    736       FILE_PATH_LITERAL("manifest.json"),
    737       "",
    738       FLAGS_NONE)) << message_;
    739 }
    740 
    741 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileWatch) {
    742   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    743       "file_browser/file_watcher_test",
    744       FILE_PATH_LITERAL("manifest.json"),
    745       "",
    746       FLAGS_NONE)) << message_;
    747 }
    748 
    749 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileBrowserHandlers) {
    750   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    751       "file_browser/handler_test_runner",
    752       FILE_PATH_LITERAL("manifest.json"),
    753       "file_browser/file_browser_handler",
    754       FLAGS_USE_FILE_HANDLER)) << message_;
    755 }
    756 
    757 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, Search) {
    758   // Configure the drive service to return only one search result at a time
    759   // to simulate paginated searches.
    760   fake_drive_service_->set_default_max_results(1);
    761   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    762       "file_browser/drive_search_test",
    763       FILE_PATH_LITERAL("manifest.json"),
    764       "",
    765       FLAGS_NONE)) << message_;
    766 }
    767 
    768 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, AppFileHandler) {
    769   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    770       "file_browser/handler_test_runner",
    771       FILE_PATH_LITERAL("manifest.json"),
    772       "file_browser/app_file_handler",
    773       FLAGS_USE_FILE_HANDLER)) << message_;
    774 }
    775 
    776 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest,
    777                        FileSystemFileOriginURL) {
    778   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    779       "file_browser/filesystem_file_origin_url",
    780       FILE_PATH_LITERAL("manifest.json"),
    781       "",
    782       FLAGS_NONE)) << message_;
    783 }
    784 
    785 IN_PROC_BROWSER_TEST_F(MultiProfileDriveFileSystemExtensionApiTest,
    786                        CrossProfileCopy) {
    787   ASSERT_TRUE(AddTestHostedDocuments());
    788   EXPECT_TRUE(RunFileSystemExtensionApiTest(
    789       "file_browser/multi_profile_copy",
    790       FILE_PATH_LITERAL("manifest.json"),
    791       "",
    792       FLAGS_NONE)) << message_;
    793 }
    794 
    795 //
    796 // LocalAndDriveFileSystemExtensionApiTests.
    797 //
    798 IN_PROC_BROWSER_TEST_F(LocalAndDriveFileSystemExtensionApiTest,
    799                        AppFileHandlerMulti) {
    800   EXPECT_TRUE(
    801       RunFileSystemExtensionApiTest("file_browser/app_file_handler_multi",
    802                                     FILE_PATH_LITERAL("manifest.json"),
    803                                     "",
    804                                     FLAGS_NONE))
    805       << message_;
    806 }
    807 }  // namespace
    808 }  // namespace file_manager
    809