Commit fe2e0ce0 authored by jdufault's avatar jdufault Committed by Commit bot

Add the supporting code for the cast system tray integration

- Adds CastConfigDelegate which gathers casting data from the chromecast extension
- Provides access to the CastConfigDelegate to UI code via the SystemTrayDelegate

BUG=433140

Review URL: https://codereview.chromium.org/1115083002

Cr-Commit-Position: refs/heads/master@{#330266}
parent 8a333369
......@@ -43,6 +43,8 @@
'autoclick/autoclick_controller.h',
'cancel_mode.cc',
'cancel_mode.h',
'cast_config_delegate.cc',
'cast_config_delegate.h',
'content/display/display_color_manager_chromeos.cc',
'content/display/display_color_manager_chromeos.h',
'content/display/screen_orientation_controller_chromeos.cc',
......
// Copyright 2015 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 "ash/cast_config_delegate.h"
namespace ash {
CastConfigDelegate::Receiver::Receiver() {
}
CastConfigDelegate::Receiver::~Receiver() {
}
CastConfigDelegate::Activity::Activity() {
}
CastConfigDelegate::Activity::~Activity() {
}
CastConfigDelegate::ReceiverAndActivity::ReceiverAndActivity() {
}
CastConfigDelegate::ReceiverAndActivity::~ReceiverAndActivity() {
}
} // namespace ash
// Copyright 2015 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 ASH_CAST_CONFIG_DELEGATE_H_
#define ASH_CAST_CONFIG_DELEGATE_H_
#include <map>
#include <string>
#include "ash/ash_export.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "url/gurl.h"
namespace ash {
// This delegate allows the UI code in ash, e.g. |TrayCastDetailedView|,
// to access the cast extension.
class CastConfigDelegate {
public:
struct ASH_EXPORT Receiver {
Receiver();
~Receiver();
std::string id;
base::string16 name;
};
struct ASH_EXPORT Activity {
// The tab identifier that we are casting. These are the special tab values
// taken from the chromecast extension itself. If an actual tab is being
// casted, then the TabId will be >= 0.
enum TabId {
EXTENSION = -1,
DESKTOP = -2,
DISCOVERED_ACTIVITY = -3,
EXTERNAL_EXTENSION_CLIENT = -4
};
Activity();
~Activity();
std::string id;
base::string16 title;
std::string activity_type;
bool allow_stop = false;
// The id for the tab we are casting. Could be one of the TabId values,
// or a value >= 0 that represents that tab index of the tab we are
// casting. We default to casting the desktop, as a tab may not
// necessarily exist.
int tab_id = TabId::DESKTOP;
};
struct ASH_EXPORT ReceiverAndActivity {
ReceiverAndActivity();
~ReceiverAndActivity();
Receiver receiver;
Activity activity;
};
// The key is the receiver id.
using ReceiversAndActivites = std::map<std::string, ReceiverAndActivity>;
using ReceiversAndActivitesCallback =
base::Callback<void(const ReceiversAndActivites&)>;
virtual ~CastConfigDelegate() {}
// Returns true if cast extension is installed.
virtual bool HasCastExtension() const = 0;
// Fetches the current set of receivers and their possible activities. This
// method will lookup the current chromecast extension and query its current
// state. The |callback| will be invoked when the receiver/activity data is
// available.
virtual void GetReceiversAndActivities(
const ReceiversAndActivitesCallback& callback) = 0;
// Cast to a receiver specified by |receiver_id|.
virtual void CastToReceiver(const std::string& receiver_id) = 0;
// Stop ongoing cast. The |activity_id| is the unique identifier associated
// with the ongoing cast. Each receiver has only one possible activity
// associated with it. The |activity_id| is available by invoking
// GetReceiversAndActivities(); if the receiver is currently casting, then the
// associated activity data will have an id. This id can be used to stop the
// cast in this method.
virtual void StopCasting(const std::string& activity_id) = 0;
// Opens Options page for cast.
virtual void LaunchCastOptions() = 0;
private:
DISALLOW_ASSIGN(CastConfigDelegate);
};
} // namespace ash
#endif // ASH_CAST_CONFIG_DELEGATE_H_
......@@ -223,6 +223,10 @@ bool SystemTrayDelegate::GetBluetoothDiscovering() {
void SystemTrayDelegate::ChangeProxySettings() {
}
CastConfigDelegate* SystemTrayDelegate::GetCastConfigDelegate() const {
return nullptr;
}
NetworkingConfigDelegate* SystemTrayDelegate::GetNetworkingConfigDelegate()
const {
return nullptr;
......
......@@ -98,6 +98,7 @@ struct ASH_EXPORT UpdateInfo {
using IMEInfoList = std::vector<IMEInfo>;
class CastConfigDelegate;
class NetworkingConfigDelegate;
class VPNDelegate;
......@@ -284,6 +285,9 @@ class ASH_EXPORT SystemTrayDelegate {
// Shows UI for changing proxy settings.
virtual void ChangeProxySettings();
// Returns CastConfigDelegate. May return nullptr.
virtual CastConfigDelegate* GetCastConfigDelegate() const;
// Returns NetworkingConfigDelegate. May return nullptr.
virtual NetworkingConfigDelegate* GetNetworkingConfigDelegate() const;
......
// Copyright 2015 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 "chrome/browser/ui/ash/cast_config_delegate_chromeos.h"
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/tab_capture/tab_capture_api.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"
namespace chromeos {
namespace {
using JavaScriptResultCallback =
content::RenderFrameHost::JavaScriptResultCallback;
// Returns the cast extension if it exists.
const extensions::Extension* FindCastExtension() {
// TODO(jdufault): Figure out how to correctly handle multiprofile mode.
// See crbug.com/488751
Profile* profile = ProfileManager::GetActiveUserProfile();
const extensions::ExtensionRegistry* extension_registry =
extensions::ExtensionRegistry::Get(profile);
const extensions::ExtensionSet& enabled_extensions =
extension_registry->enabled_extensions();
for (size_t i = 0; i < arraysize(extensions::kChromecastExtensionIds); ++i) {
const std::string extension_id(extensions::kChromecastExtensionIds[i]);
if (enabled_extensions.Contains(extension_id)) {
return extension_registry->GetExtensionById(
extension_id, extensions::ExtensionRegistry::ENABLED);
}
}
return nullptr;
}
// Utility method that returns the currently active RenderViewHost.
content::RenderViewHost* GetRenderViewHost() {
const extensions::Extension* extension = FindCastExtension();
if (!extension)
return nullptr;
// TODO(jdufault): Figure out how to correctly handle multiprofile mode.
// See crbug.com/488751
Profile* profile = ProfileManager::GetActiveUserProfile();
if (!profile)
return nullptr;
extensions::ProcessManager* pm = extensions::ProcessManager::Get(profile);
return pm->GetBackgroundHostForExtension(extension->id())->render_view_host();
}
// Executes JavaScript in the context of the cast extension's background page.
void ExecuteJavaScript(const std::string& javascript) {
auto rvh = GetRenderViewHost();
if (!rvh)
return;
rvh->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(javascript));
}
// Executes JavaScript in the context of the cast extension's background page.
// Invokes |callback| with the return value of the invoked javascript.
void ExecuteJavaScriptWithCallback(const std::string& javascript,
const JavaScriptResultCallback& callback) {
auto rvh = GetRenderViewHost();
if (!rvh)
return;
rvh->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(javascript),
callback);
}
// Handler for GetReceiversAndActivities.
void GetReceiversAndActivitiesCallback(
const ash::CastConfigDelegate::ReceiversAndActivitesCallback& callback,
const base::Value* value) {
ash::CastConfigDelegate::ReceiversAndActivites receiver_activites;
const base::ListValue* ra_list = nullptr;
if (value->GetAsList(&ra_list)) {
for (auto i = ra_list->begin(); i != ra_list->end(); ++i) {
const base::DictionaryValue* ra_dict = nullptr;
if ((*i)->GetAsDictionary(&ra_dict)) {
const base::DictionaryValue* receiver_dict(nullptr),
*activity_dict(nullptr);
ash::CastConfigDelegate::ReceiverAndActivity receiver_activity;
if (ra_dict->GetDictionary("receiver", &receiver_dict)) {
receiver_dict->GetString("name", &receiver_activity.receiver.name);
receiver_dict->GetString("id", &receiver_activity.receiver.id);
}
if (ra_dict->GetDictionary("activity", &activity_dict) &&
!activity_dict->empty()) {
activity_dict->GetString("id", &receiver_activity.activity.id);
activity_dict->GetString("title", &receiver_activity.activity.title);
activity_dict->GetString("activityType",
&receiver_activity.activity.activity_type);
activity_dict->GetBoolean("allowStop",
&receiver_activity.activity.allow_stop);
activity_dict->GetInteger("tabId",
&receiver_activity.activity.tab_id);
}
receiver_activites[receiver_activity.receiver.id] = receiver_activity;
}
}
}
callback.Run(receiver_activites);
}
} // namespace
CastConfigDelegateChromeos::CastConfigDelegateChromeos() {
}
CastConfigDelegateChromeos::~CastConfigDelegateChromeos() {
}
bool CastConfigDelegateChromeos::HasCastExtension() const {
return FindCastExtension() != nullptr;
}
void CastConfigDelegateChromeos::GetReceiversAndActivities(
const ReceiversAndActivitesCallback& callback) {
ExecuteJavaScriptWithCallback(
"backgroundSetup.getMirrorCapableReceiversAndActivities();",
base::Bind(&GetReceiversAndActivitiesCallback, callback));
}
void CastConfigDelegateChromeos::CastToReceiver(
const std::string& receiver_id) {
ExecuteJavaScript("backgroundSetup.launchDesktopMirroring('" + receiver_id +
"');");
}
void CastConfigDelegateChromeos::StopCasting(const std::string& activity_id) {
ExecuteJavaScript("backgroundSetup.stopCastMirroring('user-stop');");
}
void CastConfigDelegateChromeos::LaunchCastOptions() {
chrome::NavigateParams params(
ProfileManager::GetActiveUserProfile(),
FindCastExtension()->GetResourceURL("options.html"),
ui::PAGE_TRANSITION_LINK);
params.disposition = NEW_FOREGROUND_TAB;
params.window_action = chrome::NavigateParams::SHOW_WINDOW;
chrome::Navigate(&params);
}
} // namespace chromeos
// Copyright 2015 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 CHROME_BROWSER_UI_ASH_CAST_CONFIG_DELEGATE_CHROMEOS_H_
#define CHROME_BROWSER_UI_ASH_CAST_CONFIG_DELEGATE_CHROMEOS_H_
#include <string>
#include "ash/cast_config_delegate.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/values.h"
namespace chromeos {
// A class which allows the ash tray to communicate with the cast extension.
class CastConfigDelegateChromeos : public ash::CastConfigDelegate {
public:
CastConfigDelegateChromeos();
private:
~CastConfigDelegateChromeos() override;
// CastConfigDelegate:
bool HasCastExtension() const override;
void GetReceiversAndActivities(
const ReceiversAndActivitesCallback& callback) override;
void CastToReceiver(const std::string& receiver_id) override;
void StopCasting(const std::string& activity_id) override;
void LaunchCastOptions() override;
DISALLOW_COPY_AND_ASSIGN(CastConfigDelegateChromeos);
};
} // namespace chromeos
#endif // CHROME_BROWSER_UI_ASH_CAST_CONFIG_DELEGATE_CHROMEOS_H_
......@@ -71,6 +71,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "chrome/browser/ui/ash/cast_config_delegate_chromeos.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/networking_config_delegate_chromeos.h"
#include "chrome/browser/ui/ash/system_tray_delegate_utils.h"
......@@ -195,6 +196,7 @@ SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
have_session_length_limit_(false),
should_run_bluetooth_discovery_(false),
session_started_(false),
cast_config_delegate_(new CastConfigDelegateChromeos()),
networking_config_delegate_(new NetworkingConfigDelegateChromeos()),
volume_control_delegate_(new VolumeController()),
device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
......@@ -788,6 +790,11 @@ void SystemTrayDelegateChromeOS::ChangeProxySettings() {
LoginDisplayHostImpl::default_host()->OpenProxySettings();
}
ash::CastConfigDelegate* SystemTrayDelegateChromeOS::GetCastConfigDelegate()
const {
return cast_config_delegate_.get();
}
ash::NetworkingConfigDelegate*
SystemTrayDelegateChromeOS::GetNetworkingConfigDelegate() const {
return networking_config_delegate_.get();
......
......@@ -125,6 +125,7 @@ class SystemTrayDelegateChromeOS
bool GetBluetoothEnabled() override;
bool GetBluetoothDiscovering() override;
void ChangeProxySettings() override;
ash::CastConfigDelegate* GetCastConfigDelegate() const override;
ash::NetworkingConfigDelegate* GetNetworkingConfigDelegate() const override;
ash::VolumeControlDelegate* GetVolumeControlDelegate() const override;
void SetVolumeControlDelegate(
......@@ -292,6 +293,7 @@ class SystemTrayDelegateChromeOS
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
scoped_ptr<device::BluetoothDiscoverySession> bluetooth_discovery_session_;
scoped_ptr<ash::CastConfigDelegate> cast_config_delegate_;
scoped_ptr<ash::NetworkingConfigDelegate> networking_config_delegate_;
scoped_ptr<ash::VolumeControlDelegate> volume_control_delegate_;
scoped_ptr<CrosSettingsObserverSubscription> device_settings_observer_;
......
......@@ -548,6 +548,8 @@
'browser/ui/ash/ash_keyboard_controller_proxy.h',
'browser/ui/ash/ash_util.cc',
'browser/ui/ash/ash_util.h',
'browser/ui/ash/cast_config_delegate_chromeos.cc',
'browser/ui/ash/cast_config_delegate_chromeos.h',
'browser/ui/ash/chrome_launcher_prefs.cc',
'browser/ui/ash/chrome_launcher_prefs.h',
'browser/ui/ash/chrome_new_window_delegate.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment