blob: 095dcfd568e6b00ae052adecd5928a21108cde27 [file] [log] [blame]
// 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 "components/arc/arc_bridge_service.h"
#include <utility>
#include "base/command_line.h"
#include "base/sequenced_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "chromeos/chromeos_switches.h"
#include "components/arc/arc_bridge_service_impl.h"
namespace arc {
namespace {
// Weak pointer. This class is owned by ArcServiceManager.
ArcBridgeService* g_arc_bridge_service = nullptr;
} // namespace
ArcBridgeService::ArcBridgeService()
: available_(false), state_(State::STOPPED), weak_factory_(this) {
DCHECK(!g_arc_bridge_service);
g_arc_bridge_service = this;
}
ArcBridgeService::~ArcBridgeService() {
DCHECK(CalledOnValidThread());
DCHECK(state() == State::STOPPING || state() == State::STOPPED);
DCHECK(g_arc_bridge_service == this);
g_arc_bridge_service = nullptr;
}
// static
ArcBridgeService* ArcBridgeService::Get() {
if (!g_arc_bridge_service) {
// ArcBridgeService may be indirectly referenced in unit tests where
// ArcBridgeService is optional.
LOG(ERROR) << "ArcBridgeService is not ready.";
return nullptr;
}
DCHECK(g_arc_bridge_service->CalledOnValidThread());
return g_arc_bridge_service;
}
// static
bool ArcBridgeService::GetEnabled(const base::CommandLine* command_line) {
return command_line->HasSwitch(chromeos::switches::kEnableArc);
}
void ArcBridgeService::AddObserver(Observer* observer) {
DCHECK(CalledOnValidThread());
observer_list_.AddObserver(observer);
// If any of the instances were ready before the call to AddObserver(), the
// |observer| won't get any readiness events. For such cases, we have to call
// them explicitly now to avoid a race.
if (app_instance())
observer->OnAppInstanceReady();
if (audio_instance())
observer->OnAudioInstanceReady();
if (auth_instance())
observer->OnAuthInstanceReady();
if (bluetooth_instance())
observer->OnBluetoothInstanceReady();
if (clipboard_instance())
observer->OnClipboardInstanceReady();
if (crash_collector_instance())
observer->OnCrashCollectorInstanceReady();
if (ime_instance())
observer->OnImeInstanceReady();
if (input_instance())
observer->OnInputInstanceReady();
if (net_instance())
observer->OnNetInstanceReady();
if (notifications_instance())
observer->OnNotificationsInstanceReady();
if (policy_instance())
observer->OnPolicyInstanceReady();
if (power_instance())
observer->OnPowerInstanceReady();
if (process_instance())
observer->OnProcessInstanceReady();
if (video_instance())
observer->OnVideoInstanceReady();
}
void ArcBridgeService::RemoveObserver(Observer* observer) {
DCHECK(CalledOnValidThread());
observer_list_.RemoveObserver(observer);
}
void ArcBridgeService::OnAppInstanceReady(AppInstancePtr app_ptr) {
DCHECK(CalledOnValidThread());
temporary_app_ptr_ = std::move(app_ptr);
temporary_app_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnAppVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnAppVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
app_ptr_ = std::move(temporary_app_ptr_);
app_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseAppChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnAppInstanceReady());
}
void ArcBridgeService::CloseAppChannel() {
DCHECK(CalledOnValidThread());
if (!app_ptr_)
return;
app_ptr_.reset();
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) {
DCHECK(CalledOnValidThread());
temporary_auth_ptr_ = std::move(auth_ptr);
temporary_auth_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnAuthVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnAuthVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
auth_ptr_ = std::move(temporary_auth_ptr_);
auth_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseAuthChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnAuthInstanceReady());
}
void ArcBridgeService::CloseAuthChannel() {
DCHECK(CalledOnValidThread());
if (!auth_ptr_)
return;
auth_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnAuthInstanceClosed());
}
void ArcBridgeService::OnBluetoothInstanceReady(
BluetoothInstancePtr bluetooth_ptr) {
DCHECK(CalledOnValidThread());
temporary_bluetooth_ptr_ = std::move(bluetooth_ptr);
temporary_bluetooth_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnBluetoothVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnBluetoothVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
bluetooth_ptr_ = std::move(temporary_bluetooth_ptr_);
bluetooth_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseBluetoothChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnBluetoothInstanceReady());
}
void ArcBridgeService::CloseBluetoothChannel() {
DCHECK(CalledOnValidThread());
if (!bluetooth_ptr_)
return;
bluetooth_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnBluetoothInstanceClosed());
}
void ArcBridgeService::OnClipboardInstanceReady(
ClipboardInstancePtr clipboard_ptr) {
DCHECK(CalledOnValidThread());
temporary_clipboard_ptr_ = std::move(clipboard_ptr);
temporary_clipboard_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnClipboardVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnClipboardVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
clipboard_ptr_ = std::move(temporary_clipboard_ptr_);
clipboard_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseClipboardChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnClipboardInstanceReady());
}
void ArcBridgeService::CloseClipboardChannel() {
DCHECK(CalledOnValidThread());
if (!clipboard_ptr_)
return;
clipboard_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnClipboardInstanceClosed());
}
void ArcBridgeService::OnCrashCollectorInstanceReady(
CrashCollectorInstancePtr crash_collector_ptr) {
DCHECK(CalledOnValidThread());
temporary_crash_collector_ptr_ = std::move(crash_collector_ptr);
temporary_crash_collector_ptr_.QueryVersion(
base::Bind(&ArcBridgeService::OnCrashCollectorVersionReady,
weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnCrashCollectorVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
crash_collector_ptr_ = std::move(temporary_crash_collector_ptr_);
crash_collector_ptr_.set_connection_error_handler(
base::Bind(&ArcBridgeService::CloseCrashCollectorChannel,
weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnCrashCollectorInstanceReady());
}
void ArcBridgeService::CloseCrashCollectorChannel() {
DCHECK(CalledOnValidThread());
if (!crash_collector_ptr_)
return;
crash_collector_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(),
OnCrashCollectorInstanceClosed());
}
void ArcBridgeService::OnImeInstanceReady(ImeInstancePtr ime_ptr) {
DCHECK(CalledOnValidThread());
temporary_ime_ptr_ = std::move(ime_ptr);
temporary_ime_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnImeVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnImeVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
ime_ptr_ = std::move(temporary_ime_ptr_);
ime_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseImeChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnImeInstanceReady());
}
void ArcBridgeService::CloseImeChannel() {
DCHECK(CalledOnValidThread());
if (!ime_ptr_)
return;
ime_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnImeInstanceClosed());
}
void ArcBridgeService::OnInputInstanceReady(InputInstancePtr input_ptr) {
DCHECK(CalledOnValidThread());
temporary_input_ptr_ = std::move(input_ptr);
temporary_input_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnInputVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnInputVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
input_ptr_ = std::move(temporary_input_ptr_);
input_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseInputChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnInputInstanceReady());
}
void ArcBridgeService::CloseInputChannel() {
DCHECK(CalledOnValidThread());
if (!input_ptr_)
return;
input_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnInputInstanceClosed());
}
void ArcBridgeService::OnIntentHelperInstanceReady(
IntentHelperInstancePtr intent_helper_ptr) {
DCHECK(CalledOnValidThread());
temporary_intent_helper_ptr_ = std::move(intent_helper_ptr);
temporary_intent_helper_ptr_.QueryVersion(
base::Bind(&ArcBridgeService::OnIntentHelperVersionReady,
weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnIntentHelperVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
intent_helper_ptr_ = std::move(temporary_intent_helper_ptr_);
intent_helper_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseIntentHelperChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnIntentHelperInstanceReady());
}
void ArcBridgeService::CloseIntentHelperChannel() {
DCHECK(CalledOnValidThread());
if (!intent_helper_ptr_)
return;
intent_helper_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnIntentHelperInstanceClosed());
}
void ArcBridgeService::OnNetInstanceReady(NetInstancePtr net_ptr) {
DCHECK(CalledOnValidThread());
temporary_net_ptr_ = std::move(net_ptr);
temporary_net_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnNetVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnNetVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
net_ptr_ = std::move(temporary_net_ptr_);
net_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseNetChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnNetInstanceReady());
}
void ArcBridgeService::CloseNetChannel() {
DCHECK(CalledOnValidThread());
if (!net_ptr_)
return;
net_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnNetInstanceClosed());
}
void ArcBridgeService::OnNotificationsInstanceReady(
NotificationsInstancePtr notifications_ptr) {
DCHECK(CalledOnValidThread());
temporary_notifications_ptr_ = std::move(notifications_ptr);
temporary_notifications_ptr_.QueryVersion(
base::Bind(&ArcBridgeService::OnNotificationsVersionReady,
weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnNotificationsVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
notifications_ptr_ = std::move(temporary_notifications_ptr_);
notifications_ptr_.set_connection_error_handler(
base::Bind(&ArcBridgeService::CloseNotificationsChannel,
weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnNotificationsInstanceReady());
}
void ArcBridgeService::CloseNotificationsChannel() {
DCHECK(CalledOnValidThread());
if (!notifications_ptr_)
return;
notifications_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnNotificationsInstanceClosed());
}
void ArcBridgeService::OnPolicyInstanceReady(PolicyInstancePtr policy_ptr) {
DCHECK(CalledOnValidThread());
temporary_policy_ptr_ = std::move(policy_ptr);
temporary_policy_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnPolicyVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnPolicyVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
policy_ptr_ = std::move(temporary_policy_ptr_);
policy_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::ClosePolicyChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnPolicyInstanceReady());
}
void ArcBridgeService::ClosePolicyChannel() {
DCHECK(CalledOnValidThread());
if (!policy_ptr_)
return;
policy_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnPolicyInstanceClosed());
}
void ArcBridgeService::OnPowerInstanceReady(PowerInstancePtr power_ptr) {
DCHECK(CalledOnValidThread());
temporary_power_ptr_ = std::move(power_ptr);
temporary_power_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnPowerVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnPowerVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
power_ptr_ = std::move(temporary_power_ptr_);
power_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::ClosePowerChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnPowerInstanceReady());
}
void ArcBridgeService::ClosePowerChannel() {
DCHECK(CalledOnValidThread());
if (!power_ptr_)
return;
power_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnPowerInstanceClosed());
}
void ArcBridgeService::OnProcessInstanceReady(ProcessInstancePtr process_ptr) {
DCHECK(CalledOnValidThread());
temporary_process_ptr_ = std::move(process_ptr);
temporary_process_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnProcessVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnProcessVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
process_ptr_ = std::move(temporary_process_ptr_);
process_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseProcessChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnProcessInstanceReady());
}
void ArcBridgeService::CloseProcessChannel() {
DCHECK(CalledOnValidThread());
if (!process_ptr_)
return;
process_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnProcessInstanceClosed());
}
void ArcBridgeService::OnVideoInstanceReady(VideoInstancePtr video_ptr) {
DCHECK(CalledOnValidThread());
temporary_video_ptr_ = std::move(video_ptr);
temporary_video_ptr_.QueryVersion(base::Bind(
&ArcBridgeService::OnVideoVersionReady, weak_factory_.GetWeakPtr()));
}
void ArcBridgeService::OnVideoVersionReady(int32_t version) {
DCHECK(CalledOnValidThread());
video_ptr_ = std::move(temporary_video_ptr_);
video_ptr_.set_connection_error_handler(base::Bind(
&ArcBridgeService::CloseVideoChannel, weak_factory_.GetWeakPtr()));
FOR_EACH_OBSERVER(Observer, observer_list(), OnVideoInstanceReady());
}
void ArcBridgeService::CloseVideoChannel() {
DCHECK(CalledOnValidThread());
if (!video_ptr_)
return;
video_ptr_.reset();
FOR_EACH_OBSERVER(Observer, observer_list(), OnVideoInstanceClosed());
}
void ArcBridgeService::SetState(State state) {
DCHECK(CalledOnValidThread());
// DCHECK on enum classes not supported.
DCHECK(state_ != state);
state_ = state;
FOR_EACH_OBSERVER(Observer, observer_list(), OnStateChanged(state_));
}
void ArcBridgeService::SetAvailable(bool available) {
DCHECK(CalledOnValidThread());
DCHECK(available_ != available);
available_ = available;
FOR_EACH_OBSERVER(Observer, observer_list(), OnAvailableChanged(available_));
}
bool ArcBridgeService::CalledOnValidThread() {
return thread_checker_.CalledOnValidThread();
}
void ArcBridgeService::CloseAllChannels() {
// Call all the error handlers of all the channels to both close the channel
// and notify any observers that the channel is closed.
CloseAppChannel();
CloseAudioChannel();
CloseAuthChannel();
CloseBluetoothChannel();
CloseClipboardChannel();
CloseCrashCollectorChannel();
CloseImeChannel();
CloseInputChannel();
CloseIntentHelperChannel();
CloseNetChannel();
CloseNotificationsChannel();
ClosePolicyChannel();
ClosePowerChannel();
CloseProcessChannel();
CloseVideoChannel();
}
} // namespace arc