1//
2//  Copyright (C) 2015 Google, Inc.
3//
4//  Licensed under the Apache License, Version 2.0 (the "License");
5//  you may not use this file except in compliance with the License.
6//  You may obtain a copy of the License at:
7//
8//  http://www.apache.org/licenses/LICENSE-2.0
9//
10//  Unless required by applicable law or agreed to in writing, software
11//  distributed under the License is distributed on an "AS IS" BASIS,
12//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13//  See the License for the specific language governing permissions and
14//  limitations under the License.
15//
16
17#pragma once
18
19#include <memory>
20
21#include <base/macros.h>
22#include <base/memory/ref_counted.h>
23
24namespace bluetooth {
25class Adapter;
26}  // namespace bluetooth
27
28namespace ipc {
29
30class IPCHandler;
31
32// IPCManager is a class for initializing and running supported IPC mechanisms.
33// It manages the life-time of different IPC flavors that are available on the
34// system. There are two flavors: a Linux sequential packet domain socket based
35// system and one based on the Binder-based android.bluetooth framework.
36class IPCManager {
37 public:
38  // Possible IPC types.
39  enum Type {
40    TYPE_LINUX,   // IPC based on a Linux sequential packet domain socket
41    TYPE_BINDER,  // IPC based on the Binder
42    TYPE_DBUS     // IPC based on the DBus
43  };
44
45  // Interface for observing events from an IPC mechanism. These methods will be
46  // called on the thread that started the particular IPC type.
47  class Delegate {
48   public:
49    Delegate() = default;
50    virtual ~Delegate() = default;
51
52    // Called when an IPC mechanism has successfully started and is ready for
53    // client connections.
54    virtual void OnIPCHandlerStarted(Type type) = 0;
55
56    // Called when an IPC mechanism has stopped. This may happen due to an error
57    // in initialization or due to a regular shut down routine.
58    virtual void OnIPCHandlerStopped(Type type) = 0;
59
60   private:
61    DISALLOW_COPY_AND_ASSIGN(Delegate);
62  };
63
64  explicit IPCManager(bluetooth::Adapter* adapter);
65  ~IPCManager();
66
67  // Initialize the underlying IPC handler based on |type|, if that type has not
68  // yet been initialized and returns true on success. Returns false if that
69  // type has already been initialized or an error occurs.
70  //
71  // If TYPE_LINUX is given, the file path to use for the domain socket will be
72  // obtained from the global Settings object. Hence, the Settings object must
73  // have been initialized before calling this method.
74  //
75  // |delegate| must out-live the IPCManager and the underlying handler. Users
76  // can guarantee proper clean up by deallocating |delegate| when or after
77  // Delegate::OnIPCHandlerStopped is called. It is safe to destroy |delegate|
78  // after destroying the IPCManager instance, as the destructor will join and
79  // clean up all underlying threads.
80  bool Start(Type type, Delegate* delegate);
81
82  // Returns true if an IPC type has been initialized.
83  bool BinderStarted() const;
84  bool LinuxStarted() const;
85  bool DBusStarted() const;
86
87 private:
88  IPCManager() = default;
89
90  // Pointers to the different IPC handler classes. These are initialized and
91  // owned by us.
92  scoped_refptr<IPCHandler> binder_handler_;
93  scoped_refptr<IPCHandler> linux_handler_;
94  scoped_refptr<IPCHandler> dbus_handler_;
95
96  // The Bluetooth adapter instance. This is owned by Daemon so we keep a raw
97  // pointer to it.
98  bluetooth::Adapter* adapter_;
99
100  DISALLOW_COPY_AND_ASSIGN(IPCManager);
101};
102
103}  // namespace ipc
104