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/media_galleries/media_galleries_test_util.h"
6
7#if defined(OS_WIN)
8#include <windows.h>
9#endif
10
11#include "base/base_paths.h"
12#include "base/files/file_path.h"
13#include "base/files/file_util.h"
14#include "base/path_service.h"
15#include "base/strings/string_number_conversions.h"
16#include "base/strings/stringprintf.h"
17#include "chrome/browser/extensions/extension_service.h"
18#include "chrome/browser/media_galleries/fileapi/picasa_finder.h"
19#include "chrome/browser/profiles/profile.h"
20#include "chrome/common/chrome_paths.h"
21#include "components/crx_file/id_util.h"
22#include "extensions/browser/extension_prefs.h"
23#include "extensions/browser/extension_system.h"
24#include "extensions/common/manifest_constants.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27#if defined(OS_MACOSX)
28#include "base/mac/foundation_util.h"
29#include "base/strings/sys_string_conversions.h"
30#include "chrome/browser/media_galleries/fileapi/iapps_finder_impl.h"
31#include "components/policy/core/common/preferences_mock_mac.h"
32#endif  // OS_MACOSX
33
34#if defined(OS_WIN)
35#include "base/test/test_reg_util_win.h"
36#include "base/win/registry.h"
37#endif  // OS_WIN
38
39scoped_refptr<extensions::Extension> AddMediaGalleriesApp(
40    const std::string& name,
41    const std::vector<std::string>& media_galleries_permissions,
42    Profile* profile) {
43  scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
44  manifest->SetString(extensions::manifest_keys::kName, name);
45  manifest->SetString(extensions::manifest_keys::kVersion, "0.1");
46  manifest->SetInteger(extensions::manifest_keys::kManifestVersion, 2);
47  base::ListValue* background_script_list = new base::ListValue;
48  background_script_list->Append(new base::StringValue("background.js"));
49  manifest->Set(extensions::manifest_keys::kPlatformAppBackgroundScripts,
50                background_script_list);
51
52  base::ListValue* permission_detail_list = new base::ListValue;
53  for (size_t i = 0; i < media_galleries_permissions.size(); i++)
54    permission_detail_list->Append(
55        new base::StringValue(media_galleries_permissions[i]));
56  base::DictionaryValue* media_galleries_permission =
57      new base::DictionaryValue();
58  media_galleries_permission->Set("mediaGalleries", permission_detail_list);
59  base::ListValue* permission_list = new base::ListValue;
60  permission_list->Append(media_galleries_permission);
61  manifest->Set(extensions::manifest_keys::kPermissions, permission_list);
62
63  extensions::ExtensionPrefs* extension_prefs =
64      extensions::ExtensionPrefs::Get(profile);
65  base::FilePath path = extension_prefs->install_directory().AppendASCII(name);
66  std::string errors;
67  scoped_refptr<extensions::Extension> extension =
68      extensions::Extension::Create(path, extensions::Manifest::INTERNAL,
69                                    *manifest.get(),
70                                    extensions::Extension::NO_FLAGS, &errors);
71  EXPECT_TRUE(extension.get() != NULL) << errors;
72  EXPECT_TRUE(crx_file::id_util::IdIsValid(extension->id()));
73  if (!extension.get() || !crx_file::id_util::IdIsValid(extension->id()))
74    return NULL;
75
76  extension_prefs->OnExtensionInstalled(
77      extension.get(),
78      extensions::Extension::ENABLED,
79      syncer::StringOrdinal::CreateInitialOrdinal(),
80      std::string());
81  ExtensionService* extension_service =
82      extensions::ExtensionSystem::Get(profile)->extension_service();
83  extension_service->AddExtension(extension.get());
84  extension_service->EnableExtension(extension->id());
85
86  return extension;
87}
88
89EnsureMediaDirectoriesExists::EnsureMediaDirectoriesExists()
90    : num_galleries_(0), times_overrides_changed_(0) {
91  Init();
92}
93
94EnsureMediaDirectoriesExists::~EnsureMediaDirectoriesExists() {
95#if defined(OS_MACOSX)
96  iapps::SetMacPreferencesForTesting(NULL);
97  picasa::SetMacPreferencesForTesting(NULL);
98#endif  // OS_MACOSX
99}
100
101void EnsureMediaDirectoriesExists::ChangeMediaPathOverrides() {
102  // Each pointer must be reset an extra time so as to destroy the existing
103  // override prior to creating a new one. This is because the PathService,
104  // which supports these overrides, only allows one override to exist per path
105  // in its internal bookkeeping; attempting to add a second override invokes
106  // a CHECK crash.
107  music_override_.reset();
108  std::string music_path_string("music");
109  music_path_string.append(base::IntToString(times_overrides_changed_));
110  music_override_.reset(new base::ScopedPathOverride(
111      chrome::DIR_USER_MUSIC,
112      fake_dir_.path().AppendASCII(music_path_string)));
113
114  pictures_override_.reset();
115  std::string pictures_path_string("pictures");
116  pictures_path_string.append(base::IntToString(times_overrides_changed_));
117  pictures_override_.reset(new base::ScopedPathOverride(
118      chrome::DIR_USER_PICTURES,
119      fake_dir_.path().AppendASCII(pictures_path_string)));
120
121  video_override_.reset();
122  std::string videos_path_string("videos");
123  videos_path_string.append(base::IntToString(times_overrides_changed_));
124  video_override_.reset(new base::ScopedPathOverride(
125      chrome::DIR_USER_VIDEOS,
126      fake_dir_.path().AppendASCII(videos_path_string)));
127
128  times_overrides_changed_++;
129
130  num_galleries_ = 3;
131}
132
133base::FilePath EnsureMediaDirectoriesExists::GetFakeAppDataPath() const {
134  DCHECK(fake_dir_.IsValid());
135  return fake_dir_.path().AppendASCII("appdata");
136}
137
138#if defined(OS_WIN)
139base::FilePath EnsureMediaDirectoriesExists::GetFakeLocalAppDataPath() const {
140  DCHECK(fake_dir_.IsValid());
141  return fake_dir_.path().AppendASCII("localappdata");
142}
143
144void EnsureMediaDirectoriesExists::SetCustomPicasaAppDataPath(
145    const base::FilePath& path) {
146  base::win::RegKey key(HKEY_CURRENT_USER, picasa::kPicasaRegistryPath,
147                        KEY_SET_VALUE);
148  key.WriteValue(picasa::kPicasaRegistryAppDataPathKey, path.value().c_str());
149}
150#endif  // OS_WIN
151
152#if defined(OS_MACOSX)
153void EnsureMediaDirectoriesExists::SetCustomPicasaAppDataPath(
154    const base::FilePath& path) {
155  mac_preferences_->AddTestItem(
156      base::mac::NSToCFCast(picasa::kPicasaAppDataPathMacPreferencesKey),
157      base::SysUTF8ToNSString(path.value()),
158      false);
159}
160#endif  // OS_MACOSX
161
162#if defined(OS_WIN) || defined(OS_MACOSX)
163base::FilePath
164EnsureMediaDirectoriesExists::GetFakePicasaFoldersRootPath() const {
165  DCHECK(fake_dir_.IsValid());
166  return fake_dir_.path().AppendASCII("picasa_folders");
167}
168#endif  // OS_WIN || OS_MACOSX
169
170#if defined(OS_MACOSX)
171base::FilePath EnsureMediaDirectoriesExists::GetFakeITunesRootPath() const {
172  DCHECK(fake_dir_.IsValid());
173  return fake_dir_.path().AppendASCII("itunes");
174}
175
176base::FilePath EnsureMediaDirectoriesExists::GetFakeIPhotoRootPath() const {
177  DCHECK(fake_dir_.IsValid());
178  return fake_dir_.path().AppendASCII("iphoto");
179}
180#endif  // OS_MACOSX
181
182void EnsureMediaDirectoriesExists::Init() {
183#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
184  return;
185#else
186
187  ASSERT_TRUE(fake_dir_.CreateUniqueTempDir());
188
189#if defined(OS_WIN) || defined(OS_MACOSX)
190  // This is to control whether or not tests think iTunes (on Windows) and
191  // Picasa are installed.
192  app_data_override_.reset(new base::ScopedPathOverride(
193      base::DIR_APP_DATA, GetFakeAppDataPath()));
194#endif  // OS_WIN || OS_MACOSX
195
196#if defined(OS_WIN)
197  // Picasa on Windows is by default in the DIR_LOCAL_APP_DATA directory.
198  local_app_data_override_.reset(new base::ScopedPathOverride(
199      base::DIR_LOCAL_APP_DATA, GetFakeLocalAppDataPath()));
200  // Picasa also looks in the registry for an alternate path.
201  registry_override_.OverrideRegistry(HKEY_CURRENT_USER);
202#endif  // OS_WIN
203
204#if defined(OS_MACOSX)
205  mac_preferences_.reset(new MockPreferences);
206
207  // iTunes override.
208  base::FilePath itunes_xml =
209      GetFakeITunesRootPath().AppendASCII("iTunes Library.xml");
210  mac_preferences_->AddTestItem(
211      base::mac::NSToCFCast(iapps::kITunesRecentDatabasePathsKey),
212      base::mac::NSToCFCast(iapps::NSArrayFromFilePath(itunes_xml)),
213      false);
214
215  // iPhoto override.
216  base::FilePath iphoto_xml =
217      GetFakeIPhotoRootPath().AppendASCII("AlbumData.xml");
218  mac_preferences_->AddTestItem(
219      base::mac::NSToCFCast(iapps::kIPhotoRecentDatabasesKey),
220      base::mac::NSToCFCast(iapps::NSArrayFromFilePath(iphoto_xml)),
221      false);
222
223  iapps::SetMacPreferencesForTesting(mac_preferences_.get());
224  picasa::SetMacPreferencesForTesting(mac_preferences_.get());
225#endif  // OS_MACOSX
226
227  ChangeMediaPathOverrides();
228#endif  // OS_CHROMEOS || OS_ANDROID
229}
230
231base::FilePath MakeMediaGalleriesTestingPath(const std::string& dir) {
232#if defined(OS_WIN)
233  return base::FilePath(FILE_PATH_LITERAL("C:\\")).AppendASCII(dir);
234#elif defined(OS_POSIX)
235  return base::FilePath(FILE_PATH_LITERAL("/")).Append(dir);
236#else
237  NOTREACHED();
238#endif
239}
240