summaryrefslogtreecommitdiff
path: root/chromium/chromecast/base
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-05-09 14:22:11 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-05-09 15:11:45 +0000
commit2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c (patch)
treee75f511546c5fd1a173e87c1f9fb11d7ac8d1af3 /chromium/chromecast/base
parenta4f3d46271c57e8155ba912df46a05559d14726e (diff)
downloadqtwebengine-chromium-2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c.tar.gz
BASELINE: Update Chromium to 51.0.2704.41
Also adds in all smaller components by reversing logic for exclusion. Change-Id: Ibf90b506e7da088ea2f65dcf23f2b0992c504422 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'chromium/chromecast/base')
-rw-r--r--chromium/chromecast/base/BUILD.gn117
-rw-r--r--chromium/chromecast/base/bind_to_task_runner.h7
-rw-r--r--chromium/chromecast/base/bind_to_task_runner_unittest.cc27
-rw-r--r--chromium/chromecast/base/cast_resource.cc4
-rw-r--r--chromium/chromecast/base/cast_resource.h39
-rw-r--r--chromium/chromecast/base/cast_sys_info_android.cc5
-rw-r--r--chromium/chromecast/base/cast_sys_info_util.h4
-rw-r--r--chromium/chromecast/base/cast_sys_info_util_simple.cc5
-rw-r--r--chromium/chromecast/base/chromecast_switches.cc47
-rw-r--r--chromium/chromecast/base/chromecast_switches.h23
-rw-r--r--chromium/chromecast/base/chromecast_switches_unittest.cc61
-rw-r--r--chromium/chromecast/base/component/BUILD.gn33
-rw-r--r--chromium/chromecast/base/component/component.cc425
-rw-r--r--chromium/chromecast/base/component/component.h327
-rw-r--r--chromium/chromecast/base/component/component_internal.h121
-rw-r--r--chromium/chromecast/base/component/component_unittest.cc379
-rw-r--r--chromium/chromecast/base/device_capabilities.h24
-rw-r--r--chromium/chromecast/base/device_capabilities_impl.cc36
-rw-r--r--chromium/chromecast/base/device_capabilities_impl.h13
-rw-r--r--chromium/chromecast/base/device_capabilities_impl_unittest.cc109
-rw-r--r--chromium/chromecast/base/error_codes_unittest.cc8
-rw-r--r--chromium/chromecast/base/metrics/cast_metrics_helper.cc50
-rw-r--r--chromium/chromecast/base/metrics/cast_metrics_helper.h8
-rw-r--r--chromium/chromecast/base/metrics/cast_metrics_test_helper.cc4
-rw-r--r--chromium/chromecast/base/metrics/grouped_histogram.cc6
-rw-r--r--chromium/chromecast/base/serializers.cc13
-rw-r--r--chromium/chromecast/base/serializers.h9
-rw-r--r--chromium/chromecast/base/serializers_unittest.cc32
-rw-r--r--chromium/chromecast/base/system_time_change_notifier_unittest.cc8
29 files changed, 1775 insertions, 169 deletions
diff --git a/chromium/chromecast/base/BUILD.gn b/chromium/chromecast/base/BUILD.gn
index 355c0da7fe1..c5a54457d0d 100644
--- a/chromium/chromecast/base/BUILD.gn
+++ b/chromium/chromecast/base/BUILD.gn
@@ -6,6 +6,23 @@ import("//chrome/version.gni") # TODO layering violation!
import("//chromecast/chromecast.gni")
import("//testing/test.gni")
+if (is_android) {
+ import("//build/config/android/rules.gni")
+}
+
+declare_args() {
+ # Denotes the type of Cast product. This is #defined as CAST_PRODUCT_TYPE in
+ # version.h. This is an integer in the range [0-4].
+ cast_product_type = 0
+
+ # If true, IS_CAST_DEBUG_BUILD() will evaluate to 1 in version.h. Otherwise,
+ # it will evaluate to 0. Overriding this when is_debug=false is useful for
+ # doing engineering builds.
+ cast_is_debug = is_debug
+}
+
+assert(cast_product_type >= 0 && cast_product_type <= 4)
+
# GYP target: chromecast.gyp:cast_base
source_set("base") {
sources = [
@@ -20,6 +37,8 @@ source_set("base") {
"cast_paths.h",
"cast_resource.cc",
"cast_resource.h",
+ "chromecast_config_android.cc",
+ "chromecast_config_android.h",
"chromecast_switches.cc",
"chromecast_switches.h",
"device_capabilities.h",
@@ -49,6 +68,10 @@ source_set("base") {
deps = [
"//base",
]
+
+ if (is_android) {
+ deps += [ ":jni_headers" ]
+ }
}
# GYP target: n/a
@@ -68,6 +91,7 @@ source_set("test_support") {
test("cast_base_unittests") {
sources = [
"bind_to_task_runner_unittest.cc",
+ "chromecast_switches_unittest.cc",
"device_capabilities_impl_unittest.cc",
"error_codes_unittest.cc",
"path_utils_unittest.cc",
@@ -87,38 +111,101 @@ test("cast_base_unittests") {
source_set("cast_sys_info") {
sources = [
+ "cast_sys_info_android.cc",
+ "cast_sys_info_android.h",
"cast_sys_info_dummy.cc",
"cast_sys_info_dummy.h",
"cast_sys_info_util.h",
]
- if (chromecast_branding == "public" && !is_android) {
+ deps = [
+ "//base",
+ "//chromecast/public",
+ ]
+
+ if (is_android) {
+ deps += [
+ ":cast_version",
+ "//chromecast/browser:jni_headers",
+ ]
+ } else if (chromecast_branding == "public") {
sources += [ "cast_sys_info_util_simple.cc" ]
}
+}
- # TODO(mbjorge): put cast_sys_info_android in here
+# This target runs a script which generates a file containing key-value pairs.
+# //build/util/version.py will parse this file, creating "version.h". This
+# target shall only be depended upon by ":cast_version".
+action("generate_cast_version_params") {
+ visibility = [ ":cast_version_action" ]
- deps = [
- "//base",
- "//chromecast/public",
+ script = "//chromecast/tools/build/generate_cast_version_params.py"
+
+ params_file = "$root_gen_dir/cast_version_params"
+ outputs = [
+ params_file,
+ ]
+
+ args = [
+ "-o",
+ rebase_path(params_file),
+ "-p",
+ "$cast_product_type",
]
+
+ if (cast_is_debug) {
+ args += [ "-d" ]
+ }
+
+ if (chromecast_branding != "public") {
+ args += [
+ "-r",
+ rebase_path("//chromecast/internal/build/cast_build_release"),
+ ]
+ }
}
process_version("cast_version") {
template_file = "version.h.in"
output = "$target_gen_dir/version.h"
+
+ params_file = get_target_outputs(":generate_cast_version_params")
+ deps = [
+ ":generate_cast_version_params",
+ ]
+
extra_args = [
"-e",
"VERSION_FULL=\"%s.%s.%s.%s\"%(MAJOR,MINOR,BUILD,PATCH)",
-
- # TODO(slan): Populate the fields below with real values
- "-e",
- "CAST_BUILD_INCREMENTAL=20150608.181153",
- "-e",
- "CAST_BUILD_RELEASE=1.15",
- "-e",
- "CAST_IS_DEBUG_BUILD=1",
- "-e",
- "CAST_PRODUCT_TYPE=0",
+ "-f",
+ rebase_path(params_file[0]),
]
}
+
+if (is_android) {
+ # GYP target: chromecast.gyp:jni_headers
+ generate_jni("jni_headers") {
+ sources = [
+ "java/src/org/chromium/chromecast/base/ChromecastConfigAndroid.java",
+ "java/src/org/chromium/chromecast/base/DumpstateWriter.java",
+ "java/src/org/chromium/chromecast/base/SystemTimeChangeNotifierAndroid.java",
+ ]
+
+ jni_package = "chromecast"
+ }
+
+ # GYP target: chromecast.gyp:cast_base_java
+ android_library("base_java") {
+ java_src_dir = "//chromecast/base/java/src"
+ java_files = [
+ "$java_src_dir/org/chromium/chromecast/base/CastSettingsManager.java",
+ "$java_src_dir/org/chromium/chromecast/base/ChromecastConfigAndroid.java",
+ "$java_src_dir/org/chromium/chromecast/base/DumpstateWriter.java",
+ "$java_src_dir/org/chromium/chromecast/base/SystemTimeChangeNotifierAndroid.java",
+ ]
+
+ deps = [
+ "//base:base_java",
+ ]
+ }
+}
diff --git a/chromium/chromecast/base/bind_to_task_runner.h b/chromium/chromecast/base/bind_to_task_runner.h
index 822ced7d78b..8902be261a5 100644
--- a/chromium/chromecast/base/bind_to_task_runner.h
+++ b/chromium/chromecast/base/bind_to_task_runner.h
@@ -5,12 +5,13 @@
#ifndef CHROMECAST_BASE_BIND_TO_TASK_RUNNER_H_
#define CHROMECAST_BASE_BIND_TO_TASK_RUNNER_H_
+#include <memory>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -42,8 +43,8 @@ T& TrampolineForward(T& t) {
}
template <typename T, typename R>
-base::internal::PassedWrapper<scoped_ptr<T, R>> TrampolineForward(
- scoped_ptr<T, R>& p) {
+base::internal::PassedWrapper<std::unique_ptr<T, R>> TrampolineForward(
+ std::unique_ptr<T, R>& p) {
return base::Passed(&p);
}
diff --git a/chromium/chromecast/base/bind_to_task_runner_unittest.cc b/chromium/chromecast/base/bind_to_task_runner_unittest.cc
index 240c8f961c6..b2148095147 100644
--- a/chromium/chromecast/base/bind_to_task_runner_unittest.cc
+++ b/chromium/chromecast/base/bind_to_task_runner_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/memory/free_deleter.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,17 +17,17 @@ void BoundBoolSet(bool* var, bool val) {
*var = val;
}
-void BoundBoolSetFromScopedPtr(bool* var, scoped_ptr<bool> val) {
+void BoundBoolSetFromScopedPtr(bool* var, std::unique_ptr<bool> val) {
*var = *val;
}
void BoundBoolSetFromScopedPtrFreeDeleter(
bool* var,
- scoped_ptr<bool, base::FreeDeleter> val) {
- *var = val;
+ std::unique_ptr<bool, base::FreeDeleter> val) {
+ *var = *val;
}
-void BoundBoolSetFromScopedArray(bool* var, scoped_ptr<bool[]> val) {
+void BoundBoolSetFromScopedArray(bool* var, std::unique_ptr<bool[]> val) {
*var = val[0];
}
@@ -69,7 +70,7 @@ TEST_F(BindToTaskRunnerTest, Bool) {
TEST_F(BindToTaskRunnerTest, BoundScopedPtrBool) {
bool bool_val = false;
- scoped_ptr<bool> scoped_ptr_bool(new bool(true));
+ std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
base::Closure cb = BindToCurrentThread(base::Bind(
&BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool)));
cb.Run();
@@ -80,8 +81,8 @@ TEST_F(BindToTaskRunnerTest, BoundScopedPtrBool) {
TEST_F(BindToTaskRunnerTest, PassedScopedPtrBool) {
bool bool_val = false;
- scoped_ptr<bool> scoped_ptr_bool(new bool(true));
- base::Callback<void(scoped_ptr<bool>)> cb =
+ std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
+ base::Callback<void(std::unique_ptr<bool>)> cb =
BindToCurrentThread(base::Bind(&BoundBoolSetFromScopedPtr, &bool_val));
cb.Run(std::move(scoped_ptr_bool));
EXPECT_FALSE(bool_val);
@@ -91,7 +92,7 @@ TEST_F(BindToTaskRunnerTest, PassedScopedPtrBool) {
TEST_F(BindToTaskRunnerTest, BoundScopedArrayBool) {
bool bool_val = false;
- scoped_ptr<bool[]> scoped_array_bool(new bool[1]);
+ std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
scoped_array_bool[0] = true;
base::Closure cb =
BindToCurrentThread(base::Bind(&BoundBoolSetFromScopedArray, &bool_val,
@@ -104,9 +105,9 @@ TEST_F(BindToTaskRunnerTest, BoundScopedArrayBool) {
TEST_F(BindToTaskRunnerTest, PassedScopedArrayBool) {
bool bool_val = false;
- scoped_ptr<bool[]> scoped_array_bool(new bool[1]);
+ std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
scoped_array_bool[0] = true;
- base::Callback<void(scoped_ptr<bool[]>)> cb =
+ base::Callback<void(std::unique_ptr<bool[]>)> cb =
BindToCurrentThread(base::Bind(&BoundBoolSetFromScopedArray, &bool_val));
cb.Run(std::move(scoped_array_bool));
EXPECT_FALSE(bool_val);
@@ -116,7 +117,7 @@ TEST_F(BindToTaskRunnerTest, PassedScopedArrayBool) {
TEST_F(BindToTaskRunnerTest, BoundScopedPtrFreeDeleterBool) {
bool bool_val = false;
- scoped_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
+ std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
static_cast<bool*>(malloc(sizeof(bool))));
*scoped_ptr_free_deleter_bool = true;
base::Closure cb = BindToCurrentThread(
@@ -130,10 +131,10 @@ TEST_F(BindToTaskRunnerTest, BoundScopedPtrFreeDeleterBool) {
TEST_F(BindToTaskRunnerTest, PassedScopedPtrFreeDeleterBool) {
bool bool_val = false;
- scoped_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
+ std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
static_cast<bool*>(malloc(sizeof(bool))));
*scoped_ptr_free_deleter_bool = true;
- base::Callback<void(scoped_ptr<bool, base::FreeDeleter>)> cb =
+ base::Callback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
BindToCurrentThread(
base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, &bool_val));
cb.Run(std::move(scoped_ptr_free_deleter_bool));
diff --git a/chromium/chromecast/base/cast_resource.cc b/chromium/chromecast/base/cast_resource.cc
index cbe9b51d7cd..7978d868fbd 100644
--- a/chromium/chromecast/base/cast_resource.cc
+++ b/chromium/chromecast/base/cast_resource.cc
@@ -10,9 +10,9 @@ void CastResource::SetCastResourceClient(Client* client) {
client_ = client;
}
-void CastResource::NotifyResourceAcquired() {
+void CastResource::RegisterWithClient() {
if (client_)
- client_->OnResourceAcquired(this);
+ client_->RegisterCastResource(this);
}
void CastResource::NotifyResourceReleased(Resource remain) {
diff --git a/chromium/chromecast/base/cast_resource.h b/chromium/chromecast/base/cast_resource.h
index cd248d77edc..67315ec392a 100644
--- a/chromium/chromecast/base/cast_resource.h
+++ b/chromium/chromecast/base/cast_resource.h
@@ -9,7 +9,13 @@
namespace chromecast {
-// Interface for resources needed to run application.
+// A CastResource is a user of 1 or more Resources (primary screen, audio,
+// etc). As a user, it is responsible for doing any cast-specific component
+// initialization when the Resources it uses are granted. This initialization
+// is referred to as "acquiring" the Resources. Conversely, when the Resources
+// it uses are revoked, it must deinitialize these cast-specific components.
+// This deinitialization is referred to as "releasing" the Resources.
+// TODO(maclellant): RENAME/DESIGN THIS CLASS IN COMING REFACTOR.
class CastResource {
public:
// Resources necessary to run cast apps. CastResource may contain union of the
@@ -33,11 +39,22 @@ class CastResource {
(kResourceAudio | kResourceScreenPrimary | kResourceScreenSecondary),
};
+ // A Client is responsible for notifying all registered CastResource's when
+ // Resources are granted/revoked so that they can acquire/release those
+ // Resources. When a CastResource is done acquiring/releasing, it responds
+ // to the Client that it has completed. A Client can have multiple registered
+ // CastResource's, but each CastResouce has 1 Client that it responds to.
class Client {
public:
- // Called when resource is created. CastResource should not be owned by
- // Client. It can be called from any thread.
- virtual void OnResourceAcquired(CastResource* cast_resource) = 0;
+ // Called to register a CastResource with a Client. After registering, a
+ // CastResource will start getting notified when to acquire/release
+ // Resources. The Client does not take ownership of |cast_resource|. It can
+ // be called from any thread.
+ virtual void RegisterCastResource(CastResource* cast_resource) = 0;
+
+ // TODO(esum): Add OnResourceAcquired() here once AcquireResource is
+ // allowed to be asynchronous.
+
// Called when part or all resources are released. It can be called from any
// thread.
// |cast_resource| the CastResource that is released. The pointer may be
@@ -52,7 +69,17 @@ class CastResource {
virtual ~Client() {}
};
+ // Sets the Client for the CastResource to respond to when it is done with
+ // Acquire/ReleaseResource.
void SetCastResourceClient(Client* client);
+ // Called to acquire resources after OEM has granted them, and before
+ // they start getting used by consumers. Implementation must be synchronous
+ // since consumers will start using the resource immediately afterwards.
+ // TODO(esum): We should allow this method to be asynchronous in case an
+ // implementer needs to make expensive calls and doesn't want to block the
+ // UI thread (b/26239576). For now, don't do anything expensive in your
+ // implementation; if you really need to, then this bug has to be resolved.
+ virtual void AcquireResource(Resource resource) = 0;
// Called to release resources. Implementation should call
// Client::OnResourceReleased when resource is released on its side.
virtual void ReleaseResource(Resource resource) = 0;
@@ -61,7 +88,9 @@ class CastResource {
CastResource() : client_(nullptr) {}
virtual ~CastResource() {}
- void NotifyResourceAcquired();
+ // For derived classes to register themselves with their Client through
+ // Client::RegisterCastResource.
+ void RegisterWithClient();
void NotifyResourceReleased(Resource remain);
private:
diff --git a/chromium/chromecast/base/cast_sys_info_android.cc b/chromium/chromecast/base/cast_sys_info_android.cc
index 0d85a06ad82..80eaf933894 100644
--- a/chromium/chromecast/base/cast_sys_info_android.cc
+++ b/chromium/chromecast/base/cast_sys_info_android.cc
@@ -7,6 +7,7 @@
#include "base/android/build_info.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_info.h"
#include "chromecast/base/cast_sys_info_util.h"
@@ -25,8 +26,8 @@ bool CastSysInfoAndroid::RegisterJni(JNIEnv* env) {
}
// static
-scoped_ptr<CastSysInfo> CreateSysInfo() {
- return make_scoped_ptr(new CastSysInfoAndroid());
+std::unique_ptr<CastSysInfo> CreateSysInfo() {
+ return base::WrapUnique(new CastSysInfoAndroid());
}
CastSysInfoAndroid::CastSysInfoAndroid()
diff --git a/chromium/chromecast/base/cast_sys_info_util.h b/chromium/chromecast/base/cast_sys_info_util.h
index 05ca069d655..36979377fbe 100644
--- a/chromium/chromecast/base/cast_sys_info_util.h
+++ b/chromium/chromecast/base/cast_sys_info_util.h
@@ -5,16 +5,16 @@
#ifndef CHROMECAST_BASE_CAST_SYS_INFO_UTIL_H_
#define CHROMECAST_BASE_CAST_SYS_INFO_UTIL_H_
+#include <memory>
#include <string>
#include <vector>
-#include "base/memory/scoped_ptr.h"
namespace chromecast {
class CastSysInfo;
-scoped_ptr<CastSysInfo> CreateSysInfo();
+std::unique_ptr<CastSysInfo> CreateSysInfo();
} // namespace chromecast
diff --git a/chromium/chromecast/base/cast_sys_info_util_simple.cc b/chromium/chromecast/base/cast_sys_info_util_simple.cc
index 68ab9dffb2c..0eb54a41aed 100644
--- a/chromium/chromecast/base/cast_sys_info_util_simple.cc
+++ b/chromium/chromecast/base/cast_sys_info_util_simple.cc
@@ -4,13 +4,14 @@
#include "chromecast/base/cast_sys_info_util.h"
+#include "base/memory/ptr_util.h"
#include "chromecast/base/cast_sys_info_dummy.h"
namespace chromecast {
// static
-scoped_ptr<CastSysInfo> CreateSysInfo() {
- return make_scoped_ptr(new CastSysInfoDummy());
+std::unique_ptr<CastSysInfo> CreateSysInfo() {
+ return base::WrapUnique(new CastSysInfoDummy());
}
} // namespace chromecast
diff --git a/chromium/chromecast/base/chromecast_switches.cc b/chromium/chromecast/base/chromecast_switches.cc
index 25438ac9991..432e76321b6 100644
--- a/chromium/chromecast/base/chromecast_switches.cc
+++ b/chromium/chromecast/base/chromecast_switches.cc
@@ -4,8 +4,16 @@
#include "chromecast/base/chromecast_switches.h"
+#include "base/command_line.h"
+
namespace switches {
+// Value indicating whether flag from command line switch is true.
+const char kSwitchValueTrue[] = "true";
+
+// Value indicating whether flag from command line switch is false.
+const char kSwitchValueFalse[] = "false";
+
// Enable the CMA media pipeline.
const char kEnableCmaMediaPipeline[] = "enable-cma-media-pipeline";
@@ -32,6 +40,11 @@ const char kLastLaunchedApp[] = "last-launched-app";
// started.
const char kPreviousApp[] = "previous-app";
+// Flag indicating that a resource provider must be set up to provide cast
+// receiver with resources. Apps cannot start until provided resources.
+// This flag implies --alsa-check-close-timeout=0.
+const char kAcceptResourceProvider[] = "accept-resource-provider";
+
// Size of the ALSA output buffer in frames. This directly sets the latency of
// the output device. Latency can be calculated by multiplying the sample rate
// by the output buffer size.
@@ -48,7 +61,39 @@ const char kAlsaOutputStartThreshold[] = "alsa-output-start-threshold";
const char kAlsaOutputAvailMin[] = "alsa-output-avail-min";
// Time in ms to wait before closing the PCM handle when no more mixer inputs
-// remain.
+// remain. Assumed to be 0 if --accept-resource-provider is present.
const char kAlsaCheckCloseTimeout[] = "alsa-check-close-timeout";
+// Number of channels on the alsa output device that the stream mixer uses.
+// Default is 2 channels.
+const char kAlsaNumOutputChannels[] = "alsa-num-output-channels";
+
+// Optional flag to set a fixed sample rate for the alsa device.
+const char kAlsaFixedOutputSampleRate[] = "alsa-fixed-output-sample-rate";
+
} // namespace switches
+
+namespace chromecast {
+
+bool GetSwitchValueBoolean(const std::string& switch_string,
+ const bool default_value) {
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switch_string)) {
+ if (command_line->GetSwitchValueASCII(switch_string) !=
+ switches::kSwitchValueTrue &&
+ command_line->GetSwitchValueASCII(switch_string) !=
+ switches::kSwitchValueFalse &&
+ command_line->GetSwitchValueASCII(switch_string) != "") {
+ LOG(WARNING) << "Invalid switch value " << switch_string << "="
+ << command_line->GetSwitchValueASCII(switch_string)
+ << "; assuming default value of " << default_value;
+ return default_value;
+ }
+ return command_line->GetSwitchValueASCII(switch_string) !=
+ switches::kSwitchValueFalse;
+ }
+ return default_value;
+}
+
+} // namespace chromecast
diff --git a/chromium/chromecast/base/chromecast_switches.h b/chromium/chromecast/base/chromecast_switches.h
index 1ac84d878bc..4d30f995aa3 100644
--- a/chromium/chromecast/base/chromecast_switches.h
+++ b/chromium/chromecast/base/chromecast_switches.h
@@ -5,10 +5,16 @@
#ifndef CHROMECAST_BASE_CHROMECAST_SWITCHES_H_
#define CHROMECAST_BASE_CHROMECAST_SWITCHES_H_
+#include <string>
+
#include "build/build_config.h"
namespace switches {
+// Switch values
+extern const char kSwitchValueTrue[];
+extern const char kSwitchValueFalse[];
+
// Media switches
extern const char kEnableCmaMediaPipeline[];
extern const char kHdmiSinkSupportedCodecs[];
@@ -29,13 +35,30 @@ extern const char kAllowHiddenMediaPlayback[];
extern const char kLastLaunchedApp[];
extern const char kPreviousApp[];
+// Cast Receiver switches
+extern const char kAcceptResourceProvider[];
+
// ALSA-based CMA switches. (Only valid for audio products.)
extern const char kAlsaOutputBufferSize[];
extern const char kAlsaOutputPeriodSize[];
extern const char kAlsaOutputStartThreshold[];
extern const char kAlsaOutputAvailMin[];
extern const char kAlsaCheckCloseTimeout[];
+extern const char kAlsaNumOutputChannels[];
+extern const char kAlsaFixedOutputSampleRate[];
} // namespace switches
+namespace chromecast {
+
+// Gets boolean value from switch |switch_string|.
+// --|switch_string| -> true
+// --|switch_string|="true" -> true
+// --|switch_string|="false" -> false
+// no switch named |switch_string| -> |default_value|
+bool GetSwitchValueBoolean(const std::string& switch_string,
+ const bool default_value);
+
+} // namespace chromecast
+
#endif // CHROMECAST_BASE_CHROMECAST_SWITCHES_H_
diff --git a/chromium/chromecast/base/chromecast_switches_unittest.cc b/chromium/chromecast/base/chromecast_switches_unittest.cc
new file mode 100644
index 00000000000..465456e1704
--- /dev/null
+++ b/chromium/chromecast/base/chromecast_switches_unittest.cc
@@ -0,0 +1,61 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "chromecast/base/chromecast_switches.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromecast {
+
+TEST(ChromecastSwitchesTest, NoSwitch) {
+ if (base::CommandLine::CommandLine::InitializedForCurrentProcess())
+ base::CommandLine::Reset();
+ base::CommandLine::Init(0, nullptr);
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, true));
+ EXPECT_FALSE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, false));
+}
+
+TEST(ChromecastSwitchesTest, NoSwitchValue) {
+ if (base::CommandLine::CommandLine::InitializedForCurrentProcess())
+ base::CommandLine::Reset();
+ base::CommandLine::Init(0, nullptr);
+ base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
+ cl->AppendSwitch(switches::kEnableCmaMediaPipeline);
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, true));
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, false));
+}
+
+TEST(ChromecastSwitchesTest, SwitchValueTrue) {
+ if (base::CommandLine::CommandLine::InitializedForCurrentProcess())
+ base::CommandLine::Reset();
+ base::CommandLine::Init(0, nullptr);
+ base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
+ cl->AppendSwitchASCII(switches::kEnableCmaMediaPipeline,
+ switches::kSwitchValueTrue);
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, true));
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, false));
+}
+
+TEST(ChromecastSwitchesTest, SwitchValueFalse) {
+ if (base::CommandLine::CommandLine::InitializedForCurrentProcess())
+ base::CommandLine::Reset();
+ base::CommandLine::Init(0, nullptr);
+ base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
+ cl->AppendSwitchASCII(switches::kEnableCmaMediaPipeline,
+ switches::kSwitchValueFalse);
+ EXPECT_FALSE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, true));
+ EXPECT_FALSE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, false));
+}
+
+TEST(ChromecastSwitchesTest, SwitchValueNonsense) {
+ if (base::CommandLine::CommandLine::InitializedForCurrentProcess())
+ base::CommandLine::Reset();
+ base::CommandLine::Init(0, nullptr);
+ base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
+ cl->AppendSwitchASCII(switches::kEnableCmaMediaPipeline, "silverware");
+ EXPECT_TRUE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, true));
+ EXPECT_FALSE(GetSwitchValueBoolean(switches::kEnableCmaMediaPipeline, false));
+}
+
+} // namespace chromecast
diff --git a/chromium/chromecast/base/component/BUILD.gn b/chromium/chromecast/base/component/BUILD.gn
new file mode 100644
index 00000000000..82689625bfc
--- /dev/null
+++ b/chromium/chromecast/base/component/BUILD.gn
@@ -0,0 +1,33 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chromecast/chromecast.gni")
+import("//testing/test.gni")
+
+# GYP target: chromecast.gyp:cast_component
+source_set("component") {
+ sources = [
+ "component.cc",
+ "component.h",
+ "component_internal.h",
+ ]
+
+ deps = [
+ "//base",
+ ]
+}
+
+# GYP target: chromecast_tests.gypi:cast_component_unittests
+test("cast_component_unittests") {
+ sources = [
+ "component_unittest.cc",
+ ]
+
+ deps = [
+ ":component",
+ "//base",
+ "//base/test:run_all_unittests",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/chromecast/base/component/component.cc b/chromium/chromecast/base/component/component.cc
new file mode 100644
index 00000000000..db203f9664a
--- /dev/null
+++ b/chromium/chromecast/base/component/component.cc
@@ -0,0 +1,425 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/base/component/component.h"
+
+#include <set>
+
+#include "base/atomicops.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+
+namespace chromecast {
+
+namespace {
+
+const base::subtle::AtomicWord kEnabledBit = 0x40000000;
+
+} // namespace
+
+namespace subtle {
+
+class DependencyCount : public base::RefCountedThreadSafe<DependencyCount> {
+ public:
+ explicit DependencyCount(ComponentBase* component)
+ : component_(component),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ dep_count_(0),
+ disabling_(false) {
+ DCHECK(component_);
+ }
+
+ void Detach() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ component_ = nullptr;
+ }
+
+ void Disable() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(!disabling_);
+ disabling_ = true;
+
+ std::set<DependencyBase*> dependents(strong_dependents_);
+ for (DependencyBase* dependent : dependents)
+ dependent->Disable();
+
+ while (true) {
+ AtomicWord deps = base::subtle::NoBarrier_Load(&dep_count_);
+ AtomicWord old_deps = base::subtle::Acquire_CompareAndSwap(
+ &dep_count_, deps, deps & ~kEnabledBit);
+ if (old_deps == deps) {
+ if ((deps & ~kEnabledBit) == 0)
+ DisableComplete();
+ return;
+ }
+ }
+ }
+
+ void Enable() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ disabling_ = false;
+ while (true) {
+ AtomicWord deps = base::subtle::NoBarrier_Load(&dep_count_);
+ DCHECK(!(deps & kEnabledBit));
+ AtomicWord old_deps = base::subtle::Release_CompareAndSwap(
+ &dep_count_, deps, deps | kEnabledBit);
+ if (old_deps == deps)
+ break;
+ }
+
+ for (DependencyBase* dependent : strong_dependents_)
+ dependent->Ready(component_);
+ }
+
+ ComponentBase* WeakAcquireDep() {
+ while (true) {
+ AtomicWord deps = base::subtle::NoBarrier_Load(&dep_count_);
+ if (!(deps & kEnabledBit))
+ return nullptr;
+ AtomicWord old_deps =
+ base::subtle::Acquire_CompareAndSwap(&dep_count_, deps, deps + 1);
+ // We depend on the fact that a component must be disabled (meaning that
+ // we will never reach this point) before it is destroyed. Therefore if
+ // we do reach this point, it is safe to return the raw pointer.
+ if (old_deps == deps)
+ return component_;
+ }
+ }
+
+ void StrongAcquireDep(DependencyBase* dependent) {
+ DCHECK(dependent);
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (!component_) {
+ dependent->Disable();
+ return;
+ }
+
+ strong_dependents_.insert(dependent);
+ AtomicWord count = base::subtle::NoBarrier_AtomicIncrement(&dep_count_, 1);
+ DCHECK_GT(count, 0);
+
+ if (count & kEnabledBit) {
+ dependent->Ready(component_);
+ } else {
+ component_->Enable();
+ }
+ }
+
+ void StrongReleaseDep(DependencyBase* dependent) {
+ DCHECK(dependent);
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ strong_dependents_.erase(dependent);
+ ReleaseDep();
+ }
+
+ void ReleaseDep() {
+ AtomicWord after = base::subtle::Barrier_AtomicIncrement(&dep_count_, -1);
+ DCHECK_GE(after, 0);
+ if (after == 0)
+ DisableComplete();
+ }
+
+ bool DependsOn(ComponentBase* component) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (!component_)
+ return false;
+ if (component_ == component)
+ return true;
+ return component_->DependsOn(component);
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<DependencyCount>;
+ using AtomicWord = base::subtle::AtomicWord;
+
+ ~DependencyCount() {}
+
+ void DisableComplete() {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DependencyCount::DisableComplete, this));
+ return;
+ }
+ // Need to make sure that Enable() was not called in the meantime.
+ if (base::subtle::NoBarrier_Load(&dep_count_) != 0 || !disabling_)
+ return;
+ // Ensure that we don't call DisableComplete() more than once per Disable().
+ disabling_ = false;
+ DCHECK(component_);
+ DCHECK(strong_dependents_.empty());
+ component_->DependencyCountDisableComplete();
+ }
+
+ ComponentBase* component_;
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ AtomicWord dep_count_;
+ bool disabling_;
+ std::set<DependencyBase*> strong_dependents_;
+
+ DISALLOW_COPY_AND_ASSIGN(DependencyCount);
+};
+
+DependencyBase::DependencyBase(const WeakReferenceBase& dependency,
+ ComponentBase* dependent)
+ : dependent_(dependent),
+ dependency_(nullptr),
+ counter_(dependency.counter_) {
+ DCHECK(dependent_);
+ dependent_->AddDependency(this);
+}
+
+DependencyBase::~DependencyBase() {}
+
+void DependencyBase::StartUsing() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!dependency_);
+ counter_->StrongAcquireDep(this);
+}
+
+void DependencyBase::StopUsing() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!dependency_)
+ return;
+ dependency_ = nullptr;
+ counter_->StrongReleaseDep(this);
+}
+
+void DependencyBase::Ready(ComponentBase* dependency) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!dependency_);
+ DCHECK(dependency);
+ dependency_ = dependency;
+ dependent_->DependencyReady();
+}
+
+void DependencyBase::Disable() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ dependent_->Disable();
+}
+
+bool DependencyBase::DependsOn(ComponentBase* component) {
+ return counter_->DependsOn(component);
+}
+
+WeakReferenceBase::WeakReferenceBase(const ComponentBase& dependency)
+ : counter_(dependency.counter_) {
+ DCHECK(counter_);
+}
+
+WeakReferenceBase::WeakReferenceBase(const DependencyBase& dependency)
+ : counter_(dependency.counter_) {
+ DCHECK(counter_);
+}
+
+WeakReferenceBase::WeakReferenceBase(const WeakReferenceBase& other)
+ : counter_(other.counter_) {
+ DCHECK(counter_);
+}
+
+WeakReferenceBase::WeakReferenceBase(WeakReferenceBase&& other)
+ : counter_(std::move(other.counter_)) {
+ DCHECK(counter_);
+}
+
+WeakReferenceBase::~WeakReferenceBase() {}
+
+ScopedReferenceBase::ScopedReferenceBase(
+ const scoped_refptr<DependencyCount>& counter)
+ : counter_(counter) {
+ DCHECK(counter_);
+ dependency_ = counter_->WeakAcquireDep();
+}
+
+ScopedReferenceBase::ScopedReferenceBase(ScopedReferenceBase&& other)
+ : counter_(std::move(other.counter_)), dependency_(other.dependency_) {
+ DCHECK(counter_);
+ other.dependency_ = nullptr;
+}
+
+ScopedReferenceBase::~ScopedReferenceBase() {
+ if (dependency_)
+ counter_->ReleaseDep();
+}
+
+} // namespace subtle
+
+ComponentBase::ComponentBase()
+ : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ state_(kStateDisabled),
+ async_call_in_progress_(false),
+ pending_dependency_count_(0),
+ observers_(new base::ObserverListThreadSafe<Observer>()) {
+ counter_ = new subtle::DependencyCount(this);
+}
+
+ComponentBase::~ComponentBase() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK_EQ(kStateDisabled, state_) << "Components must be disabled "
+ << "before being destroyed";
+ counter_->Detach();
+}
+
+void ComponentBase::Enable() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (state_ == kStateEnabling || state_ == kStateEnabled ||
+ state_ == kStateDestroying) {
+ return;
+ }
+ state_ = kStateEnabling;
+
+ if (strong_dependencies_.empty()) {
+ TryOnEnable();
+ } else {
+ // Enable all strong dependencies first.
+ pending_dependency_count_ = strong_dependencies_.size();
+ for (subtle::DependencyBase* dependency : strong_dependencies_)
+ dependency->StartUsing();
+ }
+}
+
+void ComponentBase::DependencyReady() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (state_ != kStateEnabling)
+ return;
+ DCHECK_GT(pending_dependency_count_, 0);
+ --pending_dependency_count_;
+ if (pending_dependency_count_ == 0)
+ TryOnEnable();
+}
+
+void ComponentBase::TryOnEnable() {
+ DCHECK_EQ(kStateEnabling, state_);
+ if (async_call_in_progress_)
+ return;
+ async_call_in_progress_ = true;
+ OnEnable();
+}
+
+void ComponentBase::OnEnableComplete(bool success) {
+ // Always post a task, to prevent the stack from getting too deep.
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ComponentBase::OnEnableCompleteInternal,
+ base::Unretained(this), success));
+}
+
+void ComponentBase::OnEnableCompleteInternal(bool success) {
+ async_call_in_progress_ = false;
+ DCHECK(state_ == kStateEnabling || state_ == kStateDisabling ||
+ state_ == kStateDestroying);
+ if (state_ != kStateEnabling) {
+ if (success) {
+ TryOnDisable();
+ } else {
+ OnDisableCompleteInternal();
+ }
+ return;
+ }
+
+ if (success) {
+ state_ = kStateEnabled;
+ counter_->Enable();
+ } else {
+ Disable();
+ }
+ observers_->Notify(FROM_HERE, &Observer::OnComponentEnabled, this, success);
+}
+
+void ComponentBase::Destroy() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK_NE(kStateDestroying, state_);
+ if (state_ == kStateDisabled) {
+ delete this;
+ } else {
+ bool should_disable = (state_ != kStateDisabling);
+ state_ = kStateDestroying;
+ if (should_disable)
+ counter_->Disable();
+ }
+}
+
+void ComponentBase::AddObserver(Observer* observer) {
+ DCHECK(observer);
+ observers_->AddObserver(observer);
+}
+
+void ComponentBase::RemoveObserver(Observer* observer) {
+ observers_->RemoveObserver(observer);
+}
+
+void ComponentBase::Disable() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (state_ == kStateDisabling || state_ == kStateDisabled ||
+ state_ == kStateDestroying) {
+ return;
+ }
+ state_ = kStateDisabling;
+ counter_->Disable();
+}
+
+void ComponentBase::DependencyCountDisableComplete() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (state_ == kStateDisabling || state_ == kStateDestroying)
+ TryOnDisable();
+}
+
+void ComponentBase::TryOnDisable() {
+ DCHECK(state_ == kStateDisabling || state_ == kStateDestroying);
+ if (async_call_in_progress_)
+ return;
+ async_call_in_progress_ = true;
+ OnDisable();
+}
+
+void ComponentBase::OnDisableComplete() {
+ // Always post a task, to prevent calls to Disable() from within Enable().
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ComponentBase::OnDisableCompleteInternal,
+ base::Unretained(this)));
+}
+
+void ComponentBase::OnDisableCompleteInternal() {
+ async_call_in_progress_ = false;
+ DCHECK(state_ == kStateEnabling || state_ == kStateDisabling ||
+ state_ == kStateDestroying);
+ if (state_ == kStateEnabling) {
+ TryOnEnable();
+ return;
+ }
+
+ if (state_ == kStateDestroying) {
+ StopUsingDependencies();
+ observers_->Notify(FROM_HERE, &Observer::OnComponentDisabled, this);
+ state_ = kStateDisabled;
+ delete this;
+ } else {
+ state_ = kStateDisabled;
+ StopUsingDependencies();
+ observers_->Notify(FROM_HERE, &Observer::OnComponentDisabled, this);
+ }
+}
+
+void ComponentBase::AddDependency(subtle::DependencyBase* dependency) {
+ DCHECK_EQ(kStateDisabled, state_);
+ DCHECK(!dependency->DependsOn(this)) << "Circular dependency detected";
+ strong_dependencies_.push_back(dependency);
+}
+
+void ComponentBase::StopUsingDependencies() {
+ for (subtle::DependencyBase* dependency : strong_dependencies_)
+ dependency->StopUsing();
+}
+
+bool ComponentBase::DependsOn(ComponentBase* component) {
+ for (subtle::DependencyBase* dependency : strong_dependencies_) {
+ if (dependency->DependsOn(component))
+ return true;
+ }
+ return false;
+}
+
+} // namespace chromecast
diff --git a/chromium/chromecast/base/component/component.h b/chromium/chromecast/base/component/component.h
new file mode 100644
index 00000000000..a545ea435d5
--- /dev/null
+++ b/chromium/chromecast/base/component/component.h
@@ -0,0 +1,327 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A component is a large, long-lived set of functionality that may be enabled
+// or disabled at runtime. Some examples include: the multizone features,
+// MetricsRecorder, or OpencastController. Components may depend on each other
+// (ie, a component may call the public methods of other components); the
+// Component infrastructure ensures that when a component is disabled, nothing
+// that depends on it will call any of its methods until it is enabled again.
+//
+// Components may be used without a dependency relationship via a weak
+// reference. A weak reference does not allow direct access to the component;
+// instead, it must be either used to create a strict dependency (see below), or
+// be converted to a scoped reference via Try(). Scoped references must be
+// checked for validity before use (they are convertible to bool); an invalid
+// scoped reference must not be used. Scoped references should be short-lived;
+// to encourage this, they are only move-constructible and cannot be copied or
+// assigned.
+//
+// If component Y depends on Component X, then Y has a Dependency reference
+// to X. This causes Y to be disabled as X is being disabled (before X's
+// OnDisable() method is called). Similarly, this dependency will cause X to be
+// enabled when Y is being enabled (X will be enabled before Y's OnEnable()
+// method is called). A component may freely access any of its dependencies
+// as long as it is enabled. When a component is disabled, it must ensure that
+// none of its dependencies will be used again until it is enabled. It is
+// recommended to set up dependencies in your component's constructor; it is an
+// error to add a dependency to a component that is not disabled.
+//
+// When a component is disabled, it will first recursively disable any other
+// components that depend on it. It will also disable the creation of
+// new scoped references. It then waits for all scoped references to be
+// destroyed before calling OnDisable() to actually disable the component.
+//
+// Components MUST be disabled before they are deleted. For ease of use, a
+// Destroy() method is provided. When Destroy() is called, it prevents the
+// component from being enabled ever again, and then disables it, deleting it
+// once it is disabled.
+//
+// Example usage:
+//
+// class MetricsRecorder : public Component<MetricsRecorder> {
+// public:
+// virtual ~MetricsRecorder() {}
+// virtual void RecordEvent(const std::string& event) = 0;
+// };
+//
+// class SetupManager : public Component<SetupManager> {
+// public:
+// virtual ~SetupManager() {}
+// virtual int GetMultizoneDelay() = 0;
+// };
+//
+// class Multizone : public Component<Multizone> {
+// public:
+// virtual ~Multizone() {}
+// virtual void DoMultizoneStuff() = 0;
+// };
+//
+// class MetricsRecorderImpl : public MetricsRecorder {
+// public:
+// void OnEnable() override {
+// // ... Enable metrics reporting ...
+// OnEnableComplete(true);
+// }
+//
+// // Release all resources; public methods will not be called after this.
+// void OnDisable() override {
+// OnDisableComplete();
+// }
+//
+// void RecordEvent(const std::string& event) override {
+// // ... Record an event ...
+// }
+// };
+//
+// class SetupManagerImpl : public SetupManager {
+// public:
+// void OnEnable() override {
+// // ... Enable setup manager ...
+// // OnEnableComplete() may be called asynchronously.
+// base::ThreadTaskRunnerHandle::Get()->PostTask(
+// FROM_HERE, base::Bind(&SetupManagerImpl::CompleteEnable,
+// base::Unretained(this)));
+// }
+//
+// void CompleteEnable() {
+// OnEnableComplete(true);
+// }
+//
+// void OnDisable() override {
+// OnDisableComplete();
+// }
+//
+// int GetMultizoneDelay() override { return 0; }
+// };
+//
+// class MultizoneImpl : public Multizone {
+// public:
+// MultizoneImpl(const MetricsRecorder::WeakRef& metrics_recorder,
+// const SetupManager::WeakRef& setup_manager)
+// : metrics_recorder_(metrics_recorder, this),
+// setup_manager_(setup_manager) {
+// // We can try to use weak deps even before this component is enabled.
+// // However, we MUST NOT attempt to use any strong dependencies.
+// if (auto setup = setup_manager_.Try()) {
+// int delay = setup->GetMultizoneDelay();
+// // ... Do something with delay ...
+// }
+// }
+//
+// void OnEnable() override {
+// // ... Enable multizone ...
+// // Can use strong dependencies directly
+// metrics_recorder_->RecordEvent("enable multizone");
+// OnEnableComplete();
+// }
+//
+// void OnDisable() override {
+// // Can still use strong dependencies here. However, this method MUST
+// // ensure that strong dependencies will NOT be used after it returns.
+// metrics_recorder_->RecordEvent("disable multizone");
+// OnDisableComplete();
+// }
+//
+// void DoMultizoneStuff() {
+// metrics_recorder_->RecordEvent("multizone stuff");
+// // You have to Try() every time you use a weak dependency.
+// if (auto setup = setup_manager_.Try()) {
+// int delay = setup->GetMultizoneDelay();
+// // ... Do something with delay ...
+// }
+// }
+//
+// private:
+// MetricsRecorder::Dependency metrics_recorder_;
+// SetupManager::WeakRef setup_manager_;
+// };
+
+#ifndef CHROMECAST_BASE_COMPONENT_COMPONENT_H_
+#define CHROMECAST_BASE_COMPONENT_COMPONENT_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/threading/thread_checker.h"
+#include "chromecast/base/component/component_internal.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace chromecast {
+
+class ComponentBase {
+ public:
+ class Observer {
+ public:
+ // Called when a component finishes being enabled. If the component was
+ // enabled successfully, |success| will be |true|. Note that access to
+ // |component| is not guaranteed to be safe; since the observers are
+ // notified asynchronously, |component| may have been already deleted.
+ virtual void OnComponentEnabled(ComponentBase* component, bool success) {}
+ // Called when a component has been disabled. Access to |component| is not
+ // guaranteed to be safe.
+ virtual void OnComponentDisabled(ComponentBase* component) {}
+
+ protected:
+ virtual ~Observer() {}
+ };
+
+ virtual ~ComponentBase();
+
+ // Enables this component if possible. Attempts to enable all strong
+ // dependencies first. It is OK to call Disable() while the component is in
+ // the process of being enabled. All components MUST be created/enabled/
+ // disabled/destroyed on the same thread.
+ // Note that enabling a component may occur asynchronously; components must
+ // always be accessed through a Dependency or WeakReference to ensure safety.
+ // TODO(kmackay) Consider allowing components to be used on any thread.
+ void Enable();
+
+ // Disables this component; disabling may complete asynchronously. It is OK to
+ // call Enable() again while the component is being disabled. Note that a
+ // component MUST be disabled (or never enabled) before it is deleted.
+ void Disable();
+
+ // Deletes this component, disabling it first if necessary.
+ void Destroy();
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ protected:
+ ComponentBase();
+
+ // Enables the component implementation. This method must set things up so
+ // that any public method calls are valid, and then call OnEnableComplete(),
+ // passing in |true| if the enable was successful, |false| otherwise.
+ // OnEnableComplete() may be called from any thread. OnEnable() will not be
+ // called again until after the component has been disabled, and will not be
+ // called during an ongoing OnDisable() call (so if OnDisable() is called,
+ // then OnEnable() will not be called until OnDisableComplete() has been
+ // called). This method is called only on the thread that the component was
+ // created on.
+ virtual void OnEnable() = 0;
+
+ // Disables the component implementation. This is not called until there are
+ // no more live dependencies, so there will be no more public method calls
+ // to the component until after OnEnable() is called again. This method must
+ // do whatever is necessary to ensure that no more calls to dependencies of
+ // this component will be made, and then call the |disabled_cb|. The
+ // |disabled_cb| may be called from any thread. This method is called only on
+ // the thread that the component was created on.
+ virtual void OnDisable() = 0;
+
+ // Handles the success/failure of a call to OnEnable(). When OnEnable() is
+ // called, it must eventually call OnEnableComplete() (after the component is
+ // ready to be used by dependents), passing in |true| if the component was
+ // enabled successfully. If |success| is false, then OnDisable() will be
+ // called immediately to return the component to a consistent disabled state.
+ // May be called on any thread.
+ void OnEnableComplete(bool success);
+
+ // Handles the completion of a call to OnDisable(). When OnDisable() is
+ // called, it must eventually call OnDisableComplete() (after ensuring that
+ // none of the component's strong dependencies will be used anymore). May be
+ // called on any thread.
+ void OnDisableComplete();
+
+ private:
+ friend class subtle::DependencyCount;
+ friend class subtle::DependencyBase;
+ friend class subtle::WeakReferenceBase;
+
+ enum State {
+ kStateDisabled,
+ kStateDisabling,
+ kStateEnabled,
+ kStateEnabling,
+ kStateDestroying
+ };
+
+ void DependencyReady();
+ void TryOnEnable();
+ void OnEnableCompleteInternal(bool success);
+ void DependencyCountDisableComplete();
+ void TryOnDisable();
+ void OnDisableCompleteInternal();
+ void AddDependency(subtle::DependencyBase* dependency);
+ void StopUsingDependencies();
+ // Returns |true| if |component| is a transitive dependency of this component.
+ bool DependsOn(ComponentBase* component);
+
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ scoped_refptr<subtle::DependencyCount> counter_;
+ std::vector<subtle::DependencyBase*> strong_dependencies_;
+ State state_;
+ // |true| when a call to OnEnable()/OnDisable() is in progress.
+ bool async_call_in_progress_;
+ int pending_dependency_count_;
+ const scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(ComponentBase);
+};
+
+template <typename C>
+class StrongDependency : public subtle::DependencyBase {
+ public:
+ StrongDependency(const WeakReference<C>& dependency, ComponentBase* dependent)
+ : subtle::DependencyBase(dependency, dependent) {}
+
+ C* operator->() const {
+ DCHECK(dependency_);
+ return static_cast<C*>(dependency_);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StrongDependency);
+};
+
+template <typename C>
+class WeakReference : public subtle::WeakReferenceBase {
+ public:
+ explicit WeakReference(const C& dependency) : WeakReferenceBase(dependency) {}
+ explicit WeakReference(const StrongDependency<C>& dependency)
+ : subtle::WeakReferenceBase(dependency) {}
+
+ // Explicitly allow copy.
+ WeakReference(const WeakReference& other) = default;
+ WeakReference(WeakReference&& other) = default;
+
+ // Disallow assignment.
+ void operator=(const WeakReference&) = delete;
+
+ // Try to get a scoped reference. Expected usage:
+ // if (auto ref = weak.Try()) {
+ // // ... use ref ...
+ // }
+ subtle::Ref_DO_NOT_DECLARE<C> Try() const {
+ return subtle::Ref_DO_NOT_DECLARE<C>(counter_);
+ }
+};
+
+template <typename C>
+class Component : public ComponentBase {
+ public:
+ using WeakRef = WeakReference<C>;
+ using Dependency = StrongDependency<C>;
+
+ Component() = default;
+
+ WeakRef GetRef() { return WeakRef(*static_cast<C*>(this)); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Component);
+};
+
+} // namespace chromecast
+
+#endif // CHROMECAST_BASE_COMPONENT_COMPONENT_H_
diff --git a/chromium/chromecast/base/component/component_internal.h b/chromium/chromecast/base/component/component_internal.h
new file mode 100644
index 00000000000..85a6757ecd2
--- /dev/null
+++ b/chromium/chromecast/base/component/component_internal.h
@@ -0,0 +1,121 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_
+#define CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/threading/thread_checker.h"
+
+namespace chromecast {
+
+template <typename C>
+class WeakReference;
+
+class ComponentBase;
+
+namespace subtle {
+
+class WeakReferenceBase;
+
+// Manages thread-safe dependency counting. Instances of this class are
+// RefCountedThreadSafe since they must live as long as any dependent.
+class DependencyCount;
+
+// Base class for strong dependencies. A strong dependency is tied to a
+// specific dependent component instance. This allows dependents to be
+// disabled before the component they depend on. May be used on any thread.
+class DependencyBase {
+ public:
+ DependencyBase(const WeakReferenceBase& dependency, ComponentBase* dependent);
+ ~DependencyBase();
+
+ void StartUsing();
+ void StopUsing();
+ bool DependsOn(ComponentBase* component);
+
+ protected:
+ ComponentBase* const dependent_;
+ ComponentBase* dependency_;
+
+ private:
+ friend class DependencyCount;
+ friend class WeakReferenceBase;
+
+ void Ready(ComponentBase* dependency);
+ void Disable();
+
+ const scoped_refptr<DependencyCount> counter_;
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(DependencyBase);
+};
+
+// Base class for weak dependencies. Weak dependencies cannot be used
+// directly; they must be converted to a strong dependency or a temp
+// dependency first. May be converted on any thread.
+class WeakReferenceBase {
+ protected:
+ friend class DependencyBase;
+
+ explicit WeakReferenceBase(const ComponentBase& dependency);
+ explicit WeakReferenceBase(const DependencyBase& dependency);
+ WeakReferenceBase(const WeakReferenceBase& other);
+ WeakReferenceBase(WeakReferenceBase&& other);
+ ~WeakReferenceBase();
+
+ const scoped_refptr<DependencyCount> counter_;
+};
+
+// Base class for temp dependencies. Temp dependencies are meant for
+// short-term use only, but can be used from any thread.
+class ScopedReferenceBase {
+ protected:
+ explicit ScopedReferenceBase(const scoped_refptr<DependencyCount>& counter);
+ ScopedReferenceBase(ScopedReferenceBase&& other);
+ ~ScopedReferenceBase();
+
+ const scoped_refptr<DependencyCount> counter_;
+ ComponentBase* dependency_;
+};
+
+// This class is not intended to be long-lived, and should not be declared as
+// a variable type (eg, don't use it as a member variable). Instead, use auto
+// (see WeakReference::Try() for an example).
+template <typename C>
+class Ref_DO_NOT_DECLARE : public ScopedReferenceBase {
+ public:
+ Ref_DO_NOT_DECLARE(Ref_DO_NOT_DECLARE&& other) = default;
+
+ C* operator->() const {
+ DCHECK(dependency_);
+ return static_cast<C*>(dependency_);
+ }
+
+ explicit operator bool() const { return (dependency_ != nullptr); }
+
+ private:
+ friend class WeakReference<C>;
+
+ explicit Ref_DO_NOT_DECLARE(const scoped_refptr<DependencyCount>& counter)
+ : ScopedReferenceBase(counter) {}
+
+ Ref_DO_NOT_DECLARE(const Ref_DO_NOT_DECLARE& other) = delete;
+ Ref_DO_NOT_DECLARE& operator=(const Ref_DO_NOT_DECLARE& rhs) = delete;
+ Ref_DO_NOT_DECLARE& operator=(Ref_DO_NOT_DECLARE&& rhs) = delete;
+};
+
+} // namespace subtle
+} // namespace chromecast
+
+#endif // CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_
diff --git a/chromium/chromecast/base/component/component_unittest.cc b/chromium/chromecast/base/component/component_unittest.cc
new file mode 100644
index 00000000000..2c0fd2ed99e
--- /dev/null
+++ b/chromium/chromecast/base/component/component_unittest.cc
@@ -0,0 +1,379 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/base/component/component.h"
+
+#include <memory>
+
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromecast {
+
+class ComponentTest : public ::testing::Test {
+ protected:
+ ComponentTest() : message_loop_(new base::MessageLoop()) {}
+
+ const std::unique_ptr<base::MessageLoop> message_loop_;
+};
+
+using ComponentDeathTest = ComponentTest;
+
+class ComponentB;
+class ComponentC;
+class ComponentA : public Component<ComponentA> {
+ public:
+ void MakeSelfDependency() {
+ a_.reset(new Component<ComponentA>::Dependency(GetRef(), this));
+ }
+
+ void MakeCircularDependency(const Component<ComponentB>::WeakRef& b) {
+ b_.reset(new Component<ComponentB>::Dependency(b, this));
+ }
+
+ void MakeTransitiveCircularDependency(
+ const Component<ComponentC>::WeakRef& c) {
+ c_.reset(new Component<ComponentC>::Dependency(c, this));
+ }
+
+ void OnEnable() override {
+ if (!fail_enable_) {
+ enabled_ = true;
+ Test();
+ }
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&ComponentA::OnEnableComplete,
+ base::Unretained(this), !fail_enable_));
+ }
+
+ void OnDisable() override {
+ if (enabled_)
+ Test();
+ enabled_ = false;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&ComponentA::OnDisableComplete, base::Unretained(this)));
+ }
+
+ void Test() {
+ EXPECT_TRUE(enabled_);
+ EXPECT_FALSE(fail_enable_);
+ }
+
+ bool enabled() const { return enabled_; }
+ void FailEnable() { fail_enable_ = true; }
+
+ private:
+ bool enabled_ = false;
+ bool fail_enable_ = false;
+
+ std::unique_ptr<Component<ComponentA>::Dependency> a_;
+ std::unique_ptr<Component<ComponentB>::Dependency> b_;
+ std::unique_ptr<Component<ComponentC>::Dependency> c_;
+};
+
+class ComponentB : public Component<ComponentB> {
+ public:
+ explicit ComponentB(const ComponentA::WeakRef& a) : a_(a, this) {}
+
+ void OnEnable() override {
+ if (!fail_enable_) {
+ enabled_ = true;
+ Test();
+ }
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&ComponentB::OnEnableComplete,
+ base::Unretained(this), !fail_enable_));
+ }
+
+ void OnDisable() override {
+ if (enabled_)
+ Test();
+ enabled_ = false;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&ComponentB::OnDisableComplete, base::Unretained(this)));
+ }
+
+ void Test() {
+ EXPECT_TRUE(enabled_);
+ EXPECT_FALSE(fail_enable_);
+ a_->Test();
+ }
+
+ bool enabled() const { return enabled_; }
+ void FailEnable() { fail_enable_ = true; }
+
+ private:
+ bool enabled_ = false;
+ bool fail_enable_ = false;
+
+ ComponentA::Dependency a_;
+};
+
+class ComponentC : public Component<ComponentC> {
+ public:
+ explicit ComponentC(const ComponentB::WeakRef& b) : b_(b, this) {}
+
+ void OnEnable() override {
+ if (!fail_enable_) {
+ enabled_ = true;
+ Test();
+ }
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&ComponentC::OnEnableComplete,
+ base::Unretained(this), !fail_enable_));
+ }
+
+ void OnDisable() override {
+ if (enabled_)
+ Test();
+ enabled_ = false;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&ComponentC::OnDisableComplete, base::Unretained(this)));
+ }
+
+ void Test() {
+ EXPECT_TRUE(enabled_);
+ EXPECT_FALSE(fail_enable_);
+ b_->Test();
+ }
+
+ bool enabled() const { return enabled_; }
+ void FailEnable() { fail_enable_ = true; }
+
+ private:
+ bool enabled_ = false;
+ bool fail_enable_ = false;
+
+ ComponentB::Dependency b_;
+};
+
+#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
+TEST_F(ComponentDeathTest, SelfDependency) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ComponentA a;
+ EXPECT_DEATH(a.MakeSelfDependency(), "Circular dependency");
+}
+
+TEST_F(ComponentDeathTest, CircularDependency) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ComponentA a;
+ ComponentB b(a.GetRef());
+ EXPECT_DEATH(a.MakeCircularDependency(b.GetRef()), "Circular dependency");
+}
+
+TEST_F(ComponentDeathTest, TransitiveCircularDependency) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ComponentA a;
+ ComponentB b(a.GetRef());
+ ComponentC c(b.GetRef());
+ EXPECT_DEATH(a.MakeTransitiveCircularDependency(c.GetRef()),
+ "Circular dependency");
+}
+#endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) &&
+ // GTEST_HAS_DEATH_TEST
+
+TEST_F(ComponentTest, SimpleEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, TransitiveEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ std::unique_ptr<ComponentB> b(new ComponentB(a->GetRef()));
+ std::unique_ptr<ComponentC> c(new ComponentC(b->GetRef()));
+ c->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ EXPECT_TRUE(b->enabled());
+ EXPECT_TRUE(c->enabled());
+ a.release()->Destroy();
+ b.release()->Destroy();
+ c.release()->Destroy();
+}
+
+TEST_F(ComponentTest, FailEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->FailEnable();
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, TransitiveFailEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ std::unique_ptr<ComponentB> b(new ComponentB(a->GetRef()));
+ std::unique_ptr<ComponentC> c(new ComponentC(b->GetRef()));
+ a->FailEnable();
+ c->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ EXPECT_FALSE(b->enabled());
+ EXPECT_FALSE(c->enabled());
+ a.release()->Destroy();
+ b.release()->Destroy();
+ c.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableWhileEnabling) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, EnableTwice) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableTwice) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableAfterFailedEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->FailEnable();
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableAfterNeverEnabled) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableDependencyWhileEnabling) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ std::unique_ptr<ComponentB> b(new ComponentB(a->GetRef()));
+ std::unique_ptr<ComponentC> c(new ComponentC(b->GetRef()));
+ b->Enable();
+ message_loop_->RunUntilIdle();
+ c->Enable();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ EXPECT_FALSE(b->enabled());
+ EXPECT_FALSE(c->enabled());
+ a.release()->Destroy();
+ b.release()->Destroy();
+ c.release()->Destroy();
+}
+
+TEST_F(ComponentTest, EnableDisableEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ a->Disable();
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, DisableEnableDisable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ a->Disable();
+ a->Enable();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, TransitiveEnableDisableEnable) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ std::unique_ptr<ComponentB> b(new ComponentB(a->GetRef()));
+ std::unique_ptr<ComponentC> c(new ComponentC(b->GetRef()));
+ a->Enable();
+ message_loop_->RunUntilIdle();
+ c->Enable();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ EXPECT_FALSE(b->enabled());
+ EXPECT_FALSE(c->enabled());
+ c->Enable();
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(a->enabled());
+ EXPECT_TRUE(b->enabled());
+ EXPECT_TRUE(c->enabled());
+ a.release()->Destroy();
+ b.release()->Destroy();
+ c.release()->Destroy();
+}
+
+TEST_F(ComponentTest, WeakRefs) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ ComponentA::WeakRef weak = a->GetRef();
+ EXPECT_FALSE(weak.Try());
+ a->Enable();
+ EXPECT_FALSE(weak.Try());
+ message_loop_->RunUntilIdle();
+ EXPECT_TRUE(weak.Try());
+ weak.Try()->Test();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(weak.Try());
+ a.release()->Destroy();
+}
+
+TEST_F(ComponentTest, WeakRefsKeepEnabled) {
+ std::unique_ptr<ComponentA> a(new ComponentA());
+ ComponentA::WeakRef weak = a->GetRef();
+ EXPECT_FALSE(weak.Try());
+ a->Enable();
+ EXPECT_FALSE(weak.Try());
+ message_loop_->RunUntilIdle();
+ {
+ auto held_ref = weak.Try();
+ EXPECT_TRUE(held_ref);
+ held_ref->Test();
+ a->Disable();
+ message_loop_->RunUntilIdle();
+ // The held ref keeps |a| enabled until it goes out of scope.
+ EXPECT_TRUE(a->enabled());
+ }
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(a->enabled());
+ EXPECT_FALSE(weak.Try());
+ a.release()->Destroy();
+}
+
+} // namespace chromecast
diff --git a/chromium/chromecast/base/device_capabilities.h b/chromium/chromecast/base/device_capabilities.h
index 88d952569a3..bac412e774f 100644
--- a/chromium/chromecast/base/device_capabilities.h
+++ b/chromium/chromecast/base/device_capabilities.h
@@ -5,11 +5,11 @@
#ifndef CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
#define CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
+#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
namespace base {
class DictionaryValue;
@@ -75,7 +75,7 @@ class DeviceCapabilities {
// to it must be handled serially. Returns response through
// SetValidatedValue().
virtual void Validate(const std::string& path,
- scoped_ptr<base::Value> proposed_value) = 0;
+ std::unique_ptr<base::Value> proposed_value) = 0;
protected:
explicit Validator(DeviceCapabilities* capabilities);
@@ -88,7 +88,7 @@ class DeviceCapabilities {
// DeviceCapabilities. This method passes these parameters to
// DeviceCapabilities, where |path| is updated internally to |new_value|.
void SetValidatedValue(const std::string& path,
- scoped_ptr<base::Value> new_value) const;
+ std::unique_ptr<base::Value> new_value) const;
private:
DeviceCapabilities* const capabilities_;
@@ -118,11 +118,11 @@ class DeviceCapabilities {
// Constructs empty dictionary with no capabilities.
Data();
// Uses |dictionary| as capabilities dictionary.
- explicit Data(scoped_ptr<const base::DictionaryValue> dictionary);
+ explicit Data(std::unique_ptr<const base::DictionaryValue> dictionary);
~Data();
- const scoped_ptr<const base::DictionaryValue> dictionary_;
- const scoped_ptr<const std::string> json_string_;
+ const std::unique_ptr<const base::DictionaryValue> dictionary_;
+ const std::unique_ptr<const std::string> json_string_;
DISALLOW_COPY_AND_ASSIGN(Data);
};
@@ -141,11 +141,11 @@ class DeviceCapabilities {
// singleton, there is meant to be a single instance owned by another module.
// The instance should be created early enough for all managers to register
// themselves, and then live long enough for all managers to unregister.
- static scoped_ptr<DeviceCapabilities> Create();
+ static std::unique_ptr<DeviceCapabilities> Create();
// Creates an instance where all the default capabilities are initialized
// to a predefined default value, and no Validators are registered. For use
// only in unit tests.
- static scoped_ptr<DeviceCapabilities> CreateForTesting();
+ static std::unique_ptr<DeviceCapabilities> CreateForTesting();
// Registers a Validator for a capability. A given key must only be
// registered once, and must be unregistered before calling Register() again.
@@ -180,7 +180,7 @@ class DeviceCapabilities {
// Returns a deep copy of the value at |path|. If the capability at |path|
// does not exist, a null scoped_ptr is returned.
- virtual scoped_ptr<base::Value> GetCapability(
+ virtual std::unique_ptr<base::Value> GetCapability(
const std::string& path) const = 0;
// Use this method to access dictionary and JSON string. No deep copying is
@@ -199,7 +199,7 @@ class DeviceCapabilities {
// method. Client code may use the Observer interface to determine the
// ultimate value used. This method is asynchronous.
virtual void SetCapability(const std::string& path,
- scoped_ptr<base::Value> proposed_value) = 0;
+ std::unique_ptr<base::Value> proposed_value) = 0;
// Iterates through entries in |dict_value| and calls SetCapability() for
// each one. This method is asynchronous.
virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0;
@@ -217,12 +217,12 @@ class DeviceCapabilities {
static scoped_refptr<Data> CreateData();
// Uses |dictionary| as capabilities dictionary.
static scoped_refptr<Data> CreateData(
- scoped_ptr<const base::DictionaryValue> dictionary);
+ std::unique_ptr<const base::DictionaryValue> dictionary);
private:
// Does actual internal update of |path| to |new_value|.
virtual void SetValidatedValue(const std::string& path,
- scoped_ptr<base::Value> new_value) = 0;
+ std::unique_ptr<base::Value> new_value) = 0;
DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities);
};
diff --git a/chromium/chromecast/base/device_capabilities_impl.cc b/chromium/chromecast/base/device_capabilities_impl.cc
index 6fb75bec2aa..c3dfea0d07e 100644
--- a/chromium/chromecast/base/device_capabilities_impl.cc
+++ b/chromium/chromecast/base/device_capabilities_impl.cc
@@ -5,9 +5,11 @@
#include "chromecast/base/device_capabilities_impl.h"
#include <stddef.h>
+
#include <utility>
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
@@ -51,22 +53,22 @@ const char DeviceCapabilities::kKeyHiResAudioSupported[] =
"hi_res_audio_supported";
// static
-scoped_ptr<DeviceCapabilities> DeviceCapabilities::Create() {
- return make_scoped_ptr(new DeviceCapabilitiesImpl);
+std::unique_ptr<DeviceCapabilities> DeviceCapabilities::Create() {
+ return base::WrapUnique(new DeviceCapabilitiesImpl);
}
// static
-scoped_ptr<DeviceCapabilities> DeviceCapabilities::CreateForTesting() {
+std::unique_ptr<DeviceCapabilities> DeviceCapabilities::CreateForTesting() {
DeviceCapabilities* capabilities = new DeviceCapabilitiesImpl;
capabilities->SetCapability(
kKeyBluetoothSupported,
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
capabilities->SetCapability(
- kKeyDisplaySupported, make_scoped_ptr(new base::FundamentalValue(true)));
+ kKeyDisplaySupported, base::WrapUnique(new base::FundamentalValue(true)));
capabilities->SetCapability(
kKeyHiResAudioSupported,
- make_scoped_ptr(new base::FundamentalValue(false)));
- return make_scoped_ptr(capabilities);
+ base::WrapUnique(new base::FundamentalValue(false)));
+ return base::WrapUnique(capabilities);
}
scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() {
@@ -74,7 +76,7 @@ scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() {
}
scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData(
- scoped_ptr<const base::DictionaryValue> dictionary) {
+ std::unique_ptr<const base::DictionaryValue> dictionary) {
DCHECK(dictionary.get());
return make_scoped_refptr(new Data(std::move(dictionary)));
}
@@ -86,7 +88,7 @@ DeviceCapabilities::Validator::Validator(DeviceCapabilities* capabilities)
void DeviceCapabilities::Validator::SetValidatedValue(
const std::string& path,
- scoped_ptr<base::Value> new_value) const {
+ std::unique_ptr<base::Value> new_value) const {
capabilities_->SetValidatedValue(path, std::move(new_value));
}
@@ -97,7 +99,7 @@ DeviceCapabilities::Data::Data()
}
DeviceCapabilities::Data::Data(
- scoped_ptr<const base::DictionaryValue> dictionary)
+ std::unique_ptr<const base::DictionaryValue> dictionary)
: dictionary_(std::move(dictionary)),
json_string_(SerializeToJson(*dictionary_)) {
DCHECK(dictionary_.get());
@@ -120,7 +122,7 @@ DeviceCapabilitiesImpl::ValidatorInfo::~ValidatorInfo() {
void DeviceCapabilitiesImpl::ValidatorInfo::Validate(
const std::string& path,
- scoped_ptr<base::Value> proposed_value) const {
+ std::unique_ptr<base::Value> proposed_value) const {
// Check that we are running Validate on the same thread that ValidatorInfo
// was constructed on.
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -148,7 +150,7 @@ void DeviceCapabilitiesImpl::Register(const std::string& key,
base::AutoLock auto_lock(validation_lock_);
bool added =
- validator_map_.add(key, make_scoped_ptr(new ValidatorInfo(validator)))
+ validator_map_.add(key, base::WrapUnique(new ValidatorInfo(validator)))
.second;
// Check that a validator has not already been registered for this key
DCHECK(added);
@@ -205,12 +207,12 @@ bool DeviceCapabilitiesImpl::HiResAudioSupported() const {
return hi_res_audio_supported;
}
-scoped_ptr<base::Value> DeviceCapabilitiesImpl::GetCapability(
+std::unique_ptr<base::Value> DeviceCapabilitiesImpl::GetCapability(
const std::string& path) const {
scoped_refptr<Data> data_ref = GetData();
const base::Value* value = nullptr;
bool found_path = data_ref->dictionary().Get(path, &value);
- return found_path ? value->CreateDeepCopy() : scoped_ptr<base::Value>();
+ return found_path ? value->CreateDeepCopy() : std::unique_ptr<base::Value>();
}
scoped_refptr<DeviceCapabilities::Data>
@@ -224,7 +226,7 @@ DeviceCapabilitiesImpl::GetData() const {
void DeviceCapabilitiesImpl::SetCapability(
const std::string& path,
- scoped_ptr<base::Value> proposed_value) {
+ std::unique_ptr<base::Value> proposed_value) {
DCHECK(proposed_value.get());
if (!IsValidPath(path)) {
LOG(DFATAL) << "Invalid capability path encountered for SetCapability()";
@@ -276,7 +278,7 @@ void DeviceCapabilitiesImpl::RemoveCapabilitiesObserver(Observer* observer) {
void DeviceCapabilitiesImpl::SetValidatedValue(
const std::string& path,
- scoped_ptr<base::Value> new_value) {
+ std::unique_ptr<base::Value> new_value) {
// All internal writes/modifications of capabilities must occur on same
// thread to avoid race conditions.
if (!task_runner_for_writes_->BelongsToCurrentThread()) {
@@ -305,7 +307,7 @@ void DeviceCapabilitiesImpl::SetValidatedValue(
// data_lock_. If we were to lock and modify the capabilities
// dictionary directly, there may be expensive writes that block other
// threads.
- scoped_ptr<base::DictionaryValue> dictionary_deep_copy(
+ std::unique_ptr<base::DictionaryValue> dictionary_deep_copy(
data_->dictionary().CreateDeepCopy());
dictionary_deep_copy->Set(path, std::move(new_value));
scoped_refptr<Data> new_data(CreateData(std::move(dictionary_deep_copy)));
diff --git a/chromium/chromecast/base/device_capabilities_impl.h b/chromium/chromecast/base/device_capabilities_impl.h
index 07666208d63..70917a5acb3 100644
--- a/chromium/chromecast/base/device_capabilities_impl.h
+++ b/chromium/chromecast/base/device_capabilities_impl.h
@@ -5,6 +5,8 @@
#ifndef CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_
#define CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_
+#include <string>
+
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -29,10 +31,11 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
bool BluetoothSupported() const override;
bool DisplaySupported() const override;
bool HiResAudioSupported() const override;
- scoped_ptr<base::Value> GetCapability(const std::string& path) const override;
+ std::unique_ptr<base::Value> GetCapability(
+ const std::string& path) const override;
scoped_refptr<Data> GetData() const override;
void SetCapability(const std::string& path,
- scoped_ptr<base::Value> proposed_value) override;
+ std::unique_ptr<base::Value> proposed_value) override;
void MergeDictionary(const base::DictionaryValue& dict_value) override;
void AddCapabilitiesObserver(Observer* observer) override;
void RemoveCapabilitiesObserver(Observer* observer) override;
@@ -50,7 +53,7 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
}
void Validate(const std::string& path,
- scoped_ptr<base::Value> proposed_value) const;
+ std::unique_ptr<base::Value> proposed_value) const;
private:
Validator* const validator_;
@@ -67,14 +70,14 @@ class DeviceCapabilitiesImpl : public DeviceCapabilities {
// Map from capability key to corresponding ValidatorInfo. Gets updated
// in Register()/Unregister().
- typedef base::ScopedPtrHashMap<std::string, scoped_ptr<ValidatorInfo>>
+ typedef base::ScopedPtrHashMap<std::string, std::unique_ptr<ValidatorInfo>>
ValidatorMap;
// Internal constructor used by static DeviceCapabilities::Create*() methods.
DeviceCapabilitiesImpl();
void SetValidatedValue(const std::string& path,
- scoped_ptr<base::Value> new_value) override;
+ std::unique_ptr<base::Value> new_value) override;
// Lock for reading/writing data_ pointer
mutable base::Lock data_lock_;
diff --git a/chromium/chromecast/base/device_capabilities_impl_unittest.cc b/chromium/chromecast/base/device_capabilities_impl_unittest.cc
index c1889fc5d97..abfba30926a 100644
--- a/chromium/chromecast/base/device_capabilities_impl_unittest.cc
+++ b/chromium/chromecast/base/device_capabilities_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
@@ -26,7 +27,7 @@ const char kSampleDictionaryCapability[] =
"}";
void GetSampleDefaultCapability(std::string* key,
- scoped_ptr<base::Value>* init_value);
+ std::unique_ptr<base::Value>* init_value);
void TestBasicOperations(DeviceCapabilities* capabilities);
// Simple capability manager that implements the Validator interface. Either
@@ -39,7 +40,7 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
// untouched.
FakeCapabilityManagerSimple(DeviceCapabilities* capabilities,
const std::string& key,
- scoped_ptr<base::Value> init_value,
+ std::unique_ptr<base::Value> init_value,
bool accept_changes)
: DeviceCapabilities::Validator(capabilities),
key_(key),
@@ -55,8 +56,8 @@ class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
}
void Validate(const std::string& path,
- scoped_ptr<base::Value> proposed_value) override {
- ASSERT_TRUE(path.find(key_) == 0);
+ std::unique_ptr<base::Value> proposed_value) override {
+ ASSERT_EQ(path.find(key_), 0ul);
if (accept_changes_)
SetValidatedValue(path, std::move(proposed_value));
}
@@ -83,7 +84,7 @@ class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator {
// Runs TestBasicOperations().
void Validate(const std::string& path,
- scoped_ptr<base::Value> proposed_value) override {
+ std::unique_ptr<base::Value> proposed_value) override {
TestBasicOperations(capabilities());
}
@@ -95,7 +96,7 @@ class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator {
// OnCapabilitiesChanged() without encountering deadlocks/unexpected behavior.
class FakeCapabilitiesObserver : public DeviceCapabilities::Observer {
public:
- FakeCapabilitiesObserver(DeviceCapabilities* capabilities)
+ explicit FakeCapabilitiesObserver(DeviceCapabilities* capabilities)
: capabilities_(capabilities), removed_as_observer(false) {
capabilities_->AddCapabilitiesObserver(this);
}
@@ -135,35 +136,35 @@ class MockCapabilitiesObserver : public DeviceCapabilities::Observer {
// Test fixtures needs an example default capability to test DeviceCapabilities
// methods. Gets a sample key and initial value.
void GetSampleDefaultCapability(std::string* key,
- scoped_ptr<base::Value>* init_value) {
+ std::unique_ptr<base::Value>* init_value) {
DCHECK(key);
DCHECK(init_value);
*key = DeviceCapabilities::kKeyBluetoothSupported;
- *init_value = make_scoped_ptr(new base::FundamentalValue(true));
+ *init_value = base::WrapUnique(new base::FundamentalValue(true));
}
// For test fixtures that test dynamic capabilities, gets a sample key
// and initial value.
void GetSampleDynamicCapability(std::string* key,
- scoped_ptr<base::Value>* init_value) {
+ std::unique_ptr<base::Value>* init_value) {
DCHECK(key);
DCHECK(init_value);
*key = "dummy_dynamic_key";
- *init_value = make_scoped_ptr(new base::FundamentalValue(99));
+ *init_value = base::WrapUnique(new base::FundamentalValue(99));
}
// Gets a value for sample default capability different from |init_value|
// returned in GetSampleDefaultCapability(). Must be of same type as
// |init_value| of course.
-scoped_ptr<base::Value> GetSampleDefaultCapabilityNewValue() {
- return make_scoped_ptr(new base::FundamentalValue(false));
+std::unique_ptr<base::Value> GetSampleDefaultCapabilityNewValue() {
+ return base::WrapUnique(new base::FundamentalValue(false));
}
// Gets a value for sample dynamic capability different from |init_value|
// returned in GetSampleDynamicCapability(). Must be of same type as
// |init_value| of course.
-scoped_ptr<base::Value> GetSampleDynamicCapabilityNewValue() {
- return make_scoped_ptr(new base::FundamentalValue(100));
+std::unique_ptr<base::Value> GetSampleDynamicCapabilityNewValue() {
+ return base::WrapUnique(new base::FundamentalValue(100));
}
// Tests that |json| string matches contents of a DictionaryValue with one entry
@@ -173,7 +174,7 @@ bool JsonStringEquals(const std::string& json,
const base::Value& value) {
base::DictionaryValue dict_value;
dict_value.Set(key, value.CreateDeepCopy());
- scoped_ptr<const std::string> dict_json(SerializeToJson(dict_value));
+ std::unique_ptr<const std::string> dict_json(SerializeToJson(dict_value));
return dict_json.get() && *dict_json == json;
}
@@ -185,7 +186,7 @@ bool JsonStringEquals(const std::string& json,
// class before this function is called.
void TestBasicOperations(DeviceCapabilities* capabilities) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
ASSERT_FALSE(capabilities->GetCapability(key));
@@ -204,7 +205,7 @@ void TestBasicOperations(DeviceCapabilities* capabilities) {
// Write capability again. Provides way of checking that this function
// ran and was successful.
- scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
+ std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
capabilities->SetCapability(key, std::move(new_value));
}
@@ -212,11 +213,11 @@ void TestBasicOperations(DeviceCapabilities* capabilities) {
void AssertBasicOperationsSuccessful(const DeviceCapabilities* capabilities) {
base::RunLoop().RunUntilIdle();
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
- scoped_ptr<base::Value> value = capabilities->GetCapability(key);
+ std::unique_ptr<base::Value> value = capabilities->GetCapability(key);
ASSERT_TRUE(value);
- scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
+ std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
EXPECT_TRUE(base::Value::Equals(value.get(), new_value.get()));
}
@@ -253,14 +254,14 @@ class DeviceCapabilitiesImplTest : public ::testing::Test {
}
private:
- scoped_ptr<base::MessageLoop> message_loop_;
- scoped_ptr<DeviceCapabilities> capabilities_;
- scoped_ptr<MockCapabilitiesObserver> mock_capabilities_observer_;
+ std::unique_ptr<base::MessageLoop> message_loop_;
+ std::unique_ptr<DeviceCapabilities> capabilities_;
+ std::unique_ptr<MockCapabilitiesObserver> mock_capabilities_observer_;
};
// Tests that class is in correct state after Create().
TEST_F(DeviceCapabilitiesImplTest, Create) {
- scoped_ptr<const std::string> empty_dict_string(
+ std::unique_ptr<const std::string> empty_dict_string(
SerializeToJson(base::DictionaryValue()));
EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string);
EXPECT_TRUE(capabilities()->GetData()->dictionary().empty());
@@ -269,14 +270,14 @@ TEST_F(DeviceCapabilitiesImplTest, Create) {
// Tests Register() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Register) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
FakeCapabilityManagerSimple manager(capabilities(), key, nullptr, true);
EXPECT_EQ(capabilities()->GetValidator(key), &manager);
- scoped_ptr<const std::string> empty_dict_string(
+ std::unique_ptr<const std::string> empty_dict_string(
SerializeToJson(base::DictionaryValue()));
EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string);
EXPECT_FALSE(capabilities()->GetCapability(key));
@@ -285,7 +286,7 @@ TEST_F(DeviceCapabilitiesImplTest, Register) {
// Tests Unregister() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Unregister) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
@@ -295,7 +296,7 @@ TEST_F(DeviceCapabilitiesImplTest, Unregister) {
delete manager;
EXPECT_FALSE(capabilities()->GetValidator(key));
- scoped_ptr<const std::string> empty_dict_string(
+ std::unique_ptr<const std::string> empty_dict_string(
SerializeToJson(base::DictionaryValue()));
EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string);
EXPECT_FALSE(capabilities()->GetCapability(key));
@@ -304,7 +305,7 @@ TEST_F(DeviceCapabilitiesImplTest, Unregister) {
// Tests GetCapability() and updating the value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager(capabilities(), key,
init_value->CreateDeepCopy(), true);
@@ -312,7 +313,7 @@ TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) {
EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(),
init_value.get()));
- scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
+ std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(),
@@ -323,12 +324,12 @@ TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) {
TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) {
FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyBluetoothSupported,
- make_scoped_ptr(new base::FundamentalValue(true)), true);
+ base::WrapUnique(new base::FundamentalValue(true)), true);
EXPECT_TRUE(capabilities()->BluetoothSupported());
capabilities()->SetCapability(
DeviceCapabilities::kKeyBluetoothSupported,
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->BluetoothSupported());
}
@@ -337,12 +338,12 @@ TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) {
TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) {
FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyDisplaySupported,
- make_scoped_ptr(new base::FundamentalValue(true)), true);
+ base::WrapUnique(new base::FundamentalValue(true)), true);
EXPECT_TRUE(capabilities()->DisplaySupported());
capabilities()->SetCapability(
DeviceCapabilities::kKeyDisplaySupported,
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->DisplaySupported());
}
@@ -351,12 +352,12 @@ TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) {
TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) {
FakeCapabilityManagerSimple manager(
capabilities(), DeviceCapabilities::kKeyHiResAudioSupported,
- make_scoped_ptr(new base::FundamentalValue(true)), true);
+ base::WrapUnique(new base::FundamentalValue(true)), true);
EXPECT_TRUE(capabilities()->HiResAudioSupported());
capabilities()->SetCapability(
DeviceCapabilities::kKeyHiResAudioSupported,
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(capabilities()->HiResAudioSupported());
}
@@ -365,7 +366,7 @@ TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) {
// rejects the proposed change.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager(capabilities(), key,
init_value->CreateDeepCopy(), false);
@@ -380,7 +381,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) {
// Test that SetCapability() updates the capabilities string correctly
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
FakeCapabilityManagerSimple manager(capabilities(), key,
init_value->CreateDeepCopy(), true);
@@ -388,7 +389,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) {
EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key,
*init_value));
- scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
+ std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key,
@@ -399,7 +400,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) {
// changes
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDefaultCapability(&key, &init_value);
EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3);
@@ -422,7 +423,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) {
// Test adding dynamic capabilities
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) {
std::string key;
- scoped_ptr<base::Value> init_value;
+ std::unique_ptr<base::Value> init_value;
GetSampleDynamicCapability(&key, &init_value);
ASSERT_FALSE(capabilities()->GetCapability(key));
@@ -434,7 +435,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) {
EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key,
*init_value));
- scoped_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue();
+ std::unique_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue();
capabilities()->SetCapability(key, new_value->CreateDeepCopy());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(),
@@ -447,7 +448,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) {
// capability of type DictionaryValue.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
std::string key("dummy_dictionary_key");
- scoped_ptr<base::Value> init_value =
+ std::unique_ptr<base::Value> init_value =
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(init_value);
FakeCapabilityManagerSimple manager(capabilities(), key,
@@ -455,10 +456,10 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
capabilities()->SetCapability(
"dummy_dictionary_key.dummy_field_bool",
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
base::RunLoop().RunUntilIdle();
bool value_bool = true;
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
ASSERT_TRUE(value);
EXPECT_TRUE(value->GetAsBoolean(&value_bool));
@@ -466,7 +467,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
capabilities()->SetCapability(
"dummy_dictionary_key.dummy_field_int",
- make_scoped_ptr(new base::FundamentalValue(100)));
+ base::WrapUnique(new base::FundamentalValue(100)));
base::RunLoop().RunUntilIdle();
int value_int = 0;
value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
@@ -479,7 +480,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
// capability of type DictionaryValue and invalid changes are proposed.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
std::string key("dummy_dictionary_key");
- scoped_ptr<base::Value> init_value =
+ std::unique_ptr<base::Value> init_value =
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(init_value);
FakeCapabilityManagerSimple manager(capabilities(), key,
@@ -487,10 +488,10 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
capabilities()->SetCapability(
"dummy_dictionary_key.dummy_field_bool",
- make_scoped_ptr(new base::FundamentalValue(false)));
+ base::WrapUnique(new base::FundamentalValue(false)));
base::RunLoop().RunUntilIdle();
bool value_bool = false;
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
ASSERT_TRUE(value);
EXPECT_TRUE(value->GetAsBoolean(&value_bool));
@@ -498,7 +499,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
capabilities()->SetCapability(
"dummy_dictionary_key.dummy_field_int",
- make_scoped_ptr(new base::FundamentalValue(100)));
+ base::WrapUnique(new base::FundamentalValue(100)));
base::RunLoop().RunUntilIdle();
int value_int = 0;
value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
@@ -509,7 +510,7 @@ TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
// Test MergeDictionary.
TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) {
- scoped_ptr<base::Value> deserialized_value =
+ std::unique_ptr<base::Value> deserialized_value =
DeserializeFromJson(kSampleDictionaryCapability);
ASSERT_TRUE(deserialized_value);
base::DictionaryValue* dict_value = nullptr;
@@ -521,7 +522,7 @@ TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) {
// First make sure that capabilities get created if they do not exist
bool value_bool = false;
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
capabilities()->GetCapability("dummy_field_bool");
ASSERT_TRUE(value);
EXPECT_TRUE(value->GetAsBoolean(&value_bool));
@@ -561,7 +562,7 @@ TEST_F(DeviceCapabilitiesImplTest, OnCapabilitiesChangedSafe) {
// Trigger FakeCapabilitiesObserver::OnCapabilitiesChanged()
capabilities()->SetCapability(
- "dummy_trigger_key", make_scoped_ptr(new base::FundamentalValue(true)));
+ "dummy_trigger_key", base::WrapUnique(new base::FundamentalValue(true)));
base::RunLoop().RunUntilIdle();
// Check that FakeCapabilitiesObserver::OnCapabilitiesChanged() ran and that
@@ -577,7 +578,7 @@ TEST_F(DeviceCapabilitiesImplTest, ValidateSafe) {
// Trigger FakeCapabilityManagerComplex::Validate()
capabilities()->SetCapability(
- "dummy_validate_key", make_scoped_ptr(new base::FundamentalValue(true)));
+ "dummy_validate_key", base::WrapUnique(new base::FundamentalValue(true)));
base::RunLoop().RunUntilIdle();
// Check that FakeCapabilityManagerComplex::Validate() ran and that behavior
diff --git a/chromium/chromecast/base/error_codes_unittest.cc b/chromium/chromecast/base/error_codes_unittest.cc
index ef9c1924f85..42f36049078 100644
--- a/chromium/chromecast/base/error_codes_unittest.cc
+++ b/chromium/chromecast/base/error_codes_unittest.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chromecast/base/error_codes.h"
+
+#include <memory>
+
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_ptr.h"
#include "base/test/scoped_path_override.h"
-#include "chromecast/base/error_codes.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromecast {
@@ -29,7 +31,7 @@ class ErrorCodesTest : public testing::Test {
private:
base::ScopedTempDir fake_home_dir_;
- scoped_ptr<base::ScopedPathOverride> path_override_;
+ std::unique_ptr<base::ScopedPathOverride> path_override_;
};
TEST_F(ErrorCodesTest, GetInitialErrorCodeReturnsNoErrorIfMissingFile) {
diff --git a/chromium/chromecast/base/metrics/cast_metrics_helper.cc b/chromium/chromecast/base/metrics/cast_metrics_helper.cc
index 9680c8006ed..ac8b7b8f1f2 100644
--- a/chromium/chromecast/base/metrics/cast_metrics_helper.cc
+++ b/chromium/chromecast/base/metrics/cast_metrics_helper.cc
@@ -4,14 +4,21 @@
#include "chromecast/base/metrics/cast_metrics_helper.h"
+#include <memory>
+#include <string>
+#include <vector>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/json/json_string_value_serializer.h"
#include "base/location.h"
#include "base/metrics/histogram.h"
#include "base/metrics/user_metrics.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/time/time.h"
+#include "base/values.h"
#include "chromecast/base/metrics/cast_histograms.h"
#include "chromecast/base/metrics/grouped_histogram.h"
@@ -33,6 +40,14 @@ CastMetricsHelper* g_instance = NULL;
const char kMetricsNameAppInfoDelimiter = '#';
+std::unique_ptr<std::string> SerializeToJson(const base::Value& value) {
+ std::unique_ptr<std::string> json_str(new std::string());
+ JSONStringValueSerializer serializer(json_str.get());
+ if (!serializer.Serialize(value))
+ json_str.reset(nullptr);
+ return json_str;
+}
+
} // namespace
// static
@@ -91,7 +106,6 @@ CastMetricsHelper* CastMetricsHelper::GetInstance() {
CastMetricsHelper::CastMetricsHelper(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(task_runner),
- session_id_("00000000000000000000000000000000"),
metrics_sink_(NULL),
logged_first_audio_(false),
record_action_callback_(base::Bind(&base::RecordComputedAction)) {
@@ -227,6 +241,11 @@ void CastMetricsHelper::SetRecordActionCallback(
record_action_callback_ = callback;
}
+void CastMetricsHelper::SetDummySessionIdForTesting() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ session_id_ = "00000000-0000-0000-0000-000000000000";
+}
+
void CastMetricsHelper::RecordSimpleAction(const std::string& action) {
MAKE_SURE_THREAD(RecordSimpleAction, action);
@@ -272,5 +291,34 @@ void CastMetricsHelper::LogMediumTimeHistogramEvent(
50);
}
+void CastMetricsHelper::RecordApplicationEvent(const std::string& event) {
+ std::unique_ptr<base::DictionaryValue> cast_event(
+ new base::DictionaryValue());
+ cast_event->SetString("name", event);
+ base::TimeTicks now = base::TimeTicks::Now();
+ cast_event->SetDouble("time", now.ToInternalValue());
+ cast_event->SetString("app_id", app_id_);
+ cast_event->SetString("session_id", session_id_);
+ cast_event->SetString("sdk_version", sdk_version_);
+ const std::string message = *SerializeToJson(*cast_event.get()).get();
+ RecordSimpleAction(message);
+}
+
+void CastMetricsHelper::RecordApplicationEventWithValue(
+ const std::string& event,
+ int value) {
+ std::unique_ptr<base::DictionaryValue> cast_event(
+ new base::DictionaryValue());
+ cast_event->SetString("name", event);
+ base::TimeTicks now = base::TimeTicks::Now();
+ cast_event->SetDouble("time", now.ToInternalValue());
+ cast_event->SetString("app_id", app_id_);
+ cast_event->SetString("session_id", session_id_);
+ cast_event->SetString("sdk_version", sdk_version_);
+ cast_event->SetInteger("value", value);
+ const std::string message = *SerializeToJson(*cast_event.get()).get();
+ RecordSimpleAction(message);
+}
+
} // namespace metrics
} // namespace chromecast
diff --git a/chromium/chromecast/base/metrics/cast_metrics_helper.h b/chromium/chromecast/base/metrics/cast_metrics_helper.h
index 43f9f7ed45f..e4b6c6f4a11 100644
--- a/chromium/chromecast/base/metrics/cast_metrics_helper.h
+++ b/chromium/chromecast/base/metrics/cast_metrics_helper.h
@@ -77,6 +77,11 @@ class CastMetricsHelper {
// This is used as an in-place replacement of content::RecordComputedAction().
virtual void RecordSimpleAction(const std::string& action);
+ // Logs application specific events.
+ virtual void RecordApplicationEvent(const std::string& event);
+ virtual void RecordApplicationEventWithValue(const std::string& event,
+ int value);
+
// Logs UMA record of the time the app made its first paint.
virtual void LogTimeToFirstPaint();
@@ -104,6 +109,9 @@ class CastMetricsHelper {
// CastMetricsHelper only honors the last one.
virtual void SetRecordActionCallback(const RecordActionCallback& callback);
+ // Sets an all-0's session ID for running browser tests.
+ void SetDummySessionIdForTesting();
+
protected:
// Creates a CastMetricsHelper instance with no task runner. This should only
// be used by tests, since invoking any non-overridden methods on this
diff --git a/chromium/chromecast/base/metrics/cast_metrics_test_helper.cc b/chromium/chromecast/base/metrics/cast_metrics_test_helper.cc
index 043957fbe85..d0ed02a46d4 100644
--- a/chromium/chromecast/base/metrics/cast_metrics_test_helper.cc
+++ b/chromium/chromecast/base/metrics/cast_metrics_test_helper.cc
@@ -29,6 +29,7 @@ class CastMetricsHelperStub : public CastMetricsHelper {
std::string GetMetricsNameWithAppName(
const std::string& prefix, const std::string& suffix) const override;
void SetMetricsSink(MetricsSink* delegate) override;
+ void RecordSimpleAction(const std::string& action) override;
private:
DISALLOW_COPY_AND_ASSIGN(CastMetricsHelperStub);
@@ -79,6 +80,9 @@ void CastMetricsHelperStub::SetMetricsSink(MetricsSink* delegate) {
} // namespace
+void CastMetricsHelperStub::RecordSimpleAction(const std::string& action) {
+}
+
void InitializeMetricsHelperForTesting() {
if (!stub_instance_exists) {
new CastMetricsHelperStub();
diff --git a/chromium/chromecast/base/metrics/grouped_histogram.cc b/chromium/chromecast/base/metrics/grouped_histogram.cc
index 4d84929aea8..1101a7992c5 100644
--- a/chromium/chromecast/base/metrics/grouped_histogram.cc
+++ b/chromium/chromecast/base/metrics/grouped_histogram.cc
@@ -42,7 +42,7 @@ struct HistogramArgs {
const char* name;
int minimum;
int maximum;
- size_t bucket_count;
+ uint32_t bucket_count;
};
// List of metrics to collect using a GroupedHistogram.
@@ -123,7 +123,7 @@ class GroupedHistogram : public base::Histogram {
std::string metric_to_group_;
Sample minimum_;
Sample maximum_;
- size_t bucket_count_;
+ uint32_t bucket_count_;
DISALLOW_COPY_AND_ASSIGN(GroupedHistogram);
};
@@ -135,7 +135,7 @@ class GroupedHistogram : public base::Histogram {
void PreregisterHistogram(const std::string& name,
GroupedHistogram::Sample minimum,
GroupedHistogram::Sample maximum,
- size_t bucket_count,
+ uint32_t bucket_count,
int32_t flags) {
DCHECK(base::StatisticsRecorder::IsActive());
DCHECK(base::Histogram::InspectConstructionArguments(
diff --git a/chromium/chromecast/base/serializers.cc b/chromium/chromecast/base/serializers.cc
index 87e9dc51cef..7041a961de8 100644
--- a/chromium/chromecast/base/serializers.cc
+++ b/chromium/chromecast/base/serializers.cc
@@ -10,12 +10,12 @@
namespace chromecast {
-scoped_ptr<base::Value> DeserializeFromJson(const std::string& text) {
+std::unique_ptr<base::Value> DeserializeFromJson(const std::string& text) {
JSONStringValueDeserializer deserializer(text);
int error_code = -1;
std::string error_msg;
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
deserializer.Deserialize(&error_code, &error_msg);
DLOG_IF(ERROR, !value) << "JSON error " << error_code << ":" << error_msg;
@@ -23,20 +23,21 @@ scoped_ptr<base::Value> DeserializeFromJson(const std::string& text) {
return value;
}
-scoped_ptr<std::string> SerializeToJson(const base::Value& value) {
- scoped_ptr<std::string> json_str(new std::string());
+std::unique_ptr<std::string> SerializeToJson(const base::Value& value) {
+ std::unique_ptr<std::string> json_str(new std::string());
JSONStringValueSerializer serializer(json_str.get());
if (!serializer.Serialize(value))
json_str.reset(nullptr);
return json_str;
}
-scoped_ptr<base::Value> DeserializeJsonFromFile(const base::FilePath& path) {
+std::unique_ptr<base::Value> DeserializeJsonFromFile(
+ const base::FilePath& path) {
JSONFileValueDeserializer deserializer(path);
int error_code = -1;
std::string error_msg;
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
deserializer.Deserialize(&error_code, &error_msg);
DLOG_IF(ERROR, !value) << "JSON error " << error_code << ":" << error_msg;
diff --git a/chromium/chromecast/base/serializers.h b/chromium/chromecast/base/serializers.h
index 06c79b76067..df648feed65 100644
--- a/chromium/chromecast/base/serializers.h
+++ b/chromium/chromecast/base/serializers.h
@@ -5,9 +5,9 @@
#ifndef CHROMECAST_BASE_SERIALIZERS_H_
#define CHROMECAST_BASE_SERIALIZERS_H_
+#include <memory>
#include <string>
-#include "base/memory/scoped_ptr.h"
namespace base {
class Value;
@@ -19,16 +19,17 @@ namespace chromecast {
// Helper function which deserializes JSON |text| into a base::Value. If |text|
// is empty, is not valid JSON, or if some other deserialization error occurs,
// the return value will hold the NULL pointer.
-scoped_ptr<base::Value> DeserializeFromJson(const std::string& text);
+std::unique_ptr<base::Value> DeserializeFromJson(const std::string& text);
// Helper function which serializes |value| into a JSON string. If a
// serialization error occurs,the return value will hold the NULL pointer.
-scoped_ptr<std::string> SerializeToJson(const base::Value& value);
+std::unique_ptr<std::string> SerializeToJson(const base::Value& value);
// Helper function which deserializes JSON file at |path| into a base::Value.
// If file in |path| is empty, is not valid JSON, or if some other
// deserialization error occurs, the return value will hold the NULL pointer.
-scoped_ptr<base::Value> DeserializeJsonFromFile(const base::FilePath& path);
+std::unique_ptr<base::Value> DeserializeJsonFromFile(
+ const base::FilePath& path);
// Helper function which serializes |value| into the file at |path|. The
// function returns true on success, false otherwise.
diff --git a/chromium/chromecast/base/serializers_unittest.cc b/chromium/chromecast/base/serializers_unittest.cc
index 5724b4b0b79..d5c4189a7b7 100644
--- a/chromium/chromecast/base/serializers_unittest.cc
+++ b/chromium/chromecast/base/serializers_unittest.cc
@@ -30,37 +30,37 @@ const char kTestValue[] = "test_value";
TEST(DeserializeFromJson, EmptyString) {
std::string str;
- scoped_ptr<base::Value> value = DeserializeFromJson(str);
+ std::unique_ptr<base::Value> value = DeserializeFromJson(str);
EXPECT_EQ(nullptr, value.get());
}
TEST(DeserializeFromJson, EmptyJsonObject) {
std::string str = kEmptyJsonString;
- scoped_ptr<base::Value> value = DeserializeFromJson(str);
+ std::unique_ptr<base::Value> value = DeserializeFromJson(str);
EXPECT_NE(nullptr, value.get());
}
TEST(DeserializeFromJson, ProperJsonObject) {
std::string str = kProperJsonString;
- scoped_ptr<base::Value> value = DeserializeFromJson(str);
+ std::unique_ptr<base::Value> value = DeserializeFromJson(str);
EXPECT_NE(nullptr, value.get());
}
TEST(DeserializeFromJson, PoorlyFormedJsonObject) {
std::string str = kPoorlyFormedJsonString;
- scoped_ptr<base::Value> value = DeserializeFromJson(str);
+ std::unique_ptr<base::Value> value = DeserializeFromJson(str);
EXPECT_EQ(nullptr, value.get());
}
TEST(SerializeToJson, BadValue) {
- base::BinaryValue value(scoped_ptr<char[]>(new char[12]), 12);
- scoped_ptr<std::string> str = SerializeToJson(value);
+ base::BinaryValue value(std::unique_ptr<char[]>(new char[12]), 12);
+ std::unique_ptr<std::string> str = SerializeToJson(value);
EXPECT_EQ(nullptr, str.get());
}
TEST(SerializeToJson, EmptyValue) {
base::DictionaryValue value;
- scoped_ptr<std::string> str = SerializeToJson(value);
+ std::unique_ptr<std::string> str = SerializeToJson(value);
ASSERT_NE(nullptr, str.get());
EXPECT_EQ(kEmptyJsonString, *str);
}
@@ -68,16 +68,16 @@ TEST(SerializeToJson, EmptyValue) {
TEST(SerializeToJson, PopulatedValue) {
base::DictionaryValue orig_value;
orig_value.SetString(kTestKey, kTestValue);
- scoped_ptr<std::string> str = SerializeToJson(orig_value);
+ std::unique_ptr<std::string> str = SerializeToJson(orig_value);
ASSERT_NE(nullptr, str.get());
- scoped_ptr<base::Value> new_value = DeserializeFromJson(*str);
+ std::unique_ptr<base::Value> new_value = DeserializeFromJson(*str);
ASSERT_NE(nullptr, new_value.get());
EXPECT_TRUE(new_value->Equals(&orig_value));
}
TEST(DeserializeJsonFromFile, NoFile) {
- scoped_ptr<base::Value> value =
+ std::unique_ptr<base::Value> value =
DeserializeJsonFromFile(base::FilePath("/file/does/not/exist.json"));
EXPECT_EQ(nullptr, value.get());
}
@@ -85,7 +85,7 @@ TEST(DeserializeJsonFromFile, NoFile) {
TEST(DeserializeJsonFromFile, EmptyString) {
ScopedTempFile temp;
EXPECT_EQ(static_cast<int>(strlen("")), temp.Write(""));
- scoped_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
+ std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
EXPECT_EQ(nullptr, value.get());
}
@@ -93,7 +93,7 @@ TEST(DeserializeJsonFromFile, EmptyJsonObject) {
ScopedTempFile temp;
EXPECT_EQ(static_cast<int>(strlen(kEmptyJsonString)),
temp.Write(kEmptyJsonString));
- scoped_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
+ std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
EXPECT_NE(nullptr, value.get());
}
@@ -101,7 +101,7 @@ TEST(DeserializeJsonFromFile, ProperJsonObject) {
ScopedTempFile temp;
EXPECT_EQ(static_cast<int>(strlen(kProperJsonString)),
temp.Write(kProperJsonString));
- scoped_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
+ std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
EXPECT_NE(nullptr, value.get());
}
@@ -109,14 +109,14 @@ TEST(DeserializeJsonFromFile, PoorlyFormedJsonObject) {
ScopedTempFile temp;
EXPECT_EQ(static_cast<int>(strlen(kPoorlyFormedJsonString)),
temp.Write(kPoorlyFormedJsonString));
- scoped_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
+ std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path());
EXPECT_EQ(nullptr, value.get());
}
TEST(SerializeJsonToFile, BadValue) {
ScopedTempFile temp;
- base::BinaryValue value(scoped_ptr<char[]>(new char[12]), 12);
+ base::BinaryValue value(std::unique_ptr<char[]>(new char[12]), 12);
ASSERT_FALSE(SerializeJsonToFile(temp.path(), value));
std::string str(temp.Read());
EXPECT_TRUE(str.empty());
@@ -141,7 +141,7 @@ TEST(SerializeJsonToFile, PopulatedValue) {
std::string str(temp.Read());
ASSERT_FALSE(str.empty());
- scoped_ptr<base::Value> new_value = DeserializeJsonFromFile(temp.path());
+ std::unique_ptr<base::Value> new_value = DeserializeJsonFromFile(temp.path());
ASSERT_NE(nullptr, new_value.get());
EXPECT_TRUE(new_value->Equals(&orig_value));
}
diff --git a/chromium/chromecast/base/system_time_change_notifier_unittest.cc b/chromium/chromecast/base/system_time_change_notifier_unittest.cc
index 7a4ad956bb3..142a17e0504 100644
--- a/chromium/chromecast/base/system_time_change_notifier_unittest.cc
+++ b/chromium/chromecast/base/system_time_change_notifier_unittest.cc
@@ -4,6 +4,8 @@
#include "chromecast/base/system_time_change_notifier.h"
+#include <memory>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
@@ -85,9 +87,9 @@ class SystemTimeChangeNotifierTest : public testing::Test {
run_loop.Run();
}
- scoped_ptr<base::MessageLoop> message_loop_;
- scoped_ptr<SystemTimeChangeNotifierPeriodicMonitor> notifier_;
- scoped_ptr<TimeChangeObserver> observer_;
+ std::unique_ptr<base::MessageLoop> message_loop_;
+ std::unique_ptr<SystemTimeChangeNotifierPeriodicMonitor> notifier_;
+ std::unique_ptr<TimeChangeObserver> observer_;
};
TEST_F(SystemTimeChangeNotifierTest, NotChanged) {