| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromecast/media/cma/backend/cast_audio_json.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "base/files/file_util.h" |
| #include "base/functional/bind.h" |
| #include "base/json/json_reader.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/task/task_traits.h" |
| #include "base/task/thread_pool.h" |
| #include "base/task/thread_pool/thread_pool_instance.h" |
| #include "build/build_config.h" |
| |
| namespace chromecast { |
| namespace media { |
| |
| namespace { |
| |
| void ReadFileRunCallback(CastAudioJsonProvider::TuningChangedCallback callback, |
| const base::FilePath& path, |
| bool error) { |
| DCHECK(callback); |
| |
| std::string contents; |
| base::ReadFileToString(path, &contents); |
| absl::optional<base::Value> value = base::JSONReader::Read(contents); |
| if (value && value->is_dict()) { |
| callback.Run(std::move(*value).TakeDict()); |
| return; |
| } |
| LOG(ERROR) << "Unable to parse JSON in " << path; |
| } |
| |
| } // namespace |
| |
| #if BUILDFLAG(IS_FUCHSIA) |
| const char kCastAudioJsonFilePath[] = "/system/data/cast_audio.json"; |
| #else |
| const char kCastAudioJsonFilePath[] = "/etc/cast_audio.json"; |
| #endif |
| const char kCastAudioJsonFileName[] = "cast_audio.json"; |
| |
| // static |
| base::FilePath CastAudioJson::GetFilePath() { |
| base::FilePath tuning_path = CastAudioJson::GetFilePathForTuning(); |
| if (base::PathExists(tuning_path)) { |
| return tuning_path; |
| } |
| |
| return CastAudioJson::GetReadOnlyFilePath(); |
| } |
| |
| // static |
| base::FilePath CastAudioJson::GetReadOnlyFilePath() { |
| return base::FilePath(kCastAudioJsonFilePath); |
| } |
| |
| // static |
| base::FilePath CastAudioJson::GetFilePathForTuning() { |
| return base::GetHomeDir().Append(kCastAudioJsonFileName); |
| } |
| |
| CastAudioJsonProviderImpl::CastAudioJsonProviderImpl() { |
| if (base::ThreadPoolInstance::Get()) { |
| cast_audio_watcher_ = base::SequenceBound<FileWatcher>( |
| base::ThreadPool::CreateSequencedTaskRunner( |
| {base::MayBlock(), base::TaskPriority::LOWEST})); |
| } |
| } |
| |
| CastAudioJsonProviderImpl::~CastAudioJsonProviderImpl() = default; |
| |
| absl::optional<base::Value::Dict> |
| CastAudioJsonProviderImpl::GetCastAudioConfig() { |
| std::string contents; |
| base::ReadFileToString(CastAudioJson::GetFilePath(), &contents); |
| absl::optional<base::Value> value = base::JSONReader::Read(contents); |
| if (!value || value->is_dict()) { |
| return absl::nullopt; |
| } |
| |
| return std::move(*value).TakeDict(); |
| } |
| |
| void CastAudioJsonProviderImpl::SetTuningChangedCallback( |
| TuningChangedCallback callback) { |
| if (cast_audio_watcher_) { |
| cast_audio_watcher_.AsyncCall(&FileWatcher::SetTuningChangedCallback) |
| .WithArgs(std::move(callback)); |
| } |
| } |
| |
| CastAudioJsonProviderImpl::FileWatcher::FileWatcher() = default; |
| CastAudioJsonProviderImpl::FileWatcher::~FileWatcher() = default; |
| |
| void CastAudioJsonProviderImpl::FileWatcher::SetTuningChangedCallback( |
| TuningChangedCallback callback) { |
| watcher_.Watch( |
| CastAudioJson::GetFilePathForTuning(), |
| base::FilePathWatcher::Type::kNonRecursive, |
| base::BindRepeating(&ReadFileRunCallback, std::move(callback))); |
| } |
| |
| } // namespace media |
| } // namespace chromecast |