Commit c7a025a7 authored by Junbo Ke's avatar Junbo Ke Committed by Chromium LUCI CQ

[Chromecast] Avoid using heap allocated base::Value in DeviceCapabilities.

Also migrated off base::DictionaryValue.

Bug: internal b/156555613
Merge-With: eureka-internal/514526
Merge-With: eureka-internal/514525
Merge-With: eureka-internal/514524
Merge-With: eureka-internal/514186
Merge-With: eureka-internal/513401
Merge-With: eureka-internal/513298
Merge-With: eureka-internal/513381
Merge-With: eureka-internal/513294
Merge-With: eureka-internal/513296
Merge-With: eureka-internal/513299
Test: cast_base_unittests
Change-Id: If06e412cd0d8eab2374e6567a87832d6a225d9a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612108
Commit-Queue: Junbo Ke <juke@chromium.org>
Reviewed-by: default avatarSean Topping <seantopping@chromium.org>
Reviewed-by: default avatarLuke Halliwell (slow) <halliwell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846411}
parent 2ea79437
...@@ -10,11 +10,7 @@ ...@@ -10,11 +10,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/values.h"
namespace base {
class DictionaryValue;
class Value;
}
namespace chromecast { namespace chromecast {
...@@ -84,7 +80,7 @@ class DeviceCapabilities { ...@@ -84,7 +80,7 @@ class DeviceCapabilities {
// to it must be handled serially. Returns response through // to it must be handled serially. Returns response through
// SetPublicValidatedValue() or SetPrivateValidatedValue(). // SetPublicValidatedValue() or SetPrivateValidatedValue().
virtual void Validate(const std::string& path, virtual void Validate(const std::string& path,
std::unique_ptr<base::Value> proposed_value) = 0; base::Value proposed_value) = 0;
protected: protected:
explicit Validator(DeviceCapabilities* capabilities); explicit Validator(DeviceCapabilities* capabilities);
...@@ -99,9 +95,9 @@ class DeviceCapabilities { ...@@ -99,9 +95,9 @@ class DeviceCapabilities {
// TODO(seantopping): Change this interface so that Validators are not the // TODO(seantopping): Change this interface so that Validators are not the
// only means of accessing private capabilities. // only means of accessing private capabilities.
void SetPublicValidatedValue(const std::string& path, void SetPublicValidatedValue(const std::string& path,
std::unique_ptr<base::Value> new_value) const; base::Value new_value) const;
void SetPrivateValidatedValue(const std::string& path, void SetPrivateValidatedValue(const std::string& path,
std::unique_ptr<base::Value> new_value) const; base::Value new_value) const;
private: private:
DeviceCapabilities* const capabilities_; DeviceCapabilities* const capabilities_;
...@@ -115,9 +111,7 @@ class DeviceCapabilities { ...@@ -115,9 +111,7 @@ class DeviceCapabilities {
class Data : public base::RefCountedThreadSafe<Data> { class Data : public base::RefCountedThreadSafe<Data> {
public: public:
// Accessor for complete capabilities in dictionary format. // Accessor for complete capabilities in dictionary format.
const base::DictionaryValue& dictionary() const { const base::Value& dictionary() const { return dictionary_; }
return *dictionary_.get();
}
// Accessor for complete capabilities string in JSON format. // Accessor for complete capabilities string in JSON format.
const std::string& json_string() const { return json_string_; } const std::string& json_string() const { return json_string_; }
...@@ -131,11 +125,11 @@ class DeviceCapabilities { ...@@ -131,11 +125,11 @@ class DeviceCapabilities {
// Constructs empty dictionary with no capabilities. // Constructs empty dictionary with no capabilities.
Data(); Data();
// Uses |dictionary| as capabilities dictionary. // Uses |dictionary| as capabilities dictionary.
explicit Data(std::unique_ptr<const base::DictionaryValue> dictionary); explicit Data(base::Value dictionary);
~Data(); ~Data();
const std::unique_ptr<const base::DictionaryValue> dictionary_; const base::Value dictionary_;
const std::string json_string_; std::string json_string_;
DISALLOW_COPY_AND_ASSIGN(Data); DISALLOW_COPY_AND_ASSIGN(Data);
}; };
...@@ -196,8 +190,7 @@ class DeviceCapabilities { ...@@ -196,8 +190,7 @@ class DeviceCapabilities {
// Returns a deep copy of the value at |path|. If the capability at |path| // Returns a deep copy of the value at |path|. If the capability at |path|
// does not exist, a null scoped_ptr is returned. // does not exist, a null scoped_ptr is returned.
virtual std::unique_ptr<base::Value> GetCapability( virtual base::Value GetCapability(const std::string& path) const = 0;
const std::string& path) const = 0;
// Use this method to access dictionary and JSON string. No deep copying is // Use this method to access dictionary and JSON string. No deep copying is
// performed, so this method is inexpensive. Note that any capability updates // performed, so this method is inexpensive. Note that any capability updates
...@@ -223,11 +216,11 @@ class DeviceCapabilities { ...@@ -223,11 +216,11 @@ class DeviceCapabilities {
// classify the value as public or private via SetPublicValidatedValue() or // classify the value as public or private via SetPublicValidatedValue() or
// SetPrivateValidatedValue() respectively. // SetPrivateValidatedValue() respectively.
virtual void SetCapability(const std::string& path, virtual void SetCapability(const std::string& path,
std::unique_ptr<base::Value> proposed_value) = 0; base::Value proposed_value) = 0;
// Iterates through entries in |dict_value| and calls SetCapability() for // Iterates through entries in |dict_value| and calls SetCapability() for
// each one. This method is asynchronous. // each one. This method is asynchronous.
virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0; virtual void MergeDictionary(const base::Value& dict_value) = 0;
// Adds/removes an observer. It doesn't take the ownership of |observer|. // Adds/removes an observer. It doesn't take the ownership of |observer|.
virtual void AddCapabilitiesObserver(Observer* observer) = 0; virtual void AddCapabilitiesObserver(Observer* observer) = 0;
...@@ -241,20 +234,17 @@ class DeviceCapabilities { ...@@ -241,20 +234,17 @@ class DeviceCapabilities {
// Creates empty dictionary with no capabilities. // Creates empty dictionary with no capabilities.
static scoped_refptr<Data> CreateData(); static scoped_refptr<Data> CreateData();
// Uses |dictionary| as capabilities dictionary. // Uses |dictionary| as capabilities dictionary.
static scoped_refptr<Data> CreateData( static scoped_refptr<Data> CreateData(base::Value dictionary);
std::unique_ptr<const base::DictionaryValue> dictionary);
private: private:
// Internally update the capability residing at |path| to |new_value|. This // Internally update the capability residing at |path| to |new_value|. This
// capability will be visible in GetAllData() and GetPublicData(). // capability will be visible in GetAllData() and GetPublicData().
virtual void SetPublicValidatedValue( virtual void SetPublicValidatedValue(const std::string& path,
const std::string& path, base::Value new_value) = 0;
std::unique_ptr<base::Value> new_value) = 0;
// Similar to SetPublicValidatedValue(), but this capability will only be // Similar to SetPublicValidatedValue(), but this capability will only be
// visible in GetAllData(). // visible in GetAllData().
virtual void SetPrivateValidatedValue( virtual void SetPrivateValidatedValue(const std::string& path,
const std::string& path, base::Value new_value) = 0;
std::unique_ptr<base::Value> new_value) = 0;
DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities); DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities);
}; };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback_helpers.h" #include "base/callback_helpers.h"
#include "base/json/json_writer.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
...@@ -64,14 +65,10 @@ std::unique_ptr<DeviceCapabilities> DeviceCapabilities::Create() { ...@@ -64,14 +65,10 @@ std::unique_ptr<DeviceCapabilities> DeviceCapabilities::Create() {
// static // static
std::unique_ptr<DeviceCapabilities> DeviceCapabilities::CreateForTesting() { std::unique_ptr<DeviceCapabilities> DeviceCapabilities::CreateForTesting() {
DeviceCapabilities* capabilities = new DeviceCapabilitiesImpl; DeviceCapabilities* capabilities = new DeviceCapabilitiesImpl;
capabilities->SetCapability(kKeyBluetoothSupported, capabilities->SetCapability(kKeyBluetoothSupported, base::Value(false));
std::make_unique<base::Value>(false)); capabilities->SetCapability(kKeyDisplaySupported, base::Value(true));
capabilities->SetCapability(kKeyDisplaySupported, capabilities->SetCapability(kKeyHiResAudioSupported, base::Value(false));
std::make_unique<base::Value>(true)); capabilities->SetCapability(kKeyAssistantSupported, base::Value(true));
capabilities->SetCapability(kKeyHiResAudioSupported,
std::make_unique<base::Value>(false));
capabilities->SetCapability(kKeyAssistantSupported,
std::make_unique<base::Value>(true));
return base::WrapUnique(capabilities); return base::WrapUnique(capabilities);
} }
...@@ -80,8 +77,8 @@ scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() { ...@@ -80,8 +77,8 @@ scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() {
} }
scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData( scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData(
std::unique_ptr<const base::DictionaryValue> dictionary) { base::Value dictionary) {
DCHECK(dictionary.get()); DCHECK(dictionary.is_dict());
return base::WrapRefCounted(new Data(std::move(dictionary))); return base::WrapRefCounted(new Data(std::move(dictionary)));
} }
...@@ -92,25 +89,24 @@ DeviceCapabilities::Validator::Validator(DeviceCapabilities* capabilities) ...@@ -92,25 +89,24 @@ DeviceCapabilities::Validator::Validator(DeviceCapabilities* capabilities)
void DeviceCapabilities::Validator::SetPublicValidatedValue( void DeviceCapabilities::Validator::SetPublicValidatedValue(
const std::string& path, const std::string& path,
std::unique_ptr<base::Value> new_value) const { base::Value new_value) const {
capabilities_->SetPublicValidatedValue(path, std::move(new_value)); capabilities_->SetPublicValidatedValue(path, std::move(new_value));
} }
void DeviceCapabilities::Validator::SetPrivateValidatedValue( void DeviceCapabilities::Validator::SetPrivateValidatedValue(
const std::string& path, const std::string& path,
std::unique_ptr<base::Value> new_value) const { base::Value new_value) const {
capabilities_->SetPrivateValidatedValue(path, std::move(new_value)); capabilities_->SetPrivateValidatedValue(path, std::move(new_value));
} }
DeviceCapabilities::Data::Data() DeviceCapabilities::Data::Data() : dictionary_(base::Value::Type::DICTIONARY) {
: dictionary_(new base::DictionaryValue), base::JSONWriter::Write(dictionary_, &json_string_);
json_string_(*SerializeToJson(*dictionary_)) {} }
DeviceCapabilities::Data::Data( DeviceCapabilities::Data::Data(base::Value dictionary)
std::unique_ptr<const base::DictionaryValue> dictionary) : dictionary_(std::move(dictionary)) {
: dictionary_(std::move(dictionary)), DCHECK(dictionary_.is_dict());
json_string_(*SerializeToJson(*dictionary_)) { base::JSONWriter::Write(dictionary_, &json_string_);
DCHECK(dictionary_.get());
} }
DeviceCapabilitiesImpl::Data::~Data() {} DeviceCapabilitiesImpl::Data::~Data() {}
...@@ -129,7 +125,7 @@ DeviceCapabilitiesImpl::ValidatorInfo::~ValidatorInfo() { ...@@ -129,7 +125,7 @@ DeviceCapabilitiesImpl::ValidatorInfo::~ValidatorInfo() {
void DeviceCapabilitiesImpl::ValidatorInfo::Validate( void DeviceCapabilitiesImpl::ValidatorInfo::Validate(
const std::string& path, const std::string& path,
std::unique_ptr<base::Value> proposed_value) const { base::Value proposed_value) const {
// Check that we are running Validate on the same thread that ValidatorInfo // Check that we are running Validate on the same thread that ValidatorInfo
// was constructed on. // was constructed on.
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
...@@ -195,46 +191,41 @@ DeviceCapabilities::Validator* DeviceCapabilitiesImpl::GetValidator( ...@@ -195,46 +191,41 @@ DeviceCapabilities::Validator* DeviceCapabilitiesImpl::GetValidator(
bool DeviceCapabilitiesImpl::BluetoothSupported() const { bool DeviceCapabilitiesImpl::BluetoothSupported() const {
scoped_refptr<Data> data_ref = GetAllData(); scoped_refptr<Data> data_ref = GetAllData();
bool bluetooth_supported = false; auto bluetooth_supported =
bool found_key = data_ref->dictionary().GetBoolean(kKeyBluetoothSupported, data_ref->dictionary().FindBoolKey(kKeyBluetoothSupported);
&bluetooth_supported); DCHECK(bluetooth_supported);
DCHECK(found_key); return *bluetooth_supported;
return bluetooth_supported;
} }
bool DeviceCapabilitiesImpl::DisplaySupported() const { bool DeviceCapabilitiesImpl::DisplaySupported() const {
scoped_refptr<Data> data_ref = GetAllData(); scoped_refptr<Data> data_ref = GetAllData();
bool display_supported = false; auto display_supported =
bool found_key = data_ref->dictionary().GetBoolean(kKeyDisplaySupported, data_ref->dictionary().FindBoolKey(kKeyDisplaySupported);
&display_supported); DCHECK(display_supported);
DCHECK(found_key); return *display_supported;
return display_supported;
} }
bool DeviceCapabilitiesImpl::HiResAudioSupported() const { bool DeviceCapabilitiesImpl::HiResAudioSupported() const {
scoped_refptr<Data> data_ref = GetAllData(); scoped_refptr<Data> data_ref = GetAllData();
bool hi_res_audio_supported = false; auto hi_res_audio_supported =
bool found_key = data_ref->dictionary().GetBoolean(kKeyHiResAudioSupported, data_ref->dictionary().FindBoolKey(kKeyHiResAudioSupported);
&hi_res_audio_supported); DCHECK(hi_res_audio_supported);
DCHECK(found_key); return *hi_res_audio_supported;
return hi_res_audio_supported;
} }
bool DeviceCapabilitiesImpl::AssistantSupported() const { bool DeviceCapabilitiesImpl::AssistantSupported() const {
scoped_refptr<Data> data_ref = GetAllData(); scoped_refptr<Data> data_ref = GetAllData();
bool assistant_supported = false; auto assistant_supported =
bool found_key = data_ref->dictionary().GetBoolean(kKeyAssistantSupported, data_ref->dictionary().FindBoolKey(kKeyAssistantSupported);
&assistant_supported); DCHECK(assistant_supported);
DCHECK(found_key); return *assistant_supported;
return assistant_supported;
} }
std::unique_ptr<base::Value> DeviceCapabilitiesImpl::GetCapability( base::Value DeviceCapabilitiesImpl::GetCapability(
const std::string& path) const { const std::string& path) const {
scoped_refptr<Data> data_ref = GetAllData(); scoped_refptr<Data> data_ref = GetAllData();
const base::Value* value = nullptr; const base::Value* value = data_ref->dictionary().FindPath(path);
bool found_path = data_ref->dictionary().Get(path, &value); return value ? value->Clone() : base::Value();
return found_path ? value->CreateDeepCopy() : std::unique_ptr<base::Value>();
} }
scoped_refptr<DeviceCapabilities::Data> DeviceCapabilitiesImpl::GetAllData() scoped_refptr<DeviceCapabilities::Data> DeviceCapabilitiesImpl::GetAllData()
...@@ -255,10 +246,8 @@ scoped_refptr<DeviceCapabilities::Data> DeviceCapabilitiesImpl::GetPublicData() ...@@ -255,10 +246,8 @@ scoped_refptr<DeviceCapabilities::Data> DeviceCapabilitiesImpl::GetPublicData()
return public_data_; return public_data_;
} }
void DeviceCapabilitiesImpl::SetCapability( void DeviceCapabilitiesImpl::SetCapability(const std::string& path,
const std::string& path, base::Value proposed_value) {
std::unique_ptr<base::Value> proposed_value) {
DCHECK(proposed_value.get());
if (!IsValidPath(path)) { if (!IsValidPath(path)) {
LOG(DFATAL) << "Invalid capability path encountered for SetCapability()"; LOG(DFATAL) << "Invalid capability path encountered for SetCapability()";
return; return;
...@@ -290,11 +279,10 @@ void DeviceCapabilitiesImpl::SetCapability( ...@@ -290,11 +279,10 @@ void DeviceCapabilitiesImpl::SetCapability(
SetPublicValidatedValue(path, std::move(proposed_value)); SetPublicValidatedValue(path, std::move(proposed_value));
} }
void DeviceCapabilitiesImpl::MergeDictionary( void DeviceCapabilitiesImpl::MergeDictionary(const base::Value& dict_value) {
const base::DictionaryValue& dict_value) { DCHECK(dict_value.is_dict());
for (base::DictionaryValue::Iterator it(dict_value); !it.IsAtEnd(); for (const auto& kv : dict_value.DictItems()) {
it.Advance()) { SetCapability(kv.first, kv.second.Clone());
SetCapability(it.key(), it.value().CreateDeepCopy());
} }
} }
...@@ -308,9 +296,8 @@ void DeviceCapabilitiesImpl::RemoveCapabilitiesObserver(Observer* observer) { ...@@ -308,9 +296,8 @@ void DeviceCapabilitiesImpl::RemoveCapabilitiesObserver(Observer* observer) {
observer_list_->RemoveObserver(observer); observer_list_->RemoveObserver(observer);
} }
void DeviceCapabilitiesImpl::SetPublicValidatedValue( void DeviceCapabilitiesImpl::SetPublicValidatedValue(const std::string& path,
const std::string& path, base::Value new_value) {
std::unique_ptr<base::Value> new_value) {
// All internal writes/modifications of capabilities must occur on same // All internal writes/modifications of capabilities must occur on same
// thread to avoid race conditions. // thread to avoid race conditions.
if (!task_runner_for_writes_->BelongsToCurrentThread()) { if (!task_runner_for_writes_->BelongsToCurrentThread()) {
...@@ -322,13 +309,12 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue( ...@@ -322,13 +309,12 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue(
} }
DCHECK(IsValidPath(path)); DCHECK(IsValidPath(path));
DCHECK(new_value.get());
// If the capability exists, it must be public (present in all_data_ and // If the capability exists, it must be public (present in all_data_ and
// public_data_). We cannot change the privacy of an already existing // public_data_). We cannot change the privacy of an already existing
// capability. // capability.
bool is_private = all_data_->dictionary().HasKey(path) && bool is_private = all_data_->dictionary().FindKey(path) &&
!public_data_->dictionary().HasKey(path); !public_data_->dictionary().FindKey(path);
if (is_private) { if (is_private) {
NOTREACHED() << "Cannot make a private capability '" << path << "' public."; NOTREACHED() << "Cannot make a private capability '" << path << "' public.";
return; return;
...@@ -337,10 +323,8 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue( ...@@ -337,10 +323,8 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue(
// We don't need to acquire lock here when reading public_data_ because we // We don't need to acquire lock here when reading public_data_ because we
// know that all writes to public_data_ must occur serially on thread that // know that all writes to public_data_ must occur serially on thread that
// we're on. // we're on.
const base::Value* cur_value = nullptr; const base::Value* cur_value = public_data_->dictionary().FindPath(path);
bool capability_unchanged = bool capability_unchanged = cur_value && *cur_value == new_value;
public_data_->dictionary().Get(path, &cur_value) &&
cur_value->Equals(new_value.get());
if (capability_unchanged) { if (capability_unchanged) {
DVLOG(1) << "Ignoring unchanged public capability: " << path; DVLOG(1) << "Ignoring unchanged public capability: " << path;
return; return;
...@@ -352,7 +336,7 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue( ...@@ -352,7 +336,7 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue(
// dictionary directly, there may be expensive writes that block other // dictionary directly, there may be expensive writes that block other
// threads. // threads.
scoped_refptr<Data> new_public_data = GenerateDataWithNewValue( scoped_refptr<Data> new_public_data = GenerateDataWithNewValue(
public_data_->dictionary(), path, new_value->CreateDeepCopy()); public_data_->dictionary(), path, new_value.Clone());
scoped_refptr<Data> new_data = GenerateDataWithNewValue( scoped_refptr<Data> new_data = GenerateDataWithNewValue(
all_data_->dictionary(), path, std::move(new_value)); all_data_->dictionary(), path, std::move(new_value));
...@@ -371,9 +355,8 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue( ...@@ -371,9 +355,8 @@ void DeviceCapabilitiesImpl::SetPublicValidatedValue(
observer_list_->Notify(FROM_HERE, &Observer::OnCapabilitiesChanged, path); observer_list_->Notify(FROM_HERE, &Observer::OnCapabilitiesChanged, path);
} }
void DeviceCapabilitiesImpl::SetPrivateValidatedValue( void DeviceCapabilitiesImpl::SetPrivateValidatedValue(const std::string& path,
const std::string& path, base::Value new_value) {
std::unique_ptr<base::Value> new_value) {
// All internal writes/modifications of capabilities must occur on same // All internal writes/modifications of capabilities must occur on same
// thread to avoid race conditions. // thread to avoid race conditions.
if (!task_runner_for_writes_->BelongsToCurrentThread()) { if (!task_runner_for_writes_->BelongsToCurrentThread()) {
...@@ -385,11 +368,10 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue( ...@@ -385,11 +368,10 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue(
} }
DCHECK(IsValidPath(path)); DCHECK(IsValidPath(path));
DCHECK(new_value.get());
// If the capability exists, it must be private (present in all_data_ only). // If the capability exists, it must be private (present in all_data_ only).
// We cannot change the privacy of an already existing capability. // We cannot change the privacy of an already existing capability.
bool is_public = public_data_->dictionary().HasKey(path); const auto* is_public = public_data_->dictionary().FindKey(path);
if (is_public) { if (is_public) {
NOTREACHED() << "Cannot make a public capability '" << path << "' private."; NOTREACHED() << "Cannot make a public capability '" << path << "' private.";
return; return;
...@@ -397,9 +379,8 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue( ...@@ -397,9 +379,8 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue(
// We don't need to acquire lock here when reading all_data_ because we know // We don't need to acquire lock here when reading all_data_ because we know
// that all writes to all_data_ must occur serially on thread that we're on. // that all writes to all_data_ must occur serially on thread that we're on.
const base::Value* cur_value = nullptr; const base::Value* cur_value = all_data_->dictionary().FindPath(path);
bool capability_unchanged = all_data_->dictionary().Get(path, &cur_value) && bool capability_unchanged = cur_value && *cur_value == new_value;
cur_value->Equals(new_value.get());
if (capability_unchanged) { if (capability_unchanged) {
DVLOG(1) << "Ignoring unchanged capability: " << path; DVLOG(1) << "Ignoring unchanged capability: " << path;
return; return;
...@@ -428,12 +409,11 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue( ...@@ -428,12 +409,11 @@ void DeviceCapabilitiesImpl::SetPrivateValidatedValue(
} }
scoped_refptr<DeviceCapabilities::Data> scoped_refptr<DeviceCapabilities::Data>
DeviceCapabilitiesImpl::GenerateDataWithNewValue( DeviceCapabilitiesImpl::GenerateDataWithNewValue(const base::Value& dict,
const base::DictionaryValue& dict,
const std::string& path, const std::string& path,
std::unique_ptr<base::Value> new_value) { base::Value new_value) {
std::unique_ptr<base::DictionaryValue> dict_deep_copy(dict.CreateDeepCopy()); base::Value dict_deep_copy(dict.Clone());
dict_deep_copy->Set(path, std::move(new_value)); dict_deep_copy.SetPath(path, std::move(new_value));
return CreateData(std::move(dict_deep_copy)); return CreateData(std::move(dict_deep_copy));
} }
......
...@@ -33,13 +33,12 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities { ...@@ -33,13 +33,12 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
bool BluetoothSupported() const override; bool BluetoothSupported() const override;
bool DisplaySupported() const override; bool DisplaySupported() const override;
bool HiResAudioSupported() const override; bool HiResAudioSupported() const override;
std::unique_ptr<base::Value> GetCapability( base::Value GetCapability(const std::string& path) const override;
const std::string& path) const override;
scoped_refptr<Data> GetAllData() const override; scoped_refptr<Data> GetAllData() const override;
scoped_refptr<Data> GetPublicData() const override; scoped_refptr<Data> GetPublicData() const override;
void SetCapability(const std::string& path, void SetCapability(const std::string& path,
std::unique_ptr<base::Value> proposed_value) override; base::Value proposed_value) override;
void MergeDictionary(const base::DictionaryValue& dict_value) override; void MergeDictionary(const base::Value& dict_value) override;
void AddCapabilitiesObserver(Observer* observer) override; void AddCapabilitiesObserver(Observer* observer) override;
void RemoveCapabilitiesObserver(Observer* observer) override; void RemoveCapabilitiesObserver(Observer* observer) override;
...@@ -55,8 +54,7 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities { ...@@ -55,8 +54,7 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
return task_runner_; return task_runner_;
} }
void Validate(const std::string& path, void Validate(const std::string& path, base::Value proposed_value) const;
std::unique_ptr<base::Value> proposed_value) const;
private: private:
Validator* const validator_; Validator* const validator_;
...@@ -78,17 +76,15 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities { ...@@ -78,17 +76,15 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
DeviceCapabilitiesImpl(); DeviceCapabilitiesImpl();
void SetPublicValidatedValue(const std::string& path, void SetPublicValidatedValue(const std::string& path,
std::unique_ptr<base::Value> new_value) override; base::Value new_value) override;
void SetPrivateValidatedValue( void SetPrivateValidatedValue(const std::string& path,
const std::string& path, base::Value new_value) override;
std::unique_ptr<base::Value> new_value) override;
void SetValidatedValueInternal(const std::string& path, void SetValidatedValueInternal(const std::string& path,
std::unique_ptr<base::Value> new_value); base::Value new_value);
scoped_refptr<Data> GenerateDataWithNewValue( scoped_refptr<Data> GenerateDataWithNewValue(const base::Value& dict,
const base::DictionaryValue& dict,
const std::string& path, const std::string& path,
std::unique_ptr<base::Value> new_value); base::Value new_value);
// Lock for reading/writing all_data_ or public_data_ pointers // Lock for reading/writing all_data_ or public_data_ pointers
mutable base::Lock data_lock_; mutable base::Lock data_lock_;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
...@@ -14,7 +16,6 @@ ...@@ -14,7 +16,6 @@
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/values.h" #include "base/values.h"
#include "chromecast/base/serializers.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -28,8 +29,7 @@ const char kSampleDictionaryCapability[] = ...@@ -28,8 +29,7 @@ const char kSampleDictionaryCapability[] =
" \"dummy_field_int\": 99" " \"dummy_field_int\": 99"
"}"; "}";
void GetSampleDefaultCapability(std::string* key, void GetSampleDefaultCapability(std::string* key, base::Value* init_value);
std::unique_ptr<base::Value>* init_value);
void TestBasicOperations(DeviceCapabilities* capabilities); void TestBasicOperations(DeviceCapabilities* capabilities);
// Simple capability manager that implements the Validator interface. Either // Simple capability manager that implements the Validator interface. Either
...@@ -42,7 +42,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator { ...@@ -42,7 +42,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
// untouched. // untouched.
FakeCapabilityManagerSimple(DeviceCapabilities* capabilities, FakeCapabilityManagerSimple(DeviceCapabilities* capabilities,
const std::string& key, const std::string& key,
std::unique_ptr<base::Value> init_value, base::Value init_value,
bool accept_changes, bool accept_changes,
bool validate_private) bool validate_private)
: DeviceCapabilities::Validator(capabilities), : DeviceCapabilities::Validator(capabilities),
...@@ -50,7 +50,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator { ...@@ -50,7 +50,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
accept_changes_(accept_changes), accept_changes_(accept_changes),
validate_private_(validate_private) { validate_private_(validate_private) {
capabilities->Register(key, this); capabilities->Register(key, this);
if (init_value) { if (!init_value.is_none()) {
if (validate_private_) { if (validate_private_) {
SetPrivateValidatedValue(key, std::move(init_value)); SetPrivateValidatedValue(key, std::move(init_value));
} else { } else {
...@@ -64,8 +64,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator { ...@@ -64,8 +64,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
capabilities()->Unregister(key_, this); capabilities()->Unregister(key_, this);
} }
void Validate(const std::string& path, void Validate(const std::string& path, base::Value proposed_value) override {
std::unique_ptr<base::Value> proposed_value) override {
ASSERT_EQ(path.find(key_), 0ul); ASSERT_EQ(path.find(key_), 0ul);
if (!accept_changes_) if (!accept_changes_)
return; return;
...@@ -98,8 +97,7 @@ class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator { ...@@ -98,8 +97,7 @@ class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator {
} }
// Runs TestBasicOperations(). // Runs TestBasicOperations().
void Validate(const std::string& path, void Validate(const std::string& path, base::Value proposed_value) override {
std::unique_ptr<base::Value> proposed_value) override {
TestBasicOperations(capabilities()); TestBasicOperations(capabilities());
} }
...@@ -150,36 +148,34 @@ class MockCapabilitiesObserver : public DeviceCapabilities::Observer { ...@@ -150,36 +148,34 @@ class MockCapabilitiesObserver : public DeviceCapabilities::Observer {
// Test fixtures needs an example default capability to test DeviceCapabilities // Test fixtures needs an example default capability to test DeviceCapabilities
// methods. Gets a sample key and initial value. // methods. Gets a sample key and initial value.
void GetSampleDefaultCapability(std::string* key, void GetSampleDefaultCapability(std::string* key, base::Value* init_value) {
std::unique_ptr<base::Value>* init_value) {
DCHECK(key); DCHECK(key);
DCHECK(init_value); DCHECK(init_value);
*key = DeviceCapabilities::kKeyBluetoothSupported; *key = DeviceCapabilities::kKeyBluetoothSupported;
*init_value = std::make_unique<base::Value>(true); *init_value = base::Value(true);
} }
// For test fixtures that test dynamic capabilities, gets a sample key // For test fixtures that test dynamic capabilities, gets a sample key
// and initial value. // and initial value.
void GetSampleDynamicCapability(std::string* key, void GetSampleDynamicCapability(std::string* key, base::Value* init_value) {
std::unique_ptr<base::Value>* init_value) {
DCHECK(key); DCHECK(key);
DCHECK(init_value); DCHECK(init_value);
*key = "dummy_dynamic_key"; *key = "dummy_dynamic_key";
*init_value = std::make_unique<base::Value>(99); *init_value = base::Value(99);
} }
// Gets a value for sample default capability different from |init_value| // Gets a value for sample default capability different from |init_value|
// returned in GetSampleDefaultCapability(). Must be of same type as // returned in GetSampleDefaultCapability(). Must be of same type as
// |init_value| of course. // |init_value| of course.
std::unique_ptr<base::Value> GetSampleDefaultCapabilityNewValue() { base::Value GetSampleDefaultCapabilityNewValue() {
return std::make_unique<base::Value>(false); return base::Value(false);
} }
// Gets a value for sample dynamic capability different from |init_value| // Gets a value for sample dynamic capability different from |init_value|
// returned in GetSampleDynamicCapability(). Must be of same type as // returned in GetSampleDynamicCapability(). Must be of same type as
// |init_value| of course. // |init_value| of course.
std::unique_ptr<base::Value> GetSampleDynamicCapabilityNewValue() { base::Value GetSampleDynamicCapabilityNewValue() {
return std::make_unique<base::Value>(100); return base::Value(100);
} }
// Tests that |json| string matches contents of a DictionaryValue with one entry // Tests that |json| string matches contents of a DictionaryValue with one entry
...@@ -187,10 +183,10 @@ std::unique_ptr<base::Value> GetSampleDynamicCapabilityNewValue() { ...@@ -187,10 +183,10 @@ std::unique_ptr<base::Value> GetSampleDynamicCapabilityNewValue() {
bool JsonStringEquals(const std::string& json, bool JsonStringEquals(const std::string& json,
const std::string& key, const std::string& key,
const base::Value& value) { const base::Value& value) {
base::DictionaryValue dict_value; base::Value dict_value(base::Value::Type::DICTIONARY);
dict_value.Set(key, value.CreateDeepCopy()); dict_value.SetKey(key, value.Clone());
base::Optional<std::string> dict_json = SerializeToJson(dict_value); std::string dict_json;
return dict_json && *dict_json == json; return base::JSONWriter::Write(dict_value, &dict_json) && dict_json == json;
} }
// The function runs through the set of basic operations of DeviceCapabilities. // The function runs through the set of basic operations of DeviceCapabilities.
...@@ -201,25 +197,25 @@ bool JsonStringEquals(const std::string& json, ...@@ -201,25 +197,25 @@ bool JsonStringEquals(const std::string& json,
// class before this function is called. // class before this function is called.
void TestBasicOperations(DeviceCapabilities* capabilities) { void TestBasicOperations(DeviceCapabilities* capabilities) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
ASSERT_FALSE(capabilities->GetCapability(key)); ASSERT_TRUE(capabilities->GetCapability(key).is_none());
ASSERT_FALSE(capabilities->GetValidator(key)); ASSERT_FALSE(capabilities->GetValidator(key));
// Register and write capability // Register and write capability
FakeCapabilityManagerSimple* manager(new FakeCapabilityManagerSimple( FakeCapabilityManagerSimple* manager(new FakeCapabilityManagerSimple(
capabilities, key, init_value->CreateDeepCopy(), true, false)); capabilities, key, init_value.Clone(), true, false));
// Read Validator // Read Validator
EXPECT_EQ(capabilities->GetValidator(key), manager); EXPECT_EQ(capabilities->GetValidator(key), manager);
// Read Capability // Read Capability
EXPECT_EQ(*capabilities->GetCapability(key), *init_value); EXPECT_EQ(capabilities->GetCapability(key), init_value);
// Unregister // Unregister
delete manager; delete manager;
// Write capability again. Provides way of checking that this function // Write capability again. Provides way of checking that this function
// ran and was successful. // ran and was successful.
std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); base::Value new_value = GetSampleDefaultCapabilityNewValue();
capabilities->SetCapability(key, std::move(new_value)); capabilities->SetCapability(key, std::move(new_value));
} }
...@@ -227,12 +223,11 @@ void TestBasicOperations(DeviceCapabilities* capabilities) { ...@@ -227,12 +223,11 @@ void TestBasicOperations(DeviceCapabilities* capabilities) {
void AssertBasicOperationsSuccessful(const DeviceCapabilities* capabilities) { void AssertBasicOperationsSuccessful(const DeviceCapabilities* capabilities) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
std::unique_ptr<base::Value> value = capabilities->GetCapability(key); base::Value value = capabilities->GetCapability(key);
ASSERT_TRUE(value); base::Value new_value = GetSampleDefaultCapabilityNewValue();
std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); EXPECT_EQ(value, new_value);
EXPECT_EQ(*value, *new_value);
} }
} // namespace } // namespace
...@@ -273,83 +268,89 @@ class DeviceCapabilitiesImplTest : public ::testing::Test { ...@@ -273,83 +268,89 @@ class DeviceCapabilitiesImplTest : public ::testing::Test {
// Tests that class is in correct state after Create(). // Tests that class is in correct state after Create().
TEST_F(DeviceCapabilitiesImplTest, Create) { TEST_F(DeviceCapabilitiesImplTest, Create) {
std::string empty_dict_string = *SerializeToJson(base::DictionaryValue()); std::string empty_dict_string;
base::JSONWriter::Write(base::Value(base::Value::Type::DICTIONARY),
&empty_dict_string);
EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string); EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
EXPECT_TRUE(capabilities()->GetAllData()->dictionary().empty()); EXPECT_TRUE(capabilities()->GetAllData()->dictionary().DictEmpty());
} }
// Tests Register() of a default capability. // Tests Register() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Register) { TEST_F(DeviceCapabilitiesImplTest, Register) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
FakeCapabilityManagerSimple manager(capabilities(), key, nullptr, true, FakeCapabilityManagerSimple manager(capabilities(), key, base::Value(), true,
false); false);
EXPECT_EQ(capabilities()->GetValidator(key), &manager); EXPECT_EQ(capabilities()->GetValidator(key), &manager);
std::string empty_dict_string = *SerializeToJson(base::DictionaryValue()); std::string empty_dict_string;
base::JSONWriter::Write(base::Value(base::Value::Type::DICTIONARY),
&empty_dict_string);
EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string); EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
EXPECT_FALSE(capabilities()->GetCapability(key)); EXPECT_TRUE(capabilities()->GetCapability(key).is_none());
} }
// Tests Unregister() of a default capability. // Tests Unregister() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Unregister) { TEST_F(DeviceCapabilitiesImplTest, Unregister) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
FakeCapabilityManagerSimple* manager = new FakeCapabilityManagerSimple( FakeCapabilityManagerSimple* manager = new FakeCapabilityManagerSimple(
capabilities(), key, nullptr, true, false); capabilities(), key, base::Value(), true, false);
delete manager; delete manager;
EXPECT_FALSE(capabilities()->GetValidator(key)); EXPECT_FALSE(capabilities()->GetValidator(key));
std::string empty_dict_string = *SerializeToJson(base::DictionaryValue()); std::string empty_dict_string;
base::JSONWriter::Write(base::Value(base::Value::Type::DICTIONARY),
&empty_dict_string);
EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string); EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
EXPECT_FALSE(capabilities()->GetCapability(key)); EXPECT_TRUE(capabilities()->GetCapability(key).is_none());
} }
// Tests GetCapability() and updating the value through SetCapability(). // Tests GetCapability() and updating the value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) { TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Clone(),
capabilities(), key, init_value->CreateDeepCopy(), true, false); true, false);
EXPECT_EQ(*capabilities()->GetCapability(key), *init_value); EXPECT_EQ(capabilities()->GetCapability(key), init_value);
std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); base::Value new_value = GetSampleDefaultCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy()); capabilities()->SetCapability(key, new_value.Clone());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(*capabilities()->GetCapability(key), *new_value); EXPECT_EQ(capabilities()->GetCapability(key), new_value);
} }
// Tests BluetoothSupported() and updating this value through SetCapability(). // Tests BluetoothSupported() and updating this value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) { TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) {
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyBluetoothSupported, capabilities(), DeviceCapabilities::kKeyBluetoothSupported,
base::WrapUnique(new base::Value(true)), true, false); base::Value(true), true, false);
EXPECT_TRUE(capabilities()->BluetoothSupported()); EXPECT_TRUE(capabilities()->BluetoothSupported());
capabilities()->SetCapability(DeviceCapabilities::kKeyBluetoothSupported, capabilities()->SetCapability(DeviceCapabilities::kKeyBluetoothSupported,
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->BluetoothSupported()); EXPECT_FALSE(capabilities()->BluetoothSupported());
} }
// Tests DisplaySupported() and updating this value through SetCapability(). // Tests DisplaySupported() and updating this value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) { TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) {
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(capabilities(),
capabilities(), DeviceCapabilities::kKeyDisplaySupported, DeviceCapabilities::kKeyDisplaySupported,
base::WrapUnique(new base::Value(true)), true, false); base::Value(true), true, false);
EXPECT_TRUE(capabilities()->DisplaySupported()); EXPECT_TRUE(capabilities()->DisplaySupported());
capabilities()->SetCapability(DeviceCapabilities::kKeyDisplaySupported, capabilities()->SetCapability(DeviceCapabilities::kKeyDisplaySupported,
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->DisplaySupported()); EXPECT_FALSE(capabilities()->DisplaySupported());
} }
...@@ -358,11 +359,11 @@ TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) { ...@@ -358,11 +359,11 @@ TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) {
TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) { TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) {
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyHiResAudioSupported, capabilities(), DeviceCapabilities::kKeyHiResAudioSupported,
base::WrapUnique(new base::Value(true)), true, false); base::Value(true), true, false);
EXPECT_TRUE(capabilities()->HiResAudioSupported()); EXPECT_TRUE(capabilities()->HiResAudioSupported());
capabilities()->SetCapability(DeviceCapabilities::kKeyHiResAudioSupported, capabilities()->SetCapability(DeviceCapabilities::kKeyHiResAudioSupported,
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->HiResAudioSupported()); EXPECT_FALSE(capabilities()->HiResAudioSupported());
} }
...@@ -371,11 +372,11 @@ TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) { ...@@ -371,11 +372,11 @@ TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) {
TEST_F(DeviceCapabilitiesImplTest, AssistantSupportedAndSetCapability) { TEST_F(DeviceCapabilitiesImplTest, AssistantSupportedAndSetCapability) {
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyAssistantSupported, capabilities(), DeviceCapabilities::kKeyAssistantSupported,
base::WrapUnique(new base::Value(true)), true, false); base::Value(true), true, false);
EXPECT_TRUE(capabilities()->AssistantSupported()); EXPECT_TRUE(capabilities()->AssistantSupported());
capabilities()->SetCapability(DeviceCapabilities::kKeyAssistantSupported, capabilities()->SetCapability(DeviceCapabilities::kKeyAssistantSupported,
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->AssistantSupported()); EXPECT_FALSE(capabilities()->AssistantSupported());
} }
...@@ -384,97 +385,95 @@ TEST_F(DeviceCapabilitiesImplTest, AssistantSupportedAndSetCapability) { ...@@ -384,97 +385,95 @@ TEST_F(DeviceCapabilitiesImplTest, AssistantSupportedAndSetCapability) {
// rejects the proposed change. // rejects the proposed change.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Clone(),
capabilities(), key, init_value->CreateDeepCopy(), false, false); false, false);
capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(*capabilities()->GetCapability(key), *init_value); EXPECT_EQ(capabilities()->GetCapability(key), init_value);
} }
// Test that SetCapability() updates the capabilities string correctly // Test that SetCapability() updates the capabilities string correctly
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Clone(),
capabilities(), key, init_value->CreateDeepCopy(), true, false); true, false);
EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key, EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
*init_value)); init_value));
std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); base::Value new_value = GetSampleDefaultCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy()); capabilities()->SetCapability(key, new_value.Clone());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key, EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
*new_value)); new_value));
} }
// Tests that GetPublicData() does not include private capabilities // Tests that GetPublicData() does not include private capabilities
TEST_F(DeviceCapabilitiesImplTest, SetPublicPrivateCapabilities) { TEST_F(DeviceCapabilitiesImplTest, SetPublicPrivateCapabilities) {
std::string key_private = "private"; std::string key_private = "private";
std::string key_public = "public"; std::string key_public = "public";
std::unique_ptr<base::Value> init_value(new base::Value(true)); base::Value init_value(true);
// Dictionary of only public values. // Dictionary of only public values.
base::DictionaryValue public_dict; base::Value public_dict(base::Value::Type::DICTIONARY);
public_dict.Set(key_public, init_value->CreateDeepCopy()); public_dict.SetKey(key_public, init_value.Clone());
// Dictionary of public and private values. // Dictionary of public and private values.
base::DictionaryValue full_dict; base::Value full_dict(base::Value::Type::DICTIONARY);
full_dict.Set(key_public, init_value->CreateDeepCopy()); full_dict.SetKey(key_public, init_value.Clone());
full_dict.Set(key_private, init_value->CreateDeepCopy()); full_dict.SetKey(key_private, init_value.Clone());
FakeCapabilityManagerSimple public_manager( FakeCapabilityManagerSimple public_manager(capabilities(), key_public,
capabilities(), key_public, init_value->CreateDeepCopy(), true, false); init_value.Clone(), true, false);
FakeCapabilityManagerSimple private_manager( FakeCapabilityManagerSimple private_manager(capabilities(), key_private,
capabilities(), key_private, init_value->CreateDeepCopy(), true, true); init_value.Clone(), true, true);
EXPECT_TRUE(capabilities()->GetAllData()->dictionary().Equals(&full_dict)); EXPECT_EQ(capabilities()->GetAllData()->dictionary(), full_dict);
EXPECT_TRUE( EXPECT_EQ(capabilities()->GetPublicData()->dictionary(), public_dict);
capabilities()->GetPublicData()->dictionary().Equals(&public_dict));
} }
// Tests that SetCapability() defaults to making a capability public // Tests that SetCapability() defaults to making a capability public
TEST_F(DeviceCapabilitiesImplTest, NoValidatorDefaultsToPublicCapability) { TEST_F(DeviceCapabilitiesImplTest, NoValidatorDefaultsToPublicCapability) {
std::string key_private = "private"; std::string key_private = "private";
std::string key_public = "public"; std::string key_public = "public";
std::unique_ptr<base::Value> init_value(new base::Value(true)); base::Value init_value(true);
// Dictionary of only public values. // Dictionary of only public values.
base::DictionaryValue public_dict; base::Value public_dict(base::Value::Type::DICTIONARY);
public_dict.Set(key_public, init_value->CreateDeepCopy()); public_dict.SetKey(key_public, init_value.Clone());
// Dictionary of public and private values. // Dictionary of public and private values.
base::DictionaryValue full_dict; base::Value full_dict(base::Value::Type::DICTIONARY);
full_dict.Set(key_public, init_value->CreateDeepCopy()); full_dict.SetKey(key_public, init_value.Clone());
full_dict.Set(key_private, init_value->CreateDeepCopy()); full_dict.SetKey(key_private, init_value.Clone());
// We will not create a validator for the public capability; instead we will // We will not create a validator for the public capability; instead we will
// set the capability directly. It will be registered as a public capability. // set the capability directly. It will be registered as a public capability.
capabilities()->SetCapability(key_public, init_value->CreateDeepCopy()); capabilities()->SetCapability(key_public, init_value.Clone());
FakeCapabilityManagerSimple private_manager( FakeCapabilityManagerSimple private_manager(capabilities(), key_private,
capabilities(), key_private, init_value->CreateDeepCopy(), true, true); init_value.Clone(), true, true);
EXPECT_TRUE(capabilities()->GetAllData()->dictionary().Equals(&full_dict)); EXPECT_EQ(capabilities()->GetAllData()->dictionary(), full_dict);
EXPECT_TRUE( EXPECT_EQ(capabilities()->GetPublicData()->dictionary(), public_dict);
capabilities()->GetPublicData()->dictionary().Equals(&public_dict));
} }
// Test that SetCapability() notifies Observers when the capability's value // Test that SetCapability() notifies Observers when the capability's value
// changes // changes
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3); EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3);
// 1st call (register) // 1st call (register)
FakeCapabilityManagerSimple manager( FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Clone(),
capabilities(), key, init_value->CreateDeepCopy(), true, false); true, false);
// 2nd call // 2nd call
capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());
...@@ -491,15 +490,15 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) { ...@@ -491,15 +490,15 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) {
// value changes // value changes
TEST_F(DeviceCapabilitiesImplTest, SetPrivateCapabilityNotifiesObservers) { TEST_F(DeviceCapabilitiesImplTest, SetPrivateCapabilityNotifiesObservers) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDefaultCapability(&key, &init_value); GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3); EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3);
// 1st call (register), this manager validates and sets the capability // 1st call (register), this manager validates and sets the capability
// privately. // privately.
FakeCapabilityManagerSimple manager(capabilities(), key, FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Clone(),
init_value->CreateDeepCopy(), true, true); true, true);
// 2nd call // 2nd call
capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());
...@@ -515,129 +514,108 @@ TEST_F(DeviceCapabilitiesImplTest, SetPrivateCapabilityNotifiesObservers) { ...@@ -515,129 +514,108 @@ TEST_F(DeviceCapabilitiesImplTest, SetPrivateCapabilityNotifiesObservers) {
// Test adding dynamic capabilities // Test adding dynamic capabilities
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) {
std::string key; std::string key;
std::unique_ptr<base::Value> init_value; base::Value init_value;
GetSampleDynamicCapability(&key, &init_value); GetSampleDynamicCapability(&key, &init_value);
ASSERT_FALSE(capabilities()->GetCapability(key)); ASSERT_TRUE(capabilities()->GetCapability(key).is_none());
capabilities()->SetCapability(key, init_value->CreateDeepCopy()); capabilities()->SetCapability(key, init_value.Clone());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(*capabilities()->GetCapability(key), *init_value); EXPECT_EQ(capabilities()->GetCapability(key), init_value);
EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key, EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
*init_value)); init_value));
std::unique_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue(); base::Value new_value = GetSampleDynamicCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy()); capabilities()->SetCapability(key, new_value.Clone());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(*capabilities()->GetCapability(key), *new_value); EXPECT_EQ(capabilities()->GetCapability(key), new_value);
EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key, EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
*new_value)); new_value));
} }
// Tests that SetCapability() works with expanded paths when there is a // Tests that SetCapability() works with expanded paths when there is a
// capability of type DictionaryValue. // capability of type DictionaryValue.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
std::string key("dummy_dictionary_key"); std::string key("dummy_dictionary_key");
std::unique_ptr<base::Value> init_value = auto init_value = base::JSONReader::Read(kSampleDictionaryCapability);
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(init_value); ASSERT_TRUE(init_value);
FakeCapabilityManagerSimple manager(capabilities(), key, FakeCapabilityManagerSimple manager(capabilities(), key,
std::move(init_value), true, false); std::move(*init_value), true, false);
capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool", capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool",
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
bool value_bool = true; base::Value value =
std::unique_ptr<base::Value> value =
capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool"); capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_bool());
EXPECT_TRUE(value->GetAsBoolean(&value_bool)); EXPECT_FALSE(value.GetBool());
EXPECT_FALSE(value_bool);
capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int", capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int",
base::WrapUnique(new base::Value(100))); base::Value(100));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
int value_int = 0;
value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int"); value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_int());
EXPECT_TRUE(value->GetAsInteger(&value_int)); EXPECT_EQ(value.GetInt(), 100);
EXPECT_EQ(value_int, 100);
} }
// Tests that SetCapability() works with expanded paths when there is a // Tests that SetCapability() works with expanded paths when there is a
// capability of type DictionaryValue and invalid changes are proposed. // capability of type DictionaryValue and invalid changes are proposed.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) { TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
std::string key("dummy_dictionary_key"); std::string key("dummy_dictionary_key");
std::unique_ptr<base::Value> init_value = auto init_value = base::JSONReader::Read(kSampleDictionaryCapability);
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(init_value); ASSERT_TRUE(init_value);
FakeCapabilityManagerSimple manager(capabilities(), key, FakeCapabilityManagerSimple manager(capabilities(), key,
std::move(init_value), false, false); std::move(*init_value), false, false);
capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool", capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool",
base::WrapUnique(new base::Value(false))); base::Value(false));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
bool value_bool = false; base::Value value =
std::unique_ptr<base::Value> value =
capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool"); capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_bool());
EXPECT_TRUE(value->GetAsBoolean(&value_bool)); EXPECT_TRUE(value.GetBool());
EXPECT_TRUE(value_bool);
capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int", capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int",
base::WrapUnique(new base::Value(100))); base::Value(100));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
int value_int = 0;
value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int"); value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_int());
EXPECT_TRUE(value->GetAsInteger(&value_int)); EXPECT_EQ(value.GetInt(), 99);
EXPECT_EQ(value_int, 99);
} }
// Test MergeDictionary. // Test MergeDictionary.
TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) { TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) {
std::unique_ptr<base::Value> deserialized_value = auto deserialized_value = base::JSONReader::Read(kSampleDictionaryCapability);
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(deserialized_value); ASSERT_TRUE(deserialized_value);
base::DictionaryValue* dict_value = nullptr; ASSERT_TRUE(deserialized_value->is_dict());
ASSERT_TRUE(deserialized_value->GetAsDictionary(&dict_value));
ASSERT_TRUE(dict_value);
capabilities()->MergeDictionary(*dict_value); capabilities()->MergeDictionary(*deserialized_value);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// First make sure that capabilities get created if they do not exist // First make sure that capabilities get created if they do not exist
bool value_bool = false; base::Value value = capabilities()->GetCapability("dummy_field_bool");
std::unique_ptr<base::Value> value = ASSERT_TRUE(value.is_bool());
capabilities()->GetCapability("dummy_field_bool"); EXPECT_TRUE(value.GetBool());
ASSERT_TRUE(value);
EXPECT_TRUE(value->GetAsBoolean(&value_bool));
EXPECT_TRUE(value_bool);
int value_int = 0;
value = capabilities()->GetCapability("dummy_field_int"); value = capabilities()->GetCapability("dummy_field_int");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_int());
EXPECT_TRUE(value->GetAsInteger(&value_int)); EXPECT_EQ(value.GetInt(), 99);
EXPECT_EQ(value_int, 99);
// Now just update one of the fields. Make sure the updated value is changed // Now just update one of the fields. Make sure the updated value is changed
// in DeviceCapabilities and the other field remains untouched. // in DeviceCapabilities and the other field remains untouched.
dict_value->SetInteger("dummy_field_int", 100); deserialized_value->SetIntKey("dummy_field_int", 100);
ASSERT_TRUE(dict_value->Remove("dummy_field_bool", nullptr)); ASSERT_TRUE(deserialized_value->RemoveKey("dummy_field_bool"));
capabilities()->MergeDictionary(*dict_value); capabilities()->MergeDictionary(*deserialized_value);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
value_bool = false;
value = capabilities()->GetCapability("dummy_field_bool"); value = capabilities()->GetCapability("dummy_field_bool");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_bool());
EXPECT_TRUE(value->GetAsBoolean(&value_bool)); EXPECT_TRUE(value.GetBool());
EXPECT_TRUE(value_bool);
value = capabilities()->GetCapability("dummy_field_int"); value = capabilities()->GetCapability("dummy_field_int");
ASSERT_TRUE(value); ASSERT_TRUE(value.is_int());
EXPECT_TRUE(value->GetAsInteger(&value_int)); EXPECT_EQ(value.GetInt(), 100);
EXPECT_EQ(value_int, 100);
} }
// Tests that it is safe to call DeviceCapabilities methods in // Tests that it is safe to call DeviceCapabilities methods in
...@@ -647,8 +625,7 @@ TEST_F(DeviceCapabilitiesImplTest, OnCapabilitiesChangedSafe) { ...@@ -647,8 +625,7 @@ TEST_F(DeviceCapabilitiesImplTest, OnCapabilitiesChangedSafe) {
FakeCapabilitiesObserver observer(capabilities()); FakeCapabilitiesObserver observer(capabilities());
// Trigger FakeCapabilitiesObserver::OnCapabilitiesChanged() // Trigger FakeCapabilitiesObserver::OnCapabilitiesChanged()
capabilities()->SetCapability("dummy_trigger_key", capabilities()->SetCapability("dummy_trigger_key", base::Value(true));
base::WrapUnique(new base::Value(true)));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// Check that FakeCapabilitiesObserver::OnCapabilitiesChanged() ran and that // Check that FakeCapabilitiesObserver::OnCapabilitiesChanged() ran and that
...@@ -663,8 +640,7 @@ TEST_F(DeviceCapabilitiesImplTest, ValidateSafe) { ...@@ -663,8 +640,7 @@ TEST_F(DeviceCapabilitiesImplTest, ValidateSafe) {
FakeCapabilityManagerComplex manager(capabilities(), "dummy_validate_key"); FakeCapabilityManagerComplex manager(capabilities(), "dummy_validate_key");
// Trigger FakeCapabilityManagerComplex::Validate() // Trigger FakeCapabilityManagerComplex::Validate()
capabilities()->SetCapability("dummy_validate_key", capabilities()->SetCapability("dummy_validate_key", base::Value(true));
base::WrapUnique(new base::Value(true)));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// Check that FakeCapabilityManagerComplex::Validate() ran and that behavior // Check that FakeCapabilityManagerComplex::Validate() ran and that behavior
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment