1*6fa2df46SAndroid Build Coastguard Worker // Copyright (C) 2023 The Android Open Source Project
2*6fa2df46SAndroid Build Coastguard Worker //
3*6fa2df46SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*6fa2df46SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*6fa2df46SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*6fa2df46SAndroid Build Coastguard Worker //
7*6fa2df46SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*6fa2df46SAndroid Build Coastguard Worker //
9*6fa2df46SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*6fa2df46SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*6fa2df46SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6fa2df46SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*6fa2df46SAndroid Build Coastguard Worker // limitations under the License.
14*6fa2df46SAndroid Build Coastguard Worker
15*6fa2df46SAndroid Build Coastguard Worker #if __ANDROID__
16*6fa2df46SAndroid Build Coastguard Worker
17*6fa2df46SAndroid Build Coastguard Worker #include <ditto/binder.h>
18*6fa2df46SAndroid Build Coastguard Worker
19*6fa2df46SAndroid Build Coastguard Worker #include <ditto/logger.h>
20*6fa2df46SAndroid Build Coastguard Worker
21*6fa2df46SAndroid Build Coastguard Worker namespace dittosuite {
22*6fa2df46SAndroid Build Coastguard Worker
23*6fa2df46SAndroid Build Coastguard Worker // Client
BpDittoBinder(const sp<IBinder> & impl)24*6fa2df46SAndroid Build Coastguard Worker BpDittoBinder::BpDittoBinder(const sp<IBinder>& impl) : BpInterface<IDittoBinder>(impl) {
25*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::BpDittoBinder()");
26*6fa2df46SAndroid Build Coastguard Worker }
27*6fa2df46SAndroid Build Coastguard Worker
async()28*6fa2df46SAndroid Build Coastguard Worker void BpDittoBinder::async() {
29*6fa2df46SAndroid Build Coastguard Worker Parcel data, reply;
30*6fa2df46SAndroid Build Coastguard Worker data.writeInterfaceToken(IDittoBinder::getInterfaceDescriptor());
31*6fa2df46SAndroid Build Coastguard Worker data.writeString16(String16(""));
32*6fa2df46SAndroid Build Coastguard Worker remote()->transact(ASYNC, data, &reply, IBinder::FLAG_ONEWAY); // asynchronous call
33*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::async()");
34*6fa2df46SAndroid Build Coastguard Worker }
35*6fa2df46SAndroid Build Coastguard Worker
sync(int8_t c)36*6fa2df46SAndroid Build Coastguard Worker int8_t BpDittoBinder::sync(int8_t c) {
37*6fa2df46SAndroid Build Coastguard Worker Parcel data, reply;
38*6fa2df46SAndroid Build Coastguard Worker data.writeInterfaceToken(IDittoBinder::getInterfaceDescriptor());
39*6fa2df46SAndroid Build Coastguard Worker data.writeByte(c);
40*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::sync parcel to be sent:");
41*6fa2df46SAndroid Build Coastguard Worker remote()->transact(SYNC, data, &reply);
42*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::sync transact reply");
43*6fa2df46SAndroid Build Coastguard Worker
44*6fa2df46SAndroid Build Coastguard Worker int8_t res;
45*6fa2df46SAndroid Build Coastguard Worker reply.readByte(&res);
46*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::sync()");
47*6fa2df46SAndroid Build Coastguard Worker return res;
48*6fa2df46SAndroid Build Coastguard Worker }
49*6fa2df46SAndroid Build Coastguard Worker
start()50*6fa2df46SAndroid Build Coastguard Worker void BpDittoBinder::start() {
51*6fa2df46SAndroid Build Coastguard Worker Parcel data, reply;
52*6fa2df46SAndroid Build Coastguard Worker data.writeInterfaceToken(IDittoBinder::getInterfaceDescriptor());
53*6fa2df46SAndroid Build Coastguard Worker data.writeString16(String16(""));
54*6fa2df46SAndroid Build Coastguard Worker remote()->transact(START, data, &reply, IBinder::FLAG_ONEWAY); // asynchronous call
55*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::start()");
56*6fa2df46SAndroid Build Coastguard Worker }
57*6fa2df46SAndroid Build Coastguard Worker
end()58*6fa2df46SAndroid Build Coastguard Worker void BpDittoBinder::end() {
59*6fa2df46SAndroid Build Coastguard Worker Parcel data, reply;
60*6fa2df46SAndroid Build Coastguard Worker data.writeInterfaceToken(IDittoBinder::getInterfaceDescriptor());
61*6fa2df46SAndroid Build Coastguard Worker data.writeString16(String16(""));
62*6fa2df46SAndroid Build Coastguard Worker remote()->transact(END, data, &reply, IBinder::FLAG_ONEWAY); // asynchronous call
63*6fa2df46SAndroid Build Coastguard Worker LOGD("BpDittoBinder::end()");
64*6fa2df46SAndroid Build Coastguard Worker }
65*6fa2df46SAndroid Build Coastguard Worker
66*6fa2df46SAndroid Build Coastguard Worker // IMPLEMENT_META_INTERFACE(DittoBinder, "DittoBinder");
67*6fa2df46SAndroid Build Coastguard Worker // Macro above expands to code below. Doing it by hand so we can log ctor and destructor calls.
68*6fa2df46SAndroid Build Coastguard Worker const String16 IDittoBinder::descriptor("DittoBinder");
getInterfaceDescriptor() const69*6fa2df46SAndroid Build Coastguard Worker const String16& IDittoBinder::getInterfaceDescriptor() const {
70*6fa2df46SAndroid Build Coastguard Worker return IDittoBinder::descriptor;
71*6fa2df46SAndroid Build Coastguard Worker }
72*6fa2df46SAndroid Build Coastguard Worker
asInterface(const sp<IBinder> & obj)73*6fa2df46SAndroid Build Coastguard Worker sp<IDittoBinder> IDittoBinder::asInterface(const sp<IBinder>& obj) {
74*6fa2df46SAndroid Build Coastguard Worker sp<IDittoBinder> intr;
75*6fa2df46SAndroid Build Coastguard Worker if (obj != nullptr) {
76*6fa2df46SAndroid Build Coastguard Worker intr = static_cast<IDittoBinder*>(obj->queryLocalInterface(IDittoBinder::descriptor).get());
77*6fa2df46SAndroid Build Coastguard Worker if (intr == nullptr) {
78*6fa2df46SAndroid Build Coastguard Worker intr = new BpDittoBinder(obj);
79*6fa2df46SAndroid Build Coastguard Worker }
80*6fa2df46SAndroid Build Coastguard Worker }
81*6fa2df46SAndroid Build Coastguard Worker return intr;
82*6fa2df46SAndroid Build Coastguard Worker }
IDittoBinder()83*6fa2df46SAndroid Build Coastguard Worker IDittoBinder::IDittoBinder() {
84*6fa2df46SAndroid Build Coastguard Worker LOGD("IDittoBinder::IDittoBinder()");
85*6fa2df46SAndroid Build Coastguard Worker }
~IDittoBinder()86*6fa2df46SAndroid Build Coastguard Worker IDittoBinder::~IDittoBinder() {
87*6fa2df46SAndroid Build Coastguard Worker LOGD("IDittoBinder::~IDittoBinder()");
88*6fa2df46SAndroid Build Coastguard Worker }
89*6fa2df46SAndroid Build Coastguard Worker
90*6fa2df46SAndroid Build Coastguard Worker // Server
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)91*6fa2df46SAndroid Build Coastguard Worker status_t BnDittoBinder::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
92*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact(), code: " + std::to_string(code));
93*6fa2df46SAndroid Build Coastguard Worker data.checkInterface(this);
94*6fa2df46SAndroid Build Coastguard Worker
95*6fa2df46SAndroid Build Coastguard Worker switch (code) {
96*6fa2df46SAndroid Build Coastguard Worker case START: {
97*6fa2df46SAndroid Build Coastguard Worker start();
98*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact START, refcount: " + std::to_string(client_cnt_));
99*6fa2df46SAndroid Build Coastguard Worker return NO_ERROR;
100*6fa2df46SAndroid Build Coastguard Worker } break;
101*6fa2df46SAndroid Build Coastguard Worker case END: {
102*6fa2df46SAndroid Build Coastguard Worker end();
103*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact END, refcount: " + std::to_string(client_cnt_));
104*6fa2df46SAndroid Build Coastguard Worker if (client_cnt_ <= 0) {
105*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact END, unblocking thread pool");
106*6fa2df46SAndroid Build Coastguard Worker pthread_cond_signal(thread_condition_);
107*6fa2df46SAndroid Build Coastguard Worker }
108*6fa2df46SAndroid Build Coastguard Worker return NO_ERROR;
109*6fa2df46SAndroid Build Coastguard Worker } break;
110*6fa2df46SAndroid Build Coastguard Worker case ASYNC: {
111*6fa2df46SAndroid Build Coastguard Worker async();
112*6fa2df46SAndroid Build Coastguard Worker return NO_ERROR;
113*6fa2df46SAndroid Build Coastguard Worker } break;
114*6fa2df46SAndroid Build Coastguard Worker case SYNC: {
115*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact SYNC");
116*6fa2df46SAndroid Build Coastguard Worker int8_t c = data.readByte();
117*6fa2df46SAndroid Build Coastguard Worker int8_t res = sync(c);
118*6fa2df46SAndroid Build Coastguard Worker if (!reply) {
119*6fa2df46SAndroid Build Coastguard Worker LOGF("No reply");
120*6fa2df46SAndroid Build Coastguard Worker }
121*6fa2df46SAndroid Build Coastguard Worker reply->writeByte(res);
122*6fa2df46SAndroid Build Coastguard Worker return NO_ERROR;
123*6fa2df46SAndroid Build Coastguard Worker } break;
124*6fa2df46SAndroid Build Coastguard Worker default:
125*6fa2df46SAndroid Build Coastguard Worker LOGD("BnDittoBinder::onTransact OTHER");
126*6fa2df46SAndroid Build Coastguard Worker return BBinder::onTransact(code, data, reply, flags);
127*6fa2df46SAndroid Build Coastguard Worker }
128*6fa2df46SAndroid Build Coastguard Worker }
129*6fa2df46SAndroid Build Coastguard Worker
start()130*6fa2df46SAndroid Build Coastguard Worker void DittoBinder::start() {
131*6fa2df46SAndroid Build Coastguard Worker LOGD("DittoBinder::start()");
132*6fa2df46SAndroid Build Coastguard Worker client_cnt_++;
133*6fa2df46SAndroid Build Coastguard Worker }
end()134*6fa2df46SAndroid Build Coastguard Worker void DittoBinder::end() {
135*6fa2df46SAndroid Build Coastguard Worker LOGD("DittoBinder::end()");
136*6fa2df46SAndroid Build Coastguard Worker client_cnt_--;
137*6fa2df46SAndroid Build Coastguard Worker }
138*6fa2df46SAndroid Build Coastguard Worker
async()139*6fa2df46SAndroid Build Coastguard Worker void DittoBinder::async() {
140*6fa2df46SAndroid Build Coastguard Worker LOGD("DittoBinder::async()");
141*6fa2df46SAndroid Build Coastguard Worker }
142*6fa2df46SAndroid Build Coastguard Worker
sync(int8_t c)143*6fa2df46SAndroid Build Coastguard Worker int8_t DittoBinder::sync(int8_t c) {
144*6fa2df46SAndroid Build Coastguard Worker LOGD("DittoBinder::sync()");
145*6fa2df46SAndroid Build Coastguard Worker return ~c;
146*6fa2df46SAndroid Build Coastguard Worker }
147*6fa2df46SAndroid Build Coastguard Worker
148*6fa2df46SAndroid Build Coastguard Worker } // namespace dittosuite
149*6fa2df46SAndroid Build Coastguard Worker
150*6fa2df46SAndroid Build Coastguard Worker #endif
151