Skip to content

Commit

Permalink
Provide app session id to CAOS
Browse files Browse the repository at this point in the history
Creates a mapping between the audio group ids and the application
session id. When the CAOS is created, it uses the group id in the audio
params to look up the session id and uses that to retrieve the proper
MultiroomInfo.

Bug: b/111669896
Test: Cast to a MZ group, cast_media_unittests, cast_base_unittests, cast_shell_unittests
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I6979bbb2bfc118e4d135bfd354ce1ad956503182
Reviewed-on: https://chromium-review.googlesource.com/c/1221067
Commit-Queue: Aidan Wolter <awolter@chromium.org>
Reviewed-by: Olga Sharonova <olka@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Reviewed-by: Max Morin <maxmorin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607886}
  • Loading branch information
Aidan Wolter authored and Commit Bot committed Nov 14, 2018
1 parent 0d55cfd commit 52bcc12
Show file tree
Hide file tree
Showing 28 changed files with 516 additions and 52 deletions.
9 changes: 7 additions & 2 deletions chromecast/base/cast_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"

namespace chromecast {
namespace {
Expand Down Expand Up @@ -179,15 +180,19 @@ const std::vector<const base::Feature*>& GetFeatures() {
void InitializeFeatureList(const base::DictionaryValue& dcs_features,
const base::ListValue& dcs_experiment_ids,
const std::string& cmd_line_enable_features,
const std::string& cmd_line_disable_features) {
const std::string& cmd_line_disable_features,
const std::string& extra_enable_features) {
DCHECK(!base::FeatureList::GetInstance());

// Set the experiments.
SetExperimentIds(dcs_experiment_ids);

std::string all_enable_features =
cmd_line_enable_features + "," + extra_enable_features;

// Initialize the FeatureList from the command line.
auto feature_list = std::make_unique<base::FeatureList>();
feature_list->InitializeFromCommandLine(cmd_line_enable_features,
feature_list->InitializeFromCommandLine(all_enable_features,
cmd_line_disable_features);

// Override defaults from the DCS config.
Expand Down
6 changes: 4 additions & 2 deletions chromecast/base/cast_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ const std::vector<const base::Feature*>& GetFeatures();
// overrides from DCS and the command line. |dcs_features| and
// |dcs_experiment_ids| are read from the PrefService in the browser process.
// |cmd_line_enable_features| and |cmd_line_disable_features| should be passed
// to this function, unmodified from the command line.
// to this function, unmodified from the command line. |extra_enable_features|
// should contain any extra features to be enabled.
//
// This function should be called before the browser's main loop. After this is
// called, the other functions in this file may be called on any thread.
void InitializeFeatureList(const base::DictionaryValue& dcs_features,
const base::ListValue& dcs_experiment_ids,
const std::string& cmd_line_enable_features,
const std::string& cmd_line_disable_features);
const std::string& cmd_line_disable_features,
const std::string& extra_enable_features);

// Determine whether or not a feature is enabled. This replaces
// base::FeatureList::IsEnabled for Cast builds.
Expand Down
14 changes: 7 additions & 7 deletions chromecast/base/cast_features_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TEST_F(CastFeaturesTest, EnableDisableMultipleBooleanFeatures) {
features->SetBoolean(kTestBooleanFeatureName3, true);
features->SetBoolean(kTestBooleanFeatureName4, true);

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");

// Test that features are properly enabled (they should match the
// DCS config).
Expand Down Expand Up @@ -91,7 +91,7 @@ TEST_F(CastFeaturesTest, EnableSingleFeatureWithParams) {
params->SetString("bool_key", "true");
features->Set(kTestParamsFeatureName, std::move(params));

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");

// Test that this feature is enabled, and params are correct.
ASSERT_TRUE(chromecast::IsFeatureEnabled(test_feature));
Expand Down Expand Up @@ -150,7 +150,7 @@ TEST_F(CastFeaturesTest, CommandLineOverridesDcsAndDefault) {
.append(kTestParamsFeatureName);

InitializeFeatureList(*features, *experiments, enabled_features,
disabled_features);
disabled_features, "");

// Test that features are properly enabled (they should match the
// DCS config).
Expand All @@ -170,7 +170,7 @@ TEST_F(CastFeaturesTest, SetEmptyExperiments) {
auto experiments = std::make_unique<base::ListValue>();
auto features = std::make_unique<base::DictionaryValue>();

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");
ASSERT_EQ(0u, GetDCSExperimentIds().size());
}

Expand All @@ -186,7 +186,7 @@ TEST_F(CastFeaturesTest, SetGoodExperiments) {
expected.insert(id);
}

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");
ASSERT_EQ(expected, GetDCSExperimentIds());
}

Expand All @@ -204,7 +204,7 @@ TEST_F(CastFeaturesTest, SetSomeGoodExperiments) {
expected.insert(1234);
expected.insert(1);

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");
ASSERT_EQ(expected, GetDCSExperimentIds());
}

Expand All @@ -218,7 +218,7 @@ TEST_F(CastFeaturesTest, SetAllBadExperiments) {

std::unordered_set<int32_t> expected;

InitializeFeatureList(*features, *experiments, "", "");
InitializeFeatureList(*features, *experiments, "", "", "");
ASSERT_EQ(expected, GetDCSExperimentIds());
}

Expand Down
8 changes: 7 additions & 1 deletion chromecast/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ cast_source_set("browser") {
"cast_quota_permission_context.h",
"cast_resource_dispatcher_host_delegate.cc",
"cast_resource_dispatcher_host_delegate.h",
"cast_session_id_map.cc",
"cast_session_id_map.h",
"cast_web_contents_impl.cc",
"cast_web_contents_impl.h",
"cast_web_contents_manager.cc",
Expand Down Expand Up @@ -495,7 +497,7 @@ cast_source_set("unittests") {
"bluetooth/cast_bluetooth_chooser_unittest.cc",
"cast_media_blocker_unittest.cc",
"cast_network_delegate_unittest.cc",
"cast_touch_device_manager_unittest.cc",
"cast_session_id_map_unittest.cc",
"devtools/cast_devtools_manager_delegate_unittest.cc",
"lru_renderer_cache_test.cc",
"network_context_manager_unittest.cc",
Expand All @@ -513,6 +515,10 @@ cast_source_set("unittests") {
"//ui/gl:test_support",
]

if (!is_android) {
sources += [ "cast_touch_device_manager_unittest.cc" ]
}

if (enable_chromecast_extensions && use_aura) {
sources += [ "accessibility/touch_exploration_controller_unittest.cc" ]
deps += [
Expand Down
26 changes: 23 additions & 3 deletions chromecast/browser/cast_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
#include "chromecast/browser/cast_browser_context.h"
#include "chromecast/browser/cast_browser_main_parts.h"
#include "chromecast/browser/cast_browser_process.h"
#include "chromecast/browser/cast_feature_list_creator.h"
#include "chromecast/browser/cast_http_user_agent_settings.h"
#include "chromecast/browser/cast_navigation_ui_data.h"
#include "chromecast/browser/cast_network_delegate.h"
#include "chromecast/browser/cast_quota_permission_context.h"
#include "chromecast/browser/cast_resource_dispatcher_host_delegate.h"
#include "chromecast/browser/cast_session_id_map.h"
#include "chromecast/browser/default_navigation_throttle.h"
#include "chromecast/browser/devtools/cast_devtools_manager_delegate.h"
#include "chromecast/browser/grit/cast_browser_resources.h"
Expand Down Expand Up @@ -62,6 +64,7 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
Expand Down Expand Up @@ -168,7 +171,16 @@ CastContentBrowserClient::CastContentBrowserClient(
CastFeatureListCreator* cast_feature_list_creator)
: cast_browser_main_parts_(nullptr),
url_request_context_factory_(new URLRequestContextFactory()),
cast_feature_list_creator_(cast_feature_list_creator) {}
cast_feature_list_creator_(cast_feature_list_creator) {
// TODO(awolter): Remove this once the feature is on by default.
const std::string extra_enable_features =
#if defined(OS_ANDROID)
features::kAudioServiceAudioStreams.name;
#else
std::string();
#endif
cast_feature_list_creator_->SetExtraEnableFeatures(extra_enable_features);
}

CastContentBrowserClient::~CastContentBrowserClient() {
#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND)
Expand Down Expand Up @@ -266,21 +278,29 @@ CastContentBrowserClient::CreateAudioManager(
}
#endif

// Create the audio thread and initialize the CastSessionIdMap. We need to
// initialize the CastSessionIdMap as soon as possible, so that the task
// runner gets set before any calls to it.
auto audio_thread = std::make_unique<::media::AudioThreadImpl>();
shell::CastSessionIdMap::GetInstance(audio_thread->GetTaskRunner());

#if defined(USE_ALSA)
return std::make_unique<media::CastAudioManagerAlsa>(
std::make_unique<::media::AudioThreadImpl>(), audio_log_factory,
std::move(audio_thread), audio_log_factory,
base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory,
base::Unretained(this)),
base::BindRepeating(&shell::CastSessionIdMap::GetSessionId),
base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::UI}),
GetMediaTaskRunner(),
content::ServiceManagerConnection::GetForProcess()->GetConnector(),
use_mixer);
#else
return std::make_unique<media::CastAudioManager>(
std::make_unique<::media::AudioThreadImpl>(), audio_log_factory,
std::move(audio_thread), audio_log_factory,
base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory,
base::Unretained(this)),
base::BindRepeating(&shell::CastSessionIdMap::GetSessionId),
base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::UI}),
GetMediaTaskRunner(),
Expand Down
8 changes: 7 additions & 1 deletion chromecast/browser/cast_feature_list_creator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ void CastFeatureListCreator::CreatePrefServiceAndFeatureList() {
InitializeFeatureList(
*features_dict, *experiment_ids,
command_line->GetSwitchValueASCII(switches::kEnableFeatures),
command_line->GetSwitchValueASCII(switches::kDisableFeatures));
command_line->GetSwitchValueASCII(switches::kDisableFeatures),
extra_enable_features_);
}

std::unique_ptr<PrefService> CastFeatureListCreator::TakePrefService() {
return std::move(pref_service_);
}

void CastFeatureListCreator::SetExtraEnableFeatures(
std::string extra_enable_features) {
extra_enable_features_ = extra_enable_features;
}

} // namespace chromecast
6 changes: 6 additions & 0 deletions chromecast/browser/cast_feature_list_creator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define CHROMECAST_BROWSER_CAST_FEATURE_LIST_CREATOR_H_

#include <memory>
#include <string>

class PrefService;

Expand All @@ -26,10 +27,15 @@ class CastFeatureListCreator {
// Takes ownership of the |PrefService| previously created.
std::unique_ptr<PrefService> TakePrefService();

// Sets the extra features to be enabled.
void SetExtraEnableFeatures(std::string extra_enable_features);

private:
// Holds the |PrefService| until TakePrefService() is called and ownership
// is taken away.
std::unique_ptr<PrefService> pref_service_;
// Extra features that can be enabled at run time.
std::string extra_enable_features_;
};

} // namespace chromecast
Expand Down
2 changes: 2 additions & 0 deletions chromecast/browser/cast_navigation_ui_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "chromecast/browser/cast_navigation_ui_data.h"

#include "chromecast/browser/cast_session_id_map.h"
#include "content/public/browser/web_contents.h"

namespace chromecast {
Expand Down Expand Up @@ -32,6 +33,7 @@ void CastNavigationUIData::SetSessionIdForWebContents(
DCHECK(web_contents);
web_contents->SetUserData(kUserDataKey,
std::make_unique<SessionIdUserData>(session_id));
CastSessionIdMap::SetSessionId(session_id, web_contents);
}

// static
Expand Down
126 changes: 126 additions & 0 deletions chromecast/browser/cast_session_id_map.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2018 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/browser/cast_session_id_map.h"

#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner_util.h"
#include "base/time/time.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"

namespace chromecast {
namespace shell {

// A small class that listens for the destruction of a WebContents, and forwards
// the event to the CastSessionIdMap with the appropriate group_id.
class CastSessionIdMap::GroupObserver : content::WebContentsObserver {
public:
using GroupDestroyedCallback =
base::OnceCallback<void(base::UnguessableToken)>;

GroupObserver(content::WebContents* web_contents,
GroupDestroyedCallback destroyed_callback)
: destroyed_callback_(std::move(destroyed_callback)),
group_id_(web_contents->GetAudioGroupId()) {
content::WebContentsObserver::Observe(web_contents);
}

private:
// content::WebContentsObserver implementation:
void WebContentsDestroyed() override {
DCHECK(destroyed_callback_);
content::WebContentsObserver::Observe(nullptr);
std::move(destroyed_callback_).Run(group_id_);
}

GroupDestroyedCallback destroyed_callback_;
base::UnguessableToken group_id_;
};

// static
CastSessionIdMap* CastSessionIdMap::GetInstance(
base::SequencedTaskRunner* task_runner) {
static base::NoDestructor<CastSessionIdMap> map(task_runner);
return map.get();
}

// static
void CastSessionIdMap::SetSessionId(std::string session_id,
content::WebContents* web_contents) {
base::UnguessableToken group_id = web_contents->GetAudioGroupId();
GetInstance()->SetSessionIdInternal(session_id, group_id, web_contents);
}

// static
std::string CastSessionIdMap::GetSessionId(std::string group_id) {
return GetInstance()->GetSessionIdInternal(group_id);
}

CastSessionIdMap::CastSessionIdMap(base::SequencedTaskRunner* task_runner)
: task_runner_(task_runner), weak_factory_(this) {
DCHECK(task_runner_);
DETACH_FROM_SEQUENCE(sequence_checker_);
}

CastSessionIdMap::~CastSessionIdMap() = default;

void CastSessionIdMap::SetSessionIdInternal(
std::string session_id,
base::UnguessableToken group_id,
content::WebContents* web_contents) {
if (!task_runner_->RunsTasksInCurrentSequence()) {
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&CastSessionIdMap::SetSessionIdInternal,
weak_factory_.GetWeakPtr(), std::move(session_id),
group_id, web_contents));
return;
}

// This check is required to bind to the current sequence.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(web_contents);

VLOG(1) << "Mapping session_id=" << session_id
<< " to group_id=" << group_id.ToString();
// Unretained is safe because the GroupObserver is always owned by the
// CastSessionIdMap.
auto destroyed_callback = base::BindOnce(&CastSessionIdMap::OnGroupDestroyed,
base::Unretained(this));
auto group_observer = std::make_unique<GroupObserver>(
web_contents, std::move(destroyed_callback));
auto group_data = std::make_pair(session_id, std::move(group_observer));
mapping_.emplace(group_id.ToString(), std::move(group_data));
}

std::string CastSessionIdMap::GetSessionIdInternal(std::string group_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

auto it = mapping_.find(group_id);
if (it != mapping_.end())
return it->second.first;
return std::string();
}

void CastSessionIdMap::OnGroupDestroyed(base::UnguessableToken group_id) {
task_runner_->PostTask(FROM_HERE,
base::BindOnce(&CastSessionIdMap::RemoveGroupId,
weak_factory_.GetWeakPtr(), group_id));
}

void CastSessionIdMap::RemoveGroupId(base::UnguessableToken group_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

auto it = mapping_.find(group_id.ToString());
if (it != mapping_.end()) {
VLOG(1) << "Removing mapping for session_id=" << it->second.first
<< " to group_id=" << group_id.ToString();
mapping_.erase(it);
}
}

} // namespace shell
} // namespace chromecast
Loading

0 comments on commit 52bcc12

Please sign in to comment.