blob: 164a4a3c77edd91253088db0a2c62f84766237fd [file] [log] [blame]
Mathias Agopian7922fa22009-05-18 15:08:03 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jason Parks2b17f142009-11-03 12:14:38 -080017#define LOG_TAG "IPCThreadState"
18
Martijn Coenen4080edc2016-05-04 14:17:02 +020019#include <hwbinder/IPCThreadState.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070020
Martijn Coenen4080edc2016-05-04 14:17:02 +020021#include <hwbinder/Binder.h>
22#include <hwbinder/BpBinder.h>
23#include <hwbinder/TextOutput.h>
Mathias Agopian4ea13dc2013-05-06 20:20:50 -070024
Glenn Kastencb5e2422012-03-16 07:15:23 -070025#include <cutils/sched_policy.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070026#include <utils/Log.h>
Colin Crossb1dc6542016-04-15 14:29:55 -070027#include <utils/SystemClock.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070028#include <utils/threads.h>
29
30#include <private/binder/binder_module.h>
Martijn Coenene01f4f22016-05-12 12:33:28 +020031#include <hwbinder/Static.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070032
Mathias Agopian7922fa22009-05-18 15:08:03 -070033#include <errno.h>
Colin Crossb1dc6542016-04-15 14:29:55 -070034#include <inttypes.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070035#include <pthread.h>
36#include <sched.h>
Yabin Cuibbef2ba2015-01-26 19:45:47 -080037#include <signal.h>
38#include <stdio.h>
39#include <sys/ioctl.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070040#include <sys/resource.h>
Yabin Cuibbef2ba2015-01-26 19:45:47 -080041#include <unistd.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070042
43#if LOG_NDEBUG
44
45#define IF_LOG_TRANSACTIONS() if (false)
46#define IF_LOG_COMMANDS() if (false)
47#define LOG_REMOTEREFS(...)
48#define IF_LOG_REMOTEREFS() if (false)
49#define LOG_THREADPOOL(...)
50#define LOG_ONEWAY(...)
51
52#else
53
Steve Block5854b912011-10-12 17:27:03 +010054#define IF_LOG_TRANSACTIONS() IF_ALOG(LOG_VERBOSE, "transact")
55#define IF_LOG_COMMANDS() IF_ALOG(LOG_VERBOSE, "ipc")
56#define LOG_REMOTEREFS(...) ALOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
57#define IF_LOG_REMOTEREFS() IF_ALOG(LOG_DEBUG, "remoterefs")
58#define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
59#define LOG_ONEWAY(...) ALOG(LOG_DEBUG, "ipc", __VA_ARGS__)
Mathias Agopian7922fa22009-05-18 15:08:03 -070060
61#endif
62
63// ---------------------------------------------------------------------------
64
65namespace android {
Martijn Coenene01f4f22016-05-12 12:33:28 +020066namespace hidl {
Mathias Agopian7922fa22009-05-18 15:08:03 -070067
68static const char* getReturnString(size_t idx);
Mathias Agopian7922fa22009-05-18 15:08:03 -070069static const void* printReturnCommand(TextOutput& out, const void* _cmd);
70static const void* printCommand(TextOutput& out, const void* _cmd);
71
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -070072// Static const and functions will be optimized out if not used,
73// when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
Mathias Agopian7922fa22009-05-18 15:08:03 -070074static const char *kReturnStrings[] = {
Andy McFadden457d51f2011-08-31 07:43:40 -070075 "BR_ERROR",
Mathias Agopian7922fa22009-05-18 15:08:03 -070076 "BR_OK",
Mathias Agopian7922fa22009-05-18 15:08:03 -070077 "BR_TRANSACTION",
78 "BR_REPLY",
79 "BR_ACQUIRE_RESULT",
80 "BR_DEAD_REPLY",
81 "BR_TRANSACTION_COMPLETE",
82 "BR_INCREFS",
83 "BR_ACQUIRE",
84 "BR_RELEASE",
85 "BR_DECREFS",
86 "BR_ATTEMPT_ACQUIRE",
Mathias Agopian7922fa22009-05-18 15:08:03 -070087 "BR_NOOP",
88 "BR_SPAWN_LOOPER",
89 "BR_FINISHED",
90 "BR_DEAD_BINDER",
Andy McFadden457d51f2011-08-31 07:43:40 -070091 "BR_CLEAR_DEATH_NOTIFICATION_DONE",
92 "BR_FAILED_REPLY"
Mathias Agopian7922fa22009-05-18 15:08:03 -070093};
94
95static const char *kCommandStrings[] = {
Mathias Agopian7922fa22009-05-18 15:08:03 -070096 "BC_TRANSACTION",
97 "BC_REPLY",
98 "BC_ACQUIRE_RESULT",
99 "BC_FREE_BUFFER",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700100 "BC_INCREFS",
101 "BC_ACQUIRE",
102 "BC_RELEASE",
103 "BC_DECREFS",
104 "BC_INCREFS_DONE",
105 "BC_ACQUIRE_DONE",
106 "BC_ATTEMPT_ACQUIRE",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700107 "BC_REGISTER_LOOPER",
108 "BC_ENTER_LOOPER",
109 "BC_EXIT_LOOPER",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700110 "BC_REQUEST_DEATH_NOTIFICATION",
111 "BC_CLEAR_DEATH_NOTIFICATION",
112 "BC_DEAD_BINDER_DONE"
Mathias Agopian7922fa22009-05-18 15:08:03 -0700113};
114
115static const char* getReturnString(size_t idx)
116{
117 if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
118 return kReturnStrings[idx];
119 else
120 return "unknown";
121}
122
Mathias Agopian7922fa22009-05-18 15:08:03 -0700123static const void* printBinderTransactionData(TextOutput& out, const void* data)
124{
125 const binder_transaction_data* btd =
126 (const binder_transaction_data*)data;
Andy McFadden457d51f2011-08-31 07:43:40 -0700127 if (btd->target.handle < 1024) {
128 /* want to print descriptors in decimal; guess based on value */
129 out << "target.desc=" << btd->target.handle;
130 } else {
131 out << "target.ptr=" << btd->target.ptr;
132 }
133 out << " (cookie " << btd->cookie << ")" << endl
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700134 << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
Mathias Agopian7922fa22009-05-18 15:08:03 -0700135 << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
136 << " bytes)" << endl
137 << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
Andy McFadden457d51f2011-08-31 07:43:40 -0700138 << " bytes)";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700139 return btd+1;
140}
141
142static const void* printReturnCommand(TextOutput& out, const void* _cmd)
143{
Andy McFadden457d51f2011-08-31 07:43:40 -0700144 static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700145 const int32_t* cmd = (const int32_t*)_cmd;
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100146 uint32_t code = (uint32_t)*cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700147 size_t cmdIndex = code & 0xff;
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100148 if (code == BR_ERROR) {
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700149 out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700150 return cmd;
Andy McFadden457d51f2011-08-31 07:43:40 -0700151 } else if (cmdIndex >= N) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700152 out << "Unknown reply: " << code << endl;
153 return cmd;
154 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700155 out << kReturnStrings[cmdIndex];
Mathias Agopian7922fa22009-05-18 15:08:03 -0700156
Mathias Agopian7922fa22009-05-18 15:08:03 -0700157 switch (code) {
158 case BR_TRANSACTION:
159 case BR_REPLY: {
160 out << ": " << indent;
161 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
162 out << dedent;
163 } break;
164
165 case BR_ACQUIRE_RESULT: {
166 const int32_t res = *cmd++;
167 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
168 } break;
169
170 case BR_INCREFS:
171 case BR_ACQUIRE:
172 case BR_RELEASE:
173 case BR_DECREFS: {
174 const int32_t b = *cmd++;
175 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700176 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700177 } break;
178
179 case BR_ATTEMPT_ACQUIRE: {
180 const int32_t p = *cmd++;
181 const int32_t b = *cmd++;
182 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700183 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
Mathias Agopian7922fa22009-05-18 15:08:03 -0700184 << "), pri=" << p;
185 } break;
186
187 case BR_DEAD_BINDER:
188 case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
189 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700190 out << ": death cookie " << (void*)(long)c;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700191 } break;
Andy McFadden457d51f2011-08-31 07:43:40 -0700192
193 default:
194 // no details to show for: BR_OK, BR_DEAD_REPLY,
195 // BR_TRANSACTION_COMPLETE, BR_FINISHED
196 break;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700197 }
198
199 out << endl;
200 return cmd;
201}
202
203static const void* printCommand(TextOutput& out, const void* _cmd)
204{
Andy McFadden457d51f2011-08-31 07:43:40 -0700205 static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700206 const int32_t* cmd = (const int32_t*)_cmd;
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100207 uint32_t code = (uint32_t)*cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700208 size_t cmdIndex = code & 0xff;
209
210 if (cmdIndex >= N) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700211 out << "Unknown command: " << code << endl;
212 return cmd;
213 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700214 out << kCommandStrings[cmdIndex];
215
Mathias Agopian7922fa22009-05-18 15:08:03 -0700216 switch (code) {
217 case BC_TRANSACTION:
218 case BC_REPLY: {
219 out << ": " << indent;
220 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
221 out << dedent;
222 } break;
223
224 case BC_ACQUIRE_RESULT: {
225 const int32_t res = *cmd++;
226 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
227 } break;
228
229 case BC_FREE_BUFFER: {
230 const int32_t buf = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700231 out << ": buffer=" << (void*)(long)buf;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700232 } break;
233
234 case BC_INCREFS:
235 case BC_ACQUIRE:
236 case BC_RELEASE:
237 case BC_DECREFS: {
238 const int32_t d = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700239 out << ": desc=" << d;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700240 } break;
241
242 case BC_INCREFS_DONE:
243 case BC_ACQUIRE_DONE: {
244 const int32_t b = *cmd++;
245 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700246 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700247 } break;
248
249 case BC_ATTEMPT_ACQUIRE: {
250 const int32_t p = *cmd++;
251 const int32_t d = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700252 out << ": desc=" << d << ", pri=" << p;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700253 } break;
254
255 case BC_REQUEST_DEATH_NOTIFICATION:
256 case BC_CLEAR_DEATH_NOTIFICATION: {
257 const int32_t h = *cmd++;
258 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700259 out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700260 } break;
261
262 case BC_DEAD_BINDER_DONE: {
263 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700264 out << ": death cookie " << (void*)(long)c;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700265 } break;
Andy McFadden457d51f2011-08-31 07:43:40 -0700266
267 default:
268 // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
269 // BC_EXIT_LOOPER
270 break;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700271 }
272
273 out << endl;
274 return cmd;
275}
Mathias Agopian7922fa22009-05-18 15:08:03 -0700276
277static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
278static bool gHaveTLS = false;
279static pthread_key_t gTLS = 0;
280static bool gShutdown = false;
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800281static bool gDisableBackgroundScheduling = false;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700282
283IPCThreadState* IPCThreadState::self()
284{
285 if (gHaveTLS) {
286restart:
287 const pthread_key_t k = gTLS;
288 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
289 if (st) return st;
290 return new IPCThreadState;
291 }
292
Andreas Gampe1d5dc2b2016-02-01 13:21:56 -0800293 if (gShutdown) {
294 ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
295 return NULL;
296 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700297
298 pthread_mutex_lock(&gTLSMutex);
299 if (!gHaveTLS) {
Andreas Gampe1d5dc2b2016-02-01 13:21:56 -0800300 int key_create_value = pthread_key_create(&gTLS, threadDestructor);
301 if (key_create_value != 0) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700302 pthread_mutex_unlock(&gTLSMutex);
Andreas Gampe1d5dc2b2016-02-01 13:21:56 -0800303 ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
304 strerror(key_create_value));
Mathias Agopian7922fa22009-05-18 15:08:03 -0700305 return NULL;
306 }
307 gHaveTLS = true;
308 }
309 pthread_mutex_unlock(&gTLSMutex);
310 goto restart;
311}
312
Brad Fitzpatrick77949942010-12-13 16:52:35 -0800313IPCThreadState* IPCThreadState::selfOrNull()
314{
315 if (gHaveTLS) {
316 const pthread_key_t k = gTLS;
317 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
318 return st;
319 }
320 return NULL;
321}
322
Mathias Agopian7922fa22009-05-18 15:08:03 -0700323void IPCThreadState::shutdown()
324{
325 gShutdown = true;
326
327 if (gHaveTLS) {
328 // XXX Need to wait for all thread pool threads to exit!
329 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
330 if (st) {
331 delete st;
332 pthread_setspecific(gTLS, NULL);
333 }
zhongjie8e8a0252016-03-09 15:05:04 +0800334 pthread_key_delete(gTLS);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700335 gHaveTLS = false;
336 }
337}
338
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800339void IPCThreadState::disableBackgroundScheduling(bool disable)
340{
341 gDisableBackgroundScheduling = disable;
342}
343
Mathias Agopian7922fa22009-05-18 15:08:03 -0700344sp<ProcessState> IPCThreadState::process()
345{
346 return mProcess;
347}
348
349status_t IPCThreadState::clearLastError()
350{
351 const status_t err = mLastError;
352 mLastError = NO_ERROR;
353 return err;
354}
355
Dan Stozae8da8a42014-11-26 12:23:23 -0800356pid_t IPCThreadState::getCallingPid() const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700357{
358 return mCallingPid;
359}
360
Dan Stozae8da8a42014-11-26 12:23:23 -0800361uid_t IPCThreadState::getCallingUid() const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700362{
363 return mCallingUid;
364}
365
366int64_t IPCThreadState::clearCallingIdentity()
367{
368 int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
369 clearCaller();
370 return token;
371}
372
Brad Fitzpatrick94c36342010-06-18 13:07:53 -0700373void IPCThreadState::setStrictModePolicy(int32_t policy)
374{
375 mStrictModePolicy = policy;
376}
377
Brad Fitzpatrick3f4ef592010-07-07 16:06:39 -0700378int32_t IPCThreadState::getStrictModePolicy() const
379{
Brad Fitzpatrick94c36342010-06-18 13:07:53 -0700380 return mStrictModePolicy;
381}
382
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700383void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
384{
385 mLastTransactionBinderFlags = flags;
386}
387
388int32_t IPCThreadState::getLastTransactionBinderFlags() const
389{
390 return mLastTransactionBinderFlags;
391}
392
Mathias Agopian7922fa22009-05-18 15:08:03 -0700393void IPCThreadState::restoreCallingIdentity(int64_t token)
394{
395 mCallingUid = (int)(token>>32);
396 mCallingPid = (int)token;
397}
398
399void IPCThreadState::clearCaller()
400{
Marco Nelissenb4f35d02009-07-17 07:59:17 -0700401 mCallingPid = getpid();
402 mCallingUid = getuid();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700403}
404
405void IPCThreadState::flushCommands()
406{
407 if (mProcess->mDriverFD <= 0)
408 return;
409 talkWithDriver(false);
410}
411
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700412void IPCThreadState::blockUntilThreadAvailable()
413{
414 pthread_mutex_lock(&mProcess->mThreadCountLock);
415 while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) {
Wale Ogunwale319900a2015-04-21 12:29:50 -0700416 ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n",
417 static_cast<unsigned long>(mProcess->mExecutingThreadsCount),
418 static_cast<unsigned long>(mProcess->mMaxThreads));
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700419 pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock);
420 }
421 pthread_mutex_unlock(&mProcess->mThreadCountLock);
422}
423
Todd Poynor0646cb02013-06-25 19:12:18 -0700424status_t IPCThreadState::getAndExecuteCommand()
425{
426 status_t result;
427 int32_t cmd;
428
429 result = talkWithDriver();
430 if (result >= NO_ERROR) {
431 size_t IN = mIn.dataAvail();
432 if (IN < sizeof(int32_t)) return result;
433 cmd = mIn.readInt32();
434 IF_LOG_COMMANDS() {
435 alog << "Processing top-level Command: "
436 << getReturnString(cmd) << endl;
437 }
438
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700439 pthread_mutex_lock(&mProcess->mThreadCountLock);
440 mProcess->mExecutingThreadsCount++;
Colin Crossb1dc6542016-04-15 14:29:55 -0700441 if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
442 mProcess->mStarvationStartTimeMs == 0) {
443 mProcess->mStarvationStartTimeMs = uptimeMillis();
444 }
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700445 pthread_mutex_unlock(&mProcess->mThreadCountLock);
446
Todd Poynor0646cb02013-06-25 19:12:18 -0700447 result = executeCommand(cmd);
448
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700449 pthread_mutex_lock(&mProcess->mThreadCountLock);
450 mProcess->mExecutingThreadsCount--;
Colin Crossb1dc6542016-04-15 14:29:55 -0700451 if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
452 mProcess->mStarvationStartTimeMs != 0) {
453 int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
454 if (starvationTimeMs > 100) {
455 ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms",
456 mProcess->mMaxThreads, starvationTimeMs);
457 }
458 mProcess->mStarvationStartTimeMs = 0;
459 }
Wale Ogunwale2e604f02015-04-13 16:16:10 -0700460 pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
461 pthread_mutex_unlock(&mProcess->mThreadCountLock);
462
Todd Poynor0646cb02013-06-25 19:12:18 -0700463 // After executing the command, ensure that the thread is returned to the
464 // foreground cgroup before rejoining the pool. The driver takes care of
465 // restoring the priority, but doesn't do anything with cgroups so we
466 // need to take care of that here in userspace. Note that we do make
467 // sure to go in the foreground after executing a transaction, but
468 // there are other callbacks into user code that could have changed
469 // our group so we want to make absolutely sure it is put back.
470 set_sched_policy(mMyThreadId, SP_FOREGROUND);
471 }
472
473 return result;
474}
475
476// When we've cleared the incoming command queue, process any pending derefs
477void IPCThreadState::processPendingDerefs()
478{
479 if (mIn.dataPosition() >= mIn.dataSize()) {
480 size_t numPending = mPendingWeakDerefs.size();
481 if (numPending > 0) {
482 for (size_t i = 0; i < numPending; i++) {
483 RefBase::weakref_type* refs = mPendingWeakDerefs[i];
484 refs->decWeak(mProcess.get());
485 }
486 mPendingWeakDerefs.clear();
487 }
488
489 numPending = mPendingStrongDerefs.size();
490 if (numPending > 0) {
491 for (size_t i = 0; i < numPending; i++) {
492 BBinder* obj = mPendingStrongDerefs[i];
493 obj->decStrong(mProcess.get());
494 }
495 mPendingStrongDerefs.clear();
496 }
497 }
498}
499
Mathias Agopian7922fa22009-05-18 15:08:03 -0700500void IPCThreadState::joinThreadPool(bool isMain)
501{
502 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
503
504 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
505
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800506 // This thread may have been spawned by a thread that was in the background
Glenn Kastencb5e2422012-03-16 07:15:23 -0700507 // scheduling group, so first we will make sure it is in the foreground
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800508 // one to avoid performing an initial transaction in the background.
Glenn Kastencb5e2422012-03-16 07:15:23 -0700509 set_sched_policy(mMyThreadId, SP_FOREGROUND);
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800510
Mathias Agopian7922fa22009-05-18 15:08:03 -0700511 status_t result;
512 do {
Todd Poynor0646cb02013-06-25 19:12:18 -0700513 processPendingDerefs();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700514 // now get the next command to be processed, waiting if necessary
Todd Poynor0646cb02013-06-25 19:12:18 -0700515 result = getAndExecuteCommand();
Jason Parks2b17f142009-11-03 12:14:38 -0800516
Todd Poynor0646cb02013-06-25 19:12:18 -0700517 if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
518 ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
Jeff Tinkeree711ec2013-06-11 11:30:21 -0700519 mProcess->mDriverFD, result);
520 abort();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700521 }
522
Mathias Agopian7922fa22009-05-18 15:08:03 -0700523 // Let this thread exit the thread pool if it is no longer
524 // needed and it is not the main process thread.
525 if(result == TIMED_OUT && !isMain) {
526 break;
527 }
528 } while (result != -ECONNREFUSED && result != -EBADF);
529
530 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
531 (void*)pthread_self(), getpid(), (void*)result);
532
533 mOut.writeInt32(BC_EXIT_LOOPER);
534 talkWithDriver(false);
535}
536
Todd Poynor0646cb02013-06-25 19:12:18 -0700537int IPCThreadState::setupPolling(int* fd)
538{
539 if (mProcess->mDriverFD <= 0) {
540 return -EBADF;
541 }
542
543 mOut.writeInt32(BC_ENTER_LOOPER);
544 *fd = mProcess->mDriverFD;
545 return 0;
546}
547
548status_t IPCThreadState::handlePolledCommands()
549{
550 status_t result;
551
552 do {
553 result = getAndExecuteCommand();
554 } while (mIn.dataPosition() < mIn.dataSize());
555
556 processPendingDerefs();
557 flushCommands();
558 return result;
559}
560
Colin Crossf0487982014-02-05 17:42:44 -0800561void IPCThreadState::stopProcess(bool /*immediate*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700562{
Steve Block93cf8542012-01-04 20:05:49 +0000563 //ALOGI("**** STOPPING PROCESS");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700564 flushCommands();
565 int fd = mProcess->mDriverFD;
566 mProcess->mDriverFD = -1;
567 close(fd);
568 //kill(getpid(), SIGKILL);
569}
570
571status_t IPCThreadState::transact(int32_t handle,
572 uint32_t code, const Parcel& data,
573 Parcel* reply, uint32_t flags)
574{
575 status_t err = data.errorCheck();
576
577 flags |= TF_ACCEPT_FDS;
578
579 IF_LOG_TRANSACTIONS() {
580 TextOutput::Bundle _b(alog);
581 alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
582 << handle << " / code " << TypeCode(code) << ": "
583 << indent << data << dedent << endl;
584 }
585
586 if (err == NO_ERROR) {
587 LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
588 (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
589 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
590 }
591
592 if (err != NO_ERROR) {
593 if (reply) reply->setError(err);
594 return (mLastError = err);
595 }
596
597 if ((flags & TF_ONE_WAY) == 0) {
Dianne Hackborn98878262010-09-24 11:16:23 -0700598 #if 0
599 if (code == 4) { // relayout
Steve Block93cf8542012-01-04 20:05:49 +0000600 ALOGI(">>>>>> CALLING transaction 4");
Dianne Hackborn98878262010-09-24 11:16:23 -0700601 } else {
Steve Block93cf8542012-01-04 20:05:49 +0000602 ALOGI(">>>>>> CALLING transaction %d", code);
Dianne Hackborn98878262010-09-24 11:16:23 -0700603 }
604 #endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700605 if (reply) {
606 err = waitForResponse(reply);
607 } else {
608 Parcel fakeReply;
609 err = waitForResponse(&fakeReply);
610 }
Dianne Hackborn98878262010-09-24 11:16:23 -0700611 #if 0
612 if (code == 4) { // relayout
Steve Block93cf8542012-01-04 20:05:49 +0000613 ALOGI("<<<<<< RETURNING transaction 4");
Dianne Hackborn98878262010-09-24 11:16:23 -0700614 } else {
Steve Block93cf8542012-01-04 20:05:49 +0000615 ALOGI("<<<<<< RETURNING transaction %d", code);
Dianne Hackborn98878262010-09-24 11:16:23 -0700616 }
617 #endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700618
619 IF_LOG_TRANSACTIONS() {
620 TextOutput::Bundle _b(alog);
621 alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
622 << handle << ": ";
623 if (reply) alog << indent << *reply << dedent << endl;
624 else alog << "(none requested)" << endl;
625 }
626 } else {
627 err = waitForResponse(NULL, NULL);
628 }
629
630 return err;
631}
632
633void IPCThreadState::incStrongHandle(int32_t handle)
634{
635 LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
636 mOut.writeInt32(BC_ACQUIRE);
637 mOut.writeInt32(handle);
638}
639
640void IPCThreadState::decStrongHandle(int32_t handle)
641{
642 LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
643 mOut.writeInt32(BC_RELEASE);
644 mOut.writeInt32(handle);
645}
646
647void IPCThreadState::incWeakHandle(int32_t handle)
648{
649 LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
650 mOut.writeInt32(BC_INCREFS);
651 mOut.writeInt32(handle);
652}
653
654void IPCThreadState::decWeakHandle(int32_t handle)
655{
656 LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
657 mOut.writeInt32(BC_DECREFS);
658 mOut.writeInt32(handle);
659}
660
661status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
662{
Arve Hjønnevåg304dcae2014-02-14 20:14:02 -0800663#if HAS_BC_ATTEMPT_ACQUIRE
Andy McFadden457d51f2011-08-31 07:43:40 -0700664 LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700665 mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
666 mOut.writeInt32(0); // xxx was thread priority
667 mOut.writeInt32(handle);
668 status_t result = UNKNOWN_ERROR;
669
670 waitForResponse(NULL, &result);
671
672#if LOG_REFCOUNTS
673 printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
674 handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
675#endif
676
677 return result;
Arve Hjønnevåg304dcae2014-02-14 20:14:02 -0800678#else
679 (void)handle;
680 ALOGE("%s(%d): Not supported\n", __func__, handle);
681 return INVALID_OPERATION;
682#endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700683}
684
685void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
686{
687#if LOG_REFCOUNTS
688 printf("IPCThreadState::expungeHandle(%ld)\n", handle);
689#endif
690 self()->mProcess->expungeHandle(handle, binder);
691}
692
693status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
694{
695 mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
696 mOut.writeInt32((int32_t)handle);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000697 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700698 return NO_ERROR;
699}
700
701status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
702{
703 mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
704 mOut.writeInt32((int32_t)handle);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000705 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700706 return NO_ERROR;
707}
708
709IPCThreadState::IPCThreadState()
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700710 : mProcess(ProcessState::self()),
Elliott Hughes07cf48a2014-08-18 10:38:38 -0700711 mMyThreadId(gettid()),
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700712 mStrictModePolicy(0),
713 mLastTransactionBinderFlags(0)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700714{
715 pthread_setspecific(gTLS, this);
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800716 clearCaller();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700717 mIn.setDataCapacity(256);
718 mOut.setDataCapacity(256);
719}
720
721IPCThreadState::~IPCThreadState()
722{
723}
724
725status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
726{
727 status_t err;
728 status_t statusBuffer;
729 err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
730 if (err < NO_ERROR) return err;
731
732 return waitForResponse(NULL, NULL);
733}
734
735status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
736{
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100737 uint32_t cmd;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700738 int32_t err;
739
740 while (1) {
741 if ((err=talkWithDriver()) < NO_ERROR) break;
742 err = mIn.errorCheck();
743 if (err < NO_ERROR) break;
744 if (mIn.dataAvail() == 0) continue;
745
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100746 cmd = (uint32_t)mIn.readInt32();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700747
748 IF_LOG_COMMANDS() {
749 alog << "Processing waitForResponse Command: "
750 << getReturnString(cmd) << endl;
751 }
752
753 switch (cmd) {
754 case BR_TRANSACTION_COMPLETE:
755 if (!reply && !acquireResult) goto finish;
756 break;
757
758 case BR_DEAD_REPLY:
759 err = DEAD_OBJECT;
760 goto finish;
761
762 case BR_FAILED_REPLY:
763 err = FAILED_TRANSACTION;
764 goto finish;
765
766 case BR_ACQUIRE_RESULT:
767 {
Steve Blockd0bfabc2012-01-09 18:35:44 +0000768 ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700769 const int32_t result = mIn.readInt32();
770 if (!acquireResult) continue;
771 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
772 }
773 goto finish;
774
775 case BR_REPLY:
776 {
777 binder_transaction_data tr;
778 err = mIn.read(&tr, sizeof(tr));
Steve Blockd0bfabc2012-01-09 18:35:44 +0000779 ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700780 if (err != NO_ERROR) goto finish;
781
782 if (reply) {
783 if ((tr.flags & TF_STATUS_CODE) == 0) {
784 reply->ipcSetDataReference(
785 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
786 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800787 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
788 tr.offsets_size/sizeof(binder_size_t),
Mathias Agopian7922fa22009-05-18 15:08:03 -0700789 freeBuffer, this);
790 } else {
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800791 err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700792 freeBuffer(NULL,
793 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
794 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800795 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
796 tr.offsets_size/sizeof(binder_size_t), this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700797 }
798 } else {
799 freeBuffer(NULL,
800 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
801 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800802 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
803 tr.offsets_size/sizeof(binder_size_t), this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700804 continue;
805 }
806 }
807 goto finish;
808
809 default:
810 err = executeCommand(cmd);
811 if (err != NO_ERROR) goto finish;
812 break;
813 }
814 }
815
816finish:
817 if (err != NO_ERROR) {
818 if (acquireResult) *acquireResult = err;
819 if (reply) reply->setError(err);
820 mLastError = err;
821 }
822
823 return err;
824}
825
826status_t IPCThreadState::talkWithDriver(bool doReceive)
827{
Johannes Carlsson597a3c72011-02-17 14:06:53 +0100828 if (mProcess->mDriverFD <= 0) {
829 return -EBADF;
830 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700831
832 binder_write_read bwr;
833
834 // Is the read buffer empty?
835 const bool needRead = mIn.dataPosition() >= mIn.dataSize();
836
837 // We don't want to write anything if we are still reading
838 // from data left in the input buffer and the caller
839 // has requested to read the next data.
840 const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
841
842 bwr.write_size = outAvail;
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800843 bwr.write_buffer = (uintptr_t)mOut.data();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700844
845 // This is what we'll read.
846 if (doReceive && needRead) {
847 bwr.read_size = mIn.dataCapacity();
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800848 bwr.read_buffer = (uintptr_t)mIn.data();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700849 } else {
850 bwr.read_size = 0;
Ben Cheng455a70a2011-12-01 17:11:32 -0800851 bwr.read_buffer = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700852 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700853
Mathias Agopian7922fa22009-05-18 15:08:03 -0700854 IF_LOG_COMMANDS() {
855 TextOutput::Bundle _b(alog);
856 if (outAvail != 0) {
857 alog << "Sending commands to driver: " << indent;
858 const void* cmds = (const void*)bwr.write_buffer;
859 const void* end = ((const uint8_t*)cmds)+bwr.write_size;
860 alog << HexDump(cmds, bwr.write_size) << endl;
861 while (cmds < end) cmds = printCommand(alog, cmds);
862 alog << dedent;
863 }
864 alog << "Size of receive buffer: " << bwr.read_size
865 << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
866 }
867
868 // Return immediately if there is nothing to do.
869 if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
Andy McFadden457d51f2011-08-31 07:43:40 -0700870
Mathias Agopian7922fa22009-05-18 15:08:03 -0700871 bwr.write_consumed = 0;
872 bwr.read_consumed = 0;
873 status_t err;
874 do {
875 IF_LOG_COMMANDS() {
876 alog << "About to read/write, write size = " << mOut.dataSize() << endl;
877 }
Elliott Hughese5e70552015-08-12 15:27:47 -0700878#if defined(__ANDROID__)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700879 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
880 err = NO_ERROR;
881 else
882 err = -errno;
883#else
884 err = INVALID_OPERATION;
885#endif
Johannes Carlsson597a3c72011-02-17 14:06:53 +0100886 if (mProcess->mDriverFD <= 0) {
887 err = -EBADF;
888 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700889 IF_LOG_COMMANDS() {
890 alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
891 }
892 } while (err == -EINTR);
Andy McFadden457d51f2011-08-31 07:43:40 -0700893
Mathias Agopian7922fa22009-05-18 15:08:03 -0700894 IF_LOG_COMMANDS() {
Colin Crossf0487982014-02-05 17:42:44 -0800895 alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
Mathias Agopian7922fa22009-05-18 15:08:03 -0700896 << bwr.write_consumed << " (of " << mOut.dataSize()
Todd Poynor0646cb02013-06-25 19:12:18 -0700897 << "), read consumed: " << bwr.read_consumed << endl;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700898 }
899
900 if (err >= NO_ERROR) {
901 if (bwr.write_consumed > 0) {
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800902 if (bwr.write_consumed < mOut.dataSize())
Mathias Agopian7922fa22009-05-18 15:08:03 -0700903 mOut.remove(0, bwr.write_consumed);
904 else
905 mOut.setDataSize(0);
906 }
907 if (bwr.read_consumed > 0) {
908 mIn.setDataSize(bwr.read_consumed);
909 mIn.setDataPosition(0);
910 }
911 IF_LOG_COMMANDS() {
912 TextOutput::Bundle _b(alog);
913 alog << "Remaining data size: " << mOut.dataSize() << endl;
914 alog << "Received commands from driver: " << indent;
915 const void* cmds = mIn.data();
916 const void* end = mIn.data() + mIn.dataSize();
917 alog << HexDump(cmds, mIn.dataSize()) << endl;
918 while (cmds < end) cmds = printReturnCommand(alog, cmds);
919 alog << dedent;
920 }
921 return NO_ERROR;
922 }
923
924 return err;
925}
926
927status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
928 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
929{
930 binder_transaction_data tr;
931
Arve Hjønnevågea8e05d2014-02-18 21:10:29 -0800932 tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
Mathias Agopian7922fa22009-05-18 15:08:03 -0700933 tr.target.handle = handle;
934 tr.code = code;
935 tr.flags = binderFlags;
Evgeniy Stepanov68c8a652011-04-21 14:15:00 +0400936 tr.cookie = 0;
937 tr.sender_pid = 0;
938 tr.sender_euid = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700939
940 const status_t err = data.errorCheck();
941 if (err == NO_ERROR) {
942 tr.data_size = data.ipcDataSize();
943 tr.data.ptr.buffer = data.ipcData();
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800944 tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700945 tr.data.ptr.offsets = data.ipcObjects();
946 } else if (statusBuffer) {
947 tr.flags |= TF_STATUS_CODE;
948 *statusBuffer = err;
949 tr.data_size = sizeof(status_t);
Arve Hjønnevåg4bdf7e92014-02-18 21:04:31 -0800950 tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700951 tr.offsets_size = 0;
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800952 tr.data.ptr.offsets = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700953 } else {
954 return (mLastError = err);
955 }
956
957 mOut.writeInt32(cmd);
958 mOut.write(&tr, sizeof(tr));
959
960 return NO_ERROR;
961}
962
Martijn Coenena660cbc2016-05-12 11:29:23 +0200963void IPCThreadState::setTheContextObject(sp<BBinder> obj)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700964{
Martijn Coenena660cbc2016-05-12 11:29:23 +0200965 mContextObject = obj;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700966}
967
968status_t IPCThreadState::executeCommand(int32_t cmd)
969{
970 BBinder* obj;
971 RefBase::weakref_type* refs;
972 status_t result = NO_ERROR;
Bernhard Rosenkränzerb184ed02014-11-25 21:55:33 +0100973 switch ((uint32_t)cmd) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700974 case BR_ERROR:
975 result = mIn.readInt32();
976 break;
977
978 case BR_OK:
979 break;
980
981 case BR_ACQUIRE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000982 refs = (RefBase::weakref_type*)mIn.readPointer();
983 obj = (BBinder*)mIn.readPointer();
Steve Blockd0bfabc2012-01-09 18:35:44 +0000984 ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -0700985 "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
986 refs, obj, refs->refBase());
987 obj->incStrong(mProcess.get());
988 IF_LOG_REMOTEREFS() {
989 LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
990 obj->printRefs();
991 }
992 mOut.writeInt32(BC_ACQUIRE_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000993 mOut.writePointer((uintptr_t)refs);
994 mOut.writePointer((uintptr_t)obj);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700995 break;
996
997 case BR_RELEASE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000998 refs = (RefBase::weakref_type*)mIn.readPointer();
999 obj = (BBinder*)mIn.readPointer();
Steve Blockd0bfabc2012-01-09 18:35:44 +00001000 ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001001 "BR_RELEASE: object %p does not match cookie %p (expected %p)",
1002 refs, obj, refs->refBase());
1003 IF_LOG_REMOTEREFS() {
1004 LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
1005 obj->printRefs();
1006 }
1007 mPendingStrongDerefs.push(obj);
1008 break;
1009
1010 case BR_INCREFS:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001011 refs = (RefBase::weakref_type*)mIn.readPointer();
1012 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001013 refs->incWeak(mProcess.get());
1014 mOut.writeInt32(BC_INCREFS_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001015 mOut.writePointer((uintptr_t)refs);
1016 mOut.writePointer((uintptr_t)obj);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001017 break;
1018
1019 case BR_DECREFS:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001020 refs = (RefBase::weakref_type*)mIn.readPointer();
1021 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001022 // NOTE: This assertion is not valid, because the object may no
1023 // longer exist (thus the (BBinder*)cast above resulting in a different
1024 // memory address).
Steve Blockd0bfabc2012-01-09 18:35:44 +00001025 //ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001026 // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
1027 // refs, obj, refs->refBase());
1028 mPendingWeakDerefs.push(refs);
1029 break;
1030
1031 case BR_ATTEMPT_ACQUIRE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001032 refs = (RefBase::weakref_type*)mIn.readPointer();
1033 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001034
1035 {
1036 const bool success = refs->attemptIncStrong(mProcess.get());
Steve Blockd0bfabc2012-01-09 18:35:44 +00001037 ALOG_ASSERT(success && refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001038 "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
1039 refs, obj, refs->refBase());
1040
1041 mOut.writeInt32(BC_ACQUIRE_RESULT);
1042 mOut.writeInt32((int32_t)success);
1043 }
1044 break;
1045
1046 case BR_TRANSACTION:
1047 {
1048 binder_transaction_data tr;
1049 result = mIn.read(&tr, sizeof(tr));
Steve Blockd0bfabc2012-01-09 18:35:44 +00001050 ALOG_ASSERT(result == NO_ERROR,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001051 "Not enough command data for brTRANSACTION");
1052 if (result != NO_ERROR) break;
1053
1054 Parcel buffer;
1055 buffer.ipcSetDataReference(
1056 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
1057 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -08001058 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
1059 tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001060
1061 const pid_t origPid = mCallingPid;
1062 const uid_t origUid = mCallingUid;
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001063 const int32_t origStrictModePolicy = mStrictModePolicy;
1064 const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
1065
Mathias Agopian7922fa22009-05-18 15:08:03 -07001066 mCallingPid = tr.sender_pid;
1067 mCallingUid = tr.sender_euid;
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001068 mLastTransactionBinderFlags = tr.flags;
1069
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001070 int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
1071 if (gDisableBackgroundScheduling) {
1072 if (curPrio > ANDROID_PRIORITY_NORMAL) {
1073 // We have inherited a reduced priority from the caller, but do not
1074 // want to run in that state in this process. The driver set our
1075 // priority already (though not our scheduling class), so bounce
1076 // it back to the default before invoking the transaction.
1077 setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
1078 }
1079 } else {
1080 if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
1081 // We want to use the inherited priority from the caller.
1082 // Ensure this thread is in the background scheduling class,
1083 // since the driver won't modify scheduling classes for us.
1084 // The scheduling group is reset to default by the caller
1085 // once this method returns after the transaction is complete.
Glenn Kastencb5e2422012-03-16 07:15:23 -07001086 set_sched_policy(mMyThreadId, SP_BACKGROUND);
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001087 }
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -08001088 }
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001089
Steve Block93cf8542012-01-04 20:05:49 +00001090 //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001091
Mathias Agopian7922fa22009-05-18 15:08:03 -07001092 Parcel reply;
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001093 status_t error;
Martijn Coenen79c2f4d2016-05-20 10:55:59 +02001094 bool reply_sent = false;
Mathias Agopian7922fa22009-05-18 15:08:03 -07001095 IF_LOG_TRANSACTIONS() {
1096 TextOutput::Bundle _b(alog);
1097 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
1098 << " / obj " << tr.target.ptr << " / code "
1099 << TypeCode(tr.code) << ": " << indent << buffer
1100 << dedent << endl
1101 << "Data addr = "
1102 << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
1103 << ", offsets addr="
1104 << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
1105 }
Martijn Coenen79c2f4d2016-05-20 10:55:59 +02001106
1107 auto reply_callback = [&] (auto &replyParcel) {
1108 if (reply_sent) {
1109 // Reply was sent earlier, ignore it.
1110 ALOGE("Dropping binder reply, it was sent already.");
1111 return;
1112 }
1113 reply_sent = true;
1114 if ((tr.flags & TF_ONE_WAY) == 0) {
1115 replyParcel.setError(NO_ERROR);
1116 sendReply(replyParcel, 0);
1117 } else {
1118 ALOGE("Not sending reply in one-way transaction");
1119 }
1120 };
1121
Mathias Agopian7922fa22009-05-18 15:08:03 -07001122 if (tr.target.ptr) {
Dianne Hackborn839f7072016-03-21 10:36:54 -07001123 // We only have a weak reference on the target object, so we must first try to
1124 // safely acquire a strong reference before doing anything else with it.
1125 if (reinterpret_cast<RefBase::weakref_type*>(
1126 tr.target.ptr)->attemptIncStrong(this)) {
1127 error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
Martijn Coenen79c2f4d2016-05-20 10:55:59 +02001128 &reply, tr.flags, reply_callback);
Dianne Hackborn839f7072016-03-21 10:36:54 -07001129 reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
1130 } else {
1131 error = UNKNOWN_TRANSACTION;
1132 }
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -07001133
Mathias Agopian7922fa22009-05-18 15:08:03 -07001134 } else {
Martijn Coenena660cbc2016-05-12 11:29:23 +02001135 error = mContextObject->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
Martijn Coenen79c2f4d2016-05-20 10:55:59 +02001136 }
1137
1138 if ((tr.flags & TF_ONE_WAY) == 0) {
1139 if (!reply_sent) {
1140 // Should have been a reply but there wasn't, so there
1141 // must have been an error instead.
1142 reply.setError(error);
1143 sendReply(reply, 0);
1144 } else {
1145 if (error != NO_ERROR) {
1146 ALOGE("transact() returned error after sending reply.");
1147 } else {
1148 // Ok, reply sent and transact didn't return an error.
1149 }
1150 }
1151 } else {
1152 // One-way transaction, don't care about return value or reply.
Mathias Agopian7922fa22009-05-18 15:08:03 -07001153 }
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001154
Steve Block93cf8542012-01-04 20:05:49 +00001155 //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
Mathias Agopian7922fa22009-05-18 15:08:03 -07001156 // mCallingPid, origPid, origUid);
Martijn Coenen79c2f4d2016-05-20 10:55:59 +02001157
Mathias Agopian7922fa22009-05-18 15:08:03 -07001158
1159 mCallingPid = origPid;
1160 mCallingUid = origUid;
Dianne Hackbornf99aec62014-09-30 11:30:03 -07001161 mStrictModePolicy = origStrictModePolicy;
1162 mLastTransactionBinderFlags = origTransactionBinderFlags;
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001163
Mathias Agopian7922fa22009-05-18 15:08:03 -07001164 IF_LOG_TRANSACTIONS() {
1165 TextOutput::Bundle _b(alog);
1166 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
1167 << tr.target.ptr << ": " << indent << reply << dedent << endl;
1168 }
1169
1170 }
1171 break;
1172
1173 case BR_DEAD_BINDER:
1174 {
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001175 BpBinder *proxy = (BpBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001176 proxy->sendObituary();
1177 mOut.writeInt32(BC_DEAD_BINDER_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001178 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001179 } break;
1180
1181 case BR_CLEAR_DEATH_NOTIFICATION_DONE:
1182 {
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001183 BpBinder *proxy = (BpBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001184 proxy->getWeakRefs()->decWeak(proxy);
1185 } break;
1186
1187 case BR_FINISHED:
1188 result = TIMED_OUT;
1189 break;
1190
1191 case BR_NOOP:
1192 break;
1193
1194 case BR_SPAWN_LOOPER:
1195 mProcess->spawnPooledThread(false);
1196 break;
1197
1198 default:
1199 printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
1200 result = UNKNOWN_ERROR;
1201 break;
1202 }
1203
1204 if (result != NO_ERROR) {
1205 mLastError = result;
1206 }
1207
1208 return result;
1209}
1210
1211void IPCThreadState::threadDestructor(void *st)
1212{
Todd Poynor0646cb02013-06-25 19:12:18 -07001213 IPCThreadState* const self = static_cast<IPCThreadState*>(st);
1214 if (self) {
1215 self->flushCommands();
Elliott Hughese5e70552015-08-12 15:27:47 -07001216#if defined(__ANDROID__)
Johannes Carlsson597a3c72011-02-17 14:06:53 +01001217 if (self->mProcess->mDriverFD > 0) {
1218 ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1219 }
Mathias Agopian7922fa22009-05-18 15:08:03 -07001220#endif
Todd Poynor0646cb02013-06-25 19:12:18 -07001221 delete self;
1222 }
Mathias Agopian7922fa22009-05-18 15:08:03 -07001223}
1224
1225
Colin Crossf0487982014-02-05 17:42:44 -08001226void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
1227 size_t /*dataSize*/,
1228 const binder_size_t* /*objects*/,
1229 size_t /*objectsSize*/, void* /*cookie*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -07001230{
Steve Block93cf8542012-01-04 20:05:49 +00001231 //ALOGI("Freeing parcel %p", &parcel);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001232 IF_LOG_COMMANDS() {
1233 alog << "Writing BC_FREE_BUFFER for " << data << endl;
1234 }
Steve Blockd0bfabc2012-01-09 18:35:44 +00001235 ALOG_ASSERT(data != NULL, "Called with NULL data");
Mathias Agopian7922fa22009-05-18 15:08:03 -07001236 if (parcel != NULL) parcel->closeFileDescriptors();
1237 IPCThreadState* state = self();
1238 state->mOut.writeInt32(BC_FREE_BUFFER);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001239 state->mOut.writePointer((uintptr_t)data);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001240}
1241
Martijn Coenene01f4f22016-05-12 12:33:28 +02001242}; // namespace hidl
Mathias Agopian7922fa22009-05-18 15:08:03 -07001243}; // namespace android