0

Add initial cecPrivate API

This adds the plumbing from JavaScript to D-Bus. There's currently
nothing that will act on the D-Bus events.

BUG=chromium:824667

Change-Id: Iaf87c97ec874b2dccd50453e6b7b3f4fcffc8df5
Reviewed-on: https://chromium-review.googlesource.com/992332
Reviewed-by: Jesse Doherty <jwd@chromium.org>
Reviewed-by: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: Steven Bennetts <stevenjb@chromium.org>
Reviewed-by: Dan Erat <derat@chromium.org>
Commit-Queue: Felix Ekblom <felixe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551973}
This commit is contained in:
Felix Ekblom
2018-04-19 09:38:43 +00:00
committed by Commit Bot
parent 78e2273bb4
commit bba090eb66
22 changed files with 403 additions and 1 deletions

@ -808,6 +808,7 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermission::kBrailleDisplayPrivate);
skip.insert(APIPermission::kCast);
skip.insert(APIPermission::kCastStreaming);
skip.insert(APIPermission::kCecPrivate);
skip.insert(APIPermission::kChromeosInfoPrivate);
skip.insert(APIPermission::kCloudPrintPrivate);
skip.insert(APIPermission::kCommandLinePrivate);

@ -153,6 +153,8 @@ component("chromeos") {
"dbus/biod/fake_biod_client.h",
"dbus/blocking_method_caller.cc",
"dbus/blocking_method_caller.h",
"dbus/cec_service_client.cc",
"dbus/cec_service_client.h",
"dbus/concierge_client.cc",
"dbus/concierge_client.h",
"dbus/cras_audio_client.cc",
@ -182,6 +184,8 @@ component("chromeos") {
"dbus/fake_arc_oemcrypto_client.h",
"dbus/fake_auth_policy_client.cc",
"dbus/fake_auth_policy_client.h",
"dbus/fake_cec_service_client.cc",
"dbus/fake_cec_service_client.h",
"dbus/fake_concierge_client.cc",
"dbus/fake_concierge_client.h",
"dbus/fake_cras_audio_client.cc",

@ -0,0 +1,78 @@
// 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 "chromeos/dbus/cec_service_client.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/dbus/fake_cec_service_client.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
namespace {
// Real implementation of CecServiceClient.
class CecServiceClientImpl : public CecServiceClient {
public:
CecServiceClientImpl() = default;
~CecServiceClientImpl() override = default;
void SendStandBy() override {
dbus::MethodCall method_call(cecservice::kCecServiceInterface,
cecservice::kSendStandByToAllDevicesMethod);
cec_service_proxy_->CallMethod(&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::DoNothing());
}
void SendWakeUp() override {
dbus::MethodCall method_call(cecservice::kCecServiceInterface,
cecservice::kSendWakeUpToAllDevicesMethod);
cec_service_proxy_->CallMethod(&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::DoNothing());
}
protected:
void Init(dbus::Bus* bus) override {
cec_service_proxy_ =
bus->GetObjectProxy(cecservice::kCecServiceName,
dbus::ObjectPath(cecservice::kCecServicePath));
}
private:
scoped_refptr<dbus::ObjectProxy> cec_service_proxy_;
DISALLOW_COPY_AND_ASSIGN(CecServiceClientImpl);
};
} // namespace
////////////////////////////////////////////////////////////////////////////////
// CecServiceClient
CecServiceClient::CecServiceClient() = default;
CecServiceClient::~CecServiceClient() = default;
// static
std::unique_ptr<CecServiceClient> CecServiceClient::Create(
DBusClientImplementationType type) {
if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
return std::make_unique<CecServiceClientImpl>();
DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
return std::make_unique<FakeCecServiceClient>();
}
} // namespace chromeos

@ -0,0 +1,51 @@
// 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.
#ifndef CHROMEOS_DBUS_CEC_SERVICE_CLIENT_H_
#define CHROMEOS_DBUS_CEC_SERVICE_CLIENT_H_
#include <memory>
#include "base/macros.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/dbus_client_implementation_type.h"
#include "chromeos/dbus/dbus_method_call_status.h"
namespace chromeos {
// CecServiceClient is used to communicate with org.chromium.CecService.
//
// CecService offers a small subset of HDMI CEC capabilities focused on power
// management of connected displays.
//
// All methods should be called from the origin thread (UI thread)
// which initializes the DBusThreadManager instance.
class CHROMEOS_EXPORT CecServiceClient : public DBusClient {
public:
~CecServiceClient() override;
// For normal usage, access the singleton via DBusThreadManager::Get().
static std::unique_ptr<CecServiceClient> Create(
DBusClientImplementationType type);
// Puts all connected HDMI CEC capable displays into stand-by mode. The effect
// of calling this method is on a best effort basis, no guarantees of displays
// going into stand-by is made.
virtual void SendStandBy() = 0;
// Wakes up all connected HDMI CEC capable displays from stand-by mode. The
// effect of calling this method is on a best effort basis, no guarantees of
// displays going into stand-by is made.
virtual void SendWakeUp() = 0;
protected:
CecServiceClient();
private:
DISALLOW_COPY_AND_ASSIGN(CecServiceClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_CEC_SERVICE_CLIENT_H_

@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/biod/biod_client.h"
#include "chromeos/dbus/cec_service_client.h"
#include "chromeos/dbus/cras_audio_client.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_client_implementation_type.h"
@ -53,6 +54,8 @@ DBusClientsCommon::DBusClientsCommon(bool use_real_clients) {
biod_client_.reset(BiodClient::Create(client_impl_type));
cec_service_client_ = CecServiceClient::Create(client_impl_type);
if (use_real_clients)
cras_audio_client_.reset(CrasAudioClient::Create());
else
@ -135,6 +138,7 @@ void DBusClientsCommon::Initialize(dbus::Bus* system_bus) {
DCHECK(DBusThreadManager::IsInitialized());
biod_client_->Init(system_bus);
cec_service_client_->Init(system_bus);
cras_audio_client_->Init(system_bus);
cryptohome_client_->Init(system_bus);
gsm_sms_client_->Init(system_bus);

@ -17,6 +17,7 @@ class Bus;
namespace chromeos {
class BiodClient;
class CecServiceClient;
class CrasAudioClient;
class CryptohomeClient;
class GsmSMSClient;
@ -52,6 +53,7 @@ class CHROMEOS_EXPORT DBusClientsCommon {
friend class DBusThreadManagerSetter;
std::unique_ptr<BiodClient> biod_client_;
std::unique_ptr<CecServiceClient> cec_service_client_;
std::unique_ptr<CrasAudioClient> cras_audio_client_;
std::unique_ptr<CryptohomeClient> cryptohome_client_;
std::unique_ptr<GsmSMSClient> gsm_sms_client_;

@ -17,6 +17,7 @@
#include "chromeos/dbus/arc_oemcrypto_client.h"
#include "chromeos/dbus/auth_policy_client.h"
#include "chromeos/dbus/biod/biod_client.h"
#include "chromeos/dbus/cec_service_client.h"
#include "chromeos/dbus/concierge_client.h"
#include "chromeos/dbus/cras_audio_client.h"
#include "chromeos/dbus/cros_disks_client.h"
@ -138,6 +139,10 @@ BiodClient* DBusThreadManager::GetBiodClient() {
return clients_common_->biod_client_.get();
}
CecServiceClient* DBusThreadManager::GetCecServiceClient() {
return clients_common_->cec_service_client_.get();
}
ConciergeClient* DBusThreadManager::GetConciergeClient() {
return clients_browser_ ? clients_browser_->concierge_client_.get() : nullptr;
}

@ -29,6 +29,7 @@ class ArcObbMounterClient;
class ArcOemCryptoClient;
class AuthPolicyClient;
class BiodClient;
class CecServiceClient;
class ConciergeClient;
class CrasAudioClient;
class CrosDisksClient;
@ -134,6 +135,7 @@ class CHROMEOS_EXPORT DBusThreadManager {
ArcOemCryptoClient* GetArcOemCryptoClient();
AuthPolicyClient* GetAuthPolicyClient();
BiodClient* GetBiodClient();
CecServiceClient* GetCecServiceClient();
ConciergeClient* GetConciergeClient();
CrasAudioClient* GetCrasAudioClient();
CrosDisksClient* GetCrosDisksClient();

@ -0,0 +1,38 @@
// 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 "chromeos/dbus/fake_cec_service_client.h"
#include "chromeos/dbus/dbus_method_call_status.h"
namespace chromeos {
FakeCecServiceClient::FakeCecServiceClient() = default;
FakeCecServiceClient::~FakeCecServiceClient() = default;
void FakeCecServiceClient::SendStandBy() {
stand_by_call_count_++;
current_state_ = kStandBy;
}
void FakeCecServiceClient::SendWakeUp() {
wake_up_call_count_++;
current_state_ = kAwake;
}
int FakeCecServiceClient::stand_by_call_count() {
return stand_by_call_count_;
}
int FakeCecServiceClient::wake_up_call_count() {
return wake_up_call_count_;
}
FakeCecServiceClient::CurrentState FakeCecServiceClient::current_state() {
return current_state_;
}
void FakeCecServiceClient::Init(dbus::Bus* bus) {}
} // namespace chromeos

@ -0,0 +1,42 @@
// 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.
#ifndef CHROMEOS_DBUS_FAKE_CEC_SERVICE_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_CEC_SERVICE_CLIENT_H_
#include "base/macros.h"
#include "chromeos/dbus/cec_service_client.h"
namespace chromeos {
class CHROMEOS_EXPORT FakeCecServiceClient : public CecServiceClient {
public:
FakeCecServiceClient();
~FakeCecServiceClient() override;
enum CurrentState { kUndefined, kStandBy, kAwake };
// CecServiceClient
void SendStandBy() override;
void SendWakeUp() override;
int stand_by_call_count();
int wake_up_call_count();
CurrentState current_state();
protected:
void Init(dbus::Bus* bus) override;
private:
int stand_by_call_count_ = 0;
int wake_up_call_count_ = 0;
CurrentState current_state_ = kUndefined;
DISALLOW_COPY_AND_ASSIGN(FakeCecServiceClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_CEC_SERVICE_CLIENT_H_

@ -131,6 +131,7 @@ source_set("api") {
]
public_deps += [
"//extensions/browser/api/cec_private",
"//extensions/browser/api/clipboard",
"//extensions/browser/api/diagnostics",
"//extensions/browser/api/networking_config",

@ -0,0 +1,19 @@
# 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.
import("//extensions/buildflags/buildflags.gni")
assert(enable_extensions,
"Cannot depend on extensions because enable_extensions=false.")
source_set("cec_private") {
sources = [
"cec_private_api.cc",
"cec_private_api.h",
]
deps = [
"//extensions/common/api",
]
}

@ -0,0 +1,54 @@
// 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 "extensions/browser/api/cec_private/cec_private_api.h"
#include "chromeos/dbus/cec_service_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
namespace extensions {
namespace {
const char kKioskOnlyError[] =
"Only kiosk enabled extensions are allowed to use this function.";
} // namespace
CecPrivateFunction::CecPrivateFunction() = default;
CecPrivateFunction::~CecPrivateFunction() = default;
// Only allow calls from kiosk mode extensions.
bool CecPrivateFunction::PreRunValidation(std::string* error) {
if (!UIThreadExtensionFunction::PreRunValidation(error))
return false;
if (KioskModeInfo::IsKioskEnabled(extension()))
return true;
*error = kKioskOnlyError;
return false;
}
CecPrivateSendStandByFunction::CecPrivateSendStandByFunction() = default;
CecPrivateSendStandByFunction::~CecPrivateSendStandByFunction() = default;
ExtensionFunction::ResponseAction CecPrivateSendStandByFunction::Run() {
chromeos::DBusThreadManager::Get()->GetCecServiceClient()->SendStandBy();
return RespondNow(NoArguments());
}
CecPrivateSendWakeUpFunction::CecPrivateSendWakeUpFunction() = default;
CecPrivateSendWakeUpFunction::~CecPrivateSendWakeUpFunction() = default;
ExtensionFunction::ResponseAction CecPrivateSendWakeUpFunction::Run() {
chromeos::DBusThreadManager::Get()->GetCecServiceClient()->SendWakeUp();
return RespondNow(NoArguments());
}
} // namespace extensions

@ -0,0 +1,53 @@
// 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.
#ifndef EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_
#define EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_function_histogram_value.h"
namespace extensions {
class CecPrivateFunction : public UIThreadExtensionFunction {
public:
CecPrivateFunction();
protected:
~CecPrivateFunction() override;
bool PreRunValidation(std::string* error) override;
private:
DISALLOW_COPY_AND_ASSIGN(CecPrivateFunction);
};
class CecPrivateSendStandByFunction : public CecPrivateFunction {
public:
CecPrivateSendStandByFunction();
DECLARE_EXTENSION_FUNCTION("cecPrivate.sendStandBy", CECPRIVATE_SENDSTANDBY)
protected:
~CecPrivateSendStandByFunction() override;
ResponseAction Run() override;
private:
DISALLOW_COPY_AND_ASSIGN(CecPrivateSendStandByFunction);
};
class CecPrivateSendWakeUpFunction : public CecPrivateFunction {
public:
CecPrivateSendWakeUpFunction();
DECLARE_EXTENSION_FUNCTION("cecPrivate.sendWakeUp", CECPRIVATE_SENDWAKEUP)
protected:
~CecPrivateSendWakeUpFunction() override;
ResponseAction Run() override;
private:
DISALLOW_COPY_AND_ASSIGN(CecPrivateSendWakeUpFunction);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_

@ -1302,6 +1302,8 @@ enum HistogramValue {
FILEMANAGERPRIVATE_ENSUREFILEDOWNLOADED,
FILEMANAGERPRIVATE_OPENSETTINGSSUBPAGE,
ENTERPRISEREPORTINGPRIVATE_UPLOADCHROMEDESKTOPREPORT,
CECPRIVATE_SENDSTANDBY,
CECPRIVATE_SENDWAKEUP,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY

@ -108,6 +108,10 @@
"dependencies": ["manifest:bluetooth"],
"contexts": ["blessed_extension"]
},
"cecPrivate": {
"dependencies": ["permission:cecPrivate"],
"contexts": ["blessed_extension"]
},
"clipboard": {
"dependencies": ["permission:clipboard"],
"contexts": ["blessed_extension"]

@ -158,6 +158,20 @@
"226CF815E39A363090A1E547D53063472B8279FA" // Media Router Stable
]
},
"cecPrivate": {
"channel": "stable",
"extension_types": ["extension", "platform_app"],
"whitelist": [
"1C93BD3CF875F4A73C0B2A163BB8FBDA8B8B3D80", // http://crbug.com/824667#c15
"A3BC37E2148AC4E99BE4B16AF9D42DD1E592BBBE", // http://crbug.com/824667#c15
"307E96539209F95A1A8740C713E6998A73657D96", // http://crbug.com/824667#c15
"E703483CEF33DEC18B4B6DD84B5C776FB9182BDB", // http://crbug.com/824667#c15
"4F25792AF1AA7483936DE29C07806F203C7170A0", // http://crbug.com/824667#c15
"BD8781D757D830FC2E85470A1B6E8A718B7EE0D9", // http://crbug.com/824667#c15
"4AC2B6C63C6480D150DFDA13E4A5956EB1D0DDBB", // http://crbug.com/824667#c15
"81986D4F846CEDDDB962643FA501D1780DD441BB" // http://crbug.com/824667#c15
]
},
"clipboard": {
"channel": "dev",
"extension_types": ["platform_app"],

@ -0,0 +1,21 @@
// 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.
// Private API for HDMI CEC functionality.
[platforms=("chromeos")]
namespace cecPrivate {
interface Functions {
// Attempt to put all HDMI CEC compatible devices in stand-by.
//
// This is not guaranteed to have any effect on the connected displays.
// Displays that do not support HDMI CEC will not be affected.
static void sendStandBy();
// Attempt to announce this device as the active input source towards all
// HDMI CEC enabled displays connected, waking them from standby if
// necessary.
static void sendWakeUp();
};
};

@ -14,6 +14,7 @@ extensions_api_schema_files_ = [
"bluetooth_private.idl",
"bluetooth_socket.idl",
"cast_channel.idl",
"cec_private.idl",
"clipboard.idl",
"declarative_net_request.idl",
"display_source.idl",

@ -252,6 +252,7 @@ class APIPermission {
kDeclarativeNetRequest,
kLockWindowFullscreenPrivate,
kWebrtcLoggingPrivateAudioDebug,
kCecPrivate,
// Last entry: Add new entries above and ensure to update the
// "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
// (by running update_extension_permission.py).

@ -43,6 +43,8 @@ ExtensionsAPIPermissions::GetAllPermissions() const {
{APIPermission::kAudioCapture, "audioCapture"},
{APIPermission::kBluetoothPrivate, "bluetoothPrivate",
APIPermissionInfo::kFlagCannotBeOptional},
{APIPermission::kCecPrivate, "cecPrivate",
APIPermissionInfo::kFlagCannotBeOptional},
{APIPermission::kClipboard, "clipboard"},
{APIPermission::kClipboardRead, "clipboardRead",
APIPermissionInfo::kFlagSupportsContentCapabilities},

@ -15198,6 +15198,8 @@ Called by update_net_error_codes.py.-->
<int value="1240" label="FILEMANAGERPRIVATE_OPENSETTINGSSUBPAGE"/>
<int value="1241"
label="ENTERPRISEREPORTINGPRIVATE_UPLOADCHROMEDESKTOPREPORT"/>
<int value="1242" label="CECPRIVATE_SENDSTANDBY"/>
<int value="1243" label="CECPRIVATE_SENDWAKEUP"/>
</enum>
<enum name="ExtensionIconState">
@ -15481,7 +15483,7 @@ Called by update_net_error_codes.py.-->
<int value="57" label="kEmbeddedExtensionOptions"/>
<int value="58" label="kEnterprisePlatformKeys"/>
<int value="59" label="kEnterprisePlatformKeysPrivate"/>
<int value="60" label="kExperienceSamplingPrivate"/>
<int value="60" label="kDeleted_ExperienceSamplingPrivate"/>
<int value="61" label="kExperimental"/>
<int value="62" label="kExtensionView"/>
<int value="63" label="kExternallyConnectableAllUrls"/>
@ -15632,6 +15634,7 @@ Called by update_net_error_codes.py.-->
<int value="208" label="kLockWindowFullscreenPrivate"/>
<int value="209" label="kWebrtcLoggingPrivateAudioDebug"/>
<int value="210" label="kEnterpriseReportingPrivate"/>
<int value="211" label="kCecPrivate"/>
</enum>
<enum name="ExtensionServiceVerifyAllSuccess">