Home | History | Annotate | Download | only in media_galleries
      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/auto_reset.h"
      6 #include "base/file_util.h"
      7 #include "base/files/scoped_temp_dir.h"
      8 #include "base/json/json_writer.h"
      9 #include "base/path_service.h"
     10 #include "base/safe_numerics.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "base/values.h"
     13 #include "chrome/browser/apps/app_browsertest_util.h"
     14 #include "chrome/browser/browser_process.h"
     15 #include "chrome/browser/extensions/extension_system.h"
     16 #include "chrome/browser/media_galleries/media_file_system_registry.h"
     17 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
     18 #include "chrome/browser/media_galleries/media_galleries_test_util.h"
     19 #include "chrome/browser/storage_monitor/storage_info.h"
     20 #include "chrome/browser/storage_monitor/storage_monitor.h"
     21 #include "chrome/common/chrome_paths.h"
     22 #include "content/public/test/test_utils.h"
     23 
     24 #if defined(OS_WIN) || defined(OS_MACOSX)
     25 #include "chrome/browser/media_galleries/fileapi/picasa_finder.h"
     26 #include "chrome/common/media_galleries/picasa_test_util.h"
     27 #include "chrome/common/media_galleries/picasa_types.h"
     28 #include "chrome/common/media_galleries/pmp_test_util.h"
     29 #endif
     30 
     31 using extensions::PlatformAppBrowserTest;
     32 
     33 namespace {
     34 
     35 // Dummy device properties.
     36 const char kDeviceId[] = "testDeviceId";
     37 const char kDeviceName[] = "foobar";
     38 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
     39 base::FilePath::CharType kDevicePath[] = FILE_PATH_LITERAL("C:\\qux");
     40 #else
     41 base::FilePath::CharType kDevicePath[] = FILE_PATH_LITERAL("/qux");
     42 #endif
     43 
     44 }  // namespace
     45 
     46 class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest {
     47  protected:
     48   MediaGalleriesPlatformAppBrowserTest() : test_jpg_size_(0) {}
     49   virtual ~MediaGalleriesPlatformAppBrowserTest() {}
     50 
     51   virtual void SetUpOnMainThread() OVERRIDE {
     52     PlatformAppBrowserTest::SetUpOnMainThread();
     53     ensure_media_directories_exists_.reset(new EnsureMediaDirectoriesExists);
     54 
     55     int64 file_size;
     56     ASSERT_TRUE(base::GetFileSize(GetCommonDataDir().AppendASCII("test.jpg"),
     57                                   &file_size));
     58     test_jpg_size_ = base::checked_numeric_cast<int>(file_size);
     59   }
     60 
     61   virtual void TearDownOnMainThread() OVERRIDE {
     62     ensure_media_directories_exists_.reset();
     63     PlatformAppBrowserTest::TearDownOnMainThread();
     64   }
     65 
     66   bool RunMediaGalleriesTest(const std::string& extension_name) {
     67     base::ListValue empty_list_value;
     68     return RunMediaGalleriesTestWithArg(extension_name, empty_list_value);
     69   }
     70 
     71   bool RunMediaGalleriesTestWithArg(const std::string& extension_name,
     72                                     const base::ListValue& custom_arg_value) {
     73     // Copy the test data for this test into a temporary directory. Then add
     74     // a common_injected.js to the temporary copy and run it.
     75     const char kTestDir[] = "api_test/media_galleries/";
     76     base::FilePath from_dir =
     77         test_data_dir_.AppendASCII(kTestDir + extension_name);
     78     from_dir = from_dir.NormalizePathSeparators();
     79 
     80     base::ScopedTempDir temp_dir;
     81     if (!temp_dir.CreateUniqueTempDir())
     82       return false;
     83 
     84     if (!base::CopyDirectory(from_dir, temp_dir.path(), true))
     85       return false;
     86 
     87     base::FilePath common_js_path(
     88         GetCommonDataDir().AppendASCII("common_injected.js"));
     89     base::FilePath inject_js_path(
     90         temp_dir.path().AppendASCII(extension_name)
     91                        .AppendASCII("common_injected.js"));
     92     if (!base::CopyFile(common_js_path, inject_js_path))
     93       return false;
     94 
     95     const char* custom_arg = NULL;
     96     std::string json_string;
     97     if (!custom_arg_value.empty()) {
     98       base::JSONWriter::Write(&custom_arg_value, &json_string);
     99       custom_arg = json_string.c_str();
    100     }
    101 
    102     base::AutoReset<base::FilePath> reset(&test_data_dir_, temp_dir.path());
    103     return RunPlatformAppTestWithArg(extension_name, custom_arg);
    104   }
    105 
    106   void AttachFakeDevice() {
    107     device_id_ = StorageInfo::MakeDeviceId(
    108         StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, kDeviceId);
    109 
    110     StorageMonitor::GetInstance()->receiver()->ProcessAttach(
    111         StorageInfo(device_id_, base::string16(), kDevicePath,
    112                     ASCIIToUTF16(kDeviceName), base::string16(),
    113                     base::string16(), 0));
    114     content::RunAllPendingInMessageLoop();
    115   }
    116 
    117   void DetachFakeDevice() {
    118     StorageMonitor::GetInstance()->receiver()->ProcessDetach(device_id_);
    119     content::RunAllPendingInMessageLoop();
    120   }
    121 
    122   // Called if test only wants a single gallery it creates.
    123   void RemoveAllGalleries() {
    124     MediaGalleriesPreferences* preferences = GetAndInitializePreferences();
    125 
    126     // Make a copy, as the iterator would be invalidated otherwise.
    127     const MediaGalleriesPrefInfoMap galleries =
    128         preferences->known_galleries();
    129     for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
    130          it != galleries.end(); ++it) {
    131       preferences->ForgetGalleryById(it->first);
    132     }
    133   }
    134 
    135   // This function makes a single fake gallery. This is needed to test platforms
    136   // with no default media galleries, such as CHROMEOS. This fake gallery is
    137   // pre-populated with a test.jpg and test.txt.
    138   void MakeSingleFakeGallery() {
    139     ASSERT_TRUE(fake_gallery_temp_dir_.CreateUniqueTempDir());
    140 
    141     MediaGalleriesPreferences* preferences = GetAndInitializePreferences();
    142 
    143     MediaGalleryPrefInfo gallery_info;
    144     ASSERT_FALSE(preferences->LookUpGalleryByPath(fake_gallery_temp_dir_.path(),
    145                                                   &gallery_info));
    146     preferences->AddGallery(gallery_info.device_id,
    147                             gallery_info.path,
    148                             false /* user_added */,
    149                             gallery_info.volume_label,
    150                             gallery_info.vendor_name,
    151                             gallery_info.model_name,
    152                             gallery_info.total_size_in_bytes,
    153                             gallery_info.last_attach_time);
    154 
    155     content::RunAllPendingInMessageLoop();
    156 
    157     base::FilePath test_data_path(GetCommonDataDir());
    158     base::FilePath write_path = fake_gallery_temp_dir_.path();
    159 
    160     // Valid file, should show up in JS as a FileEntry.
    161     ASSERT_TRUE(base::CopyFile(test_data_path.AppendASCII("test.jpg"),
    162                                write_path.AppendASCII("test.jpg")));
    163 
    164     // Invalid file, should not show up as a FileEntry in JS at all.
    165     ASSERT_TRUE(base::CopyFile(test_data_path.AppendASCII("test.txt"),
    166                                write_path.AppendASCII("test.txt")));
    167   }
    168 
    169 #if defined(OS_WIN) || defined(OS_MACOSX)
    170   void PopulatePicasaTestData(const base::FilePath& picasa_app_data_root) {
    171     base::FilePath picasa_database_path =
    172         picasa::MakePicasaDatabasePath(picasa_app_data_root);
    173     base::FilePath picasa_temp_dir_path =
    174         picasa_database_path.DirName().AppendASCII(picasa::kPicasaTempDirName);
    175     ASSERT_TRUE(base::CreateDirectory(picasa_database_path));
    176     ASSERT_TRUE(base::CreateDirectory(picasa_temp_dir_path));
    177 
    178     // Create fake folder directories.
    179     base::FilePath folders_root =
    180         ensure_media_directories_exists_->GetFakePicasaFoldersRootPath();
    181     base::FilePath fake_folder_1 = folders_root.AppendASCII("folder1");
    182     base::FilePath fake_folder_2 = folders_root.AppendASCII("folder2");
    183     ASSERT_TRUE(base::CreateDirectory(fake_folder_1));
    184     ASSERT_TRUE(base::CreateDirectory(fake_folder_2));
    185 
    186     // Write folder and album contents.
    187     picasa::WriteTestAlbumTable(
    188         picasa_database_path, fake_folder_1, fake_folder_2);
    189     picasa::WriteTestAlbumsImagesIndex(fake_folder_1, fake_folder_2);
    190 
    191     base::FilePath test_jpg_path = GetCommonDataDir().AppendASCII("test.jpg");
    192     ASSERT_TRUE(base::CopyFile(
    193         test_jpg_path, fake_folder_1.AppendASCII("InBoth.jpg")));
    194     ASSERT_TRUE(base::CopyFile(
    195         test_jpg_path, fake_folder_1.AppendASCII("InSecondAlbumOnly.jpg")));
    196     ASSERT_TRUE(base::CopyFile(
    197         test_jpg_path, fake_folder_2.AppendASCII("InFirstAlbumOnly.jpg")));
    198   }
    199 #endif
    200 
    201   base::FilePath GetCommonDataDir() const {
    202     return test_data_dir_.AppendASCII("api_test")
    203                          .AppendASCII("media_galleries")
    204                          .AppendASCII("common");
    205   }
    206 
    207   int num_galleries() const {
    208     return ensure_media_directories_exists_->num_galleries();
    209   }
    210 
    211   int test_jpg_size() const { return test_jpg_size_; }
    212 
    213   EnsureMediaDirectoriesExists* ensure_media_directories_exists() const {
    214     return ensure_media_directories_exists_.get();
    215   }
    216 
    217  private:
    218   MediaGalleriesPreferences* GetAndInitializePreferences() {
    219     MediaGalleriesPreferences* preferences =
    220         g_browser_process->media_file_system_registry()->GetPreferences(
    221             browser()->profile());
    222     base::RunLoop runloop;
    223     preferences->EnsureInitialized(runloop.QuitClosure());
    224     runloop.Run();
    225     return preferences;
    226   }
    227 
    228   std::string device_id_;
    229   base::ScopedTempDir fake_gallery_temp_dir_;
    230   int test_jpg_size_;
    231   scoped_ptr<EnsureMediaDirectoriesExists> ensure_media_directories_exists_;
    232 };
    233 
    234 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    235                        MediaGalleriesNoAccess) {
    236   MakeSingleFakeGallery();
    237 
    238   base::ListValue custom_args;
    239   custom_args.AppendInteger(num_galleries() + 1);
    240 
    241   ASSERT_TRUE(RunMediaGalleriesTestWithArg("no_access", custom_args))
    242       << message_;
    243 }
    244 
    245 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest, NoGalleriesRead) {
    246   ASSERT_TRUE(RunMediaGalleriesTest("no_galleries")) << message_;
    247 }
    248 
    249 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    250                        NoGalleriesCopyTo) {
    251   ASSERT_TRUE(RunMediaGalleriesTest("no_galleries_copy_to")) << message_;
    252 }
    253 
    254 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    255                        MediaGalleriesRead) {
    256   RemoveAllGalleries();
    257   MakeSingleFakeGallery();
    258   base::ListValue custom_args;
    259   custom_args.AppendInteger(test_jpg_size());
    260 
    261   ASSERT_TRUE(RunMediaGalleriesTestWithArg("read_access", custom_args))
    262       << message_;
    263 }
    264 
    265 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    266                        MediaGalleriesCopyTo) {
    267   RemoveAllGalleries();
    268   MakeSingleFakeGallery();
    269   ASSERT_TRUE(RunMediaGalleriesTest("copy_to_access")) << message_;
    270 }
    271 
    272 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    273                        MediaGalleriesDelete) {
    274   MakeSingleFakeGallery();
    275   base::ListValue custom_args;
    276   custom_args.AppendInteger(num_galleries() + 1);
    277   ASSERT_TRUE(RunMediaGalleriesTestWithArg("delete_access", custom_args))
    278       << message_;
    279 }
    280 
    281 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    282                        MediaGalleriesAccessAttached) {
    283   AttachFakeDevice();
    284 
    285   base::ListValue custom_args;
    286   custom_args.AppendInteger(num_galleries() + 1);
    287   custom_args.AppendString(kDeviceName);
    288 
    289   ASSERT_TRUE(RunMediaGalleriesTestWithArg("access_attached", custom_args))
    290       << message_;
    291 
    292   DetachFakeDevice();
    293 }
    294 
    295 #if defined(OS_WIN)|| defined(OS_MACOSX)
    296 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    297                        PicasaDefaultLocation) {
    298 #if defined(OS_WIN)
    299   PopulatePicasaTestData(
    300       ensure_media_directories_exists()->GetFakeLocalAppDataPath());
    301 #elif defined(OS_MACOSX)
    302   PopulatePicasaTestData(
    303       ensure_media_directories_exists()->GetFakeAppDataPath());
    304 #endif
    305 
    306   base::ListValue custom_args;
    307   custom_args.AppendInteger(test_jpg_size());
    308   ASSERT_TRUE(RunMediaGalleriesTestWithArg("picasa", custom_args)) << message_;
    309 }
    310 
    311 IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
    312                        PicasaCustomLocation) {
    313   base::ScopedTempDir custom_picasa_app_data_root;
    314   ASSERT_TRUE(custom_picasa_app_data_root.CreateUniqueTempDir());
    315   ensure_media_directories_exists()->SetCustomPicasaAppDataPath(
    316       custom_picasa_app_data_root.path());
    317   PopulatePicasaTestData(custom_picasa_app_data_root.path());
    318 
    319   base::ListValue custom_args;
    320   custom_args.AppendInteger(test_jpg_size());
    321   ASSERT_TRUE(RunMediaGalleriesTestWithArg("picasa", custom_args)) << message_;
    322 }
    323 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    324