1 // Copyright 2019 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/native_file_system/chrome_native_file_system_permission_context.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "base/base_paths.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/json/json_reader.h"
14 #include "base/run_loop.h"
15 #include "base/test/bind.h"
16 #include "base/test/scoped_path_override.h"
17 #include "build/build_config.h"
18 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/chrome_paths.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "components/content_settings/core/browser/host_content_settings_map.h"
23 #include "components/content_settings/core/common/pref_names.h"
24 #include "components/sync_preferences/testing_pref_service_syncable.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/test/browser_task_environment.h"
27 #include "content/public/test/test_renderer_host.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "url/gurl.h"
30 #include "url/origin.h"
31
32 using content::BrowserContext;
33 using HandleType = ChromeNativeFileSystemPermissionContext::HandleType;
34 using PathType = ChromeNativeFileSystemPermissionContext::PathType;
35 using UserAction = ChromeNativeFileSystemPermissionContext::UserAction;
36 using PermissionStatus =
37 content::NativeFileSystemPermissionGrant::PermissionStatus;
38 using PermissionRequestOutcome =
39 content::NativeFileSystemPermissionGrant::PermissionRequestOutcome;
40 using SensitiveDirectoryResult =
41 ChromeNativeFileSystemPermissionContext::SensitiveDirectoryResult;
42
43 class TestNativeFileSystemPermissionContext
44 : public ChromeNativeFileSystemPermissionContext {
45 public:
TestNativeFileSystemPermissionContext(content::BrowserContext * context)46 explicit TestNativeFileSystemPermissionContext(
47 content::BrowserContext* context)
48 : ChromeNativeFileSystemPermissionContext(context) {}
49 ~TestNativeFileSystemPermissionContext() override = default;
50
51 // content::NativeFileSystemPermissionContext:
52 scoped_refptr<content::NativeFileSystemPermissionGrant>
GetReadPermissionGrant(const url::Origin & origin,const base::FilePath & path,HandleType handle_type,UserAction user_action)53 GetReadPermissionGrant(const url::Origin& origin,
54 const base::FilePath& path,
55 HandleType handle_type,
56 UserAction user_action) override {
57 NOTREACHED();
58 return nullptr;
59 }
60 scoped_refptr<content::NativeFileSystemPermissionGrant>
GetWritePermissionGrant(const url::Origin & origin,const base::FilePath & path,HandleType handle_type,UserAction user_action)61 GetWritePermissionGrant(const url::Origin& origin,
62 const base::FilePath& path,
63 HandleType handle_type,
64 UserAction user_action) override {
65 NOTREACHED();
66 return nullptr;
67 }
68
69 // ChromeNativeFileSystemPermissionContext:
GetPermissionGrants(const url::Origin & origin)70 Grants GetPermissionGrants(const url::Origin& origin) override {
71 NOTREACHED();
72 return {};
73 }
RevokeGrants(const url::Origin & origin)74 void RevokeGrants(const url::Origin& origin) override { NOTREACHED(); }
75
76 private:
GetWeakPtr()77 base::WeakPtr<ChromeNativeFileSystemPermissionContext> GetWeakPtr() override {
78 return weak_factory_.GetWeakPtr();
79 }
80
81 base::WeakPtrFactory<TestNativeFileSystemPermissionContext> weak_factory_{
82 this};
83 };
84
85 class ChromeNativeFileSystemPermissionContextTest : public testing::Test {
86 public:
SetUp()87 void SetUp() override {
88 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
89 permission_context_ =
90 std::make_unique<TestNativeFileSystemPermissionContext>(
91 browser_context());
92 }
93
TearDown()94 void TearDown() override {
95 ASSERT_TRUE(temp_dir_.Delete());
96 }
97
ConfirmSensitiveDirectoryAccessSync(ChromeNativeFileSystemPermissionContext * context,PathType path_type,const base::FilePath & path,HandleType handle_type)98 SensitiveDirectoryResult ConfirmSensitiveDirectoryAccessSync(
99 ChromeNativeFileSystemPermissionContext* context,
100 PathType path_type,
101 const base::FilePath& path,
102 HandleType handle_type) {
103 base::RunLoop loop;
104 SensitiveDirectoryResult out_result;
105 permission_context_->ConfirmSensitiveDirectoryAccess(
106 kTestOrigin, path_type, path, handle_type,
107 content::GlobalFrameRoutingId(),
108 base::BindLambdaForTesting([&](SensitiveDirectoryResult result) {
109 out_result = result;
110 loop.Quit();
111 }));
112 loop.Run();
113 return out_result;
114 }
115
SetDefaultContentSettingValue(ContentSettingsType type,ContentSetting value)116 void SetDefaultContentSettingValue(ContentSettingsType type,
117 ContentSetting value) {
118 HostContentSettingsMap* content_settings =
119 HostContentSettingsMapFactory::GetForProfile(&profile_);
120 content_settings->SetDefaultContentSetting(type, value);
121 }
122
SetContentSettingValueForOrigin(url::Origin origin,ContentSettingsType type,ContentSetting value)123 void SetContentSettingValueForOrigin(url::Origin origin,
124 ContentSettingsType type,
125 ContentSetting value) {
126 HostContentSettingsMap* content_settings =
127 HostContentSettingsMapFactory::GetForProfile(&profile_);
128 content_settings->SetContentSettingDefaultScope(
129 origin.GetURL(), origin.GetURL(), type, value);
130 }
131
permission_context()132 ChromeNativeFileSystemPermissionContext* permission_context() {
133 return permission_context_.get();
134 }
browser_context()135 BrowserContext* browser_context() { return &profile_; }
profile()136 TestingProfile* profile() { return &profile_; }
137
138 protected:
139 const url::Origin kTestOrigin =
140 url::Origin::Create(GURL("https://example.com"));
141 const url::Origin kTestOrigin2 =
142 url::Origin::Create(GURL("https://test.com"));
143 const base::FilePath kTestPath =
144 base::FilePath(FILE_PATH_LITERAL("/foo/bar"));
145 const url::Origin kChromeOrigin = url::Origin::Create(GURL("chrome://test"));
146
147 content::BrowserTaskEnvironment task_environment_;
148 base::ScopedTempDir temp_dir_;
149 std::unique_ptr<ChromeNativeFileSystemPermissionContext> permission_context_;
150 TestingProfile profile_;
151 };
152
153 #if !defined(OS_ANDROID)
154
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_NoSpecialPath)155 TEST_F(ChromeNativeFileSystemPermissionContextTest,
156 ConfirmSensitiveDirectoryAccess_NoSpecialPath) {
157 const base::FilePath kTestPath =
158 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
159 base::FilePath(FILE_PATH_LITERAL("c:\\foo\\bar"));
160 #else
161 base::FilePath(FILE_PATH_LITERAL("/foo/bar"));
162 #endif
163
164 // Path outside any special directories should be allowed.
165 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
166 ConfirmSensitiveDirectoryAccessSync(permission_context(),
167 PathType::kLocal, kTestPath,
168 HandleType::kFile));
169 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
170 ConfirmSensitiveDirectoryAccessSync(permission_context(),
171 PathType::kLocal, kTestPath,
172 HandleType::kDirectory));
173
174 // External (relative) paths should also be allowed.
175 EXPECT_EQ(
176 SensitiveDirectoryResult::kAllowed,
177 ConfirmSensitiveDirectoryAccessSync(
178 permission_context(), PathType::kExternal,
179 base::FilePath(FILE_PATH_LITERAL("foo/bar")), HandleType::kFile));
180 }
181
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_DontBlockAllChildren)182 TEST_F(ChromeNativeFileSystemPermissionContextTest,
183 ConfirmSensitiveDirectoryAccess_DontBlockAllChildren) {
184 base::FilePath home_dir = temp_dir_.GetPath().AppendASCII("home");
185 base::ScopedPathOverride home_override(base::DIR_HOME, home_dir, true, true);
186
187 // Home directory itself should not be allowed.
188 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
189 ConfirmSensitiveDirectoryAccessSync(permission_context(),
190 PathType::kLocal, home_dir,
191 HandleType::kDirectory));
192 // Parent of home directory should also not be allowed.
193 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
194 ConfirmSensitiveDirectoryAccessSync(
195 permission_context(), PathType::kLocal, temp_dir_.GetPath(),
196 HandleType::kDirectory));
197 // Paths inside home directory should be allowed.
198 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
199 ConfirmSensitiveDirectoryAccessSync(
200 permission_context(), PathType::kLocal,
201 home_dir.AppendASCII("foo"), HandleType::kFile));
202 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
203 ConfirmSensitiveDirectoryAccessSync(
204 permission_context(), PathType::kLocal,
205 home_dir.AppendASCII("foo"), HandleType::kDirectory));
206 }
207
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_BlockAllChildren)208 TEST_F(ChromeNativeFileSystemPermissionContextTest,
209 ConfirmSensitiveDirectoryAccess_BlockAllChildren) {
210 base::FilePath app_dir = temp_dir_.GetPath().AppendASCII("app");
211 base::ScopedPathOverride app_override(chrome::DIR_APP, app_dir, true, true);
212
213 // App directory itself should not be allowed.
214 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
215 ConfirmSensitiveDirectoryAccessSync(permission_context(),
216 PathType::kLocal, app_dir,
217 HandleType::kDirectory));
218 // Parent of App directory should also not be allowed.
219 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
220 ConfirmSensitiveDirectoryAccessSync(
221 permission_context(), PathType::kLocal, temp_dir_.GetPath(),
222 HandleType::kDirectory));
223 // Paths inside App directory should also not be allowed.
224 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
225 ConfirmSensitiveDirectoryAccessSync(
226 permission_context(), PathType::kLocal,
227 app_dir.AppendASCII("foo"), HandleType::kFile));
228 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
229 ConfirmSensitiveDirectoryAccessSync(
230 permission_context(), PathType::kLocal,
231 app_dir.AppendASCII("foo"), HandleType::kDirectory));
232 }
233
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_BlockChildrenNested)234 TEST_F(ChromeNativeFileSystemPermissionContextTest,
235 ConfirmSensitiveDirectoryAccess_BlockChildrenNested) {
236 base::FilePath user_data_dir = temp_dir_.GetPath().AppendASCII("user");
237 base::ScopedPathOverride user_data_override(chrome::DIR_USER_DATA,
238 user_data_dir, true, true);
239 base::FilePath download_dir = user_data_dir.AppendASCII("downloads");
240 base::ScopedPathOverride download_override(chrome::DIR_DEFAULT_DOWNLOADS,
241 download_dir, true, true);
242
243 // User Data directory itself should not be allowed.
244 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
245 ConfirmSensitiveDirectoryAccessSync(permission_context(),
246 PathType::kLocal, user_data_dir,
247 HandleType::kDirectory));
248 // Parent of User Data directory should also not be allowed.
249 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
250 ConfirmSensitiveDirectoryAccessSync(
251 permission_context(), PathType::kLocal, temp_dir_.GetPath(),
252 HandleType::kDirectory));
253 // The nested Download directory itself should not be allowed.
254 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
255 ConfirmSensitiveDirectoryAccessSync(permission_context(),
256 PathType::kLocal, download_dir,
257 HandleType::kDirectory));
258 // Paths inside the nested Download directory should be allowed.
259 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
260 ConfirmSensitiveDirectoryAccessSync(
261 permission_context(), PathType::kLocal,
262 download_dir.AppendASCII("foo"), HandleType::kFile));
263 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
264 ConfirmSensitiveDirectoryAccessSync(
265 permission_context(), PathType::kLocal,
266 download_dir.AppendASCII("foo"), HandleType::kDirectory));
267
268 #if defined(OS_WIN)
269 // DIR_IE_INTERNET_CACHE is an example of a directory where nested directories
270 // are blocked, but nested files should be allowed.
271 base::FilePath internet_cache = user_data_dir.AppendASCII("INetCache");
272 base::ScopedPathOverride internet_cache_override(base::DIR_IE_INTERNET_CACHE,
273 internet_cache, true, true);
274
275 // The nested INetCache directory itself should not be allowed.
276 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
277 ConfirmSensitiveDirectoryAccessSync(
278 permission_context(), PathType::kLocal, internet_cache,
279 HandleType::kDirectory));
280 // Files inside the nested INetCache directory should be allowed.
281 EXPECT_EQ(SensitiveDirectoryResult::kAllowed,
282 ConfirmSensitiveDirectoryAccessSync(
283 permission_context(), PathType::kLocal,
284 internet_cache.AppendASCII("foo"), HandleType::kFile));
285 // But directories should be blocked.
286 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
287 ConfirmSensitiveDirectoryAccessSync(
288 permission_context(), PathType::kLocal,
289 internet_cache.AppendASCII("foo"), HandleType::kDirectory));
290 #endif
291 }
292
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_RelativePathBlock)293 TEST_F(ChromeNativeFileSystemPermissionContextTest,
294 ConfirmSensitiveDirectoryAccess_RelativePathBlock) {
295 base::FilePath home_dir = temp_dir_.GetPath().AppendASCII("home");
296 base::ScopedPathOverride home_override(base::DIR_HOME, home_dir, true, true);
297
298 // ~/.ssh should be blocked
299 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
300 ConfirmSensitiveDirectoryAccessSync(
301 permission_context(), PathType::kLocal,
302 home_dir.AppendASCII(".ssh"), HandleType::kDirectory));
303 // And anything inside ~/.ssh should also be blocked
304 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
305 ConfirmSensitiveDirectoryAccessSync(
306 permission_context(), PathType::kLocal,
307 home_dir.AppendASCII(".ssh/id_rsa"), HandleType::kFile));
308 }
309
TEST_F(ChromeNativeFileSystemPermissionContextTest,ConfirmSensitiveDirectoryAccess_ExplicitPathBlock)310 TEST_F(ChromeNativeFileSystemPermissionContextTest,
311 ConfirmSensitiveDirectoryAccess_ExplicitPathBlock) {
312 // Linux is the only OS where we have some blocked directories with explicit
313 // paths (as opposed to PathService provided paths).
314 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
315 // /dev should be blocked.
316 EXPECT_EQ(
317 SensitiveDirectoryResult::kAbort,
318 ConfirmSensitiveDirectoryAccessSync(
319 permission_context(), PathType::kLocal,
320 base::FilePath(FILE_PATH_LITERAL("/dev")), HandleType::kDirectory));
321 // As well as children of /dev.
322 EXPECT_EQ(SensitiveDirectoryResult::kAbort,
323 ConfirmSensitiveDirectoryAccessSync(
324 permission_context(), PathType::kLocal,
325 base::FilePath(FILE_PATH_LITERAL("/dev/foo")),
326 HandleType::kDirectory));
327 EXPECT_EQ(
328 SensitiveDirectoryResult::kAbort,
329 ConfirmSensitiveDirectoryAccessSync(
330 permission_context(), PathType::kLocal,
331 base::FilePath(FILE_PATH_LITERAL("/dev/foo")), HandleType::kFile));
332 #endif
333 }
334
TEST_F(ChromeNativeFileSystemPermissionContextTest,CanObtainWritePermission_ContentSettingAsk)335 TEST_F(ChromeNativeFileSystemPermissionContextTest,
336 CanObtainWritePermission_ContentSettingAsk) {
337 SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
338 CONTENT_SETTING_ASK);
339 EXPECT_TRUE(permission_context()->CanObtainWritePermission(kTestOrigin));
340 }
341
TEST_F(ChromeNativeFileSystemPermissionContextTest,CanObtainWritePermission_ContentSettingsBlock)342 TEST_F(ChromeNativeFileSystemPermissionContextTest,
343 CanObtainWritePermission_ContentSettingsBlock) {
344 SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
345 CONTENT_SETTING_BLOCK);
346 EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin));
347 }
348
TEST_F(ChromeNativeFileSystemPermissionContextTest,CanObtainWritePermission_ContentSettingAllow)349 TEST_F(ChromeNativeFileSystemPermissionContextTest,
350 CanObtainWritePermission_ContentSettingAllow) {
351 // Note, chrome:// scheme is whitelisted. But we can't set default content
352 // setting here because ALLOW is not an acceptable option.
353 EXPECT_TRUE(permission_context()->CanObtainWritePermission(kChromeOrigin));
354 }
355
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyReadGuardPermission)356 TEST_F(ChromeNativeFileSystemPermissionContextTest, PolicyReadGuardPermission) {
357 auto* prefs = profile()->GetTestingPrefService();
358 prefs->SetManagedPref(prefs::kManagedDefaultFileSystemReadGuardSetting,
359 std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
360
361 EXPECT_FALSE(permission_context()->CanObtainReadPermission(kTestOrigin));
362 }
363
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyWriteGuardPermission)364 TEST_F(ChromeNativeFileSystemPermissionContextTest,
365 PolicyWriteGuardPermission) {
366 auto* prefs = profile()->GetTestingPrefService();
367 prefs->SetManagedPref(prefs::kManagedDefaultFileSystemWriteGuardSetting,
368 std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
369
370 EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin));
371 }
372
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyReadAskForUrls)373 TEST_F(ChromeNativeFileSystemPermissionContextTest, PolicyReadAskForUrls) {
374 // Set the default to "block" so that the policy being tested overrides it.
375 auto* prefs = profile()->GetTestingPrefService();
376 prefs->SetManagedPref(prefs::kManagedDefaultFileSystemReadGuardSetting,
377 std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
378 prefs->SetManagedPref(prefs::kManagedFileSystemReadAskForUrls,
379 base::JSONReader::ReadDeprecated(
380 "[\"" + kTestOrigin.Serialize() + "\"]"));
381
382 EXPECT_TRUE(permission_context()->CanObtainReadPermission(kTestOrigin));
383 EXPECT_FALSE(permission_context()->CanObtainReadPermission(kTestOrigin2));
384 }
385
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyReadBlockedForUrls)386 TEST_F(ChromeNativeFileSystemPermissionContextTest, PolicyReadBlockedForUrls) {
387 auto* prefs = profile()->GetTestingPrefService();
388 prefs->SetManagedPref(prefs::kManagedFileSystemReadBlockedForUrls,
389 base::JSONReader::ReadDeprecated(
390 "[\"" + kTestOrigin.Serialize() + "\"]"));
391
392 EXPECT_FALSE(permission_context()->CanObtainReadPermission(kTestOrigin));
393 EXPECT_TRUE(permission_context()->CanObtainReadPermission(kTestOrigin2));
394 }
395
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyWriteAskForUrls)396 TEST_F(ChromeNativeFileSystemPermissionContextTest, PolicyWriteAskForUrls) {
397 // Set the default to "block" so that the policy being tested overrides it.
398 auto* prefs = profile()->GetTestingPrefService();
399 prefs->SetManagedPref(prefs::kManagedDefaultFileSystemWriteGuardSetting,
400 std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
401 prefs->SetManagedPref(prefs::kManagedFileSystemWriteAskForUrls,
402 base::JSONReader::ReadDeprecated(
403 "[\"" + kTestOrigin.Serialize() + "\"]"));
404
405 EXPECT_TRUE(permission_context()->CanObtainWritePermission(kTestOrigin));
406 EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin2));
407 }
408
TEST_F(ChromeNativeFileSystemPermissionContextTest,PolicyWriteBlockedForUrls)409 TEST_F(ChromeNativeFileSystemPermissionContextTest, PolicyWriteBlockedForUrls) {
410 auto* prefs = profile()->GetTestingPrefService();
411 prefs->SetManagedPref(prefs::kManagedFileSystemWriteBlockedForUrls,
412 base::JSONReader::ReadDeprecated(
413 "[\"" + kTestOrigin.Serialize() + "\"]"));
414
415 EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin));
416 EXPECT_TRUE(permission_context()->CanObtainWritePermission(kTestOrigin2));
417 }
418
TEST_F(ChromeNativeFileSystemPermissionContextTest,GetLastPickedDirectory)419 TEST_F(ChromeNativeFileSystemPermissionContextTest, GetLastPickedDirectory) {
420 EXPECT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin),
421 base::FilePath());
422 }
423
TEST_F(ChromeNativeFileSystemPermissionContextTest,SetLastPickedDirectory)424 TEST_F(ChromeNativeFileSystemPermissionContextTest, SetLastPickedDirectory) {
425 EXPECT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin),
426 base::FilePath());
427
428 permission_context()->SetLastPickedDirectory(kTestOrigin, kTestPath);
429 auto path = permission_context()->GetLastPickedDirectory(kTestOrigin);
430 EXPECT_EQ(path, kTestPath);
431
432 auto new_path = path.AppendASCII("baz");
433 permission_context()->SetLastPickedDirectory(kTestOrigin, new_path);
434 EXPECT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin),
435 new_path);
436 }
437
TEST_F(ChromeNativeFileSystemPermissionContextTest,SetLastPickedDirectory_NewPermissionContext)438 TEST_F(ChromeNativeFileSystemPermissionContextTest,
439 SetLastPickedDirectory_NewPermissionContext) {
440 EXPECT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin),
441 base::FilePath());
442
443 const base::FilePath path = base::FilePath(FILE_PATH_LITERAL("/baz/bar"));
444
445 permission_context()->SetLastPickedDirectory(kTestOrigin, path);
446 ASSERT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin), path);
447
448 TestNativeFileSystemPermissionContext new_permission_context(
449 browser_context());
450 EXPECT_EQ(new_permission_context.GetLastPickedDirectory(kTestOrigin), path);
451
452 auto new_path = path.AppendASCII("foo");
453 new_permission_context.SetLastPickedDirectory(kTestOrigin, new_path);
454 EXPECT_EQ(permission_context()->GetLastPickedDirectory(kTestOrigin),
455 new_path);
456 }
457
TEST_F(ChromeNativeFileSystemPermissionContextTest,GetDefaultDirectory)458 TEST_F(ChromeNativeFileSystemPermissionContextTest, GetDefaultDirectory) {
459 base::ScopedPathOverride user_documents_override(
460 chrome::DIR_USER_DOCUMENTS, temp_dir_.GetPath(), true, true);
461 EXPECT_EQ(permission_context_->GetDefaultDirectory(), temp_dir_.GetPath());
462 }
463
464 #endif // !defined(OS_ANDROID)
465