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  };
43
44  // Interface for observing events from an IPC mechanism. These methods will be
45  // called on the thread that started the particular IPC type.
46  class Delegate {
47   public:
48    Delegate() = default;
49    virtual ~Delegate() = default;
50
51    // Called when an IPC mechanism has successfully started and is ready for
52    // client connections.
53    virtual void OnIPCHandlerStarted(Type type) = 0;
54
55    // Called when an IPC mechanism has stopped. This may happen due to an error
56    // in initialization or due to a regular shut down routine.
57    virtual void OnIPCHandlerStopped(Type type) = 0;
58
59   private:
60    DISALLOW_COPY_AND_ASSIGN(Delegate);
61  };
62
63  explicit IPCManager(bluetooth::Adapter* adapter);
64  ~IPCManager();
65
66  // Initialize the underlying IPC handler based on |type|, if that type has not
67  // yet been initialized and returns true on success. Returns false if that
68  // type has already been initialized or an error occurs.
69  //
70  // If TYPE_LINUX is given, the file path to use for the domain socket will be
71  // obtained from the global Settings object. Hence, the Settings object must
72  // have been initialized before calling this method.
73  //
74  // |delegate| must out-live the IPCManager and the underlying handler. Users
75  // can guarantee proper clean up by deallocating |delegate| when or after
76  // Delegate::OnIPCHandlerStopped is called. It is safe to destroy |delegate|
77  // after destroying the IPCManager instance, as the destructor will join and
78  // clean up all underlying threads.
79  bool Start(Type type, Delegate* delegate);
80
81  // Returns true if an IPC type has been initialized.
82  bool BinderStarted() const;
83  bool LinuxStarted() const;
84
85 private:
86  IPCManager() = default;
87
88  // Pointers to the different IPC handler classes. These are initialized and
89  // owned by us.
90  scoped_refptr<IPCHandler> binder_handler_;
91  scoped_refptr<IPCHandler> linux_handler_;
92
93  // The Bluetooth adapter instance. This is owned by Daemon so we keep a raw
94  // pointer to it.
95  bluetooth::Adapter* adapter_;
96
97  DISALLOW_COPY_AND_ASSIGN(IPCManager);
98};
99
100}  // namespace ipc
101