1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #ifdef __ANDROID__
18 
19 #include <binder/IInterface.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/Parcel.h>
22 
23 #include <ditto/logger.h>
24 
25 using android::BnInterface;
26 using android::BpInterface;
27 using android::IBinder;
28 using android::IInterface;
29 using android::NO_ERROR;
30 using android::Parcel;
31 using android::sp;
32 using android::status_t;
33 using android::String16;
34 
35 namespace dittosuite {
36 
37 // AIDL interface
38 class IDittoBinder : public IInterface {
39  public:
40   DECLARE_META_INTERFACE(DittoBinder);
41 
42   enum { START = IBinder::FIRST_CALL_TRANSACTION, END, SYNC, ASYNC };
43 
44   // Sends an asynchronous request to the service
45   virtual void async() = 0;
46 
47   // Sends a synchronous request to the service
48   virtual int8_t sync(int8_t c) = 0;
49 
50   // This should be called when a new binder client is created, to refcount
51   // number of callers.
52   virtual void start() = 0;
53 
54   // This should be called when a binder client finishes. When the refcount
55   // reaches 0, then the binder server can stop.
56   virtual void end() = 0;
57 };
58 
59 // Client
60 class BpDittoBinder : public BpInterface<IDittoBinder> {
61  public:
62   BpDittoBinder(const sp<IBinder>& impl);
63 
64   virtual void async();
65   virtual int8_t sync(int8_t c);
66   virtual void start();
67   virtual void end();
68 };
69 
70 // Server
71 class BnDittoBinder : public BnInterface<IDittoBinder> {
72   virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
73 
74  protected:
75   std::atomic_int client_cnt_;
76   pthread_cond_t* thread_condition_;
77 };
78 
79 class DittoBinder : public BnDittoBinder {
80  public:
81   DittoBinder() = delete;
DittoBinder(pthread_cond_t * thread_condition)82   DittoBinder(pthread_cond_t* thread_condition) { thread_condition_ = thread_condition; }
83 
84  private:
85   virtual void async();
86   virtual int8_t sync(int8_t c);
87   virtual void start();
88   virtual void end();
89 };
90 
91 template <class T>
getBinderService(const std::string & service_name)92 android::sp<T> getBinderService(const std::string& service_name) {
93   LOGD("Getting default Binder ServiceManager");
94   android::sp<android::IServiceManager> sm = android::defaultServiceManager();
95   if (!sm) {
96     LOGF("No Binder ServiceManager found");
97   }
98 
99   LOGD("Getting Binder Service: " + service_name);
100   android::sp<android::IBinder> binder = sm->waitForService(android::String16(service_name.c_str()));
101   if (!binder) {
102     LOGF("Unable to fetch Binder Interface");
103   }
104 
105   LOGD("Getting Binder Service interface");
106   android::sp<T> interface = android::interface_cast<T>(binder);
107   if (!interface) {
108     LOGF("Unable to cast Binder Service");
109   }
110 
111   return interface;
112 }
113 
114 
115 }  // namespace dittosuite
116 
117 #endif
118