• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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/path_service.h"
6 
7 #include "base/base_paths.h"
8 #include "base/containers/contains.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/scoped_environment_variable_override.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/gtest_util.h"
17 #include "build/build_config.h"
18 #include "testing/gtest/include/gtest/gtest-spi.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/platform_test.h"
21 
22 #if BUILDFLAG(IS_WIN)
23 #include <shlobj.h>
24 
25 #include "base/win/windows_version.h"
26 #endif
27 
28 #if BUILDFLAG(IS_APPLE)
29 #include "base/apple/bundle_locations.h"
30 #endif
31 
32 namespace base {
33 
34 namespace {
35 
36 #if BUILDFLAG(IS_ANDROID)
37 // Defined in
38 // //base/test/android/javatests/src/org/chromium/base/test/util/UrlUtils.java.
39 constexpr char kExpectedChromiumTestsRoot[] =
40     "/storage/emulated/0/chromium_tests_root";
41 #endif
42 
43 // Returns true if PathService::Get returns true and sets the path parameter
44 // to non-empty for the given PathService key enumeration value.
ReturnsValidPath(int key)45 bool ReturnsValidPath(int key) {
46   FilePath path;
47   bool result = PathService::Get(key, &path);
48 
49   // Some paths might not exist on some platforms in which case confirming
50   // |result| is true and !path.empty() is the best we can do.
51   bool check_path_exists = true;
52 
53 #if BUILDFLAG(IS_POSIX)
54   // If chromium has never been started on this account, the cache path may not
55   // exist.
56   if (key == DIR_CACHE)
57     check_path_exists = false;
58 #endif
59 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
60   // On the linux try-bots: a path is returned (e.g. /home/chrome-bot/Desktop),
61   // but it doesn't exist.
62   if (key == DIR_USER_DESKTOP)
63     check_path_exists = false;
64 #endif
65 #if BUILDFLAG(IS_WIN)
66   if (key == DIR_TASKBAR_PINS)
67     check_path_exists = false;
68 #endif
69 #if BUILDFLAG(IS_MAC)
70   if (key != DIR_EXE && key != DIR_MODULE && key != FILE_EXE &&
71       key != FILE_MODULE) {
72     if (path.ReferencesParent()) {
73       LOG(INFO) << "Path (" << path << ") references parent.";
74       return false;
75     }
76   }
77 #else
78   if (path.ReferencesParent()) {
79     LOG(INFO) << "Path (" << path << ") references parent.";
80     return false;
81   }
82 #endif  // BUILDFLAG(IS_MAC)
83   if (!result) {
84     LOG(INFO) << "PathService::Get() returned false.";
85     return false;
86   }
87   if (path.empty()) {
88     LOG(INFO) << "PathService::Get() returned an empty path.";
89     return false;
90   }
91   if (check_path_exists && !PathExists(path)) {
92     LOG(INFO) << "Path (" << path << ") does not exist.";
93     return false;
94   }
95   return true;
96 }
97 
98 // Returns true if PathService::Get returns false and path parameter is empty
99 // for the given PathService key enumeration value. Used to test path keys that
100 // are not supported on the platform or on some versions of Windows.
ReturnsInvalidPath(int key)101 bool ReturnsInvalidPath(int key) {
102   FilePath path;
103   bool result = PathService::Get(key, &path);
104   return !result && path.empty();
105 }
106 
107 }  // namespace
108 
109 // On the Mac this winds up using some autoreleased objects, so we need to
110 // be a PlatformTest.
111 typedef PlatformTest PathServiceTest;
112 
113 // Test that all PathService::Get calls return a value and a true result
114 // in the development environment.  (This test was created because a few
115 // later changes to Get broke the semantics of the function and yielded the
116 // correct value while returning false.)
117 // If this test fails for specific value(s) on a specific platform, consider not
118 // defining the enum value on that platform rather than skipping or expecting
119 // failure for the value(s) on that platform in this test.
TEST_F(PathServiceTest,Get)120 TEST_F(PathServiceTest, Get) {
121   // Contains keys that are defined but not supported on the platform.
122 #if BUILDFLAG(IS_ANDROID)
123   // The following keys are not intended to be implemented on Android (see
124   // crbug.com/1257402). Current implementation is described before each key.
125   // TODO(crbug.com/40796336): Remove the definition of these keys on Android
126   // or at least fix the behavior of DIR_HOME.
127   constexpr std::array kUnsupportedKeys = {
128       // Though DIR_HOME is not intended to be supported, PathProviderPosix
129       // handles it and returns true. Thus, it is NOT included in the array.
130       /* DIR_HOME, */
131       // PathProviderAndroid and PathProviderPosix both return false.
132       FILE_MODULE,
133       // PathProviderPosix handles it but fails at some point.
134       DIR_USER_DESKTOP};
135 #elif BUILDFLAG(IS_FUCHSIA)
136   constexpr std::array kUnsupportedKeys = {
137       // TODO(crbug.com/42050322): Implement DIR_USER_DESKTOP.
138       DIR_USER_DESKTOP};
139 #else
140   constexpr std::array<BasePathKey, 0> kUnsupportedKeys = {};
141 #endif  // BUILDFLAG(IS_ANDROID)
142   for (int key = PATH_START + 1; key < PATH_END; ++key) {
143     EXPECT_PRED1(Contains(kUnsupportedKeys, key) ? &ReturnsInvalidPath
144                                                  : &ReturnsValidPath,
145                  key);
146   }
147 #if BUILDFLAG(IS_WIN)
148   for (int key = PATH_WIN_START + 1; key < PATH_WIN_END; ++key) {
149     if (key == DIR_SYSTEM_TEMP) {
150       EXPECT_PRED1(::IsUserAnAdmin() ? &ReturnsValidPath : &ReturnsInvalidPath,
151                    key);
152     } else {
153       EXPECT_PRED1(ReturnsValidPath, key);
154     }
155   }
156 #elif BUILDFLAG(IS_MAC)
157   for (int key = PATH_MAC_START + 1; key < PATH_MAC_END; ++key) {
158     EXPECT_PRED1(ReturnsValidPath, key);
159   }
160 #elif BUILDFLAG(IS_IOS)
161   for (int key = PATH_IOS_START + 1; key < PATH_IOS_END; ++key) {
162     EXPECT_PRED1(ReturnsValidPath, key);
163   }
164 #elif BUILDFLAG(IS_ANDROID)
165   for (int key = PATH_ANDROID_START + 1; key < PATH_ANDROID_END;
166        ++key) {
167     EXPECT_PRED1(ReturnsValidPath, key);
168   }
169 #elif BUILDFLAG(IS_POSIX)
170   for (int key = PATH_POSIX_START + 1; key < PATH_POSIX_END;
171        ++key) {
172     EXPECT_PRED1(ReturnsValidPath, key);
173   }
174 #endif  // BUILDFLAG(IS_WIN)
175 }
176 
177 // Tests that CheckedGet returns the same path as Get.
TEST_F(PathServiceTest,CheckedGet)178 TEST_F(PathServiceTest, CheckedGet) {
179   constexpr int kKey = DIR_CURRENT;
180   FilePath path;
181   ASSERT_TRUE(PathService::Get(kKey, &path));
182   EXPECT_EQ(path, PathService::CheckedGet(kKey));
183 }
184 
185 #if defined(GTEST_HAS_DEATH_TEST)
186 
187 // Tests that CheckedGet CHECKs on failure.
TEST_F(PathServiceTest,CheckedGetFailure)188 TEST_F(PathServiceTest, CheckedGetFailure) {
189   constexpr int kBadKey = PATH_END;
190   FilePath path;
191   EXPECT_FALSE(PathService::Get(kBadKey, &path));
192   EXPECT_DEATH(PathService::CheckedGet(kBadKey), "Failed to get the path");
193 }
194 
195 #endif  // defined(GTEST_HAS_DEATH_TEST)
196 
197 // Test that all versions of the Override function of PathService do what they
198 // are supposed to do.
TEST_F(PathServiceTest,Override)199 TEST_F(PathServiceTest, Override) {
200   int my_special_key = 666;
201   ScopedTempDir temp_dir;
202   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
203   FilePath fake_cache_dir(temp_dir.GetPath().AppendASCII("cache"));
204   // PathService::Override should always create the path provided if it doesn't
205   // exist.
206   EXPECT_TRUE(PathService::Override(my_special_key, fake_cache_dir));
207   EXPECT_TRUE(PathExists(fake_cache_dir));
208 
209   FilePath fake_cache_dir2(temp_dir.GetPath().AppendASCII("cache2"));
210   // PathService::OverrideAndCreateIfNeeded should obey the |create| parameter.
211   PathService::OverrideAndCreateIfNeeded(my_special_key,
212                                          fake_cache_dir2,
213                                          false,
214                                          false);
215   EXPECT_FALSE(PathExists(fake_cache_dir2));
216   EXPECT_TRUE(PathService::OverrideAndCreateIfNeeded(my_special_key,
217                                                      fake_cache_dir2,
218                                                      false,
219                                                      true));
220   EXPECT_TRUE(PathExists(fake_cache_dir2));
221 
222 #if BUILDFLAG(IS_POSIX)
223   FilePath non_existent(
224       MakeAbsoluteFilePath(temp_dir.GetPath()).AppendASCII("non_existent"));
225   EXPECT_TRUE(non_existent.IsAbsolute());
226   EXPECT_FALSE(PathExists(non_existent));
227 #if !BUILDFLAG(IS_ANDROID)
228   // This fails because MakeAbsoluteFilePath fails for non-existent files.
229   // Earlier versions of Bionic libc don't fail for non-existent files, so
230   // skip this check on Android.
231   EXPECT_FALSE(PathService::OverrideAndCreateIfNeeded(my_special_key,
232                                                       non_existent,
233                                                       false,
234                                                       false));
235 #endif  // !BUILDFLAG(IS_ANDROID)
236   // This works because indicating that |non_existent| is absolute skips the
237   // internal MakeAbsoluteFilePath call.
238   EXPECT_TRUE(PathService::OverrideAndCreateIfNeeded(my_special_key,
239                                                      non_existent,
240                                                      true,
241                                                      false));
242   // Check that the path has been overridden and no directory was created.
243   EXPECT_FALSE(PathExists(non_existent));
244   FilePath path;
245   EXPECT_TRUE(PathService::Get(my_special_key, &path));
246   EXPECT_EQ(non_existent, path);
247 #endif  // BUILDFLAG(IS_POSIX)
248 }
249 
250 // Check if multiple overrides can co-exist.
TEST_F(PathServiceTest,OverrideMultiple)251 TEST_F(PathServiceTest, OverrideMultiple) {
252   int my_special_key = 666;
253   ScopedTempDir temp_dir;
254   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
255   FilePath fake_cache_dir1(temp_dir.GetPath().AppendASCII("1"));
256   EXPECT_TRUE(PathService::Override(my_special_key, fake_cache_dir1));
257   EXPECT_TRUE(PathExists(fake_cache_dir1));
258   ASSERT_TRUE(WriteFile(fake_cache_dir1.AppendASCII("t1"), "."));
259 
260   FilePath fake_cache_dir2(temp_dir.GetPath().AppendASCII("2"));
261   EXPECT_TRUE(PathService::Override(my_special_key + 1, fake_cache_dir2));
262   EXPECT_TRUE(PathExists(fake_cache_dir2));
263   ASSERT_TRUE(WriteFile(fake_cache_dir2.AppendASCII("t2"), "."));
264 
265   FilePath result;
266   EXPECT_TRUE(PathService::Get(my_special_key, &result));
267   // Override might have changed the path representation but our test file
268   // should be still there.
269   EXPECT_TRUE(PathExists(result.AppendASCII("t1")));
270   EXPECT_TRUE(PathService::Get(my_special_key + 1, &result));
271   EXPECT_TRUE(PathExists(result.AppendASCII("t2")));
272 }
273 
TEST_F(PathServiceTest,RemoveOverride)274 TEST_F(PathServiceTest, RemoveOverride) {
275   // Before we start the test we have to call RemoveOverride at least once to
276   // clear any overrides that might have been left from other tests.
277   PathService::RemoveOverrideForTests(DIR_TEMP);
278 
279   FilePath original_user_data_dir;
280   EXPECT_TRUE(PathService::Get(DIR_TEMP, &original_user_data_dir));
281   EXPECT_FALSE(PathService::RemoveOverrideForTests(DIR_TEMP));
282 
283   ScopedTempDir temp_dir;
284   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
285   EXPECT_TRUE(PathService::Override(DIR_TEMP, temp_dir.GetPath()));
286   FilePath new_user_data_dir;
287   EXPECT_TRUE(PathService::Get(DIR_TEMP, &new_user_data_dir));
288   EXPECT_NE(original_user_data_dir, new_user_data_dir);
289 
290   EXPECT_TRUE(PathService::RemoveOverrideForTests(DIR_TEMP));
291   EXPECT_TRUE(PathService::Get(DIR_TEMP, &new_user_data_dir));
292   EXPECT_EQ(original_user_data_dir, new_user_data_dir);
293 }
294 
295 #if BUILDFLAG(IS_WIN)
TEST_F(PathServiceTest,GetProgramFiles)296 TEST_F(PathServiceTest, GetProgramFiles) {
297   FilePath programfiles_dir;
298 #if defined(_WIN64)
299   // 64-bit on 64-bit.
300   EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES,
301       &programfiles_dir));
302   EXPECT_EQ(programfiles_dir.value(),
303       FILE_PATH_LITERAL("C:\\Program Files"));
304   EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILESX86,
305       &programfiles_dir));
306   EXPECT_EQ(programfiles_dir.value(),
307       FILE_PATH_LITERAL("C:\\Program Files (x86)"));
308   EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES6432,
309       &programfiles_dir));
310   EXPECT_EQ(programfiles_dir.value(),
311       FILE_PATH_LITERAL("C:\\Program Files"));
312 #else
313   if (base::win::OSInfo::GetInstance()->IsWowX86OnAMD64() ||
314       base::win::OSInfo::GetInstance()->IsWowX86OnARM64()) {
315     // 32-bit on 64-bit.
316     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES,
317         &programfiles_dir));
318     EXPECT_EQ(programfiles_dir.value(),
319         FILE_PATH_LITERAL("C:\\Program Files (x86)"));
320     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILESX86,
321         &programfiles_dir));
322     EXPECT_EQ(programfiles_dir.value(),
323         FILE_PATH_LITERAL("C:\\Program Files (x86)"));
324     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES6432,
325         &programfiles_dir));
326     EXPECT_EQ(programfiles_dir.value(),
327         FILE_PATH_LITERAL("C:\\Program Files"));
328   } else {
329     // 32-bit on 32-bit.
330     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES,
331         &programfiles_dir));
332     EXPECT_EQ(programfiles_dir.value(),
333         FILE_PATH_LITERAL("C:\\Program Files"));
334     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILESX86,
335         &programfiles_dir));
336     EXPECT_EQ(programfiles_dir.value(),
337         FILE_PATH_LITERAL("C:\\Program Files"));
338     EXPECT_TRUE(PathService::Get(DIR_PROGRAM_FILES6432,
339         &programfiles_dir));
340     EXPECT_EQ(programfiles_dir.value(),
341         FILE_PATH_LITERAL("C:\\Program Files"));
342   }
343 #endif  // defined(_WIN64)
344 }
345 
TEST_F(PathServiceTest,GetSystemTemp)346 TEST_F(PathServiceTest, GetSystemTemp) {
347   FilePath secure_system_temp;
348 
349   EXPECT_EQ(PathService::Get(DIR_SYSTEM_TEMP, &secure_system_temp),
350             ::IsUserAnAdmin());
351   if (!secure_system_temp.empty()) {
352     FilePath dir_windows;
353     ASSERT_TRUE(PathService::Get(DIR_WINDOWS, &dir_windows));
354     FilePath dir_program_files;
355     ASSERT_TRUE(PathService::Get(DIR_PROGRAM_FILES, &dir_program_files));
356 
357     ASSERT_TRUE((dir_windows.AppendASCII("SystemTemp") == secure_system_temp) ||
358                 (dir_program_files == secure_system_temp));
359   }
360 }
361 #endif  // BUILDFLAG(IS_WIN)
362 
363 // Tests that DIR_ASSETS is
364 // - the package root on Fuchsia,
365 // - overridden in tests by test_support_android.cc,
366 // - equals to base::apple::FrameworkBundlePath() on iOS,
367 // - a sub-directory of base::apple::FrameworkBundlePath() on iOS catalyst,
368 // - equals to DIR_MODULE otherwise.
TEST_F(PathServiceTest,DIR_ASSETS)369 TEST_F(PathServiceTest, DIR_ASSETS) {
370   FilePath path;
371   ASSERT_TRUE(PathService::Get(DIR_ASSETS, &path));
372 #if BUILDFLAG(IS_FUCHSIA)
373   EXPECT_EQ(path.value(), "/pkg");
374 #elif BUILDFLAG(IS_ANDROID)
375   // This key is overridden in //base/test/test_support_android.cc.
376   EXPECT_EQ(path.value(), kExpectedChromiumTestsRoot);
377 #elif BUILDFLAG(IS_IOS_MACCATALYST)
378   EXPECT_TRUE(base::apple::FrameworkBundlePath().IsParent(path));
379 #elif BUILDFLAG(IS_IOS)
380   EXPECT_EQ(path, base::apple::FrameworkBundlePath());
381 #else
382   EXPECT_EQ(path, PathService::CheckedGet(DIR_MODULE));
383 #endif
384 }
385 
386 // DIR_OUT_TEST_DATA_ROOT is DIR_MODULE except on Fuchsia where it is the
387 // package root, on ios where it is the resources directory and on Android
388 // where it is overridden in tests by test_support_android.cc.
TEST_F(PathServiceTest,DIR_OUT_TEST_DATA_ROOT)389 TEST_F(PathServiceTest, DIR_OUT_TEST_DATA_ROOT) {
390   FilePath path;
391   ASSERT_TRUE(PathService::Get(DIR_OUT_TEST_DATA_ROOT, &path));
392 #if BUILDFLAG(IS_FUCHSIA)
393   EXPECT_EQ(path.value(), "/pkg");
394 #elif BUILDFLAG(IS_ANDROID)
395   // This key is overridden in //base/test/test_support_android.cc.
396   EXPECT_EQ(path.value(), kExpectedChromiumTestsRoot);
397 #elif BUILDFLAG(IS_IOS)
398   // On iOS, build output files are moved to the resources directory.
399   EXPECT_EQ(path, base::apple::FrameworkBundlePath());
400 #else
401   // On other platforms all build output is in the same directory,
402   // so DIR_OUT_TEST_DATA_ROOT should match DIR_MODULE.
403   EXPECT_EQ(path, PathService::CheckedGet(DIR_MODULE));
404 #endif
405 }
406 
407 // Test that DIR_GEN_TEST_DATA_ROOT contains dummy_generated.txt which is
408 // generated for this test.
TEST_F(PathServiceTest,DIR_GEN_TEST_DATA_ROOT)409 TEST_F(PathServiceTest, DIR_GEN_TEST_DATA_ROOT) {
410   FilePath path;
411   ASSERT_TRUE(PathService::Get(DIR_GEN_TEST_DATA_ROOT, &path));
412   EXPECT_TRUE(base::PathExists(
413       path.Append(FILE_PATH_LITERAL("base/generated_file_for_test.txt"))));
414 }
415 
416 #if ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) && \
417       !BUILDFLAG(IS_ANDROID)) ||                     \
418      BUILDFLAG(IS_WIN))
419 
420 // Test that CR_SOURCE_ROOT is being used when set.
421 // By default on those platforms, this directory is set to two directories up
422 // the current executable directory ("../../").
TEST_F(PathServiceTest,SetTestDataRootAsAbsolutePath)423 TEST_F(PathServiceTest, SetTestDataRootAsAbsolutePath) {
424   // This is needed because on some platform `DIR_SRC_TEST_DATA_ROOT` can be
425   // cached before reaching this function.
426   PathService::DisableCache();
427   base::ScopedTempDir tempdir;
428   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
429 
430 #if BUILDFLAG(IS_WIN)
431   auto scoped_env = base::ScopedEnvironmentVariableOverride(
432       "CR_SOURCE_ROOT", base::WideToUTF8(tempdir.GetPath().value()));
433 #else
434   auto scoped_env = base::ScopedEnvironmentVariableOverride(
435       "CR_SOURCE_ROOT", tempdir.GetPath().value());
436 #endif
437 
438   base::FilePath test_data_root;
439   ASSERT_TRUE(PathService::Get(DIR_SRC_TEST_DATA_ROOT, &test_data_root));
440 
441   ASSERT_EQ(test_data_root, tempdir.GetPath());
442 }
443 
444 // Test that CR_SOURCE_ROOT is being used when set.
TEST_F(PathServiceTest,SetTestDataRootAsRelativePath)445 TEST_F(PathServiceTest, SetTestDataRootAsRelativePath) {
446   // This is needed because on some platform `DIR_SRC_TEST_DATA_ROOT` can be
447   // cached before reaching this function.
448   PathService::DisableCache();
449 #if BUILDFLAG(IS_WIN)
450   auto scoped_env = base::ScopedEnvironmentVariableOverride(
451       "CR_SOURCE_ROOT", base::WideToUTF8(base::FilePath::kParentDirectory));
452 #else
453   auto scoped_env = base::ScopedEnvironmentVariableOverride(
454       "CR_SOURCE_ROOT", base::FilePath::kParentDirectory);
455 #endif
456   base::FilePath path;
457   ASSERT_TRUE(PathService::Get(DIR_EXE, &path));
458 
459   base::FilePath test_data_root;
460   ASSERT_TRUE(PathService::Get(DIR_SRC_TEST_DATA_ROOT, &test_data_root));
461 
462   path = MakeAbsoluteFilePath(path.Append(base::FilePath::kParentDirectory));
463   ASSERT_EQ(test_data_root, path);
464 }
465 
466 #endif
467 
468 #if BUILDFLAG(IS_FUCHSIA)
469 // On Fuchsia, some keys have fixed paths that are easy to test.
470 
TEST_F(PathServiceTest,DIR_SRC_TEST_DATA_ROOT)471 TEST_F(PathServiceTest, DIR_SRC_TEST_DATA_ROOT) {
472   FilePath test_binary_path;
473   EXPECT_EQ(PathService::CheckedGet(DIR_SRC_TEST_DATA_ROOT).value(), "/pkg");
474 }
475 
476 #elif BUILDFLAG(IS_ANDROID)
477 
478 // These keys are overridden in //base/test/test_support_android.cc.
TEST_F(PathServiceTest,AndroidTestOverrides)479 TEST_F(PathServiceTest, AndroidTestOverrides) {
480   EXPECT_EQ(PathService::CheckedGet(DIR_ANDROID_APP_DATA).value(),
481             kExpectedChromiumTestsRoot);
482   EXPECT_EQ(PathService::CheckedGet(DIR_ASSETS).value(),
483             kExpectedChromiumTestsRoot);
484   EXPECT_EQ(PathService::CheckedGet(DIR_SRC_TEST_DATA_ROOT).value(),
485             kExpectedChromiumTestsRoot);
486   EXPECT_EQ(PathService::CheckedGet(DIR_OUT_TEST_DATA_ROOT).value(),
487             kExpectedChromiumTestsRoot);
488 }
489 
490 #endif  // BUILDFLAG(IS_FUCHSIA)
491 
492 }  // namespace base
493