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 @@ ...@@ -8,6 +8,7 @@
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/safe_numerics.h" #include "base/safe_numerics.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/apps/app_browsertest_util.h"
...@@ -28,6 +29,12 @@ ...@@ -28,6 +29,12 @@
#include "chrome/common/media_galleries/pmp_test_util.h" #include "chrome/common/media_galleries/pmp_test_util.h"
#endif #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; using extensions::PlatformAppBrowserTest;
namespace { namespace {
...@@ -100,7 +107,9 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest { ...@@ -100,7 +107,9 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest {
} }
base::AutoReset<base::FilePath> reset(&test_data_dir_, temp_dir.path()); 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() { void AttachFakeDevice() {
...@@ -196,7 +205,108 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest { ...@@ -196,7 +205,108 @@ class MediaGalleriesPlatformAppBrowserTest : public PlatformAppBrowserTest {
ASSERT_TRUE(base::CopyFile( ASSERT_TRUE(base::CopyFile(
test_jpg_path, fake_folder_2.AppendASCII("InFirstAlbumOnly.jpg"))); 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 { base::FilePath GetCommonDataDir() const {
return test_data_dir_.AppendASCII("api_test") return test_data_dir_.AppendASCII("api_test")
...@@ -321,3 +431,17 @@ IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest, ...@@ -321,3 +431,17 @@ IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest,
ASSERT_TRUE(RunMediaGalleriesTestWithArg("picasa", custom_args)) << message_; ASSERT_TRUE(RunMediaGalleriesTestWithArg("picasa", custom_args)) << message_;
} }
#endif // defined(OS_WIN) || defined(OS_MACOSX) #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 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h"
#include "chrome/browser/media_galleries/fileapi/iapps_finder.h" #include "chrome/browser/media_galleries/fileapi/iapps_finder.h"
#include "chrome/browser/storage_monitor/storage_info.h" #include "chrome/browser/storage_monitor/storage_info.h"
...@@ -15,8 +16,10 @@ ...@@ -15,8 +16,10 @@
class MacPreferences; class MacPreferences;
#if defined(__OBJC__) #if defined(__OBJC__)
@class NSArray;
@class NSString; @class NSString;
#else // __OBJC__ #else // __OBJC__
class NSArray;
class NSString; class NSString;
#endif // __OBJC__ #endif // __OBJC__
...@@ -34,6 +37,9 @@ extern NSString* const kITunesRecentDatabasePathsKey; ...@@ -34,6 +37,9 @@ extern NSString* const kITunesRecentDatabasePathsKey;
// it. // it.
void SetMacPreferencesForTesting(MacPreferences* preferences); 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 #endif // OS_MACOSX
typedef base::Callback<void(const IAppsFinderCallback&)> IAppsFinderTask; typedef base::Callback<void(const IAppsFinderCallback&)> IAppsFinderTask;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/logging.h" #include "base/logging.h"
#import "base/mac/foundation_util.h" #import "base/mac/foundation_util.h"
#import "base/mac/scoped_nsobject.h" #import "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/storage_monitor/storage_info.h" #include "chrome/browser/storage_monitor/storage_info.h"
#include "components/policy/core/common/preferences_mac.h" #include "components/policy/core/common/preferences_mac.h"
...@@ -112,4 +113,11 @@ void SetMacPreferencesForTesting(MacPreferences* preferences) { ...@@ -112,4 +113,11 @@ void SetMacPreferencesForTesting(MacPreferences* preferences) {
g_test_mac_preferences = 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 } // namespace iapps
...@@ -148,7 +148,14 @@ class RPHReferenceManager : public content::NotificationObserver { ...@@ -148,7 +148,14 @@ class RPHReferenceManager : public content::NotificationObserver {
void OnRendererProcessTerminated(const RenderProcessHost* rph) { void OnRendererProcessTerminated(const RenderProcessHost* rph) {
RPHRefCount::iterator rph_info = refs_.find(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; delete rph_info->second;
refs_.erase(rph_info); refs_.erase(rph_info);
if (refs_.empty()) if (refs_.empty())
...@@ -287,7 +294,6 @@ class ExtensionGalleriesHost ...@@ -287,7 +294,6 @@ class ExtensionGalleriesHost
virtual ~ExtensionGalleriesHost() { virtual ~ExtensionGalleriesHost() {
DCHECK(rph_refs_.empty()); DCHECK(rph_refs_.empty());
DCHECK(pref_id_map_.empty()); DCHECK(pref_id_map_.empty());
} }
void GetMediaFileSystemsForAttachedDevices( void GetMediaFileSystemsForAttachedDevices(
...@@ -296,6 +302,15 @@ class ExtensionGalleriesHost ...@@ -296,6 +302,15 @@ class ExtensionGalleriesHost
const MediaGalleriesPrefInfoMap& galleries_info, const MediaGalleriesPrefInfoMap& galleries_info,
const MediaFileSystemsCallback& callback) { const MediaFileSystemsCallback& callback) {
std::vector<MediaFileSystemInfo> result; 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; MediaGalleryPrefIdSet new_galleries;
for (std::set<MediaGalleryPrefId>::const_iterator pref_id_it = for (std::set<MediaGalleryPrefId>::const_iterator pref_id_it =
galleries.begin(); galleries.begin();
...@@ -421,6 +436,8 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension( ...@@ -421,6 +436,8 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
extension->id())); extension->id()));
extension_hosts_map_[profile][extension->id()] = extension_host; 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->ReferenceFromRVH(rvh);
extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(), extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(),
......
...@@ -401,7 +401,7 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) { ...@@ -401,7 +401,7 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
// It cannot be incremented inline with each callback, as some may return // It cannot be incremented inline with each callback, as some may return
// synchronously, decrement the counter to 0, and prematurely trigger // synchronously, decrement the counter to 0, and prematurely trigger
// FinishInitialization. // FinishInitialization.
pre_initialization_callbacks_waiting_ = 3; pre_initialization_callbacks_waiting_ = 4;
// Check whether we should be initializing -- are there any extensions that // Check whether we should be initializing -- are there any extensions that
// are using media galleries? // are using media galleries?
...@@ -426,11 +426,9 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) { ...@@ -426,11 +426,9 @@ void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID, base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
#if 0
iapps::FindIPhotoLibrary( iapps::FindIPhotoLibrary(
base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID, base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
#endif
} }
bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; } bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; }
......
...@@ -135,6 +135,18 @@ EnsureMediaDirectoriesExists::GetFakePicasaFoldersRootPath() const { ...@@ -135,6 +135,18 @@ EnsureMediaDirectoriesExists::GetFakePicasaFoldersRootPath() const {
} }
#endif // OS_WIN || OS_MACOSX #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() { void EnsureMediaDirectoriesExists::Init() {
#if defined(OS_CHROMEOS) || defined(OS_ANDROID) #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
return; return;
...@@ -159,20 +171,25 @@ void EnsureMediaDirectoriesExists::Init() { ...@@ -159,20 +171,25 @@ void EnsureMediaDirectoriesExists::Init() {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
mac_preferences_.reset(new MockPreferences); mac_preferences_.reset(new MockPreferences);
iapps::SetMacPreferencesForTesting(mac_preferences_.get());
picasa::SetMacPreferencesForTesting(mac_preferences_.get());
// iTunes override. // iTunes override.
base::FilePath itunes_xml =
GetFakeITunesRootPath().AppendASCII("iTunes Library.xml");
mac_preferences_->AddTestItem( mac_preferences_->AddTestItem(
base::mac::NSToCFCast(iapps::kITunesRecentDatabasePathsKey), base::mac::NSToCFCast(iapps::kITunesRecentDatabasePathsKey),
base::SysUTF8ToNSString(fake_dir_.path().AppendASCII("itunes").value()), base::mac::NSToCFCast(iapps::NSArrayFromFilePath(itunes_xml)),
false); false);
// iPhoto override. // iPhoto override.
base::FilePath iphoto_xml =
GetFakeIPhotoRootPath().AppendASCII("AlbumData.xml");
mac_preferences_->AddTestItem( mac_preferences_->AddTestItem(
base::mac::NSToCFCast(iapps::kIPhotoRecentDatabasesKey), base::mac::NSToCFCast(iapps::kIPhotoRecentDatabasesKey),
base::SysUTF8ToNSString(fake_dir_.path().AppendASCII("iphoto").value()), base::mac::NSToCFCast(iapps::NSArrayFromFilePath(iphoto_xml)),
false); false);
iapps::SetMacPreferencesForTesting(mac_preferences_.get());
picasa::SetMacPreferencesForTesting(mac_preferences_.get());
#endif // OS_MACOSX #endif // OS_MACOSX
music_override_.reset(new base::ScopedPathOverride( music_override_.reset(new base::ScopedPathOverride(
......
...@@ -50,6 +50,11 @@ class EnsureMediaDirectoriesExists { ...@@ -50,6 +50,11 @@ class EnsureMediaDirectoriesExists {
base::FilePath GetFakePicasaFoldersRootPath() const; base::FilePath GetFakePicasaFoldersRootPath() const;
#endif #endif
#if defined(OS_MACOSX)
base::FilePath GetFakeITunesRootPath() const;
base::FilePath GetFakeIPhotoRootPath() const;
#endif
private: private:
void Init(); 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