Commit beb9aec5 authored by chinyue's avatar chinyue Committed by Commit bot

Host-side implementation of ARC audio bridge.

BUG=b:26933097

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

Cr-Commit-Position: refs/heads/master@{#383926}
parent b0b70b1a
...@@ -218,6 +218,8 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -218,6 +218,8 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
virtual void SetActiveHDMIOutoutRediscoveringIfNecessary( virtual void SetActiveHDMIOutoutRediscoveringIfNecessary(
bool force_rediscovering); bool force_rediscovering);
virtual const AudioDevice* GetDeviceFromId(uint64_t device_id) const;
protected: protected:
explicit CrasAudioHandler( explicit CrasAudioHandler(
scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler);
...@@ -260,7 +262,6 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -260,7 +262,6 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Sets up the additional active audio node's state. // Sets up the additional active audio node's state.
void SetupAdditionalActiveAudioNodeState(uint64_t node_id); void SetupAdditionalActiveAudioNodeState(uint64_t node_id);
const AudioDevice* GetDeviceFromId(uint64_t device_id) const;
const AudioDevice* GetDeviceFromStableDeviceId( const AudioDevice* GetDeviceFromStableDeviceId(
uint64_t stable_device_id) const; uint64_t stable_device_id) const;
const AudioDevice* GetKeyboardMic() const; const AudioDevice* GetKeyboardMic() const;
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
'arc/arc_service.h', 'arc/arc_service.h',
'arc/arc_service_manager.cc', 'arc/arc_service_manager.cc',
'arc/arc_service_manager.h', 'arc/arc_service_manager.h',
'arc/audio/arc_audio_bridge.cc',
'arc/audio/arc_audio_bridge.h',
'arc/auth/arc_auth_fetcher.cc', 'arc/auth/arc_auth_fetcher.cc',
'arc/auth/arc_auth_fetcher.h', 'arc/auth/arc_auth_fetcher.h',
'arc/clipboard/arc_clipboard_bridge.cc', 'arc/clipboard/arc_clipboard_bridge.cc',
...@@ -94,6 +96,7 @@ ...@@ -94,6 +96,7 @@
'sources': [ 'sources': [
'arc/common/app.mojom', 'arc/common/app.mojom',
'arc/common/arc_bridge.mojom', 'arc/common/arc_bridge.mojom',
'arc/common/audio.mojom',
'arc/common/auth.mojom', 'arc/common/auth.mojom',
'arc/common/clipboard.mojom', 'arc/common/clipboard.mojom',
'arc/common/crash_collector.mojom', 'arc/common/crash_collector.mojom',
......
...@@ -17,6 +17,8 @@ static_library("arc") { ...@@ -17,6 +17,8 @@ static_library("arc") {
"arc_service.h", "arc_service.h",
"arc_service_manager.cc", "arc_service_manager.cc",
"arc_service_manager.h", "arc_service_manager.h",
"audio/arc_audio_bridge.cc",
"audio/arc_audio_bridge.h",
"auth/arc_auth_fetcher.cc", "auth/arc_auth_fetcher.cc",
"auth/arc_auth_fetcher.h", "auth/arc_auth_fetcher.h",
"clipboard/arc_clipboard_bridge.cc", "clipboard/arc_clipboard_bridge.cc",
...@@ -72,6 +74,7 @@ mojom("arc_bindings") { ...@@ -72,6 +74,7 @@ mojom("arc_bindings") {
sources = [ sources = [
"common/app.mojom", "common/app.mojom",
"common/arc_bridge.mojom", "common/arc_bridge.mojom",
"common/audio.mojom",
"common/auth.mojom", "common/auth.mojom",
"common/clipboard.mojom", "common/clipboard.mojom",
"common/crash_collector.mojom", "common/crash_collector.mojom",
......
...@@ -60,6 +60,8 @@ void ArcBridgeService::AddObserver(Observer* observer) { ...@@ -60,6 +60,8 @@ void ArcBridgeService::AddObserver(Observer* observer) {
// them explicitly now to avoid a race. // them explicitly now to avoid a race.
if (app_instance()) if (app_instance())
observer->OnAppInstanceReady(); observer->OnAppInstanceReady();
if (audio_instance())
observer->OnAudioInstanceReady();
if (auth_instance()) if (auth_instance())
observer->OnAuthInstanceReady(); observer->OnAuthInstanceReady();
if (clipboard_instance()) if (clipboard_instance())
...@@ -113,6 +115,29 @@ void ArcBridgeService::CloseAppChannel() { ...@@ -113,6 +115,29 @@ void ArcBridgeService::CloseAppChannel() {
FOR_EACH_OBSERVER(Observer, observer_list(), OnAppInstanceClosed()); FOR_EACH_OBSERVER(Observer, observer_list(), OnAppInstanceClosed());
} }
void ArcBridgeService::OnAudioInstanceReady(AudioInstancePtr audio_ptr) {
DCHECK(CalledOnValidThread());
temporary_audio_ptr_ = std::move(audio_ptr);
temporary_audio_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnAudioVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnAudioVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
audio_ptr_ = std::move(temporary_audio_ptr_);
audio_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseAudioChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnAudioInstanceReady());
}
void ArcBridgeService::CloseAudioChannel() {
if (!audio_ptr_)
return;
audio_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnAudioInstanceClosed());
}
void ArcBridgeService::OnAuthInstanceReady(AuthInstancePtr auth_ptr) { void ArcBridgeService::OnAuthInstanceReady(AuthInstancePtr auth_ptr) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
temporary_auth_ptr_ = std::move(auth_ptr); temporary_auth_ptr_ = std::move(auth_ptr);
...@@ -434,6 +459,7 @@ void ArcBridgeService::CloseAllChannels() { ...@@ -434,6 +459,7 @@ void ArcBridgeService::CloseAllChannels() {
// Call all the error handlers of all the channels to both close the channel // Call all the error handlers of all the channels to both close the channel
// and notify any observers that the channel is closed. // and notify any observers that the channel is closed.
CloseAppChannel(); CloseAppChannel();
CloseAudioChannel();
CloseAuthChannel(); CloseAuthChannel();
CloseClipboardChannel(); CloseClipboardChannel();
CloseCrashCollectorChannel(); CloseCrashCollectorChannel();
......
...@@ -77,6 +77,10 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -77,6 +77,10 @@ class ArcBridgeService : public ArcBridgeHost {
virtual void OnAppInstanceReady() {} virtual void OnAppInstanceReady() {}
virtual void OnAppInstanceClosed() {} virtual void OnAppInstanceClosed() {}
// Called whenever the ARC audio interface state changes.
virtual void OnAudioInstanceReady() {}
virtual void OnAudioInstanceClosed() {}
// Called whenever the ARC auth interface state changes. // Called whenever the ARC auth interface state changes.
virtual void OnAuthInstanceReady() {} virtual void OnAuthInstanceReady() {}
virtual void OnAuthInstanceClosed() {} virtual void OnAuthInstanceClosed() {}
...@@ -163,6 +167,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -163,6 +167,7 @@ class ArcBridgeService : public ArcBridgeHost {
// you want to be notified when this is ready. This can only be called on the // you want to be notified when this is ready. This can only be called on the
// thread that this class was created on. // thread that this class was created on.
AppInstance* app_instance() { return app_ptr_.get(); } AppInstance* app_instance() { return app_ptr_.get(); }
AudioInstance* audio_instance() { return audio_ptr_.get(); }
AuthInstance* auth_instance() { return auth_ptr_.get(); } AuthInstance* auth_instance() { return auth_ptr_.get(); }
ClipboardInstance* clipboard_instance() { return clipboard_ptr_.get(); } ClipboardInstance* clipboard_instance() { return clipboard_ptr_.get(); }
CrashCollectorInstance* crash_collector_instance() { CrashCollectorInstance* crash_collector_instance() {
...@@ -183,6 +188,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -183,6 +188,7 @@ class ArcBridgeService : public ArcBridgeHost {
VideoInstance* video_instance() { return video_ptr_.get(); } VideoInstance* video_instance() { return video_ptr_.get(); }
int32_t app_version() const { return app_ptr_.version(); } int32_t app_version() const { return app_ptr_.version(); }
int32_t audio_version() const { return audio_ptr_.version(); }
int32_t auth_version() const { return auth_ptr_.version(); } int32_t auth_version() const { return auth_ptr_.version(); }
int32_t clipboard_version() const { return clipboard_ptr_.version(); } int32_t clipboard_version() const { return clipboard_ptr_.version(); }
int32_t crash_collector_version() const { int32_t crash_collector_version() const {
...@@ -200,6 +206,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -200,6 +206,7 @@ class ArcBridgeService : public ArcBridgeHost {
// ArcHost: // ArcHost:
void OnAppInstanceReady(AppInstancePtr app_ptr) override; void OnAppInstanceReady(AppInstancePtr app_ptr) override;
void OnAudioInstanceReady(AudioInstancePtr audio_ptr) override;
void OnAuthInstanceReady(AuthInstancePtr auth_ptr) override; void OnAuthInstanceReady(AuthInstancePtr auth_ptr) override;
void OnClipboardInstanceReady(ClipboardInstancePtr clipboard_ptr) override; void OnClipboardInstanceReady(ClipboardInstancePtr clipboard_ptr) override;
void OnCrashCollectorInstanceReady( void OnCrashCollectorInstanceReady(
...@@ -247,6 +254,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -247,6 +254,7 @@ class ArcBridgeService : public ArcBridgeHost {
// Called when one of the individual channels is closed. // Called when one of the individual channels is closed.
void CloseAppChannel(); void CloseAppChannel();
void CloseAudioChannel();
void CloseAuthChannel(); void CloseAuthChannel();
void CloseClipboardChannel(); void CloseClipboardChannel();
void CloseCrashCollectorChannel(); void CloseCrashCollectorChannel();
...@@ -262,6 +270,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -262,6 +270,7 @@ class ArcBridgeService : public ArcBridgeHost {
// Callbacks for QueryVersion. // Callbacks for QueryVersion.
void OnAppVersionReady(int32_t version); void OnAppVersionReady(int32_t version);
void OnAudioVersionReady(int32_t version);
void OnAuthVersionReady(int32_t version); void OnAuthVersionReady(int32_t version);
void OnClipboardVersionReady(int32_t version); void OnClipboardVersionReady(int32_t version);
void OnCrashCollectorVersionReady(int32_t version); void OnCrashCollectorVersionReady(int32_t version);
...@@ -277,6 +286,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -277,6 +286,7 @@ class ArcBridgeService : public ArcBridgeHost {
// Mojo interfaces. // Mojo interfaces.
AppInstancePtr app_ptr_; AppInstancePtr app_ptr_;
AudioInstancePtr audio_ptr_;
AuthInstancePtr auth_ptr_; AuthInstancePtr auth_ptr_;
ClipboardInstancePtr clipboard_ptr_; ClipboardInstancePtr clipboard_ptr_;
CrashCollectorInstancePtr crash_collector_ptr_; CrashCollectorInstancePtr crash_collector_ptr_;
...@@ -297,6 +307,7 @@ class ArcBridgeService : public ArcBridgeHost { ...@@ -297,6 +307,7 @@ class ArcBridgeService : public ArcBridgeHost {
// To keep the xxx_instance() functions being trivial, store the instance // To keep the xxx_instance() functions being trivial, store the instance
// pointer in a temporary variable to avoid losing its reference. // pointer in a temporary variable to avoid losing its reference.
AppInstancePtr temporary_app_ptr_; AppInstancePtr temporary_app_ptr_;
AudioInstancePtr temporary_audio_ptr_;
AuthInstancePtr temporary_auth_ptr_; AuthInstancePtr temporary_auth_ptr_;
ClipboardInstancePtr temporary_clipboard_ptr_; ClipboardInstancePtr temporary_clipboard_ptr_;
CrashCollectorInstancePtr temporary_crash_collector_ptr_; CrashCollectorInstancePtr temporary_crash_collector_ptr_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/thread_task_runner_handle.h" #include "base/thread_task_runner_handle.h"
#include "components/arc/arc_bridge_bootstrap.h" #include "components/arc/arc_bridge_bootstrap.h"
#include "components/arc/arc_bridge_service_impl.h" #include "components/arc/arc_bridge_service_impl.h"
#include "components/arc/audio/arc_audio_bridge.h"
#include "components/arc/clipboard/arc_clipboard_bridge.h" #include "components/arc/clipboard/arc_clipboard_bridge.h"
#include "components/arc/crash_collector/arc_crash_collector_bridge.h" #include "components/arc/crash_collector/arc_crash_collector_bridge.h"
#include "components/arc/ime/arc_ime_service.h" #include "components/arc/ime/arc_ime_service.h"
...@@ -32,6 +33,7 @@ ArcServiceManager::ArcServiceManager() ...@@ -32,6 +33,7 @@ ArcServiceManager::ArcServiceManager()
DCHECK(!g_arc_service_manager); DCHECK(!g_arc_service_manager);
g_arc_service_manager = this; g_arc_service_manager = this;
AddService(make_scoped_ptr(new ArcAudioBridge(arc_bridge_service())));
AddService(make_scoped_ptr(new ArcClipboardBridge(arc_bridge_service()))); AddService(make_scoped_ptr(new ArcClipboardBridge(arc_bridge_service())));
AddService( AddService(
make_scoped_ptr(new ArcCrashCollectorBridge(arc_bridge_service()))); make_scoped_ptr(new ArcCrashCollectorBridge(arc_bridge_service())));
......
include_rules = [
"+chromeos/audio",
]
// 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 "components/arc/audio/arc_audio_bridge.h"
#include "base/logging.h"
#include "chromeos/audio/audio_device.h"
namespace arc {
ArcAudioBridge::ArcAudioBridge(ArcBridgeService* bridge_service)
: ArcService(bridge_service) {
arc_bridge_service()->AddObserver(this);
if (chromeos::CrasAudioHandler::IsInitialized()) {
cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
cras_audio_handler_->AddAudioObserver(this);
}
}
ArcAudioBridge::~ArcAudioBridge() {
arc_bridge_service()->RemoveObserver(this);
if (cras_audio_handler_ && chromeos::CrasAudioHandler::IsInitialized()) {
cras_audio_handler_->RemoveAudioObserver(this);
}
}
void ArcAudioBridge::OnAudioNodesChanged() {
uint64_t output_id = cras_audio_handler_->GetPrimaryActiveOutputNode();
const chromeos::AudioDevice* output_device =
cras_audio_handler_->GetDeviceFromId(output_id);
bool headphone_inserted =
(output_device &&
output_device->type == chromeos::AudioDeviceType::AUDIO_TYPE_HEADPHONE);
uint64_t input_id = cras_audio_handler_->GetPrimaryActiveInputNode();
const chromeos::AudioDevice* input_device =
cras_audio_handler_->GetDeviceFromId(input_id);
bool microphone_inserted =
(input_device &&
input_device->type == chromeos::AudioDeviceType::AUDIO_TYPE_MIC);
VLOG(1) << "HEADPHONE " << headphone_inserted
<< " MICROPHONE " << microphone_inserted;
SendSwitchState(headphone_inserted, microphone_inserted);
}
void ArcAudioBridge::SendSwitchState(bool headphone_inserted,
bool microphone_inserted) {
uint32_t switch_state = 0;
if (headphone_inserted) {
switch_state |=
(1 << static_cast<uint32_t>(AudioSwitch::SW_HEADPHONE_INSERT));
}
if (microphone_inserted) {
switch_state |=
(1 << static_cast<uint32_t>(AudioSwitch::SW_MICROPHONE_INSERT));
}
VLOG(1) << "Send switch state " << switch_state;
AudioInstance* audio_instance = arc_bridge_service()->audio_instance();
if (audio_instance)
audio_instance->NotifySwitchState(switch_state);
}
} // namespace arc
// 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 COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_
#define COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_
#include <string>
#include "base/macros.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace arc {
class ArcAudioBridge : public ArcService,
public ArcBridgeService::Observer,
public chromeos::CrasAudioHandler::AudioObserver {
public:
explicit ArcAudioBridge(ArcBridgeService* bridge_service);
~ArcAudioBridge() override;
private:
chromeos::CrasAudioHandler* cras_audio_handler_ = nullptr;
// chromeos::CrasAudioHandler::AudioObserver overrides.
void OnAudioNodesChanged() override;
void SendSwitchState(bool headphone_inserted, bool microphone_inserted);
DISALLOW_COPY_AND_ASSIGN(ArcAudioBridge);
};
} // namespace arc
#endif // COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
module arc; module arc;
import "app.mojom"; import "app.mojom";
import "audio.mojom";
import "auth.mojom"; import "auth.mojom";
import "clipboard.mojom"; import "clipboard.mojom";
import "crash_collector.mojom"; import "crash_collector.mojom";
...@@ -26,6 +27,9 @@ interface ArcBridgeHost { ...@@ -26,6 +27,9 @@ interface ArcBridgeHost {
// Notifies Chrome that the AppInstance interface is ready. // Notifies Chrome that the AppInstance interface is ready.
OnAppInstanceReady@100(AppInstance instance_ptr); OnAppInstanceReady@100(AppInstance instance_ptr);
// Notifies Chrome that the AudioInstance interface is ready.
[MinVersion=8] OnAudioInstanceReady@115(AudioInstance instance_ptr);
// Notifies Chrome that the AuthInstance interface is ready. // Notifies Chrome that the AuthInstance interface is ready.
[MinVersion=1] OnAuthInstanceReady@106(AuthInstance instance_ptr); [MinVersion=1] OnAuthInstanceReady@106(AuthInstance instance_ptr);
......
// 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.
module arc;
// Use same switch values as kernel switch events.
[Extensible]
enum AudioSwitch {
SW_HEADPHONE_INSERT = 0x02,
SW_MICROPHONE_INSERT = 0x04
};
interface AudioInstance {
// Notify plug states of headphone, microphone, etc. Each switch state is
// represented by the corresponding bit, if the bit is set then the switch
// is plugged/inserted.
NotifySwitchState(uint32 state);
};
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