[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / fuchsia_component_support / config_reader.cc
1 // Copyright 2020 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 "components/fuchsia_component_support/config_reader.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/check.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/logging.h"
16 #include "base/no_destructor.h"
17
18 namespace fuchsia_component_support {
19
20 namespace {
21
22 bool HaveConflicts(const base::Value::Dict& dict1,
23                    const base::Value::Dict& dict2) {
24   for (auto item : dict1) {
25     const base::Value* value = dict2.Find(item.first);
26     if (!value)
27       continue;
28     if (!value->is_dict())
29       return true;
30     if (HaveConflicts(item.second.GetDict(), value->GetDict()))
31       return true;
32   }
33
34   return false;
35 }
36
37 base::Value::Dict ReadConfigFile(const base::FilePath& path) {
38   std::string file_content;
39   bool loaded = base::ReadFileToString(path, &file_content);
40   CHECK(loaded) << "Couldn't read config file: " << path;
41
42   auto parsed = base::JSONReader::ReadAndReturnValueWithError(file_content);
43   CHECK(parsed.has_value())
44       << "Failed to parse " << path << ": " << parsed.error().message;
45   CHECK(parsed->is_dict()) << "Config is not a JSON dictionary: " << path;
46
47   return std::move(parsed->GetDict());
48 }
49
50 absl::optional<base::Value::Dict> ReadConfigsFromDir(
51     const base::FilePath& dir) {
52   base::FileEnumerator configs(dir, false, base::FileEnumerator::FILES,
53                                "*.json");
54   absl::optional<base::Value::Dict> config;
55   for (base::FilePath path; !(path = configs.Next()).empty();) {
56     base::Value::Dict path_config = ReadConfigFile(path);
57     if (config) {
58       CHECK(!HaveConflicts(*config, path_config));
59       config->Merge(std::move(path_config));
60     } else {
61       config = std::move(path_config);
62     }
63   }
64
65   return config;
66 }
67
68 }  // namespace
69
70 const absl::optional<base::Value::Dict>& LoadPackageConfig() {
71   // Package configurations do not change at run-time, so read the configuration
72   // on the first call and cache the result.
73   static base::NoDestructor<absl::optional<base::Value::Dict>> config(
74       ReadConfigsFromDir(base::FilePath("/config/data")));
75
76   return *config;
77 }
78
79 absl::optional<base::Value::Dict> LoadConfigFromDirForTest(  // IN-TEST
80     const base::FilePath& dir) {
81   return ReadConfigsFromDir(dir);
82 }
83
84 }  // namespace fuchsia_component_support