xref: /aosp_15_r20/system/libhwbinder/IPCThreadState.cpp (revision 77b80299c8bdfeca3ae6d0ce27ae1ad3db289be3)
1*77b80299SAndroid Build Coastguard Worker /*
2*77b80299SAndroid Build Coastguard Worker  * Copyright (C) 2005 The Android Open Source Project
3*77b80299SAndroid Build Coastguard Worker  *
4*77b80299SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*77b80299SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*77b80299SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*77b80299SAndroid Build Coastguard Worker  *
8*77b80299SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*77b80299SAndroid Build Coastguard Worker  *
10*77b80299SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*77b80299SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*77b80299SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*77b80299SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*77b80299SAndroid Build Coastguard Worker  * limitations under the License.
15*77b80299SAndroid Build Coastguard Worker  */
16*77b80299SAndroid Build Coastguard Worker 
17*77b80299SAndroid Build Coastguard Worker #define LOG_TAG "hw-IPCThreadState"
18*77b80299SAndroid Build Coastguard Worker 
19*77b80299SAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
20*77b80299SAndroid Build Coastguard Worker 
21*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Binder.h>
22*77b80299SAndroid Build Coastguard Worker #include <hwbinder/BpHwBinder.h>
23*77b80299SAndroid Build Coastguard Worker #include <hwbinder/HidlSupport.h>
24*77b80299SAndroid Build Coastguard Worker 
25*77b80299SAndroid Build Coastguard Worker #include <android-base/macros.h>
26*77b80299SAndroid Build Coastguard Worker #include <utils/CallStack.h>
27*77b80299SAndroid Build Coastguard Worker #include <utils/Log.h>
28*77b80299SAndroid Build Coastguard Worker #include <utils/SystemClock.h>
29*77b80299SAndroid Build Coastguard Worker #include <utils/threads.h>
30*77b80299SAndroid Build Coastguard Worker 
31*77b80299SAndroid Build Coastguard Worker #include "binder_kernel.h"
32*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Static.h>
33*77b80299SAndroid Build Coastguard Worker #include "TextOutput.h"
34*77b80299SAndroid Build Coastguard Worker 
35*77b80299SAndroid Build Coastguard Worker #include <atomic>
36*77b80299SAndroid Build Coastguard Worker #include <errno.h>
37*77b80299SAndroid Build Coastguard Worker #include <inttypes.h>
38*77b80299SAndroid Build Coastguard Worker #include <linux/sched.h>
39*77b80299SAndroid Build Coastguard Worker #include <pthread.h>
40*77b80299SAndroid Build Coastguard Worker #include <signal.h>
41*77b80299SAndroid Build Coastguard Worker #include <stdio.h>
42*77b80299SAndroid Build Coastguard Worker #include <sys/ioctl.h>
43*77b80299SAndroid Build Coastguard Worker #include <sys/resource.h>
44*77b80299SAndroid Build Coastguard Worker #include <unistd.h>
45*77b80299SAndroid Build Coastguard Worker 
46*77b80299SAndroid Build Coastguard Worker #if LOG_NDEBUG
47*77b80299SAndroid Build Coastguard Worker 
48*77b80299SAndroid Build Coastguard Worker #define IF_LOG_TRANSACTIONS() if (false)
49*77b80299SAndroid Build Coastguard Worker #define IF_LOG_COMMANDS() if (false)
50*77b80299SAndroid Build Coastguard Worker #define LOG_REMOTEREFS(...)
51*77b80299SAndroid Build Coastguard Worker #define IF_LOG_REMOTEREFS() if (false)
52*77b80299SAndroid Build Coastguard Worker #define LOG_THREADPOOL(...)
53*77b80299SAndroid Build Coastguard Worker #define LOG_ONEWAY(...)
54*77b80299SAndroid Build Coastguard Worker 
55*77b80299SAndroid Build Coastguard Worker #else
56*77b80299SAndroid Build Coastguard Worker 
57*77b80299SAndroid Build Coastguard Worker #define IF_LOG_TRANSACTIONS() IF_ALOG(LOG_VERBOSE, "transact")
58*77b80299SAndroid Build Coastguard Worker #define IF_LOG_COMMANDS() IF_ALOG(LOG_VERBOSE, "ipc")
59*77b80299SAndroid Build Coastguard Worker #define LOG_REMOTEREFS(...) ALOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
60*77b80299SAndroid Build Coastguard Worker #define IF_LOG_REMOTEREFS() IF_ALOG(LOG_DEBUG, "remoterefs")
61*77b80299SAndroid Build Coastguard Worker #define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
62*77b80299SAndroid Build Coastguard Worker #define LOG_ONEWAY(...) ALOG(LOG_DEBUG, "ipc", __VA_ARGS__)
63*77b80299SAndroid Build Coastguard Worker 
64*77b80299SAndroid Build Coastguard Worker #endif
65*77b80299SAndroid Build Coastguard Worker 
66*77b80299SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
67*77b80299SAndroid Build Coastguard Worker 
68*77b80299SAndroid Build Coastguard Worker namespace android {
69*77b80299SAndroid Build Coastguard Worker namespace hardware {
70*77b80299SAndroid Build Coastguard Worker 
71*77b80299SAndroid Build Coastguard Worker // Static const and functions will be optimized out if not used,
72*77b80299SAndroid Build Coastguard Worker // when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
73*77b80299SAndroid Build Coastguard Worker static const char *kReturnStrings[] = {
74*77b80299SAndroid Build Coastguard Worker     "BR_ERROR",
75*77b80299SAndroid Build Coastguard Worker     "BR_OK",
76*77b80299SAndroid Build Coastguard Worker     "BR_TRANSACTION/BR_TRANSACTION_SEC_CTX",
77*77b80299SAndroid Build Coastguard Worker     "BR_REPLY",
78*77b80299SAndroid Build Coastguard Worker     "BR_ACQUIRE_RESULT",
79*77b80299SAndroid Build Coastguard Worker     "BR_DEAD_REPLY",
80*77b80299SAndroid Build Coastguard Worker     "BR_TRANSACTION_COMPLETE",
81*77b80299SAndroid Build Coastguard Worker     "BR_INCREFS",
82*77b80299SAndroid Build Coastguard Worker     "BR_ACQUIRE",
83*77b80299SAndroid Build Coastguard Worker     "BR_RELEASE",
84*77b80299SAndroid Build Coastguard Worker     "BR_DECREFS",
85*77b80299SAndroid Build Coastguard Worker     "BR_ATTEMPT_ACQUIRE",
86*77b80299SAndroid Build Coastguard Worker     "BR_NOOP",
87*77b80299SAndroid Build Coastguard Worker     "BR_SPAWN_LOOPER",
88*77b80299SAndroid Build Coastguard Worker     "BR_FINISHED",
89*77b80299SAndroid Build Coastguard Worker     "BR_DEAD_BINDER",
90*77b80299SAndroid Build Coastguard Worker     "BR_CLEAR_DEATH_NOTIFICATION_DONE",
91*77b80299SAndroid Build Coastguard Worker     "BR_FAILED_REPLY",
92*77b80299SAndroid Build Coastguard Worker     "BR_FROZEN_REPLY",
93*77b80299SAndroid Build Coastguard Worker     "BR_ONEWAY_SPAM_SUSPECT",
94*77b80299SAndroid Build Coastguard Worker     "BR_TRANSACTION_PENDING_FROZEN",
95*77b80299SAndroid Build Coastguard Worker };
96*77b80299SAndroid Build Coastguard Worker 
97*77b80299SAndroid Build Coastguard Worker static const char *kCommandStrings[] = {
98*77b80299SAndroid Build Coastguard Worker     "BC_TRANSACTION",
99*77b80299SAndroid Build Coastguard Worker     "BC_REPLY",
100*77b80299SAndroid Build Coastguard Worker     "BC_ACQUIRE_RESULT",
101*77b80299SAndroid Build Coastguard Worker     "BC_FREE_BUFFER",
102*77b80299SAndroid Build Coastguard Worker     "BC_INCREFS",
103*77b80299SAndroid Build Coastguard Worker     "BC_ACQUIRE",
104*77b80299SAndroid Build Coastguard Worker     "BC_RELEASE",
105*77b80299SAndroid Build Coastguard Worker     "BC_DECREFS",
106*77b80299SAndroid Build Coastguard Worker     "BC_INCREFS_DONE",
107*77b80299SAndroid Build Coastguard Worker     "BC_ACQUIRE_DONE",
108*77b80299SAndroid Build Coastguard Worker     "BC_ATTEMPT_ACQUIRE",
109*77b80299SAndroid Build Coastguard Worker     "BC_REGISTER_LOOPER",
110*77b80299SAndroid Build Coastguard Worker     "BC_ENTER_LOOPER",
111*77b80299SAndroid Build Coastguard Worker     "BC_EXIT_LOOPER",
112*77b80299SAndroid Build Coastguard Worker     "BC_REQUEST_DEATH_NOTIFICATION",
113*77b80299SAndroid Build Coastguard Worker     "BC_CLEAR_DEATH_NOTIFICATION",
114*77b80299SAndroid Build Coastguard Worker     "BC_DEAD_BINDER_DONE"
115*77b80299SAndroid Build Coastguard Worker };
116*77b80299SAndroid Build Coastguard Worker 
getReturnString(uint32_t cmd)117*77b80299SAndroid Build Coastguard Worker static const char* getReturnString(uint32_t cmd)
118*77b80299SAndroid Build Coastguard Worker {
119*77b80299SAndroid Build Coastguard Worker     size_t idx = cmd & _IOC_NRMASK;
120*77b80299SAndroid Build Coastguard Worker     if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
121*77b80299SAndroid Build Coastguard Worker         return kReturnStrings[idx];
122*77b80299SAndroid Build Coastguard Worker     else
123*77b80299SAndroid Build Coastguard Worker         return "unknown";
124*77b80299SAndroid Build Coastguard Worker }
125*77b80299SAndroid Build Coastguard Worker 
printBinderTransactionData(TextOutput & out,const void * data)126*77b80299SAndroid Build Coastguard Worker static const void* printBinderTransactionData(TextOutput& out, const void* data)
127*77b80299SAndroid Build Coastguard Worker {
128*77b80299SAndroid Build Coastguard Worker     const binder_transaction_data* btd =
129*77b80299SAndroid Build Coastguard Worker         (const binder_transaction_data*)data;
130*77b80299SAndroid Build Coastguard Worker     if (btd->target.handle < 1024) {
131*77b80299SAndroid Build Coastguard Worker         /* want to print descriptors in decimal; guess based on value */
132*77b80299SAndroid Build Coastguard Worker         out << "target.desc=" << btd->target.handle;
133*77b80299SAndroid Build Coastguard Worker     } else {
134*77b80299SAndroid Build Coastguard Worker         out << "target.ptr=" << btd->target.ptr;
135*77b80299SAndroid Build Coastguard Worker     }
136*77b80299SAndroid Build Coastguard Worker     out << " (cookie " << btd->cookie << ")" << endl
137*77b80299SAndroid Build Coastguard Worker         << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
138*77b80299SAndroid Build Coastguard Worker         << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
139*77b80299SAndroid Build Coastguard Worker         << " bytes)" << endl
140*77b80299SAndroid Build Coastguard Worker         << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
141*77b80299SAndroid Build Coastguard Worker         << " bytes)";
142*77b80299SAndroid Build Coastguard Worker     return btd+1;
143*77b80299SAndroid Build Coastguard Worker }
144*77b80299SAndroid Build Coastguard Worker 
printReturnCommand(TextOutput & out,const void * _cmd)145*77b80299SAndroid Build Coastguard Worker static const void* printReturnCommand(TextOutput& out, const void* _cmd)
146*77b80299SAndroid Build Coastguard Worker {
147*77b80299SAndroid Build Coastguard Worker     static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
148*77b80299SAndroid Build Coastguard Worker     const int32_t* cmd = (const int32_t*)_cmd;
149*77b80299SAndroid Build Coastguard Worker     uint32_t code = (uint32_t)*cmd++;
150*77b80299SAndroid Build Coastguard Worker     size_t cmdIndex = code & 0xff;
151*77b80299SAndroid Build Coastguard Worker     if (code == BR_ERROR) {
152*77b80299SAndroid Build Coastguard Worker         out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
153*77b80299SAndroid Build Coastguard Worker         return cmd;
154*77b80299SAndroid Build Coastguard Worker     } else if (cmdIndex >= N) {
155*77b80299SAndroid Build Coastguard Worker         out << "Unknown reply: " << code << endl;
156*77b80299SAndroid Build Coastguard Worker         return cmd;
157*77b80299SAndroid Build Coastguard Worker     }
158*77b80299SAndroid Build Coastguard Worker     out << kReturnStrings[cmdIndex];
159*77b80299SAndroid Build Coastguard Worker 
160*77b80299SAndroid Build Coastguard Worker     switch (code) {
161*77b80299SAndroid Build Coastguard Worker         case BR_TRANSACTION:
162*77b80299SAndroid Build Coastguard Worker         case BR_REPLY: {
163*77b80299SAndroid Build Coastguard Worker             out << ": " << indent;
164*77b80299SAndroid Build Coastguard Worker             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
165*77b80299SAndroid Build Coastguard Worker             out << dedent;
166*77b80299SAndroid Build Coastguard Worker         } break;
167*77b80299SAndroid Build Coastguard Worker 
168*77b80299SAndroid Build Coastguard Worker         case BR_ACQUIRE_RESULT: {
169*77b80299SAndroid Build Coastguard Worker             const int32_t res = *cmd++;
170*77b80299SAndroid Build Coastguard Worker             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
171*77b80299SAndroid Build Coastguard Worker         } break;
172*77b80299SAndroid Build Coastguard Worker 
173*77b80299SAndroid Build Coastguard Worker         case BR_INCREFS:
174*77b80299SAndroid Build Coastguard Worker         case BR_ACQUIRE:
175*77b80299SAndroid Build Coastguard Worker         case BR_RELEASE:
176*77b80299SAndroid Build Coastguard Worker         case BR_DECREFS: {
177*77b80299SAndroid Build Coastguard Worker             const int32_t b = *cmd++;
178*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
179*77b80299SAndroid Build Coastguard Worker             out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
180*77b80299SAndroid Build Coastguard Worker         } break;
181*77b80299SAndroid Build Coastguard Worker 
182*77b80299SAndroid Build Coastguard Worker         case BR_ATTEMPT_ACQUIRE: {
183*77b80299SAndroid Build Coastguard Worker             const int32_t p = *cmd++;
184*77b80299SAndroid Build Coastguard Worker             const int32_t b = *cmd++;
185*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
186*77b80299SAndroid Build Coastguard Worker             out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
187*77b80299SAndroid Build Coastguard Worker                 << "), pri=" << p;
188*77b80299SAndroid Build Coastguard Worker         } break;
189*77b80299SAndroid Build Coastguard Worker 
190*77b80299SAndroid Build Coastguard Worker         case BR_DEAD_BINDER:
191*77b80299SAndroid Build Coastguard Worker         case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
192*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
193*77b80299SAndroid Build Coastguard Worker             out << ": death cookie " << (void*)(long)c;
194*77b80299SAndroid Build Coastguard Worker         } break;
195*77b80299SAndroid Build Coastguard Worker 
196*77b80299SAndroid Build Coastguard Worker         default:
197*77b80299SAndroid Build Coastguard Worker             // no details to show for: BR_OK, BR_DEAD_REPLY,
198*77b80299SAndroid Build Coastguard Worker             // BR_TRANSACTION_COMPLETE, BR_FINISHED
199*77b80299SAndroid Build Coastguard Worker             break;
200*77b80299SAndroid Build Coastguard Worker     }
201*77b80299SAndroid Build Coastguard Worker 
202*77b80299SAndroid Build Coastguard Worker     out << endl;
203*77b80299SAndroid Build Coastguard Worker     return cmd;
204*77b80299SAndroid Build Coastguard Worker }
205*77b80299SAndroid Build Coastguard Worker 
printCommand(TextOutput & out,const void * _cmd)206*77b80299SAndroid Build Coastguard Worker static const void* printCommand(TextOutput& out, const void* _cmd)
207*77b80299SAndroid Build Coastguard Worker {
208*77b80299SAndroid Build Coastguard Worker     static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
209*77b80299SAndroid Build Coastguard Worker     const int32_t* cmd = (const int32_t*)_cmd;
210*77b80299SAndroid Build Coastguard Worker     uint32_t code = (uint32_t)*cmd++;
211*77b80299SAndroid Build Coastguard Worker     size_t cmdIndex = code & 0xff;
212*77b80299SAndroid Build Coastguard Worker 
213*77b80299SAndroid Build Coastguard Worker     if (cmdIndex >= N) {
214*77b80299SAndroid Build Coastguard Worker         out << "Unknown command: " << code << endl;
215*77b80299SAndroid Build Coastguard Worker         return cmd;
216*77b80299SAndroid Build Coastguard Worker     }
217*77b80299SAndroid Build Coastguard Worker     out << kCommandStrings[cmdIndex];
218*77b80299SAndroid Build Coastguard Worker 
219*77b80299SAndroid Build Coastguard Worker     switch (code) {
220*77b80299SAndroid Build Coastguard Worker         case BC_TRANSACTION:
221*77b80299SAndroid Build Coastguard Worker         case BC_REPLY: {
222*77b80299SAndroid Build Coastguard Worker             out << ": " << indent;
223*77b80299SAndroid Build Coastguard Worker             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
224*77b80299SAndroid Build Coastguard Worker             out << dedent;
225*77b80299SAndroid Build Coastguard Worker         } break;
226*77b80299SAndroid Build Coastguard Worker 
227*77b80299SAndroid Build Coastguard Worker         case BC_ACQUIRE_RESULT: {
228*77b80299SAndroid Build Coastguard Worker             const int32_t res = *cmd++;
229*77b80299SAndroid Build Coastguard Worker             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
230*77b80299SAndroid Build Coastguard Worker         } break;
231*77b80299SAndroid Build Coastguard Worker 
232*77b80299SAndroid Build Coastguard Worker         case BC_FREE_BUFFER: {
233*77b80299SAndroid Build Coastguard Worker             const int32_t buf = *cmd++;
234*77b80299SAndroid Build Coastguard Worker             out << ": buffer=" << (void*)(long)buf;
235*77b80299SAndroid Build Coastguard Worker         } break;
236*77b80299SAndroid Build Coastguard Worker 
237*77b80299SAndroid Build Coastguard Worker         case BC_INCREFS:
238*77b80299SAndroid Build Coastguard Worker         case BC_ACQUIRE:
239*77b80299SAndroid Build Coastguard Worker         case BC_RELEASE:
240*77b80299SAndroid Build Coastguard Worker         case BC_DECREFS: {
241*77b80299SAndroid Build Coastguard Worker             const int32_t d = *cmd++;
242*77b80299SAndroid Build Coastguard Worker             out << ": desc=" << d;
243*77b80299SAndroid Build Coastguard Worker         } break;
244*77b80299SAndroid Build Coastguard Worker 
245*77b80299SAndroid Build Coastguard Worker         case BC_INCREFS_DONE:
246*77b80299SAndroid Build Coastguard Worker         case BC_ACQUIRE_DONE: {
247*77b80299SAndroid Build Coastguard Worker             const int32_t b = *cmd++;
248*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
249*77b80299SAndroid Build Coastguard Worker             out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
250*77b80299SAndroid Build Coastguard Worker         } break;
251*77b80299SAndroid Build Coastguard Worker 
252*77b80299SAndroid Build Coastguard Worker         case BC_ATTEMPT_ACQUIRE: {
253*77b80299SAndroid Build Coastguard Worker             const int32_t p = *cmd++;
254*77b80299SAndroid Build Coastguard Worker             const int32_t d = *cmd++;
255*77b80299SAndroid Build Coastguard Worker             out << ": desc=" << d << ", pri=" << p;
256*77b80299SAndroid Build Coastguard Worker         } break;
257*77b80299SAndroid Build Coastguard Worker 
258*77b80299SAndroid Build Coastguard Worker         case BC_REQUEST_DEATH_NOTIFICATION:
259*77b80299SAndroid Build Coastguard Worker         case BC_CLEAR_DEATH_NOTIFICATION: {
260*77b80299SAndroid Build Coastguard Worker             const int32_t h = *cmd++;
261*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
262*77b80299SAndroid Build Coastguard Worker             out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
263*77b80299SAndroid Build Coastguard Worker         } break;
264*77b80299SAndroid Build Coastguard Worker 
265*77b80299SAndroid Build Coastguard Worker         case BC_DEAD_BINDER_DONE: {
266*77b80299SAndroid Build Coastguard Worker             const int32_t c = *cmd++;
267*77b80299SAndroid Build Coastguard Worker             out << ": death cookie " << (void*)(long)c;
268*77b80299SAndroid Build Coastguard Worker         } break;
269*77b80299SAndroid Build Coastguard Worker 
270*77b80299SAndroid Build Coastguard Worker         default:
271*77b80299SAndroid Build Coastguard Worker             // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
272*77b80299SAndroid Build Coastguard Worker             // BC_EXIT_LOOPER
273*77b80299SAndroid Build Coastguard Worker             break;
274*77b80299SAndroid Build Coastguard Worker     }
275*77b80299SAndroid Build Coastguard Worker 
276*77b80299SAndroid Build Coastguard Worker     out << endl;
277*77b80299SAndroid Build Coastguard Worker     return cmd;
278*77b80299SAndroid Build Coastguard Worker }
279*77b80299SAndroid Build Coastguard Worker 
280*77b80299SAndroid Build Coastguard Worker static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
281*77b80299SAndroid Build Coastguard Worker static std::atomic<bool> gHaveTLS = false;
282*77b80299SAndroid Build Coastguard Worker static pthread_key_t gTLS = 0;
283*77b80299SAndroid Build Coastguard Worker static std::atomic<bool> gShutdown = false;
284*77b80299SAndroid Build Coastguard Worker 
self()285*77b80299SAndroid Build Coastguard Worker IPCThreadState* IPCThreadState::self()
286*77b80299SAndroid Build Coastguard Worker {
287*77b80299SAndroid Build Coastguard Worker     if (gHaveTLS.load(std::memory_order_acquire)) {
288*77b80299SAndroid Build Coastguard Worker restart:
289*77b80299SAndroid Build Coastguard Worker         const pthread_key_t k = gTLS;
290*77b80299SAndroid Build Coastguard Worker         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
291*77b80299SAndroid Build Coastguard Worker         if (st) return st;
292*77b80299SAndroid Build Coastguard Worker         return new IPCThreadState;
293*77b80299SAndroid Build Coastguard Worker     }
294*77b80299SAndroid Build Coastguard Worker 
295*77b80299SAndroid Build Coastguard Worker     // Racey, heuristic test for simultaneous shutdown.
296*77b80299SAndroid Build Coastguard Worker     if (gShutdown.load(std::memory_order_relaxed)) {
297*77b80299SAndroid Build Coastguard Worker         ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
298*77b80299SAndroid Build Coastguard Worker         return nullptr;
299*77b80299SAndroid Build Coastguard Worker     }
300*77b80299SAndroid Build Coastguard Worker 
301*77b80299SAndroid Build Coastguard Worker     pthread_mutex_lock(&gTLSMutex);
302*77b80299SAndroid Build Coastguard Worker     if (!gHaveTLS.load(std::memory_order_relaxed)) {
303*77b80299SAndroid Build Coastguard Worker         int key_create_value = pthread_key_create(&gTLS, threadDestructor);
304*77b80299SAndroid Build Coastguard Worker         if (key_create_value != 0) {
305*77b80299SAndroid Build Coastguard Worker             pthread_mutex_unlock(&gTLSMutex);
306*77b80299SAndroid Build Coastguard Worker             ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
307*77b80299SAndroid Build Coastguard Worker                     strerror(key_create_value));
308*77b80299SAndroid Build Coastguard Worker             return nullptr;
309*77b80299SAndroid Build Coastguard Worker         }
310*77b80299SAndroid Build Coastguard Worker         gHaveTLS.store(true, std::memory_order_release);
311*77b80299SAndroid Build Coastguard Worker     }
312*77b80299SAndroid Build Coastguard Worker     pthread_mutex_unlock(&gTLSMutex);
313*77b80299SAndroid Build Coastguard Worker     goto restart;
314*77b80299SAndroid Build Coastguard Worker }
315*77b80299SAndroid Build Coastguard Worker 
selfOrNull()316*77b80299SAndroid Build Coastguard Worker IPCThreadState* IPCThreadState::selfOrNull()
317*77b80299SAndroid Build Coastguard Worker {
318*77b80299SAndroid Build Coastguard Worker     if (gHaveTLS.load(std::memory_order_acquire)) {
319*77b80299SAndroid Build Coastguard Worker         const pthread_key_t k = gTLS;
320*77b80299SAndroid Build Coastguard Worker         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
321*77b80299SAndroid Build Coastguard Worker         return st;
322*77b80299SAndroid Build Coastguard Worker     }
323*77b80299SAndroid Build Coastguard Worker     return nullptr;
324*77b80299SAndroid Build Coastguard Worker }
325*77b80299SAndroid Build Coastguard Worker 
shutdown()326*77b80299SAndroid Build Coastguard Worker void IPCThreadState::shutdown()
327*77b80299SAndroid Build Coastguard Worker {
328*77b80299SAndroid Build Coastguard Worker     gShutdown.store(true, std::memory_order_relaxed);
329*77b80299SAndroid Build Coastguard Worker 
330*77b80299SAndroid Build Coastguard Worker     if (gHaveTLS.load(std::memory_order_acquire)) {
331*77b80299SAndroid Build Coastguard Worker         // XXX Need to wait for all thread pool threads to exit!
332*77b80299SAndroid Build Coastguard Worker         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
333*77b80299SAndroid Build Coastguard Worker         if (st) {
334*77b80299SAndroid Build Coastguard Worker             delete st;
335*77b80299SAndroid Build Coastguard Worker             pthread_setspecific(gTLS, nullptr);
336*77b80299SAndroid Build Coastguard Worker         }
337*77b80299SAndroid Build Coastguard Worker         pthread_key_delete(gTLS);
338*77b80299SAndroid Build Coastguard Worker         gHaveTLS.store(false, std::memory_order_release);
339*77b80299SAndroid Build Coastguard Worker     }
340*77b80299SAndroid Build Coastguard Worker }
341*77b80299SAndroid Build Coastguard Worker 
process()342*77b80299SAndroid Build Coastguard Worker sp<ProcessState> IPCThreadState::process()
343*77b80299SAndroid Build Coastguard Worker {
344*77b80299SAndroid Build Coastguard Worker     return mProcess;
345*77b80299SAndroid Build Coastguard Worker }
346*77b80299SAndroid Build Coastguard Worker 
clearLastError()347*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::clearLastError()
348*77b80299SAndroid Build Coastguard Worker {
349*77b80299SAndroid Build Coastguard Worker     const status_t err = mLastError;
350*77b80299SAndroid Build Coastguard Worker     mLastError = NO_ERROR;
351*77b80299SAndroid Build Coastguard Worker     return err;
352*77b80299SAndroid Build Coastguard Worker }
353*77b80299SAndroid Build Coastguard Worker 
getCallingPid() const354*77b80299SAndroid Build Coastguard Worker pid_t IPCThreadState::getCallingPid() const
355*77b80299SAndroid Build Coastguard Worker {
356*77b80299SAndroid Build Coastguard Worker     return mCallingPid;
357*77b80299SAndroid Build Coastguard Worker }
358*77b80299SAndroid Build Coastguard Worker 
getCallingSid() const359*77b80299SAndroid Build Coastguard Worker const char* IPCThreadState::getCallingSid() const
360*77b80299SAndroid Build Coastguard Worker {
361*77b80299SAndroid Build Coastguard Worker     return mCallingSid;
362*77b80299SAndroid Build Coastguard Worker }
363*77b80299SAndroid Build Coastguard Worker 
getCallingUid() const364*77b80299SAndroid Build Coastguard Worker uid_t IPCThreadState::getCallingUid() const
365*77b80299SAndroid Build Coastguard Worker {
366*77b80299SAndroid Build Coastguard Worker     return mCallingUid;
367*77b80299SAndroid Build Coastguard Worker }
368*77b80299SAndroid Build Coastguard Worker 
clearCallingIdentity()369*77b80299SAndroid Build Coastguard Worker int64_t IPCThreadState::clearCallingIdentity()
370*77b80299SAndroid Build Coastguard Worker {
371*77b80299SAndroid Build Coastguard Worker     // ignore mCallingSid for legacy reasons
372*77b80299SAndroid Build Coastguard Worker     int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
373*77b80299SAndroid Build Coastguard Worker     clearCaller();
374*77b80299SAndroid Build Coastguard Worker     return token;
375*77b80299SAndroid Build Coastguard Worker }
376*77b80299SAndroid Build Coastguard Worker 
setStrictModePolicy(int32_t policy)377*77b80299SAndroid Build Coastguard Worker void IPCThreadState::setStrictModePolicy(int32_t policy)
378*77b80299SAndroid Build Coastguard Worker {
379*77b80299SAndroid Build Coastguard Worker     mStrictModePolicy = policy;
380*77b80299SAndroid Build Coastguard Worker }
381*77b80299SAndroid Build Coastguard Worker 
getStrictModePolicy() const382*77b80299SAndroid Build Coastguard Worker int32_t IPCThreadState::getStrictModePolicy() const
383*77b80299SAndroid Build Coastguard Worker {
384*77b80299SAndroid Build Coastguard Worker     return mStrictModePolicy;
385*77b80299SAndroid Build Coastguard Worker }
386*77b80299SAndroid Build Coastguard Worker 
setLastTransactionBinderFlags(int32_t flags)387*77b80299SAndroid Build Coastguard Worker void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
388*77b80299SAndroid Build Coastguard Worker {
389*77b80299SAndroid Build Coastguard Worker     mLastTransactionBinderFlags = flags;
390*77b80299SAndroid Build Coastguard Worker }
391*77b80299SAndroid Build Coastguard Worker 
getLastTransactionBinderFlags() const392*77b80299SAndroid Build Coastguard Worker int32_t IPCThreadState::getLastTransactionBinderFlags() const
393*77b80299SAndroid Build Coastguard Worker {
394*77b80299SAndroid Build Coastguard Worker     return mLastTransactionBinderFlags;
395*77b80299SAndroid Build Coastguard Worker }
396*77b80299SAndroid Build Coastguard Worker 
restoreCallingIdentity(int64_t token)397*77b80299SAndroid Build Coastguard Worker void IPCThreadState::restoreCallingIdentity(int64_t token)
398*77b80299SAndroid Build Coastguard Worker {
399*77b80299SAndroid Build Coastguard Worker     mCallingUid = (int)(token>>32);
400*77b80299SAndroid Build Coastguard Worker     mCallingSid = nullptr;  // not enough data to restore
401*77b80299SAndroid Build Coastguard Worker     mCallingPid = (int)token;
402*77b80299SAndroid Build Coastguard Worker }
403*77b80299SAndroid Build Coastguard Worker 
clearCaller()404*77b80299SAndroid Build Coastguard Worker void IPCThreadState::clearCaller()
405*77b80299SAndroid Build Coastguard Worker {
406*77b80299SAndroid Build Coastguard Worker     mCallingPid = getpid();
407*77b80299SAndroid Build Coastguard Worker     mCallingSid = nullptr;  // expensive to lookup
408*77b80299SAndroid Build Coastguard Worker     mCallingUid = getuid();
409*77b80299SAndroid Build Coastguard Worker }
410*77b80299SAndroid Build Coastguard Worker 
flushCommands()411*77b80299SAndroid Build Coastguard Worker void IPCThreadState::flushCommands()
412*77b80299SAndroid Build Coastguard Worker {
413*77b80299SAndroid Build Coastguard Worker     if (mProcess->mDriverFD < 0)
414*77b80299SAndroid Build Coastguard Worker         return;
415*77b80299SAndroid Build Coastguard Worker     talkWithDriver(false);
416*77b80299SAndroid Build Coastguard Worker     // The flush could have caused post-write refcount decrements to have
417*77b80299SAndroid Build Coastguard Worker     // been executed, which in turn could result in BC_RELEASE/BC_DECREFS
418*77b80299SAndroid Build Coastguard Worker     // being queued in mOut. So flush again, if we need to.
419*77b80299SAndroid Build Coastguard Worker     if (mOut.dataSize() > 0) {
420*77b80299SAndroid Build Coastguard Worker         talkWithDriver(false);
421*77b80299SAndroid Build Coastguard Worker     }
422*77b80299SAndroid Build Coastguard Worker     if (mOut.dataSize() > 0) {
423*77b80299SAndroid Build Coastguard Worker         ALOGW("mOut.dataSize() > 0 after flushCommands()");
424*77b80299SAndroid Build Coastguard Worker     }
425*77b80299SAndroid Build Coastguard Worker }
426*77b80299SAndroid Build Coastguard Worker 
getAndExecuteCommand()427*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::getAndExecuteCommand()
428*77b80299SAndroid Build Coastguard Worker {
429*77b80299SAndroid Build Coastguard Worker     status_t result;
430*77b80299SAndroid Build Coastguard Worker     int32_t cmd;
431*77b80299SAndroid Build Coastguard Worker 
432*77b80299SAndroid Build Coastguard Worker     result = talkWithDriver();
433*77b80299SAndroid Build Coastguard Worker     if (result >= NO_ERROR) {
434*77b80299SAndroid Build Coastguard Worker         size_t IN = mIn.dataAvail();
435*77b80299SAndroid Build Coastguard Worker         if (IN < sizeof(int32_t)) return result;
436*77b80299SAndroid Build Coastguard Worker         cmd = mIn.readInt32();
437*77b80299SAndroid Build Coastguard Worker         IF_LOG_COMMANDS() {
438*77b80299SAndroid Build Coastguard Worker             alog << "Processing top-level Command: "
439*77b80299SAndroid Build Coastguard Worker                  << getReturnString(cmd) << endl;
440*77b80299SAndroid Build Coastguard Worker         }
441*77b80299SAndroid Build Coastguard Worker 
442*77b80299SAndroid Build Coastguard Worker         pthread_mutex_lock(&mProcess->mThreadCountLock);
443*77b80299SAndroid Build Coastguard Worker         mProcess->mExecutingThreadsCount++;
444*77b80299SAndroid Build Coastguard Worker         if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
445*77b80299SAndroid Build Coastguard Worker             mProcess->mMaxThreads > 1 && mProcess->mStarvationStartTimeMs == 0) {
446*77b80299SAndroid Build Coastguard Worker             mProcess->mStarvationStartTimeMs = uptimeMillis();
447*77b80299SAndroid Build Coastguard Worker         }
448*77b80299SAndroid Build Coastguard Worker         pthread_mutex_unlock(&mProcess->mThreadCountLock);
449*77b80299SAndroid Build Coastguard Worker 
450*77b80299SAndroid Build Coastguard Worker         result = executeCommand(cmd);
451*77b80299SAndroid Build Coastguard Worker 
452*77b80299SAndroid Build Coastguard Worker         pthread_mutex_lock(&mProcess->mThreadCountLock);
453*77b80299SAndroid Build Coastguard Worker         mProcess->mExecutingThreadsCount--;
454*77b80299SAndroid Build Coastguard Worker         if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
455*77b80299SAndroid Build Coastguard Worker             mProcess->mStarvationStartTimeMs != 0) {
456*77b80299SAndroid Build Coastguard Worker             int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
457*77b80299SAndroid Build Coastguard Worker             if (starvationTimeMs > 100) {
458*77b80299SAndroid Build Coastguard Worker                 // If there is only a single-threaded client, nobody would be blocked
459*77b80299SAndroid Build Coastguard Worker                 // on this, and it's not really starvation. (see b/37647467)
460*77b80299SAndroid Build Coastguard Worker                 ALOGW("All binder threads in pool (%zu threads) busy for %" PRId64 " ms%s",
461*77b80299SAndroid Build Coastguard Worker                       mProcess->mMaxThreads, starvationTimeMs,
462*77b80299SAndroid Build Coastguard Worker                       mProcess->mMaxThreads > 1 ? "" : " (may be a false alarm)");
463*77b80299SAndroid Build Coastguard Worker             }
464*77b80299SAndroid Build Coastguard Worker             mProcess->mStarvationStartTimeMs = 0;
465*77b80299SAndroid Build Coastguard Worker         }
466*77b80299SAndroid Build Coastguard Worker         pthread_mutex_unlock(&mProcess->mThreadCountLock);
467*77b80299SAndroid Build Coastguard Worker     }
468*77b80299SAndroid Build Coastguard Worker 
469*77b80299SAndroid Build Coastguard Worker     if (UNLIKELY(!mPostCommandTasks.empty())) {
470*77b80299SAndroid Build Coastguard Worker         // make a copy in case the post transaction task makes a binder
471*77b80299SAndroid Build Coastguard Worker         // call and that other process calls back into us
472*77b80299SAndroid Build Coastguard Worker         std::vector<std::function<void(void)>> tasks = mPostCommandTasks;
473*77b80299SAndroid Build Coastguard Worker         mPostCommandTasks.clear();
474*77b80299SAndroid Build Coastguard Worker         for (const auto& func : tasks) {
475*77b80299SAndroid Build Coastguard Worker             func();
476*77b80299SAndroid Build Coastguard Worker         }
477*77b80299SAndroid Build Coastguard Worker     }
478*77b80299SAndroid Build Coastguard Worker 
479*77b80299SAndroid Build Coastguard Worker     return result;
480*77b80299SAndroid Build Coastguard Worker }
481*77b80299SAndroid Build Coastguard Worker 
482*77b80299SAndroid Build Coastguard Worker // When we've cleared the incoming command queue, process any pending derefs
processPendingDerefs()483*77b80299SAndroid Build Coastguard Worker void IPCThreadState::processPendingDerefs()
484*77b80299SAndroid Build Coastguard Worker {
485*77b80299SAndroid Build Coastguard Worker     if (mIn.dataPosition() >= mIn.dataSize()) {
486*77b80299SAndroid Build Coastguard Worker         /*
487*77b80299SAndroid Build Coastguard Worker          * The decWeak()/decStrong() calls may cause a destructor to run,
488*77b80299SAndroid Build Coastguard Worker          * which in turn could have initiated an outgoing transaction,
489*77b80299SAndroid Build Coastguard Worker          * which in turn could cause us to add to the pending refs
490*77b80299SAndroid Build Coastguard Worker          * vectors; so instead of simply iterating, loop until they're empty.
491*77b80299SAndroid Build Coastguard Worker          *
492*77b80299SAndroid Build Coastguard Worker          * We do this in an outer loop, because calling decStrong()
493*77b80299SAndroid Build Coastguard Worker          * may result in something being added to mPendingWeakDerefs,
494*77b80299SAndroid Build Coastguard Worker          * which could be delayed until the next incoming command
495*77b80299SAndroid Build Coastguard Worker          * from the driver if we don't process it now.
496*77b80299SAndroid Build Coastguard Worker          */
497*77b80299SAndroid Build Coastguard Worker         while (mPendingWeakDerefs.size() > 0 || mPendingStrongDerefs.size() > 0) {
498*77b80299SAndroid Build Coastguard Worker             while (mPendingWeakDerefs.size() > 0) {
499*77b80299SAndroid Build Coastguard Worker                 RefBase::weakref_type* refs = mPendingWeakDerefs[0];
500*77b80299SAndroid Build Coastguard Worker                 mPendingWeakDerefs.removeAt(0);
501*77b80299SAndroid Build Coastguard Worker                 refs->decWeak(mProcess.get());
502*77b80299SAndroid Build Coastguard Worker             }
503*77b80299SAndroid Build Coastguard Worker 
504*77b80299SAndroid Build Coastguard Worker             if (mPendingStrongDerefs.size() > 0) {
505*77b80299SAndroid Build Coastguard Worker                 // We don't use while() here because we don't want to re-order
506*77b80299SAndroid Build Coastguard Worker                 // strong and weak decs at all; if this decStrong() causes both a
507*77b80299SAndroid Build Coastguard Worker                 // decWeak() and a decStrong() to be queued, we want to process
508*77b80299SAndroid Build Coastguard Worker                 // the decWeak() first.
509*77b80299SAndroid Build Coastguard Worker                 BHwBinder* obj = mPendingStrongDerefs[0];
510*77b80299SAndroid Build Coastguard Worker                 mPendingStrongDerefs.removeAt(0);
511*77b80299SAndroid Build Coastguard Worker                 obj->decStrong(mProcess.get());
512*77b80299SAndroid Build Coastguard Worker             }
513*77b80299SAndroid Build Coastguard Worker         }
514*77b80299SAndroid Build Coastguard Worker     }
515*77b80299SAndroid Build Coastguard Worker }
516*77b80299SAndroid Build Coastguard Worker 
processPostWriteDerefs()517*77b80299SAndroid Build Coastguard Worker void IPCThreadState::processPostWriteDerefs()
518*77b80299SAndroid Build Coastguard Worker {
519*77b80299SAndroid Build Coastguard Worker     /*
520*77b80299SAndroid Build Coastguard Worker      * libhwbinder has a flushCommands() in the BpHwBinder destructor,
521*77b80299SAndroid Build Coastguard Worker      * which makes this function (potentially) reentrant.
522*77b80299SAndroid Build Coastguard Worker      * New entries shouldn't be added though, so just iterating until empty
523*77b80299SAndroid Build Coastguard Worker      * should be safe.
524*77b80299SAndroid Build Coastguard Worker      */
525*77b80299SAndroid Build Coastguard Worker     while (mPostWriteWeakDerefs.size() > 0) {
526*77b80299SAndroid Build Coastguard Worker         RefBase::weakref_type* refs = mPostWriteWeakDerefs[0];
527*77b80299SAndroid Build Coastguard Worker         mPostWriteWeakDerefs.removeAt(0);
528*77b80299SAndroid Build Coastguard Worker         refs->decWeak(mProcess.get());
529*77b80299SAndroid Build Coastguard Worker     }
530*77b80299SAndroid Build Coastguard Worker 
531*77b80299SAndroid Build Coastguard Worker     while (mPostWriteStrongDerefs.size() > 0) {
532*77b80299SAndroid Build Coastguard Worker         RefBase* obj = mPostWriteStrongDerefs[0];
533*77b80299SAndroid Build Coastguard Worker         mPostWriteStrongDerefs.removeAt(0);
534*77b80299SAndroid Build Coastguard Worker         obj->decStrong(mProcess.get());
535*77b80299SAndroid Build Coastguard Worker     }
536*77b80299SAndroid Build Coastguard Worker }
537*77b80299SAndroid Build Coastguard Worker 
joinThreadPool(bool isMain)538*77b80299SAndroid Build Coastguard Worker void IPCThreadState::joinThreadPool(bool isMain)
539*77b80299SAndroid Build Coastguard Worker {
540*77b80299SAndroid Build Coastguard Worker     LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
541*77b80299SAndroid Build Coastguard Worker 
542*77b80299SAndroid Build Coastguard Worker     if (!isHwbinderSupportedBlocking()) {
543*77b80299SAndroid Build Coastguard Worker         ALOGW("HwBinder is not supported on this device, but this process is calling joinThreadPool.");
544*77b80299SAndroid Build Coastguard Worker     }
545*77b80299SAndroid Build Coastguard Worker 
546*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
547*77b80299SAndroid Build Coastguard Worker 
548*77b80299SAndroid Build Coastguard Worker     status_t result;
549*77b80299SAndroid Build Coastguard Worker     mIsLooper = true;
550*77b80299SAndroid Build Coastguard Worker     do {
551*77b80299SAndroid Build Coastguard Worker         processPendingDerefs();
552*77b80299SAndroid Build Coastguard Worker         // now get the next command to be processed, waiting if necessary
553*77b80299SAndroid Build Coastguard Worker         result = getAndExecuteCommand();
554*77b80299SAndroid Build Coastguard Worker 
555*77b80299SAndroid Build Coastguard Worker         if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
556*77b80299SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
557*77b80299SAndroid Build Coastguard Worker                   mProcess->mDriverFD, result);
558*77b80299SAndroid Build Coastguard Worker         }
559*77b80299SAndroid Build Coastguard Worker 
560*77b80299SAndroid Build Coastguard Worker         // Let this thread exit the thread pool if it is no longer
561*77b80299SAndroid Build Coastguard Worker         // needed and it is not the main process thread.
562*77b80299SAndroid Build Coastguard Worker         if(result == TIMED_OUT && !isMain) {
563*77b80299SAndroid Build Coastguard Worker             break;
564*77b80299SAndroid Build Coastguard Worker         }
565*77b80299SAndroid Build Coastguard Worker     } while (result != -ECONNREFUSED && result != -EBADF);
566*77b80299SAndroid Build Coastguard Worker 
567*77b80299SAndroid Build Coastguard Worker     LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
568*77b80299SAndroid Build Coastguard Worker         (void*)pthread_self(), getpid(), result);
569*77b80299SAndroid Build Coastguard Worker 
570*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_EXIT_LOOPER);
571*77b80299SAndroid Build Coastguard Worker     mIsLooper = false;
572*77b80299SAndroid Build Coastguard Worker     talkWithDriver(false);
573*77b80299SAndroid Build Coastguard Worker }
574*77b80299SAndroid Build Coastguard Worker 
setupPolling(int * fd)575*77b80299SAndroid Build Coastguard Worker int IPCThreadState::setupPolling(int* fd)
576*77b80299SAndroid Build Coastguard Worker {
577*77b80299SAndroid Build Coastguard Worker     if (mProcess->mDriverFD < 0) {
578*77b80299SAndroid Build Coastguard Worker         return -EBADF;
579*77b80299SAndroid Build Coastguard Worker     }
580*77b80299SAndroid Build Coastguard Worker 
581*77b80299SAndroid Build Coastguard Worker     // Tells the kernel to not spawn any additional binder threads,
582*77b80299SAndroid Build Coastguard Worker     // as that won't work with polling. Also, the caller is responsible
583*77b80299SAndroid Build Coastguard Worker     // for subsequently calling handlePolledCommands()
584*77b80299SAndroid Build Coastguard Worker     mProcess->setThreadPoolConfiguration(1, true /* callerWillJoin */);
585*77b80299SAndroid Build Coastguard Worker     mIsPollingThread = true;
586*77b80299SAndroid Build Coastguard Worker 
587*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_ENTER_LOOPER);
588*77b80299SAndroid Build Coastguard Worker     *fd = mProcess->mDriverFD;
589*77b80299SAndroid Build Coastguard Worker     return 0;
590*77b80299SAndroid Build Coastguard Worker }
591*77b80299SAndroid Build Coastguard Worker 
handlePolledCommands()592*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::handlePolledCommands()
593*77b80299SAndroid Build Coastguard Worker {
594*77b80299SAndroid Build Coastguard Worker     status_t result;
595*77b80299SAndroid Build Coastguard Worker 
596*77b80299SAndroid Build Coastguard Worker     do {
597*77b80299SAndroid Build Coastguard Worker         result = getAndExecuteCommand();
598*77b80299SAndroid Build Coastguard Worker     } while (mIn.dataPosition() < mIn.dataSize());
599*77b80299SAndroid Build Coastguard Worker 
600*77b80299SAndroid Build Coastguard Worker     processPendingDerefs();
601*77b80299SAndroid Build Coastguard Worker     flushCommands();
602*77b80299SAndroid Build Coastguard Worker     return result;
603*77b80299SAndroid Build Coastguard Worker }
604*77b80299SAndroid Build Coastguard Worker 
stopProcess(bool)605*77b80299SAndroid Build Coastguard Worker void IPCThreadState::stopProcess(bool /*immediate*/)
606*77b80299SAndroid Build Coastguard Worker {
607*77b80299SAndroid Build Coastguard Worker     //ALOGI("**** STOPPING PROCESS");
608*77b80299SAndroid Build Coastguard Worker     flushCommands();
609*77b80299SAndroid Build Coastguard Worker     int fd = mProcess->mDriverFD;
610*77b80299SAndroid Build Coastguard Worker     mProcess->mDriverFD = -1;
611*77b80299SAndroid Build Coastguard Worker     close(fd);
612*77b80299SAndroid Build Coastguard Worker     //kill(getpid(), SIGKILL);
613*77b80299SAndroid Build Coastguard Worker }
614*77b80299SAndroid Build Coastguard Worker 
transact(int32_t handle,uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)615*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::transact(int32_t handle,
616*77b80299SAndroid Build Coastguard Worker                                   uint32_t code, const Parcel& data,
617*77b80299SAndroid Build Coastguard Worker                                   Parcel* reply, uint32_t flags)
618*77b80299SAndroid Build Coastguard Worker {
619*77b80299SAndroid Build Coastguard Worker     status_t err;
620*77b80299SAndroid Build Coastguard Worker 
621*77b80299SAndroid Build Coastguard Worker     flags |= TF_ACCEPT_FDS;
622*77b80299SAndroid Build Coastguard Worker 
623*77b80299SAndroid Build Coastguard Worker     IF_LOG_TRANSACTIONS() {
624*77b80299SAndroid Build Coastguard Worker         alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
625*77b80299SAndroid Build Coastguard Worker             << handle << " / code " << TypeCode(code) << ": "
626*77b80299SAndroid Build Coastguard Worker             << indent << data << dedent << endl;
627*77b80299SAndroid Build Coastguard Worker     }
628*77b80299SAndroid Build Coastguard Worker 
629*77b80299SAndroid Build Coastguard Worker     LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
630*77b80299SAndroid Build Coastguard Worker         (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
631*77b80299SAndroid Build Coastguard Worker     err = writeTransactionData(BC_TRANSACTION_SG, flags, handle, code, data, nullptr);
632*77b80299SAndroid Build Coastguard Worker 
633*77b80299SAndroid Build Coastguard Worker     if (err != NO_ERROR) {
634*77b80299SAndroid Build Coastguard Worker         if (reply) reply->setError(err);
635*77b80299SAndroid Build Coastguard Worker         return (mLastError = err);
636*77b80299SAndroid Build Coastguard Worker     }
637*77b80299SAndroid Build Coastguard Worker 
638*77b80299SAndroid Build Coastguard Worker     if ((flags & TF_ONE_WAY) == 0) {
639*77b80299SAndroid Build Coastguard Worker         if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
640*77b80299SAndroid Build Coastguard Worker             if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
641*77b80299SAndroid Build Coastguard Worker                 ALOGE("Process making non-oneway call (code: %u) but is restricted.", code);
642*77b80299SAndroid Build Coastguard Worker                 CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
643*77b80299SAndroid Build Coastguard Worker                     ANDROID_LOG_ERROR);
644*77b80299SAndroid Build Coastguard Worker             } else /* FATAL_IF_NOT_ONEWAY */ {
645*77b80299SAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Process may not make oneway calls (code: %u).", code);
646*77b80299SAndroid Build Coastguard Worker             }
647*77b80299SAndroid Build Coastguard Worker         }
648*77b80299SAndroid Build Coastguard Worker 
649*77b80299SAndroid Build Coastguard Worker         #if 0
650*77b80299SAndroid Build Coastguard Worker         if (code == 4) { // relayout
651*77b80299SAndroid Build Coastguard Worker             ALOGI(">>>>>> CALLING transaction 4");
652*77b80299SAndroid Build Coastguard Worker         } else {
653*77b80299SAndroid Build Coastguard Worker             ALOGI(">>>>>> CALLING transaction %d", code);
654*77b80299SAndroid Build Coastguard Worker         }
655*77b80299SAndroid Build Coastguard Worker         #endif
656*77b80299SAndroid Build Coastguard Worker         if (reply) {
657*77b80299SAndroid Build Coastguard Worker             err = waitForResponse(reply);
658*77b80299SAndroid Build Coastguard Worker         } else {
659*77b80299SAndroid Build Coastguard Worker             Parcel fakeReply;
660*77b80299SAndroid Build Coastguard Worker             err = waitForResponse(&fakeReply);
661*77b80299SAndroid Build Coastguard Worker         }
662*77b80299SAndroid Build Coastguard Worker         #if 0
663*77b80299SAndroid Build Coastguard Worker         if (code == 4) { // relayout
664*77b80299SAndroid Build Coastguard Worker             ALOGI("<<<<<< RETURNING transaction 4");
665*77b80299SAndroid Build Coastguard Worker         } else {
666*77b80299SAndroid Build Coastguard Worker             ALOGI("<<<<<< RETURNING transaction %d", code);
667*77b80299SAndroid Build Coastguard Worker         }
668*77b80299SAndroid Build Coastguard Worker         #endif
669*77b80299SAndroid Build Coastguard Worker 
670*77b80299SAndroid Build Coastguard Worker         IF_LOG_TRANSACTIONS() {
671*77b80299SAndroid Build Coastguard Worker             alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
672*77b80299SAndroid Build Coastguard Worker                 << handle << ": ";
673*77b80299SAndroid Build Coastguard Worker             if (reply) alog << indent << *reply << dedent << endl;
674*77b80299SAndroid Build Coastguard Worker             else alog << "(none requested)" << endl;
675*77b80299SAndroid Build Coastguard Worker         }
676*77b80299SAndroid Build Coastguard Worker     } else {
677*77b80299SAndroid Build Coastguard Worker         err = waitForResponse(nullptr, nullptr);
678*77b80299SAndroid Build Coastguard Worker     }
679*77b80299SAndroid Build Coastguard Worker 
680*77b80299SAndroid Build Coastguard Worker     return err;
681*77b80299SAndroid Build Coastguard Worker }
682*77b80299SAndroid Build Coastguard Worker 
incStrongHandle(int32_t handle,BpHwBinder * proxy)683*77b80299SAndroid Build Coastguard Worker void IPCThreadState::incStrongHandle(int32_t handle, BpHwBinder *proxy)
684*77b80299SAndroid Build Coastguard Worker {
685*77b80299SAndroid Build Coastguard Worker     LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
686*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_ACQUIRE);
687*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(handle);
688*77b80299SAndroid Build Coastguard Worker     // Create a temp reference until the driver has handled this command.
689*77b80299SAndroid Build Coastguard Worker     proxy->incStrong(mProcess.get());
690*77b80299SAndroid Build Coastguard Worker     mPostWriteStrongDerefs.push(proxy);
691*77b80299SAndroid Build Coastguard Worker }
692*77b80299SAndroid Build Coastguard Worker 
decStrongHandle(int32_t handle)693*77b80299SAndroid Build Coastguard Worker void IPCThreadState::decStrongHandle(int32_t handle)
694*77b80299SAndroid Build Coastguard Worker {
695*77b80299SAndroid Build Coastguard Worker     LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
696*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_RELEASE);
697*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(handle);
698*77b80299SAndroid Build Coastguard Worker }
699*77b80299SAndroid Build Coastguard Worker 
incWeakHandle(int32_t handle,BpHwBinder * proxy)700*77b80299SAndroid Build Coastguard Worker void IPCThreadState::incWeakHandle(int32_t handle, BpHwBinder *proxy)
701*77b80299SAndroid Build Coastguard Worker {
702*77b80299SAndroid Build Coastguard Worker     LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
703*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_INCREFS);
704*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(handle);
705*77b80299SAndroid Build Coastguard Worker     // Create a temp reference until the driver has handled this command.
706*77b80299SAndroid Build Coastguard Worker     proxy->getWeakRefs()->incWeak(mProcess.get());
707*77b80299SAndroid Build Coastguard Worker     mPostWriteWeakDerefs.push(proxy->getWeakRefs());
708*77b80299SAndroid Build Coastguard Worker }
709*77b80299SAndroid Build Coastguard Worker 
decWeakHandle(int32_t handle)710*77b80299SAndroid Build Coastguard Worker void IPCThreadState::decWeakHandle(int32_t handle)
711*77b80299SAndroid Build Coastguard Worker {
712*77b80299SAndroid Build Coastguard Worker     LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
713*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_DECREFS);
714*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(handle);
715*77b80299SAndroid Build Coastguard Worker }
716*77b80299SAndroid Build Coastguard Worker 
attemptIncStrongHandle(int32_t handle)717*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
718*77b80299SAndroid Build Coastguard Worker {
719*77b80299SAndroid Build Coastguard Worker #if HAS_BC_ATTEMPT_ACQUIRE
720*77b80299SAndroid Build Coastguard Worker     LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
721*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
722*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(0); // xxx was thread priority
723*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(handle);
724*77b80299SAndroid Build Coastguard Worker     status_t result = UNKNOWN_ERROR;
725*77b80299SAndroid Build Coastguard Worker 
726*77b80299SAndroid Build Coastguard Worker     waitForResponse(nullptr, &result);
727*77b80299SAndroid Build Coastguard Worker 
728*77b80299SAndroid Build Coastguard Worker #if LOG_REFCOUNTS
729*77b80299SAndroid Build Coastguard Worker     ALOGV("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
730*77b80299SAndroid Build Coastguard Worker         handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
731*77b80299SAndroid Build Coastguard Worker #endif
732*77b80299SAndroid Build Coastguard Worker 
733*77b80299SAndroid Build Coastguard Worker     return result;
734*77b80299SAndroid Build Coastguard Worker #else
735*77b80299SAndroid Build Coastguard Worker     (void)handle;
736*77b80299SAndroid Build Coastguard Worker     ALOGE("%s(%d): Not supported\n", __func__, handle);
737*77b80299SAndroid Build Coastguard Worker     return INVALID_OPERATION;
738*77b80299SAndroid Build Coastguard Worker #endif
739*77b80299SAndroid Build Coastguard Worker }
740*77b80299SAndroid Build Coastguard Worker 
expungeHandle(int32_t handle,IBinder * binder)741*77b80299SAndroid Build Coastguard Worker void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
742*77b80299SAndroid Build Coastguard Worker {
743*77b80299SAndroid Build Coastguard Worker #if LOG_REFCOUNTS
744*77b80299SAndroid Build Coastguard Worker     ALOGV("IPCThreadState::expungeHandle(%ld)\n", handle);
745*77b80299SAndroid Build Coastguard Worker #endif
746*77b80299SAndroid Build Coastguard Worker     self()->mProcess->expungeHandle(handle, binder);  // NOLINT
747*77b80299SAndroid Build Coastguard Worker }
748*77b80299SAndroid Build Coastguard Worker 
requestDeathNotification(int32_t handle,BpHwBinder * proxy)749*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::requestDeathNotification(int32_t handle, BpHwBinder* proxy)
750*77b80299SAndroid Build Coastguard Worker {
751*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
752*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32((int32_t)handle);
753*77b80299SAndroid Build Coastguard Worker     mOut.writePointer((uintptr_t)proxy);
754*77b80299SAndroid Build Coastguard Worker     return NO_ERROR;
755*77b80299SAndroid Build Coastguard Worker }
756*77b80299SAndroid Build Coastguard Worker 
clearDeathNotification(int32_t handle,BpHwBinder * proxy)757*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::clearDeathNotification(int32_t handle, BpHwBinder* proxy)
758*77b80299SAndroid Build Coastguard Worker {
759*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
760*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32((int32_t)handle);
761*77b80299SAndroid Build Coastguard Worker     mOut.writePointer((uintptr_t)proxy);
762*77b80299SAndroid Build Coastguard Worker     return NO_ERROR;
763*77b80299SAndroid Build Coastguard Worker }
764*77b80299SAndroid Build Coastguard Worker 
IPCThreadState()765*77b80299SAndroid Build Coastguard Worker IPCThreadState::IPCThreadState()
766*77b80299SAndroid Build Coastguard Worker     : mProcess(ProcessState::self()),
767*77b80299SAndroid Build Coastguard Worker       mServingStackPointer(nullptr),
768*77b80299SAndroid Build Coastguard Worker       mStrictModePolicy(0),
769*77b80299SAndroid Build Coastguard Worker       mLastTransactionBinderFlags(0),
770*77b80299SAndroid Build Coastguard Worker       mIsLooper(false),
771*77b80299SAndroid Build Coastguard Worker       mIsPollingThread(false),
772*77b80299SAndroid Build Coastguard Worker       mCallRestriction(mProcess->mCallRestriction) {
773*77b80299SAndroid Build Coastguard Worker     pthread_setspecific(gTLS, this);
774*77b80299SAndroid Build Coastguard Worker     clearCaller();
775*77b80299SAndroid Build Coastguard Worker     mIn.setDataCapacity(256);
776*77b80299SAndroid Build Coastguard Worker     mOut.setDataCapacity(256);
777*77b80299SAndroid Build Coastguard Worker }
778*77b80299SAndroid Build Coastguard Worker 
~IPCThreadState()779*77b80299SAndroid Build Coastguard Worker IPCThreadState::~IPCThreadState()
780*77b80299SAndroid Build Coastguard Worker {
781*77b80299SAndroid Build Coastguard Worker }
782*77b80299SAndroid Build Coastguard Worker 
sendReply(const Parcel & reply,uint32_t flags)783*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
784*77b80299SAndroid Build Coastguard Worker {
785*77b80299SAndroid Build Coastguard Worker     status_t err;
786*77b80299SAndroid Build Coastguard Worker     status_t statusBuffer;
787*77b80299SAndroid Build Coastguard Worker     err = writeTransactionData(BC_REPLY_SG, flags, -1, 0, reply, &statusBuffer);
788*77b80299SAndroid Build Coastguard Worker     if (err < NO_ERROR) return err;
789*77b80299SAndroid Build Coastguard Worker 
790*77b80299SAndroid Build Coastguard Worker     return waitForResponse(nullptr, nullptr);
791*77b80299SAndroid Build Coastguard Worker }
792*77b80299SAndroid Build Coastguard Worker 
waitForResponse(Parcel * reply,status_t * acquireResult)793*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
794*77b80299SAndroid Build Coastguard Worker {
795*77b80299SAndroid Build Coastguard Worker     uint32_t cmd;
796*77b80299SAndroid Build Coastguard Worker     int32_t err;
797*77b80299SAndroid Build Coastguard Worker 
798*77b80299SAndroid Build Coastguard Worker     while (1) {
799*77b80299SAndroid Build Coastguard Worker         if ((err=talkWithDriver()) < NO_ERROR) break;
800*77b80299SAndroid Build Coastguard Worker         err = mIn.errorCheck();
801*77b80299SAndroid Build Coastguard Worker         if (err < NO_ERROR) break;
802*77b80299SAndroid Build Coastguard Worker         if (mIn.dataAvail() == 0) continue;
803*77b80299SAndroid Build Coastguard Worker 
804*77b80299SAndroid Build Coastguard Worker         cmd = (uint32_t)mIn.readInt32();
805*77b80299SAndroid Build Coastguard Worker 
806*77b80299SAndroid Build Coastguard Worker         IF_LOG_COMMANDS() {
807*77b80299SAndroid Build Coastguard Worker             alog << "Processing waitForResponse Command: "
808*77b80299SAndroid Build Coastguard Worker                 << getReturnString(cmd) << endl;
809*77b80299SAndroid Build Coastguard Worker         }
810*77b80299SAndroid Build Coastguard Worker 
811*77b80299SAndroid Build Coastguard Worker         switch (cmd) {
812*77b80299SAndroid Build Coastguard Worker         case BR_ONEWAY_SPAM_SUSPECT:
813*77b80299SAndroid Build Coastguard Worker             ALOGE("Process seems to be sending too many oneway calls.");
814*77b80299SAndroid Build Coastguard Worker             CallStack::logStack("oneway spamming", CallStack::getCurrent().get(),
815*77b80299SAndroid Build Coastguard Worker                     ANDROID_LOG_ERROR);
816*77b80299SAndroid Build Coastguard Worker             [[fallthrough]];
817*77b80299SAndroid Build Coastguard Worker         case BR_TRANSACTION_COMPLETE:
818*77b80299SAndroid Build Coastguard Worker             if (!reply && !acquireResult) goto finish;
819*77b80299SAndroid Build Coastguard Worker             break;
820*77b80299SAndroid Build Coastguard Worker 
821*77b80299SAndroid Build Coastguard Worker         case BR_TRANSACTION_PENDING_FROZEN:
822*77b80299SAndroid Build Coastguard Worker             ALOGW("Sending oneway calls to frozen process.");
823*77b80299SAndroid Build Coastguard Worker             goto finish;
824*77b80299SAndroid Build Coastguard Worker 
825*77b80299SAndroid Build Coastguard Worker         case BR_FROZEN_REPLY:
826*77b80299SAndroid Build Coastguard Worker             ALOGW("Transaction failed because process frozen.");
827*77b80299SAndroid Build Coastguard Worker             err = FAILED_TRANSACTION;
828*77b80299SAndroid Build Coastguard Worker             goto finish;
829*77b80299SAndroid Build Coastguard Worker 
830*77b80299SAndroid Build Coastguard Worker         case BR_DEAD_REPLY:
831*77b80299SAndroid Build Coastguard Worker             err = DEAD_OBJECT;
832*77b80299SAndroid Build Coastguard Worker             goto finish;
833*77b80299SAndroid Build Coastguard Worker 
834*77b80299SAndroid Build Coastguard Worker         case BR_FAILED_REPLY:
835*77b80299SAndroid Build Coastguard Worker             err = FAILED_TRANSACTION;
836*77b80299SAndroid Build Coastguard Worker             goto finish;
837*77b80299SAndroid Build Coastguard Worker 
838*77b80299SAndroid Build Coastguard Worker         case BR_ACQUIRE_RESULT:
839*77b80299SAndroid Build Coastguard Worker             {
840*77b80299SAndroid Build Coastguard Worker                 ALOG_ASSERT(acquireResult != nullptr, "Unexpected brACQUIRE_RESULT");
841*77b80299SAndroid Build Coastguard Worker                 const int32_t result = mIn.readInt32();
842*77b80299SAndroid Build Coastguard Worker                 if (!acquireResult) continue;
843*77b80299SAndroid Build Coastguard Worker                 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
844*77b80299SAndroid Build Coastguard Worker             }
845*77b80299SAndroid Build Coastguard Worker             goto finish;
846*77b80299SAndroid Build Coastguard Worker 
847*77b80299SAndroid Build Coastguard Worker         case BR_REPLY:
848*77b80299SAndroid Build Coastguard Worker             {
849*77b80299SAndroid Build Coastguard Worker                 binder_transaction_data tr;
850*77b80299SAndroid Build Coastguard Worker                 err = mIn.read(&tr, sizeof(tr));
851*77b80299SAndroid Build Coastguard Worker                 ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
852*77b80299SAndroid Build Coastguard Worker                 if (err != NO_ERROR) goto finish;
853*77b80299SAndroid Build Coastguard Worker 
854*77b80299SAndroid Build Coastguard Worker                 if (reply) {
855*77b80299SAndroid Build Coastguard Worker                     if ((tr.flags & TF_STATUS_CODE) == 0) {
856*77b80299SAndroid Build Coastguard Worker                         reply->ipcSetDataReference(
857*77b80299SAndroid Build Coastguard Worker                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
858*77b80299SAndroid Build Coastguard Worker                             tr.data_size,
859*77b80299SAndroid Build Coastguard Worker                             reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
860*77b80299SAndroid Build Coastguard Worker                             tr.offsets_size/sizeof(binder_size_t),
861*77b80299SAndroid Build Coastguard Worker                             freeBuffer, this);
862*77b80299SAndroid Build Coastguard Worker                     } else {
863*77b80299SAndroid Build Coastguard Worker                         err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
864*77b80299SAndroid Build Coastguard Worker                         freeBuffer(nullptr,
865*77b80299SAndroid Build Coastguard Worker                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
866*77b80299SAndroid Build Coastguard Worker                             tr.data_size,
867*77b80299SAndroid Build Coastguard Worker                             reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
868*77b80299SAndroid Build Coastguard Worker                             tr.offsets_size/sizeof(binder_size_t), this);
869*77b80299SAndroid Build Coastguard Worker                     }
870*77b80299SAndroid Build Coastguard Worker                 } else {
871*77b80299SAndroid Build Coastguard Worker                     freeBuffer(nullptr,
872*77b80299SAndroid Build Coastguard Worker                         reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
873*77b80299SAndroid Build Coastguard Worker                         tr.data_size,
874*77b80299SAndroid Build Coastguard Worker                         reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
875*77b80299SAndroid Build Coastguard Worker                         tr.offsets_size/sizeof(binder_size_t), this);
876*77b80299SAndroid Build Coastguard Worker                     continue;
877*77b80299SAndroid Build Coastguard Worker                 }
878*77b80299SAndroid Build Coastguard Worker             }
879*77b80299SAndroid Build Coastguard Worker             goto finish;
880*77b80299SAndroid Build Coastguard Worker 
881*77b80299SAndroid Build Coastguard Worker         default:
882*77b80299SAndroid Build Coastguard Worker             err = executeCommand(cmd);
883*77b80299SAndroid Build Coastguard Worker             if (err != NO_ERROR) goto finish;
884*77b80299SAndroid Build Coastguard Worker             break;
885*77b80299SAndroid Build Coastguard Worker         }
886*77b80299SAndroid Build Coastguard Worker     }
887*77b80299SAndroid Build Coastguard Worker 
888*77b80299SAndroid Build Coastguard Worker finish:
889*77b80299SAndroid Build Coastguard Worker     if (err != NO_ERROR) {
890*77b80299SAndroid Build Coastguard Worker         if (acquireResult) *acquireResult = err;
891*77b80299SAndroid Build Coastguard Worker         if (reply) reply->setError(err);
892*77b80299SAndroid Build Coastguard Worker         mLastError = err;
893*77b80299SAndroid Build Coastguard Worker     }
894*77b80299SAndroid Build Coastguard Worker 
895*77b80299SAndroid Build Coastguard Worker     return err;
896*77b80299SAndroid Build Coastguard Worker }
897*77b80299SAndroid Build Coastguard Worker 
talkWithDriver(bool doReceive)898*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::talkWithDriver(bool doReceive)
899*77b80299SAndroid Build Coastguard Worker {
900*77b80299SAndroid Build Coastguard Worker     if (mProcess->mDriverFD < 0) {
901*77b80299SAndroid Build Coastguard Worker         return -EBADF;
902*77b80299SAndroid Build Coastguard Worker     }
903*77b80299SAndroid Build Coastguard Worker 
904*77b80299SAndroid Build Coastguard Worker     binder_write_read bwr;
905*77b80299SAndroid Build Coastguard Worker 
906*77b80299SAndroid Build Coastguard Worker     // Is the read buffer empty?
907*77b80299SAndroid Build Coastguard Worker     const bool needRead = mIn.dataPosition() >= mIn.dataSize();
908*77b80299SAndroid Build Coastguard Worker 
909*77b80299SAndroid Build Coastguard Worker     // We don't want to write anything if we are still reading
910*77b80299SAndroid Build Coastguard Worker     // from data left in the input buffer and the caller
911*77b80299SAndroid Build Coastguard Worker     // has requested to read the next data.
912*77b80299SAndroid Build Coastguard Worker     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
913*77b80299SAndroid Build Coastguard Worker 
914*77b80299SAndroid Build Coastguard Worker     bwr.write_size = outAvail;
915*77b80299SAndroid Build Coastguard Worker     bwr.write_buffer = (uintptr_t)mOut.data();
916*77b80299SAndroid Build Coastguard Worker 
917*77b80299SAndroid Build Coastguard Worker     // This is what we'll read.
918*77b80299SAndroid Build Coastguard Worker     if (doReceive && needRead) {
919*77b80299SAndroid Build Coastguard Worker         bwr.read_size = mIn.dataCapacity();
920*77b80299SAndroid Build Coastguard Worker         bwr.read_buffer = (uintptr_t)mIn.data();
921*77b80299SAndroid Build Coastguard Worker     } else {
922*77b80299SAndroid Build Coastguard Worker         bwr.read_size = 0;
923*77b80299SAndroid Build Coastguard Worker         bwr.read_buffer = 0;
924*77b80299SAndroid Build Coastguard Worker     }
925*77b80299SAndroid Build Coastguard Worker 
926*77b80299SAndroid Build Coastguard Worker     IF_LOG_COMMANDS() {
927*77b80299SAndroid Build Coastguard Worker         if (outAvail != 0) {
928*77b80299SAndroid Build Coastguard Worker             alog << "Sending commands to driver: " << indent;
929*77b80299SAndroid Build Coastguard Worker             const void* cmds = (const void*)bwr.write_buffer;
930*77b80299SAndroid Build Coastguard Worker             const void* end = ((const uint8_t*)cmds)+bwr.write_size;
931*77b80299SAndroid Build Coastguard Worker             alog << HexDump(cmds, bwr.write_size) << endl;
932*77b80299SAndroid Build Coastguard Worker             while (cmds < end) cmds = printCommand(alog, cmds);
933*77b80299SAndroid Build Coastguard Worker             alog << dedent;
934*77b80299SAndroid Build Coastguard Worker         }
935*77b80299SAndroid Build Coastguard Worker         alog << "Size of receive buffer: " << bwr.read_size
936*77b80299SAndroid Build Coastguard Worker             << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
937*77b80299SAndroid Build Coastguard Worker     }
938*77b80299SAndroid Build Coastguard Worker 
939*77b80299SAndroid Build Coastguard Worker     // Return immediately if there is nothing to do.
940*77b80299SAndroid Build Coastguard Worker     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
941*77b80299SAndroid Build Coastguard Worker 
942*77b80299SAndroid Build Coastguard Worker     bwr.write_consumed = 0;
943*77b80299SAndroid Build Coastguard Worker     bwr.read_consumed = 0;
944*77b80299SAndroid Build Coastguard Worker     status_t err;
945*77b80299SAndroid Build Coastguard Worker     do {
946*77b80299SAndroid Build Coastguard Worker         IF_LOG_COMMANDS() {
947*77b80299SAndroid Build Coastguard Worker             alog << "About to read/write, write size = " << mOut.dataSize() << endl;
948*77b80299SAndroid Build Coastguard Worker         }
949*77b80299SAndroid Build Coastguard Worker #if defined(__ANDROID__)
950*77b80299SAndroid Build Coastguard Worker         if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
951*77b80299SAndroid Build Coastguard Worker             err = NO_ERROR;
952*77b80299SAndroid Build Coastguard Worker         else
953*77b80299SAndroid Build Coastguard Worker             err = -errno;
954*77b80299SAndroid Build Coastguard Worker #else
955*77b80299SAndroid Build Coastguard Worker         err = INVALID_OPERATION;
956*77b80299SAndroid Build Coastguard Worker #endif
957*77b80299SAndroid Build Coastguard Worker         if (mProcess->mDriverFD < 0) {
958*77b80299SAndroid Build Coastguard Worker             err = -EBADF;
959*77b80299SAndroid Build Coastguard Worker         }
960*77b80299SAndroid Build Coastguard Worker         IF_LOG_COMMANDS() {
961*77b80299SAndroid Build Coastguard Worker             alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
962*77b80299SAndroid Build Coastguard Worker         }
963*77b80299SAndroid Build Coastguard Worker     } while (err == -EINTR);
964*77b80299SAndroid Build Coastguard Worker 
965*77b80299SAndroid Build Coastguard Worker     IF_LOG_COMMANDS() {
966*77b80299SAndroid Build Coastguard Worker         alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
967*77b80299SAndroid Build Coastguard Worker             << bwr.write_consumed << " (of " << mOut.dataSize()
968*77b80299SAndroid Build Coastguard Worker                         << "), read consumed: " << bwr.read_consumed << endl;
969*77b80299SAndroid Build Coastguard Worker     }
970*77b80299SAndroid Build Coastguard Worker 
971*77b80299SAndroid Build Coastguard Worker     if (err >= NO_ERROR) {
972*77b80299SAndroid Build Coastguard Worker         if (bwr.write_consumed > 0) {
973*77b80299SAndroid Build Coastguard Worker             if (bwr.write_consumed < mOut.dataSize())
974*77b80299SAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Driver did not consume write buffer. "
975*77b80299SAndroid Build Coastguard Worker                                  "err: %s consumed: %zu of %zu",
976*77b80299SAndroid Build Coastguard Worker                                  statusToString(err).c_str(),
977*77b80299SAndroid Build Coastguard Worker                                  (size_t)bwr.write_consumed,
978*77b80299SAndroid Build Coastguard Worker                                  mOut.dataSize());
979*77b80299SAndroid Build Coastguard Worker             else {
980*77b80299SAndroid Build Coastguard Worker                 mOut.setDataSize(0);
981*77b80299SAndroid Build Coastguard Worker                 processPostWriteDerefs();
982*77b80299SAndroid Build Coastguard Worker             }
983*77b80299SAndroid Build Coastguard Worker         }
984*77b80299SAndroid Build Coastguard Worker         if (bwr.read_consumed > 0) {
985*77b80299SAndroid Build Coastguard Worker             mIn.setDataSize(bwr.read_consumed);
986*77b80299SAndroid Build Coastguard Worker             mIn.setDataPosition(0);
987*77b80299SAndroid Build Coastguard Worker         }
988*77b80299SAndroid Build Coastguard Worker         IF_LOG_COMMANDS() {
989*77b80299SAndroid Build Coastguard Worker             alog << "Remaining data size: " << mOut.dataSize() << endl;
990*77b80299SAndroid Build Coastguard Worker             alog << "Received commands from driver: " << indent;
991*77b80299SAndroid Build Coastguard Worker             const void* cmds = mIn.data();
992*77b80299SAndroid Build Coastguard Worker             const void* end = mIn.data() + mIn.dataSize();
993*77b80299SAndroid Build Coastguard Worker             alog << HexDump(cmds, mIn.dataSize()) << endl;
994*77b80299SAndroid Build Coastguard Worker             while (cmds < end) cmds = printReturnCommand(alog, cmds);
995*77b80299SAndroid Build Coastguard Worker             alog << dedent;
996*77b80299SAndroid Build Coastguard Worker         }
997*77b80299SAndroid Build Coastguard Worker         return NO_ERROR;
998*77b80299SAndroid Build Coastguard Worker     }
999*77b80299SAndroid Build Coastguard Worker 
1000*77b80299SAndroid Build Coastguard Worker     return err;
1001*77b80299SAndroid Build Coastguard Worker }
1002*77b80299SAndroid Build Coastguard Worker 
writeTransactionData(int32_t cmd,uint32_t binderFlags,int32_t handle,uint32_t code,const Parcel & data,status_t * statusBuffer)1003*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
1004*77b80299SAndroid Build Coastguard Worker     int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
1005*77b80299SAndroid Build Coastguard Worker {
1006*77b80299SAndroid Build Coastguard Worker     binder_transaction_data_sg tr_sg;
1007*77b80299SAndroid Build Coastguard Worker     /* Don't pass uninitialized stack data to a remote process */
1008*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.target.ptr = 0;
1009*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.target.handle = handle;
1010*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.code = code;
1011*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.flags = binderFlags;
1012*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.cookie = 0;
1013*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.sender_pid = 0;
1014*77b80299SAndroid Build Coastguard Worker     tr_sg.transaction_data.sender_euid = 0;
1015*77b80299SAndroid Build Coastguard Worker 
1016*77b80299SAndroid Build Coastguard Worker     const status_t err = data.errorCheck();
1017*77b80299SAndroid Build Coastguard Worker     if (err == NO_ERROR) {
1018*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data_size = data.ipcDataSize();
1019*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data.ptr.buffer = data.ipcData();
1020*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
1021*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data.ptr.offsets = data.ipcObjects();
1022*77b80299SAndroid Build Coastguard Worker         tr_sg.buffers_size = data.ipcBufferSize();
1023*77b80299SAndroid Build Coastguard Worker     } else if (statusBuffer) {
1024*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.flags |= TF_STATUS_CODE;
1025*77b80299SAndroid Build Coastguard Worker         *statusBuffer = err;
1026*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data_size = sizeof(status_t);
1027*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
1028*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.offsets_size = 0;
1029*77b80299SAndroid Build Coastguard Worker         tr_sg.transaction_data.data.ptr.offsets = 0;
1030*77b80299SAndroid Build Coastguard Worker         tr_sg.buffers_size = 0;
1031*77b80299SAndroid Build Coastguard Worker     } else {
1032*77b80299SAndroid Build Coastguard Worker         return (mLastError = err);
1033*77b80299SAndroid Build Coastguard Worker     }
1034*77b80299SAndroid Build Coastguard Worker 
1035*77b80299SAndroid Build Coastguard Worker     mOut.writeInt32(cmd);
1036*77b80299SAndroid Build Coastguard Worker     mOut.write(&tr_sg, sizeof(tr_sg));
1037*77b80299SAndroid Build Coastguard Worker 
1038*77b80299SAndroid Build Coastguard Worker     return NO_ERROR;
1039*77b80299SAndroid Build Coastguard Worker }
1040*77b80299SAndroid Build Coastguard Worker 
1041*77b80299SAndroid Build Coastguard Worker sp<BHwBinder> the_context_object;
1042*77b80299SAndroid Build Coastguard Worker 
setTheContextObject(sp<BHwBinder> obj)1043*77b80299SAndroid Build Coastguard Worker void IPCThreadState::setTheContextObject(sp<BHwBinder> obj)
1044*77b80299SAndroid Build Coastguard Worker {
1045*77b80299SAndroid Build Coastguard Worker     the_context_object = obj;
1046*77b80299SAndroid Build Coastguard Worker }
1047*77b80299SAndroid Build Coastguard Worker 
isLooperThread()1048*77b80299SAndroid Build Coastguard Worker bool IPCThreadState::isLooperThread()
1049*77b80299SAndroid Build Coastguard Worker {
1050*77b80299SAndroid Build Coastguard Worker     return mIsLooper;
1051*77b80299SAndroid Build Coastguard Worker }
1052*77b80299SAndroid Build Coastguard Worker 
isOnlyBinderThread()1053*77b80299SAndroid Build Coastguard Worker bool IPCThreadState::isOnlyBinderThread() {
1054*77b80299SAndroid Build Coastguard Worker     return (mIsLooper && mProcess->mMaxThreads <= 1) || mIsPollingThread;
1055*77b80299SAndroid Build Coastguard Worker }
1056*77b80299SAndroid Build Coastguard Worker 
addPostCommandTask(const std::function<void (void)> & task)1057*77b80299SAndroid Build Coastguard Worker void IPCThreadState::addPostCommandTask(const std::function<void(void)>& task) {
1058*77b80299SAndroid Build Coastguard Worker     mPostCommandTasks.push_back(task);
1059*77b80299SAndroid Build Coastguard Worker }
1060*77b80299SAndroid Build Coastguard Worker 
executeCommand(int32_t cmd)1061*77b80299SAndroid Build Coastguard Worker status_t IPCThreadState::executeCommand(int32_t cmd)
1062*77b80299SAndroid Build Coastguard Worker {
1063*77b80299SAndroid Build Coastguard Worker     BHwBinder* obj;
1064*77b80299SAndroid Build Coastguard Worker     RefBase::weakref_type* refs;
1065*77b80299SAndroid Build Coastguard Worker     status_t result = NO_ERROR;
1066*77b80299SAndroid Build Coastguard Worker     switch ((uint32_t)cmd) {
1067*77b80299SAndroid Build Coastguard Worker     case BR_ERROR:
1068*77b80299SAndroid Build Coastguard Worker         result = mIn.readInt32();
1069*77b80299SAndroid Build Coastguard Worker         break;
1070*77b80299SAndroid Build Coastguard Worker 
1071*77b80299SAndroid Build Coastguard Worker     case BR_OK:
1072*77b80299SAndroid Build Coastguard Worker         break;
1073*77b80299SAndroid Build Coastguard Worker 
1074*77b80299SAndroid Build Coastguard Worker     case BR_ACQUIRE:
1075*77b80299SAndroid Build Coastguard Worker         refs = (RefBase::weakref_type*)mIn.readPointer();
1076*77b80299SAndroid Build Coastguard Worker         obj = (BHwBinder*)mIn.readPointer();
1077*77b80299SAndroid Build Coastguard Worker         ALOG_ASSERT(refs->refBase() == obj,
1078*77b80299SAndroid Build Coastguard Worker                    "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
1079*77b80299SAndroid Build Coastguard Worker                    refs, obj, refs->refBase());
1080*77b80299SAndroid Build Coastguard Worker         obj->incStrong(mProcess.get());
1081*77b80299SAndroid Build Coastguard Worker         IF_LOG_REMOTEREFS() {
1082*77b80299SAndroid Build Coastguard Worker             LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
1083*77b80299SAndroid Build Coastguard Worker             obj->printRefs();
1084*77b80299SAndroid Build Coastguard Worker         }
1085*77b80299SAndroid Build Coastguard Worker         mOut.writeInt32(BC_ACQUIRE_DONE);
1086*77b80299SAndroid Build Coastguard Worker         mOut.writePointer((uintptr_t)refs);
1087*77b80299SAndroid Build Coastguard Worker         mOut.writePointer((uintptr_t)obj);
1088*77b80299SAndroid Build Coastguard Worker         break;
1089*77b80299SAndroid Build Coastguard Worker 
1090*77b80299SAndroid Build Coastguard Worker     case BR_RELEASE:
1091*77b80299SAndroid Build Coastguard Worker         refs = (RefBase::weakref_type*)mIn.readPointer();
1092*77b80299SAndroid Build Coastguard Worker         obj = (BHwBinder*)mIn.readPointer();
1093*77b80299SAndroid Build Coastguard Worker         ALOG_ASSERT(refs->refBase() == obj,
1094*77b80299SAndroid Build Coastguard Worker                    "BR_RELEASE: object %p does not match cookie %p (expected %p)",
1095*77b80299SAndroid Build Coastguard Worker                    refs, obj, refs->refBase());
1096*77b80299SAndroid Build Coastguard Worker         IF_LOG_REMOTEREFS() {
1097*77b80299SAndroid Build Coastguard Worker             LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
1098*77b80299SAndroid Build Coastguard Worker             obj->printRefs();
1099*77b80299SAndroid Build Coastguard Worker         }
1100*77b80299SAndroid Build Coastguard Worker         mPendingStrongDerefs.push(obj);
1101*77b80299SAndroid Build Coastguard Worker         break;
1102*77b80299SAndroid Build Coastguard Worker 
1103*77b80299SAndroid Build Coastguard Worker     case BR_INCREFS:
1104*77b80299SAndroid Build Coastguard Worker         refs = (RefBase::weakref_type*)mIn.readPointer();
1105*77b80299SAndroid Build Coastguard Worker         obj = (BHwBinder*)mIn.readPointer();
1106*77b80299SAndroid Build Coastguard Worker         refs->incWeak(mProcess.get());
1107*77b80299SAndroid Build Coastguard Worker         mOut.writeInt32(BC_INCREFS_DONE);
1108*77b80299SAndroid Build Coastguard Worker         mOut.writePointer((uintptr_t)refs);
1109*77b80299SAndroid Build Coastguard Worker         mOut.writePointer((uintptr_t)obj);
1110*77b80299SAndroid Build Coastguard Worker         break;
1111*77b80299SAndroid Build Coastguard Worker 
1112*77b80299SAndroid Build Coastguard Worker     case BR_DECREFS:
1113*77b80299SAndroid Build Coastguard Worker         refs = (RefBase::weakref_type*)mIn.readPointer();
1114*77b80299SAndroid Build Coastguard Worker         obj = (BHwBinder*)mIn.readPointer();
1115*77b80299SAndroid Build Coastguard Worker         // NOTE: This assertion is not valid, because the object may no
1116*77b80299SAndroid Build Coastguard Worker         // longer exist (thus the (BHwBinder*)cast above resulting in a different
1117*77b80299SAndroid Build Coastguard Worker         // memory address).
1118*77b80299SAndroid Build Coastguard Worker         //ALOG_ASSERT(refs->refBase() == obj,
1119*77b80299SAndroid Build Coastguard Worker         //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
1120*77b80299SAndroid Build Coastguard Worker         //           refs, obj, refs->refBase());
1121*77b80299SAndroid Build Coastguard Worker         mPendingWeakDerefs.push(refs);
1122*77b80299SAndroid Build Coastguard Worker         break;
1123*77b80299SAndroid Build Coastguard Worker 
1124*77b80299SAndroid Build Coastguard Worker     case BR_ATTEMPT_ACQUIRE:
1125*77b80299SAndroid Build Coastguard Worker         refs = (RefBase::weakref_type*)mIn.readPointer();
1126*77b80299SAndroid Build Coastguard Worker         obj = (BHwBinder*)mIn.readPointer();
1127*77b80299SAndroid Build Coastguard Worker 
1128*77b80299SAndroid Build Coastguard Worker         {
1129*77b80299SAndroid Build Coastguard Worker             const bool success = refs->attemptIncStrong(mProcess.get());
1130*77b80299SAndroid Build Coastguard Worker             ALOG_ASSERT(success && refs->refBase() == obj,
1131*77b80299SAndroid Build Coastguard Worker                        "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
1132*77b80299SAndroid Build Coastguard Worker                        refs, obj, refs->refBase());
1133*77b80299SAndroid Build Coastguard Worker 
1134*77b80299SAndroid Build Coastguard Worker             mOut.writeInt32(BC_ACQUIRE_RESULT);
1135*77b80299SAndroid Build Coastguard Worker             mOut.writeInt32((int32_t)success);
1136*77b80299SAndroid Build Coastguard Worker         }
1137*77b80299SAndroid Build Coastguard Worker         break;
1138*77b80299SAndroid Build Coastguard Worker 
1139*77b80299SAndroid Build Coastguard Worker     case BR_TRANSACTION_SEC_CTX:
1140*77b80299SAndroid Build Coastguard Worker     case BR_TRANSACTION:
1141*77b80299SAndroid Build Coastguard Worker         {
1142*77b80299SAndroid Build Coastguard Worker             binder_transaction_data_secctx tr_secctx;
1143*77b80299SAndroid Build Coastguard Worker             binder_transaction_data& tr = tr_secctx.transaction_data;
1144*77b80299SAndroid Build Coastguard Worker 
1145*77b80299SAndroid Build Coastguard Worker             if (cmd == BR_TRANSACTION_SEC_CTX) {
1146*77b80299SAndroid Build Coastguard Worker                 result = mIn.read(&tr_secctx, sizeof(tr_secctx));
1147*77b80299SAndroid Build Coastguard Worker             } else {
1148*77b80299SAndroid Build Coastguard Worker                 result = mIn.read(&tr, sizeof(tr));
1149*77b80299SAndroid Build Coastguard Worker                 tr_secctx.secctx = 0;
1150*77b80299SAndroid Build Coastguard Worker             }
1151*77b80299SAndroid Build Coastguard Worker 
1152*77b80299SAndroid Build Coastguard Worker             ALOG_ASSERT(result == NO_ERROR,
1153*77b80299SAndroid Build Coastguard Worker                 "Not enough command data for brTRANSACTION");
1154*77b80299SAndroid Build Coastguard Worker             if (result != NO_ERROR) break;
1155*77b80299SAndroid Build Coastguard Worker 
1156*77b80299SAndroid Build Coastguard Worker             Parcel buffer;
1157*77b80299SAndroid Build Coastguard Worker             buffer.ipcSetDataReference(
1158*77b80299SAndroid Build Coastguard Worker                 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
1159*77b80299SAndroid Build Coastguard Worker                 tr.data_size,
1160*77b80299SAndroid Build Coastguard Worker                 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
1161*77b80299SAndroid Build Coastguard Worker                 tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
1162*77b80299SAndroid Build Coastguard Worker 
1163*77b80299SAndroid Build Coastguard Worker             const void* origServingStackPointer = mServingStackPointer;
1164*77b80299SAndroid Build Coastguard Worker             mServingStackPointer = __builtin_frame_address(0);
1165*77b80299SAndroid Build Coastguard Worker 
1166*77b80299SAndroid Build Coastguard Worker             const pid_t origPid = mCallingPid;
1167*77b80299SAndroid Build Coastguard Worker             const char* origSid = mCallingSid;
1168*77b80299SAndroid Build Coastguard Worker             const uid_t origUid = mCallingUid;
1169*77b80299SAndroid Build Coastguard Worker             const int32_t origStrictModePolicy = mStrictModePolicy;
1170*77b80299SAndroid Build Coastguard Worker             const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
1171*77b80299SAndroid Build Coastguard Worker 
1172*77b80299SAndroid Build Coastguard Worker             mCallingPid = tr.sender_pid;
1173*77b80299SAndroid Build Coastguard Worker             mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
1174*77b80299SAndroid Build Coastguard Worker             mCallingUid = tr.sender_euid;
1175*77b80299SAndroid Build Coastguard Worker             mLastTransactionBinderFlags = tr.flags;
1176*77b80299SAndroid Build Coastguard Worker 
1177*77b80299SAndroid Build Coastguard Worker             // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
1178*77b80299SAndroid Build Coastguard Worker             //    (mCallingSid ? mCallingSid : "<N/A>"), mCallingUid);
1179*77b80299SAndroid Build Coastguard Worker 
1180*77b80299SAndroid Build Coastguard Worker             Parcel reply;
1181*77b80299SAndroid Build Coastguard Worker             status_t error;
1182*77b80299SAndroid Build Coastguard Worker             bool reply_sent = false;
1183*77b80299SAndroid Build Coastguard Worker             IF_LOG_TRANSACTIONS() {
1184*77b80299SAndroid Build Coastguard Worker                 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
1185*77b80299SAndroid Build Coastguard Worker                     << " / obj " << tr.target.ptr << " / code "
1186*77b80299SAndroid Build Coastguard Worker                     << TypeCode(tr.code) << ": " << indent << buffer
1187*77b80299SAndroid Build Coastguard Worker                     << dedent << endl
1188*77b80299SAndroid Build Coastguard Worker                     << "Data addr = "
1189*77b80299SAndroid Build Coastguard Worker                     << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
1190*77b80299SAndroid Build Coastguard Worker                     << ", offsets addr="
1191*77b80299SAndroid Build Coastguard Worker                     << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
1192*77b80299SAndroid Build Coastguard Worker             }
1193*77b80299SAndroid Build Coastguard Worker 
1194*77b80299SAndroid Build Coastguard Worker             constexpr size_t kForwardReplyFlags = TF_CLEAR_BUF;
1195*77b80299SAndroid Build Coastguard Worker 
1196*77b80299SAndroid Build Coastguard Worker             auto reply_callback = [&] (auto &replyParcel) {
1197*77b80299SAndroid Build Coastguard Worker                 if (reply_sent) {
1198*77b80299SAndroid Build Coastguard Worker                     // Reply was sent earlier, ignore it.
1199*77b80299SAndroid Build Coastguard Worker                     ALOGE("Dropping binder reply, it was sent already.");
1200*77b80299SAndroid Build Coastguard Worker                     return;
1201*77b80299SAndroid Build Coastguard Worker                 }
1202*77b80299SAndroid Build Coastguard Worker                 reply_sent = true;
1203*77b80299SAndroid Build Coastguard Worker                 if ((tr.flags & TF_ONE_WAY) == 0) {
1204*77b80299SAndroid Build Coastguard Worker                     replyParcel.setError(NO_ERROR);
1205*77b80299SAndroid Build Coastguard Worker                     sendReply(replyParcel, (tr.flags & kForwardReplyFlags));
1206*77b80299SAndroid Build Coastguard Worker                 } else {
1207*77b80299SAndroid Build Coastguard Worker                     ALOGE("Not sending reply in one-way transaction");
1208*77b80299SAndroid Build Coastguard Worker                 }
1209*77b80299SAndroid Build Coastguard Worker             };
1210*77b80299SAndroid Build Coastguard Worker 
1211*77b80299SAndroid Build Coastguard Worker             if (tr.target.ptr) {
1212*77b80299SAndroid Build Coastguard Worker                 // We only have a weak reference on the target object, so we must first try to
1213*77b80299SAndroid Build Coastguard Worker                 // safely acquire a strong reference before doing anything else with it.
1214*77b80299SAndroid Build Coastguard Worker                 if (reinterpret_cast<RefBase::weakref_type*>(
1215*77b80299SAndroid Build Coastguard Worker                         tr.target.ptr)->attemptIncStrong(this)) {
1216*77b80299SAndroid Build Coastguard Worker                     error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer,
1217*77b80299SAndroid Build Coastguard Worker                             &reply, tr.flags, reply_callback);
1218*77b80299SAndroid Build Coastguard Worker                     reinterpret_cast<BHwBinder*>(tr.cookie)->decStrong(this);
1219*77b80299SAndroid Build Coastguard Worker                 } else {
1220*77b80299SAndroid Build Coastguard Worker                     error = UNKNOWN_TRANSACTION;
1221*77b80299SAndroid Build Coastguard Worker                 }
1222*77b80299SAndroid Build Coastguard Worker 
1223*77b80299SAndroid Build Coastguard Worker             } else {
1224*77b80299SAndroid Build Coastguard Worker                 error = the_context_object->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
1225*77b80299SAndroid Build Coastguard Worker             }
1226*77b80299SAndroid Build Coastguard Worker 
1227*77b80299SAndroid Build Coastguard Worker             if ((tr.flags & TF_ONE_WAY) == 0) {
1228*77b80299SAndroid Build Coastguard Worker                 if (!reply_sent) {
1229*77b80299SAndroid Build Coastguard Worker                     // Should have been a reply but there wasn't, so there
1230*77b80299SAndroid Build Coastguard Worker                     // must have been an error instead.
1231*77b80299SAndroid Build Coastguard Worker                     reply.setError(error);
1232*77b80299SAndroid Build Coastguard Worker                     sendReply(reply, (tr.flags & kForwardReplyFlags));
1233*77b80299SAndroid Build Coastguard Worker                 } else {
1234*77b80299SAndroid Build Coastguard Worker                     if (error != NO_ERROR) {
1235*77b80299SAndroid Build Coastguard Worker                         ALOGE("transact() returned error after sending reply.");
1236*77b80299SAndroid Build Coastguard Worker                     } else {
1237*77b80299SAndroid Build Coastguard Worker                         // Ok, reply sent and transact didn't return an error.
1238*77b80299SAndroid Build Coastguard Worker                     }
1239*77b80299SAndroid Build Coastguard Worker                 }
1240*77b80299SAndroid Build Coastguard Worker             } else {
1241*77b80299SAndroid Build Coastguard Worker                 // One-way transaction, don't care about return value or reply.
1242*77b80299SAndroid Build Coastguard Worker             }
1243*77b80299SAndroid Build Coastguard Worker 
1244*77b80299SAndroid Build Coastguard Worker             //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n",
1245*77b80299SAndroid Build Coastguard Worker             //     mCallingPid, origPid, (origSid ? origSid : "<N/A>"), origUid);
1246*77b80299SAndroid Build Coastguard Worker 
1247*77b80299SAndroid Build Coastguard Worker             mServingStackPointer = origServingStackPointer;
1248*77b80299SAndroid Build Coastguard Worker             mCallingPid = origPid;
1249*77b80299SAndroid Build Coastguard Worker             mCallingSid = origSid;
1250*77b80299SAndroid Build Coastguard Worker             mCallingUid = origUid;
1251*77b80299SAndroid Build Coastguard Worker             mStrictModePolicy = origStrictModePolicy;
1252*77b80299SAndroid Build Coastguard Worker             mLastTransactionBinderFlags = origTransactionBinderFlags;
1253*77b80299SAndroid Build Coastguard Worker 
1254*77b80299SAndroid Build Coastguard Worker             IF_LOG_TRANSACTIONS() {
1255*77b80299SAndroid Build Coastguard Worker                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
1256*77b80299SAndroid Build Coastguard Worker                     << tr.target.ptr << ": " << indent << reply << dedent << endl;
1257*77b80299SAndroid Build Coastguard Worker             }
1258*77b80299SAndroid Build Coastguard Worker 
1259*77b80299SAndroid Build Coastguard Worker         }
1260*77b80299SAndroid Build Coastguard Worker         break;
1261*77b80299SAndroid Build Coastguard Worker 
1262*77b80299SAndroid Build Coastguard Worker     case BR_DEAD_BINDER:
1263*77b80299SAndroid Build Coastguard Worker         {
1264*77b80299SAndroid Build Coastguard Worker             BpHwBinder *proxy = (BpHwBinder*)mIn.readPointer();
1265*77b80299SAndroid Build Coastguard Worker             proxy->sendObituary();
1266*77b80299SAndroid Build Coastguard Worker             mOut.writeInt32(BC_DEAD_BINDER_DONE);
1267*77b80299SAndroid Build Coastguard Worker             mOut.writePointer((uintptr_t)proxy);
1268*77b80299SAndroid Build Coastguard Worker         } break;
1269*77b80299SAndroid Build Coastguard Worker 
1270*77b80299SAndroid Build Coastguard Worker     case BR_CLEAR_DEATH_NOTIFICATION_DONE:
1271*77b80299SAndroid Build Coastguard Worker         {
1272*77b80299SAndroid Build Coastguard Worker             BpHwBinder *proxy = (BpHwBinder*)mIn.readPointer();
1273*77b80299SAndroid Build Coastguard Worker             proxy->getWeakRefs()->decWeak(proxy);
1274*77b80299SAndroid Build Coastguard Worker         } break;
1275*77b80299SAndroid Build Coastguard Worker 
1276*77b80299SAndroid Build Coastguard Worker     case BR_FINISHED:
1277*77b80299SAndroid Build Coastguard Worker         result = TIMED_OUT;
1278*77b80299SAndroid Build Coastguard Worker         break;
1279*77b80299SAndroid Build Coastguard Worker 
1280*77b80299SAndroid Build Coastguard Worker     case BR_NOOP:
1281*77b80299SAndroid Build Coastguard Worker         break;
1282*77b80299SAndroid Build Coastguard Worker 
1283*77b80299SAndroid Build Coastguard Worker     case BR_SPAWN_LOOPER:
1284*77b80299SAndroid Build Coastguard Worker         mProcess->spawnPooledThread(false);
1285*77b80299SAndroid Build Coastguard Worker         break;
1286*77b80299SAndroid Build Coastguard Worker 
1287*77b80299SAndroid Build Coastguard Worker     default:
1288*77b80299SAndroid Build Coastguard Worker         ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);
1289*77b80299SAndroid Build Coastguard Worker         result = UNKNOWN_ERROR;
1290*77b80299SAndroid Build Coastguard Worker         break;
1291*77b80299SAndroid Build Coastguard Worker     }
1292*77b80299SAndroid Build Coastguard Worker 
1293*77b80299SAndroid Build Coastguard Worker     if (result != NO_ERROR) {
1294*77b80299SAndroid Build Coastguard Worker         mLastError = result;
1295*77b80299SAndroid Build Coastguard Worker     }
1296*77b80299SAndroid Build Coastguard Worker 
1297*77b80299SAndroid Build Coastguard Worker     return result;
1298*77b80299SAndroid Build Coastguard Worker }
1299*77b80299SAndroid Build Coastguard Worker 
getServingStackPointer() const1300*77b80299SAndroid Build Coastguard Worker const void* IPCThreadState::getServingStackPointer() const {
1301*77b80299SAndroid Build Coastguard Worker     return mServingStackPointer;
1302*77b80299SAndroid Build Coastguard Worker }
1303*77b80299SAndroid Build Coastguard Worker 
threadDestructor(void * st)1304*77b80299SAndroid Build Coastguard Worker void IPCThreadState::threadDestructor(void *st)
1305*77b80299SAndroid Build Coastguard Worker {
1306*77b80299SAndroid Build Coastguard Worker         IPCThreadState* const self = static_cast<IPCThreadState*>(st);
1307*77b80299SAndroid Build Coastguard Worker         if (self) {
1308*77b80299SAndroid Build Coastguard Worker                 self->flushCommands();
1309*77b80299SAndroid Build Coastguard Worker #if defined(__ANDROID__)
1310*77b80299SAndroid Build Coastguard Worker         if (self->mProcess->mDriverFD >= 0) {
1311*77b80299SAndroid Build Coastguard Worker             ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1312*77b80299SAndroid Build Coastguard Worker         }
1313*77b80299SAndroid Build Coastguard Worker #endif
1314*77b80299SAndroid Build Coastguard Worker                 delete self;
1315*77b80299SAndroid Build Coastguard Worker         }
1316*77b80299SAndroid Build Coastguard Worker }
1317*77b80299SAndroid Build Coastguard Worker 
1318*77b80299SAndroid Build Coastguard Worker 
freeBuffer(Parcel * parcel,const uint8_t * data,size_t,const binder_size_t *,size_t,void *)1319*77b80299SAndroid Build Coastguard Worker void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
1320*77b80299SAndroid Build Coastguard Worker                                 size_t /*dataSize*/,
1321*77b80299SAndroid Build Coastguard Worker                                 const binder_size_t* /*objects*/,
1322*77b80299SAndroid Build Coastguard Worker                                 size_t /*objectsSize*/, void* /*cookie*/)
1323*77b80299SAndroid Build Coastguard Worker {
1324*77b80299SAndroid Build Coastguard Worker     //ALOGI("Freeing parcel %p", &parcel);
1325*77b80299SAndroid Build Coastguard Worker     IF_LOG_COMMANDS() {
1326*77b80299SAndroid Build Coastguard Worker         alog << "Writing BC_FREE_BUFFER for " << data << endl;
1327*77b80299SAndroid Build Coastguard Worker     }
1328*77b80299SAndroid Build Coastguard Worker     ALOG_ASSERT(data != nullptr, "Called with NULL data");
1329*77b80299SAndroid Build Coastguard Worker     if (parcel != nullptr) parcel->closeFileDescriptors();
1330*77b80299SAndroid Build Coastguard Worker     IPCThreadState* state = self();
1331*77b80299SAndroid Build Coastguard Worker     state->mOut.writeInt32(BC_FREE_BUFFER);
1332*77b80299SAndroid Build Coastguard Worker     state->mOut.writePointer((uintptr_t)data);
1333*77b80299SAndroid Build Coastguard Worker }
1334*77b80299SAndroid Build Coastguard Worker 
1335*77b80299SAndroid Build Coastguard Worker } // namespace hardware
1336*77b80299SAndroid Build Coastguard Worker } // namespace android
1337