You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.0 KiB
207 lines
5.0 KiB
//
|
|
// Copyright 2015 Google, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at:
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#include "service/daemon.h"
|
|
|
|
#include <memory>
|
|
|
|
#include <base/logging.h>
|
|
#include <base/run_loop.h>
|
|
|
|
#include "abstract_message_loop.h"
|
|
#include "service/adapter.h"
|
|
#include "service/hal/bluetooth_av_interface.h"
|
|
#include "service/hal/bluetooth_avrcp_interface.h"
|
|
#include "service/hal/bluetooth_gatt_interface.h"
|
|
#include "service/hal/bluetooth_interface.h"
|
|
#include "service/ipc/ipc_manager.h"
|
|
#include "service/settings.h"
|
|
#include "service/switches.h"
|
|
|
|
namespace bluetooth {
|
|
|
|
namespace {
|
|
|
|
// The global Daemon instance.
|
|
Daemon* g_daemon = nullptr;
|
|
|
|
class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
|
|
public:
|
|
DaemonImpl() : initialized_(false) {}
|
|
|
|
~DaemonImpl() override {
|
|
if (!initialized_) return;
|
|
|
|
CleanUpBluetoothStack();
|
|
}
|
|
|
|
void StartMainLoop() override { base::RunLoop().Run(); }
|
|
|
|
Settings* GetSettings() const override { return settings_.get(); }
|
|
|
|
btbase::AbstractMessageLoop* GetMessageLoop() const override {
|
|
return message_loop_.get();
|
|
}
|
|
|
|
private:
|
|
// ipc::IPCManager::Delegate implementation:
|
|
void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
|
|
if (!settings_->EnableOnStart()) return;
|
|
adapter_->Enable();
|
|
}
|
|
|
|
void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
|
|
// Do nothing.
|
|
}
|
|
|
|
bool StartUpBluetoothInterfaces() {
|
|
if (!hal::BluetoothInterface::Initialize()) goto failed;
|
|
|
|
if (!hal::BluetoothGattInterface::Initialize()) goto failed;
|
|
|
|
if (!hal::BluetoothAvInterface::Initialize()) goto failed;
|
|
|
|
if (!hal::BluetoothAvrcpInterface::Initialize()) goto failed;
|
|
|
|
return true;
|
|
|
|
failed:
|
|
ShutDownBluetoothInterfaces();
|
|
return false;
|
|
}
|
|
|
|
void ShutDownBluetoothInterfaces() {
|
|
if (hal::BluetoothGattInterface::IsInitialized())
|
|
hal::BluetoothGattInterface::CleanUp();
|
|
if (hal::BluetoothInterface::IsInitialized())
|
|
hal::BluetoothInterface::CleanUp();
|
|
if (hal::BluetoothAvInterface::IsInitialized())
|
|
hal::BluetoothAvInterface::CleanUp();
|
|
if (hal::BluetoothAvrcpInterface::IsInitialized())
|
|
hal::BluetoothAvrcpInterface::CleanUp();
|
|
}
|
|
|
|
void CleanUpBluetoothStack() {
|
|
// The Adapter object needs to be cleaned up before the HAL interfaces.
|
|
ipc_manager_.reset();
|
|
adapter_.reset();
|
|
ShutDownBluetoothInterfaces();
|
|
}
|
|
|
|
bool SetUpIPC() {
|
|
// If an IPC socket path was given, initialize IPC with it. Otherwise
|
|
// initialize Binder IPC.
|
|
if (settings_->UseSocketIPC()) {
|
|
if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) {
|
|
LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#if !defined(OS_GENERIC)
|
|
if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) {
|
|
LOG(ERROR) << "Failed to set up Binder IPCManager";
|
|
return false;
|
|
}
|
|
#else
|
|
if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) {
|
|
LOG(ERROR) << "Failed to set up DBus IPCManager";
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Init() override {
|
|
CHECK(!initialized_);
|
|
message_loop_.reset(new btbase::AbstractMessageLoop());
|
|
|
|
settings_.reset(new Settings());
|
|
if (!settings_->Init()) {
|
|
LOG(ERROR) << "Failed to set up Settings";
|
|
return false;
|
|
}
|
|
|
|
if (!StartUpBluetoothInterfaces()) {
|
|
LOG(ERROR) << "Failed to set up HAL Bluetooth interfaces";
|
|
return false;
|
|
}
|
|
|
|
adapter_ = Adapter::Create();
|
|
ipc_manager_.reset(new ipc::IPCManager(adapter_.get()));
|
|
|
|
if (!SetUpIPC()) {
|
|
CleanUpBluetoothStack();
|
|
return false;
|
|
}
|
|
|
|
initialized_ = true;
|
|
LOG(INFO) << "Daemon initialized";
|
|
|
|
return true;
|
|
}
|
|
|
|
bool initialized_;
|
|
std::unique_ptr<btbase::AbstractMessageLoop> message_loop_;
|
|
std::unique_ptr<Settings> settings_;
|
|
std::unique_ptr<Adapter> adapter_;
|
|
std::unique_ptr<ipc::IPCManager> ipc_manager_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(DaemonImpl);
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// static
|
|
bool Daemon::Initialize() {
|
|
CHECK(!g_daemon);
|
|
|
|
g_daemon = new DaemonImpl();
|
|
if (g_daemon->Init()) return true;
|
|
|
|
LOG(ERROR) << "Failed to initialize the Daemon object";
|
|
|
|
delete g_daemon;
|
|
g_daemon = nullptr;
|
|
|
|
return false;
|
|
}
|
|
|
|
// static
|
|
void Daemon::ShutDown() {
|
|
CHECK(g_daemon);
|
|
delete g_daemon;
|
|
g_daemon = nullptr;
|
|
}
|
|
|
|
// static
|
|
void Daemon::InitializeForTesting(Daemon* test_daemon) {
|
|
CHECK(test_daemon);
|
|
CHECK(!g_daemon);
|
|
|
|
g_daemon = test_daemon;
|
|
}
|
|
|
|
// static
|
|
Daemon* Daemon::Get() {
|
|
CHECK(g_daemon);
|
|
return g_daemon;
|
|
}
|
|
|
|
} // namespace bluetooth
|