Commit b2a34d53 authored by gbillock@chromium.org's avatar gbillock@chromium.org

[MediaGalleries] Enable iPhoto gallery

BUG=151703

Review URL: https://codereview.chromium.org/86743002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243389 0039d316-1c4b-4281-b951-d872f2087c98
parent 7d0c37fb
......@@ -8,6 +8,7 @@
#include "base/json/json_writer.h"
#include "base/path_service.h"
#include "base/safe_numerics.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/apps/app_browsertest_util.h"
......@@ -28,6 +29,12 @@
#include "chrome/common/media_galleries/pmp_test_util.h"
#endif
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/media_galleries/fileapi/iapps_finder_impl.h"
#endif // OS_MACOSX
using extensions::PlatformAppBrowserTest;
namespace {
......@@ -100,7 +107,9 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest {
}
base::AutoReset<base::FilePath> reset(&test_data_dir_, temp_dir.path());
return RunPlatformAppTestWithArg(extension_name, custom_arg);
bool result = RunPlatformAppTestWithArg(extension_name, custom_arg);
content::RunAllPendingInMessageLoop(); // avoid race on exit in registry.
return result;
}
void AttachFakeDevice() {
......@@ -196,7 +205,108 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest {
ASSERT_TRUE(base::CopyFile(
test_jpg_path, fake_folder_2.AppendASCII("InFirstAlbumOnly.jpg")));
}
#endif
#endif // defined(OS_WIN) || defined(OS_MACOSX)
#if defined(OS_MACOSX)
void PopulateIPhotoTestData(const base::FilePath& iphoto_data_root) {
std::string xml_contents = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<plist version=\"1.0\">"
"<dict>\n"
" <key>List of Albums</key>"
" <array>\n"
" <dict>\n"
" <key>AlbumId</key>"
" <integer>1</integer>"
" <key>AlbumName</key>"
" <string>Album1</string>"
" <key>KeyList</key>\n"
" <array>"
" <string>1</string>"
" <string>2</string>"
" </array>\n"
" </dict>\n"
" <dict>\n"
" <key>AlbumId</key>"
" <integer>2</integer>"
" <key>AlbumName</key>"
" <string>Album2</string>"
" <key>KeyList</key>\n"
" <array>"
" <string>2</string>"
" </array>\n"
" </dict>\n"
" </array>\n"
" <key>Master Image List</key>\n"
" <dict>\n"
" <key>1</key>"
" <dict>\n"
" <key>MediaType</key>"
" <string>Image</string>"
" <key>Caption</key>"
" <string>caption 1</string>"
" <key>GUID</key>"
" <string>1</string>"
" <key>ModDateAsTimerInterval</key>"
" <string>386221543.0000</string>"
" <key>DateAsTimerInterval</key>"
" <string>386221543.0000</string>"
" <key>DateAsTimerIntervalGMT</key>"
" <string>385123456.00</string>"
" <key>ImagePath</key>"
" <string>$path1</string>"
" <key>ThumbPath</key>"
" <string>/thumb/path</string>\n"
" </dict>\n"
" <key>2</key>\n"
" <dict>\n"
" <key>MediaType</key>"
" <string>Image</string>"
" <key>Caption</key>"
" <string>caption 2</string>"
" <key>GUID</key>"
" <string>2</string>"
" <key>ModDateAsTimerInterval</key>"
" <string>386221543.0000</string>"
" <key>DateAsTimerInterval</key>"
" <string>386221543.0000</string>"
" <key>DateAsTimerIntervalGMT</key>"
" <string>385123456.00</string>"
" <key>ImagePath</key>"
" <string>$path2</string>"
" <key>ThumbPath</key>"
" <string>/thumb/path2</string>\n"
" </dict>\n"
" </dict>\n" // Master Image List
"</dict>\n"
"</plist>";
base::FilePath test_jpg_path = GetCommonDataDir().AppendASCII("test.jpg");
ASSERT_TRUE(base::CreateDirectory(iphoto_data_root));
base::FilePath first_only_jpg =
iphoto_data_root.AppendASCII("InFirstAlbumOnly.jpg");
base::FilePath in_both_jpg = iphoto_data_root.AppendASCII("InBoth.jpg");
ASSERT_TRUE(base::CopyFile(test_jpg_path, first_only_jpg));
ASSERT_TRUE(base::CopyFile(test_jpg_path, in_both_jpg));
ReplaceFirstSubstringAfterOffset(
&xml_contents, 0, std::string("$path1"), first_only_jpg.value());
ReplaceFirstSubstringAfterOffset(
&xml_contents, 0, std::string("$path2"), in_both_jpg.value());
base::FilePath album_xml = iphoto_data_root.AppendASCII("AlbumData.xml");
ASSERT_NE(-1, file_util::WriteFile(album_xml,
xml_contents.c_str(),
xml_contents.size()));
}
#endif // defined(OS_MACOSX)
base::FilePath GetCommonDataDir() const {
return test_data_dir_.AppendASCII("api_test")
......@@ -321,3 +431,17 @@ IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
ASSERT_TRUE(RunMediaGalleriesTestWithArg("picasa", custom_args)) << message_;
}
#endif // defined(OS_WIN) || defined(OS_MACOSX)
#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
IPhotoTest) {
PopulateIPhotoTestData(
ensure_media_directories_exists()->GetFakeIPhotoRootPath());
base::ListValue custom_args;
custom_args.AppendInteger(test_jpg_size());
ASSERT_TRUE(RunMediaGalleriesTestWithArg("iphoto", custom_args)) << message_;
iapps::SetMacPreferencesForTesting(NULL);
}
#endif // defined(OS_MACOSX)
......@@ -8,6 +8,7 @@
#include <string>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "chrome/browser/media_galleries/fileapi/iapps_finder.h"
#include "chrome/browser/storage_monitor/storage_info.h"
......@@ -15,8 +16,10 @@
class MacPreferences;
#if defined(__OBJC__)
@class NSArray;
@class NSString;
#else // __OBJC__
class NSArray;
class NSString;
#endif // __OBJC__
......@@ -34,6 +37,9 @@ extern NSString* const kITunesRecentDatabasePathsKey;
// it.
void SetMacPreferencesForTesting(MacPreferences* preferences);
// Returns an NSArray with a single string entry which is a path value.
NSArray* NSArrayFromFilePath(const base::FilePath& path);
#endif // OS_MACOSX
typedef base::Callback<void(const IAppsFinderCallback&)> IAppsFinderTask;
......
......@@ -9,6 +9,7 @@
#include "base/logging.h"
#import "base/mac/foundation_util.h"
#import "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/storage_monitor/storage_info.h"
#include "components/policy/core/common/preferences_mac.h"
......@@ -112,4 +113,11 @@ void SetMacPreferencesForTesting(MacPreferences* preferences) {
g_test_mac_preferences = preferences;
}
NSArray* NSArrayFromFilePath(const base::FilePath& path) {
NSString* url =
[[NSURL fileURLWithPath:base::SysUTF8ToNSString(path.value())]
absoluteString];
return [NSArray arrayWithObject:url];
}
} // namespace iapps
......@@ -148,7 +148,14 @@ class RPHReferenceManager : public content::NotificationObserver {
void OnRendererProcessTerminated(const RenderProcessHost* rph) {
RPHRefCount::iterator rph_info = refs_.find(rph);
DCHECK(rph_info != refs_.end());
// This could be a potential problem if the RPH is navigated to
// a page on the same renderer (triggering OWCDON()) and then
// the renderer crashes.
if (rph_info == refs_.end()) {
NOTREACHED();
return;
}
delete rph_info->second;
refs_.erase(rph_info);
if (refs_.empty())
......@@ -287,7 +294,6 @@ class ExtensionGalleriesHost
virtual ~ExtensionGalleriesHost() {
DCHECK(rph_refs_.empty());
DCHECK(pref_id_map_.empty());
}
void GetMediaFileSystemsForAttachedDevices(
......@@ -296,6 +302,15 @@ class ExtensionGalleriesHost
const MediaGalleriesPrefInfoMap& galleries_info,
const MediaFileSystemsCallback& callback) {
std::vector<MediaFileSystemInfo> result;
if (rph_refs_.empty()) {
// We're actually in the middle of shutdown, and Filter...() lagging
// which can invoke this method interleaved in the destruction callback
// sequence and re-populate pref_id_map_.
callback.Run(result);
return;
}
MediaGalleryPrefIdSet new_galleries;
for (std::set<MediaGalleryPrefId>::const_iterator pref_id_it =
galleries.begin();
......@@ -421,6 +436,8 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
extension->id()));
extension_hosts_map_[profile][extension->id()] = extension_host;
}
// This must come before the GetMediaFileSystems call to make sure the
// RVH of the context is referenced before the filesystems are retrieved.
extension_host->ReferenceFromRVH(rvh);
extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(),
......
......@@ -401,7 +401,7 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
// It cannot be incremented inline with each callback, as some may return
// synchronously, decrement the counter to 0, and prematurely trigger
// FinishInitialization.
pre_initialization_callbacks_waiting_ = 3;
pre_initialization_callbacks_waiting_ = 4;
// Check whether we should be initializing -- are there any extensions that
// are using media galleries?
......@@ -426,11 +426,9 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr()));
#if 0
iapps::FindIPhotoLibrary(
base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr()));
#endif
}
bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; }
......
......@@ -135,6 +135,18 @@ EnsureMediaDirectoriesExists::GetFakePicasaFoldersRootPath() const {
}
#endif // OS_WIN || OS_MACOSX
#if defined(OS_MACOSX)
base::FilePath EnsureMediaDirectoriesExists::GetFakeITunesRootPath() const {
DCHECK(fake_dir_.IsValid());
return fake_dir_.path().AppendASCII("itunes");
}
base::FilePath EnsureMediaDirectoriesExists::GetFakeIPhotoRootPath() const {
DCHECK(fake_dir_.IsValid());
return fake_dir_.path().AppendASCII("iphoto");
}
#endif // OS_MACOSX
void EnsureMediaDirectoriesExists::Init() {
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
return;
......@@ -159,20 +171,25 @@ void EnsureMediaDirectoriesExists::Init() {
#if defined(OS_MACOSX)
mac_preferences_.reset(new MockPreferences);
iapps::SetMacPreferencesForTesting(mac_preferences_.get());
picasa::SetMacPreferencesForTesting(mac_preferences_.get());
// iTunes override.
base::FilePath itunes_xml =
GetFakeITunesRootPath().AppendASCII("iTunes Library.xml");
mac_preferences_->AddTestItem(
base::mac::NSToCFCast(iapps::kITunesRecentDatabasePathsKey),
base::SysUTF8ToNSString(fake_dir_.path().AppendASCII("itunes").value()),
base::mac::NSToCFCast(iapps::NSArrayFromFilePath(itunes_xml)),
false);
// iPhoto override.
base::FilePath iphoto_xml =
GetFakeIPhotoRootPath().AppendASCII("AlbumData.xml");
mac_preferences_->AddTestItem(
base::mac::NSToCFCast(iapps::kIPhotoRecentDatabasesKey),
base::SysUTF8ToNSString(fake_dir_.path().AppendASCII("iphoto").value()),
base::mac::NSToCFCast(iapps::NSArrayFromFilePath(iphoto_xml)),
false);
iapps::SetMacPreferencesForTesting(mac_preferences_.get());
picasa::SetMacPreferencesForTesting(mac_preferences_.get());
#endif // OS_MACOSX
music_override_.reset(new base::ScopedPathOverride(
......
......@@ -50,6 +50,11 @@ class EnsureMediaDirectoriesExists {
base::FilePath GetFakePicasaFoldersRootPath() const;
#endif
#if defined(OS_MACOSX)
base::FilePath GetFakeITunesRootPath() const;
base::FilePath GetFakeIPhotoRootPath() const;
#endif
private:
void Init();
......
{
"name": "chrome.mediaGalleries.iphoto",
"version": "0.1",
"description": "test IPhoto media gallery for chrome.mediaGalleries.getMediaFileSystems",
"app": {
"background": {
"scripts": ["common_injected.js", "test.js"]
}
},
"permissions": [{"mediaGalleries": ["read", "allAutoDetected"]}]
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var mediaGalleries = chrome.mediaGalleries;
var expectedGalleryEntryLength; // Size of ../common/test.jpg.
//Verifies a directory itself, then the contents.
function getAndVerifyDirectoryEntry(parentEntry, directoryName,
verifyFunction) {
function getDirectoryCallback(entry) {
chrome.test.assertTrue(entry.isDirectory);
verifyDirectoryEntry(entry, verifyFunction);
}
parentEntry.getDirectory(directoryName, {create: false},
getDirectoryCallback, chrome.test.fail);
}
function verifyAllJPEGs(parentDirectoryEntry, filenames, doneCallback) {
var remaining = filenames;
function verifyNextJPEG() {
if (remaining.length == 0) {
doneCallback();
return;
}
verifyJPEG(parentDirectoryEntry, remaining.pop(),
expectedGalleryEntryLength, verifyNextJPEG);
}
verifyNextJPEG();
}
function GalleryPropertiesTest(iphotoGallery) {
var galleryProperties =
mediaGalleries.getMediaFileSystemMetadata(iphotoGallery);
chrome.test.assertFalse(galleryProperties.isRemovable);
chrome.test.succeed();
}
function RootListingTest(iphotoGallery) {
function verify(directoryEntry, entries) {
chrome.test.assertEq(1, entries.length);
chrome.test.assertTrue(entries[0].isDirectory);
chrome.test.assertEq("Albums", entries[0].name);
chrome.test.succeed();
}
verifyDirectoryEntry(iphotoGallery.root, verify);
}
function AlbumsListingTest(iphotoGallery) {
function verify(directoryEntry, entries) {
chrome.test.assertEq(2, entries.length);
chrome.test.assertTrue(entries[0].isDirectory);
chrome.test.assertTrue(entries[1].isDirectory);
chrome.test.assertEq("Album1", entries[0].name);
chrome.test.assertEq("Album2", entries[1].name);
chrome.test.succeed();
}
getAndVerifyDirectoryEntry(iphotoGallery.root, "Albums", verify);
}
function Album1ListingTest(iphotoGallery) {
function verify(directoryEntry, entries) {
chrome.test.assertEq(2, entries.length);
chrome.test.assertTrue(entries[0].isFile);
chrome.test.assertTrue(entries[1].isFile);
chrome.test.assertEq("InBoth.jpg", entries[0].name);
chrome.test.assertEq("InFirstAlbumOnly.jpg", entries[1].name);
verifyAllJPEGs(directoryEntry, ["InBoth.jpg", "InFirstAlbumOnly.jpg"],
chrome.test.succeed);
}
getAndVerifyDirectoryEntry(iphotoGallery.root,
"Albums/Album1", verify);
}
function Album2ListingTest(iphotoGallery) {
function verify(directoryEntry, entries) {
chrome.test.assertEq(1, entries.length);
chrome.test.assertTrue(entries[0].isFile);
chrome.test.assertEq("InBoth.jpg", entries[0].name);
verifyAllJPEGs(directoryEntry, ["InBoth.jpg"],
chrome.test.succeed);
}
getAndVerifyDirectoryEntry(iphotoGallery.root,
"Albums/Album2", verify);
}
function getTest(testFunction) {
function getMediaFileSystemsList() {
mediaGalleries.getMediaFileSystems(getMediaFileSystemsCallback);
}
function getMediaFileSystemsCallback(results) {
for (var i = 0; i < results.length; ++i) {
var properties = mediaGalleries.getMediaFileSystemMetadata(results[i]);
if (properties.name == "iPhoto") {
testFunction(results[i]);
return;
}
}
chrome.test.fail("iPhoto gallery not found");
}
return function() {
getMediaFileSystemsList();
}
}
CreateDummyWindowToPreventSleep();
chrome.test.getConfig(function(config) {
customArg = JSON.parse(config.customArg);
expectedGalleryEntryLength = customArg[0];
chrome.test.runTests([
getTest(GalleryPropertiesTest),
getTest(RootListingTest),
getTest(AlbumsListingTest),
getTest(Album1ListingTest),
getTest(Album2ListingTest),
]);
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment