blob: 81833036097b1a3fa4930ed20695326ae3242cc6 [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
Mathias Agopian16475702009-05-19 19:08:10 -070019#include <binder/IPCThreadState.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070020
Mathias Agopian16475702009-05-19 19:08:10 -070021#include <binder/Binder.h>
22#include <binder/BpBinder.h>
Mathias Agopian4ea13dc2013-05-06 20:20:50 -070023#include <binder/TextOutput.h>
24
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>
Mathias Agopian7922fa22009-05-18 15:08:03 -070027#include <utils/threads.h>
28
29#include <private/binder/binder_module.h>
30#include <private/binder/Static.h>
31
32#include <sys/ioctl.h>
33#include <signal.h>
34#include <errno.h>
35#include <stdio.h>
36#include <unistd.h>
37
38#ifdef HAVE_PTHREADS
39#include <pthread.h>
40#include <sched.h>
41#include <sys/resource.h>
42#endif
43#ifdef HAVE_WIN32_THREADS
44#include <windows.h>
45#endif
46
47
48#if LOG_NDEBUG
49
50#define IF_LOG_TRANSACTIONS() if (false)
51#define IF_LOG_COMMANDS() if (false)
52#define LOG_REMOTEREFS(...)
53#define IF_LOG_REMOTEREFS() if (false)
54#define LOG_THREADPOOL(...)
55#define LOG_ONEWAY(...)
56
57#else
58
Steve Block5854b912011-10-12 17:27:03 +010059#define IF_LOG_TRANSACTIONS() IF_ALOG(LOG_VERBOSE, "transact")
60#define IF_LOG_COMMANDS() IF_ALOG(LOG_VERBOSE, "ipc")
61#define LOG_REMOTEREFS(...) ALOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
62#define IF_LOG_REMOTEREFS() IF_ALOG(LOG_DEBUG, "remoterefs")
63#define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
64#define LOG_ONEWAY(...) ALOG(LOG_DEBUG, "ipc", __VA_ARGS__)
Mathias Agopian7922fa22009-05-18 15:08:03 -070065
66#endif
67
68// ---------------------------------------------------------------------------
69
70namespace android {
71
72static const char* getReturnString(size_t idx);
73static const char* getCommandString(size_t idx);
74static const void* printReturnCommand(TextOutput& out, const void* _cmd);
75static const void* printCommand(TextOutput& out, const void* _cmd);
76
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -070077// Static const and functions will be optimized out if not used,
78// when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
Mathias Agopian7922fa22009-05-18 15:08:03 -070079static const char *kReturnStrings[] = {
Andy McFadden457d51f2011-08-31 07:43:40 -070080 "BR_ERROR",
Mathias Agopian7922fa22009-05-18 15:08:03 -070081 "BR_OK",
Mathias Agopian7922fa22009-05-18 15:08:03 -070082 "BR_TRANSACTION",
83 "BR_REPLY",
84 "BR_ACQUIRE_RESULT",
85 "BR_DEAD_REPLY",
86 "BR_TRANSACTION_COMPLETE",
87 "BR_INCREFS",
88 "BR_ACQUIRE",
89 "BR_RELEASE",
90 "BR_DECREFS",
91 "BR_ATTEMPT_ACQUIRE",
Mathias Agopian7922fa22009-05-18 15:08:03 -070092 "BR_NOOP",
93 "BR_SPAWN_LOOPER",
94 "BR_FINISHED",
95 "BR_DEAD_BINDER",
Andy McFadden457d51f2011-08-31 07:43:40 -070096 "BR_CLEAR_DEATH_NOTIFICATION_DONE",
97 "BR_FAILED_REPLY"
Mathias Agopian7922fa22009-05-18 15:08:03 -070098};
99
100static const char *kCommandStrings[] = {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700101 "BC_TRANSACTION",
102 "BC_REPLY",
103 "BC_ACQUIRE_RESULT",
104 "BC_FREE_BUFFER",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700105 "BC_INCREFS",
106 "BC_ACQUIRE",
107 "BC_RELEASE",
108 "BC_DECREFS",
109 "BC_INCREFS_DONE",
110 "BC_ACQUIRE_DONE",
111 "BC_ATTEMPT_ACQUIRE",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700112 "BC_REGISTER_LOOPER",
113 "BC_ENTER_LOOPER",
114 "BC_EXIT_LOOPER",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700115 "BC_REQUEST_DEATH_NOTIFICATION",
116 "BC_CLEAR_DEATH_NOTIFICATION",
117 "BC_DEAD_BINDER_DONE"
Mathias Agopian7922fa22009-05-18 15:08:03 -0700118};
119
120static const char* getReturnString(size_t idx)
121{
122 if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
123 return kReturnStrings[idx];
124 else
125 return "unknown";
126}
127
128static const char* getCommandString(size_t idx)
129{
130 if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
131 return kCommandStrings[idx];
132 else
133 return "unknown";
134}
135
136static const void* printBinderTransactionData(TextOutput& out, const void* data)
137{
138 const binder_transaction_data* btd =
139 (const binder_transaction_data*)data;
Andy McFadden457d51f2011-08-31 07:43:40 -0700140 if (btd->target.handle < 1024) {
141 /* want to print descriptors in decimal; guess based on value */
142 out << "target.desc=" << btd->target.handle;
143 } else {
144 out << "target.ptr=" << btd->target.ptr;
145 }
146 out << " (cookie " << btd->cookie << ")" << endl
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700147 << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
Mathias Agopian7922fa22009-05-18 15:08:03 -0700148 << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
149 << " bytes)" << endl
150 << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
Andy McFadden457d51f2011-08-31 07:43:40 -0700151 << " bytes)";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700152 return btd+1;
153}
154
155static const void* printReturnCommand(TextOutput& out, const void* _cmd)
156{
Andy McFadden457d51f2011-08-31 07:43:40 -0700157 static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700158 const int32_t* cmd = (const int32_t*)_cmd;
159 int32_t code = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700160 size_t cmdIndex = code & 0xff;
161 if (code == (int32_t) BR_ERROR) {
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700162 out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700163 return cmd;
Andy McFadden457d51f2011-08-31 07:43:40 -0700164 } else if (cmdIndex >= N) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700165 out << "Unknown reply: " << code << endl;
166 return cmd;
167 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700168 out << kReturnStrings[cmdIndex];
Mathias Agopian7922fa22009-05-18 15:08:03 -0700169
Mathias Agopian7922fa22009-05-18 15:08:03 -0700170 switch (code) {
171 case BR_TRANSACTION:
172 case BR_REPLY: {
173 out << ": " << indent;
174 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
175 out << dedent;
176 } break;
177
178 case BR_ACQUIRE_RESULT: {
179 const int32_t res = *cmd++;
180 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
181 } break;
182
183 case BR_INCREFS:
184 case BR_ACQUIRE:
185 case BR_RELEASE:
186 case BR_DECREFS: {
187 const int32_t b = *cmd++;
188 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700189 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700190 } break;
191
192 case BR_ATTEMPT_ACQUIRE: {
193 const int32_t p = *cmd++;
194 const int32_t b = *cmd++;
195 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700196 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
Mathias Agopian7922fa22009-05-18 15:08:03 -0700197 << "), pri=" << p;
198 } break;
199
200 case BR_DEAD_BINDER:
201 case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
202 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700203 out << ": death cookie " << (void*)(long)c;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700204 } break;
Andy McFadden457d51f2011-08-31 07:43:40 -0700205
206 default:
207 // no details to show for: BR_OK, BR_DEAD_REPLY,
208 // BR_TRANSACTION_COMPLETE, BR_FINISHED
209 break;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700210 }
211
212 out << endl;
213 return cmd;
214}
215
216static const void* printCommand(TextOutput& out, const void* _cmd)
217{
Andy McFadden457d51f2011-08-31 07:43:40 -0700218 static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700219 const int32_t* cmd = (const int32_t*)_cmd;
220 int32_t code = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700221 size_t cmdIndex = code & 0xff;
222
223 if (cmdIndex >= N) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700224 out << "Unknown command: " << code << endl;
225 return cmd;
226 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700227 out << kCommandStrings[cmdIndex];
228
Mathias Agopian7922fa22009-05-18 15:08:03 -0700229 switch (code) {
230 case BC_TRANSACTION:
231 case BC_REPLY: {
232 out << ": " << indent;
233 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
234 out << dedent;
235 } break;
236
237 case BC_ACQUIRE_RESULT: {
238 const int32_t res = *cmd++;
239 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
240 } break;
241
242 case BC_FREE_BUFFER: {
243 const int32_t buf = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700244 out << ": buffer=" << (void*)(long)buf;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700245 } break;
246
247 case BC_INCREFS:
248 case BC_ACQUIRE:
249 case BC_RELEASE:
250 case BC_DECREFS: {
251 const int32_t d = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700252 out << ": desc=" << d;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700253 } break;
254
255 case BC_INCREFS_DONE:
256 case BC_ACQUIRE_DONE: {
257 const int32_t b = *cmd++;
258 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700259 out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700260 } break;
261
262 case BC_ATTEMPT_ACQUIRE: {
263 const int32_t p = *cmd++;
264 const int32_t d = *cmd++;
Andy McFadden457d51f2011-08-31 07:43:40 -0700265 out << ": desc=" << d << ", pri=" << p;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700266 } break;
267
268 case BC_REQUEST_DEATH_NOTIFICATION:
269 case BC_CLEAR_DEATH_NOTIFICATION: {
270 const int32_t h = *cmd++;
271 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700272 out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
Mathias Agopian7922fa22009-05-18 15:08:03 -0700273 } break;
274
275 case BC_DEAD_BINDER_DONE: {
276 const int32_t c = *cmd++;
Chih-Hung Hsieh30dcad72014-10-24 14:10:09 -0700277 out << ": death cookie " << (void*)(long)c;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700278 } break;
Andy McFadden457d51f2011-08-31 07:43:40 -0700279
280 default:
281 // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
282 // BC_EXIT_LOOPER
283 break;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700284 }
285
286 out << endl;
287 return cmd;
288}
Mathias Agopian7922fa22009-05-18 15:08:03 -0700289
290static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
291static bool gHaveTLS = false;
292static pthread_key_t gTLS = 0;
293static bool gShutdown = false;
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800294static bool gDisableBackgroundScheduling = false;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700295
296IPCThreadState* IPCThreadState::self()
297{
298 if (gHaveTLS) {
299restart:
300 const pthread_key_t k = gTLS;
301 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
302 if (st) return st;
303 return new IPCThreadState;
304 }
305
306 if (gShutdown) return NULL;
307
308 pthread_mutex_lock(&gTLSMutex);
309 if (!gHaveTLS) {
310 if (pthread_key_create(&gTLS, threadDestructor) != 0) {
311 pthread_mutex_unlock(&gTLSMutex);
312 return NULL;
313 }
314 gHaveTLS = true;
315 }
316 pthread_mutex_unlock(&gTLSMutex);
317 goto restart;
318}
319
Brad Fitzpatrick77949942010-12-13 16:52:35 -0800320IPCThreadState* IPCThreadState::selfOrNull()
321{
322 if (gHaveTLS) {
323 const pthread_key_t k = gTLS;
324 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
325 return st;
326 }
327 return NULL;
328}
329
Mathias Agopian7922fa22009-05-18 15:08:03 -0700330void IPCThreadState::shutdown()
331{
332 gShutdown = true;
333
334 if (gHaveTLS) {
335 // XXX Need to wait for all thread pool threads to exit!
336 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
337 if (st) {
338 delete st;
339 pthread_setspecific(gTLS, NULL);
340 }
341 gHaveTLS = false;
342 }
343}
344
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800345void IPCThreadState::disableBackgroundScheduling(bool disable)
346{
347 gDisableBackgroundScheduling = disable;
348}
349
Mathias Agopian7922fa22009-05-18 15:08:03 -0700350sp<ProcessState> IPCThreadState::process()
351{
352 return mProcess;
353}
354
355status_t IPCThreadState::clearLastError()
356{
357 const status_t err = mLastError;
358 mLastError = NO_ERROR;
359 return err;
360}
361
Jeff Brownb699a792013-07-12 16:32:00 -0700362int IPCThreadState::getCallingPid() const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700363{
364 return mCallingPid;
365}
366
Jeff Brownb699a792013-07-12 16:32:00 -0700367int IPCThreadState::getCallingUid() const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700368{
369 return mCallingUid;
370}
371
372int64_t IPCThreadState::clearCallingIdentity()
373{
374 int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
375 clearCaller();
376 return token;
377}
378
Brad Fitzpatrick94c36342010-06-18 13:07:53 -0700379void IPCThreadState::setStrictModePolicy(int32_t policy)
380{
381 mStrictModePolicy = policy;
382}
383
Brad Fitzpatrick3f4ef592010-07-07 16:06:39 -0700384int32_t IPCThreadState::getStrictModePolicy() const
385{
Brad Fitzpatrick94c36342010-06-18 13:07:53 -0700386 return mStrictModePolicy;
387}
388
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700389void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
390{
391 mLastTransactionBinderFlags = flags;
392}
393
394int32_t IPCThreadState::getLastTransactionBinderFlags() const
395{
396 return mLastTransactionBinderFlags;
397}
398
Mathias Agopian7922fa22009-05-18 15:08:03 -0700399void IPCThreadState::restoreCallingIdentity(int64_t token)
400{
401 mCallingUid = (int)(token>>32);
402 mCallingPid = (int)token;
403}
404
405void IPCThreadState::clearCaller()
406{
Marco Nelissenb4f35d02009-07-17 07:59:17 -0700407 mCallingPid = getpid();
408 mCallingUid = getuid();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700409}
410
411void IPCThreadState::flushCommands()
412{
413 if (mProcess->mDriverFD <= 0)
414 return;
415 talkWithDriver(false);
416}
417
Todd Poynor0646cb02013-06-25 19:12:18 -0700418status_t IPCThreadState::getAndExecuteCommand()
419{
420 status_t result;
421 int32_t cmd;
422
423 result = talkWithDriver();
424 if (result >= NO_ERROR) {
425 size_t IN = mIn.dataAvail();
426 if (IN < sizeof(int32_t)) return result;
427 cmd = mIn.readInt32();
428 IF_LOG_COMMANDS() {
429 alog << "Processing top-level Command: "
430 << getReturnString(cmd) << endl;
431 }
432
433 result = executeCommand(cmd);
434
435 // After executing the command, ensure that the thread is returned to the
436 // foreground cgroup before rejoining the pool. The driver takes care of
437 // restoring the priority, but doesn't do anything with cgroups so we
438 // need to take care of that here in userspace. Note that we do make
439 // sure to go in the foreground after executing a transaction, but
440 // there are other callbacks into user code that could have changed
441 // our group so we want to make absolutely sure it is put back.
442 set_sched_policy(mMyThreadId, SP_FOREGROUND);
443 }
444
445 return result;
446}
447
448// When we've cleared the incoming command queue, process any pending derefs
449void IPCThreadState::processPendingDerefs()
450{
451 if (mIn.dataPosition() >= mIn.dataSize()) {
452 size_t numPending = mPendingWeakDerefs.size();
453 if (numPending > 0) {
454 for (size_t i = 0; i < numPending; i++) {
455 RefBase::weakref_type* refs = mPendingWeakDerefs[i];
456 refs->decWeak(mProcess.get());
457 }
458 mPendingWeakDerefs.clear();
459 }
460
461 numPending = mPendingStrongDerefs.size();
462 if (numPending > 0) {
463 for (size_t i = 0; i < numPending; i++) {
464 BBinder* obj = mPendingStrongDerefs[i];
465 obj->decStrong(mProcess.get());
466 }
467 mPendingStrongDerefs.clear();
468 }
469 }
470}
471
Mathias Agopian7922fa22009-05-18 15:08:03 -0700472void IPCThreadState::joinThreadPool(bool isMain)
473{
474 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
475
476 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
477
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800478 // This thread may have been spawned by a thread that was in the background
Glenn Kastencb5e2422012-03-16 07:15:23 -0700479 // scheduling group, so first we will make sure it is in the foreground
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800480 // one to avoid performing an initial transaction in the background.
Glenn Kastencb5e2422012-03-16 07:15:23 -0700481 set_sched_policy(mMyThreadId, SP_FOREGROUND);
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800482
Mathias Agopian7922fa22009-05-18 15:08:03 -0700483 status_t result;
484 do {
Todd Poynor0646cb02013-06-25 19:12:18 -0700485 processPendingDerefs();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700486 // now get the next command to be processed, waiting if necessary
Todd Poynor0646cb02013-06-25 19:12:18 -0700487 result = getAndExecuteCommand();
Jason Parks2b17f142009-11-03 12:14:38 -0800488
Todd Poynor0646cb02013-06-25 19:12:18 -0700489 if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
490 ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
Jeff Tinkeree711ec2013-06-11 11:30:21 -0700491 mProcess->mDriverFD, result);
492 abort();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700493 }
494
Mathias Agopian7922fa22009-05-18 15:08:03 -0700495 // Let this thread exit the thread pool if it is no longer
496 // needed and it is not the main process thread.
497 if(result == TIMED_OUT && !isMain) {
498 break;
499 }
500 } while (result != -ECONNREFUSED && result != -EBADF);
501
502 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
503 (void*)pthread_self(), getpid(), (void*)result);
504
505 mOut.writeInt32(BC_EXIT_LOOPER);
506 talkWithDriver(false);
507}
508
Todd Poynor0646cb02013-06-25 19:12:18 -0700509int IPCThreadState::setupPolling(int* fd)
510{
511 if (mProcess->mDriverFD <= 0) {
512 return -EBADF;
513 }
514
515 mOut.writeInt32(BC_ENTER_LOOPER);
516 *fd = mProcess->mDriverFD;
517 return 0;
518}
519
520status_t IPCThreadState::handlePolledCommands()
521{
522 status_t result;
523
524 do {
525 result = getAndExecuteCommand();
526 } while (mIn.dataPosition() < mIn.dataSize());
527
528 processPendingDerefs();
529 flushCommands();
530 return result;
531}
532
Colin Crossf0487982014-02-05 17:42:44 -0800533void IPCThreadState::stopProcess(bool /*immediate*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700534{
Steve Block93cf8542012-01-04 20:05:49 +0000535 //ALOGI("**** STOPPING PROCESS");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700536 flushCommands();
537 int fd = mProcess->mDriverFD;
538 mProcess->mDriverFD = -1;
539 close(fd);
540 //kill(getpid(), SIGKILL);
541}
542
543status_t IPCThreadState::transact(int32_t handle,
544 uint32_t code, const Parcel& data,
545 Parcel* reply, uint32_t flags)
546{
547 status_t err = data.errorCheck();
548
549 flags |= TF_ACCEPT_FDS;
550
551 IF_LOG_TRANSACTIONS() {
552 TextOutput::Bundle _b(alog);
553 alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
554 << handle << " / code " << TypeCode(code) << ": "
555 << indent << data << dedent << endl;
556 }
557
558 if (err == NO_ERROR) {
559 LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
560 (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
561 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
562 }
563
564 if (err != NO_ERROR) {
565 if (reply) reply->setError(err);
566 return (mLastError = err);
567 }
568
569 if ((flags & TF_ONE_WAY) == 0) {
Dianne Hackborn98878262010-09-24 11:16:23 -0700570 #if 0
571 if (code == 4) { // relayout
Steve Block93cf8542012-01-04 20:05:49 +0000572 ALOGI(">>>>>> CALLING transaction 4");
Dianne Hackborn98878262010-09-24 11:16:23 -0700573 } else {
Steve Block93cf8542012-01-04 20:05:49 +0000574 ALOGI(">>>>>> CALLING transaction %d", code);
Dianne Hackborn98878262010-09-24 11:16:23 -0700575 }
576 #endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700577 if (reply) {
578 err = waitForResponse(reply);
579 } else {
580 Parcel fakeReply;
581 err = waitForResponse(&fakeReply);
582 }
Dianne Hackborn98878262010-09-24 11:16:23 -0700583 #if 0
584 if (code == 4) { // relayout
Steve Block93cf8542012-01-04 20:05:49 +0000585 ALOGI("<<<<<< RETURNING transaction 4");
Dianne Hackborn98878262010-09-24 11:16:23 -0700586 } else {
Steve Block93cf8542012-01-04 20:05:49 +0000587 ALOGI("<<<<<< RETURNING transaction %d", code);
Dianne Hackborn98878262010-09-24 11:16:23 -0700588 }
589 #endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700590
591 IF_LOG_TRANSACTIONS() {
592 TextOutput::Bundle _b(alog);
593 alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
594 << handle << ": ";
595 if (reply) alog << indent << *reply << dedent << endl;
596 else alog << "(none requested)" << endl;
597 }
598 } else {
599 err = waitForResponse(NULL, NULL);
600 }
601
602 return err;
603}
604
605void IPCThreadState::incStrongHandle(int32_t handle)
606{
607 LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
608 mOut.writeInt32(BC_ACQUIRE);
609 mOut.writeInt32(handle);
610}
611
612void IPCThreadState::decStrongHandle(int32_t handle)
613{
614 LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
615 mOut.writeInt32(BC_RELEASE);
616 mOut.writeInt32(handle);
617}
618
619void IPCThreadState::incWeakHandle(int32_t handle)
620{
621 LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
622 mOut.writeInt32(BC_INCREFS);
623 mOut.writeInt32(handle);
624}
625
626void IPCThreadState::decWeakHandle(int32_t handle)
627{
628 LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
629 mOut.writeInt32(BC_DECREFS);
630 mOut.writeInt32(handle);
631}
632
633status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
634{
Arve Hjønnevåg304dcae2014-02-14 20:14:02 -0800635#if HAS_BC_ATTEMPT_ACQUIRE
Andy McFadden457d51f2011-08-31 07:43:40 -0700636 LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700637 mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
638 mOut.writeInt32(0); // xxx was thread priority
639 mOut.writeInt32(handle);
640 status_t result = UNKNOWN_ERROR;
641
642 waitForResponse(NULL, &result);
643
644#if LOG_REFCOUNTS
645 printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
646 handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
647#endif
648
649 return result;
Arve Hjønnevåg304dcae2014-02-14 20:14:02 -0800650#else
651 (void)handle;
652 ALOGE("%s(%d): Not supported\n", __func__, handle);
653 return INVALID_OPERATION;
654#endif
Mathias Agopian7922fa22009-05-18 15:08:03 -0700655}
656
657void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
658{
659#if LOG_REFCOUNTS
660 printf("IPCThreadState::expungeHandle(%ld)\n", handle);
661#endif
662 self()->mProcess->expungeHandle(handle, binder);
663}
664
665status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
666{
667 mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
668 mOut.writeInt32((int32_t)handle);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000669 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700670 return NO_ERROR;
671}
672
673status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
674{
675 mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
676 mOut.writeInt32((int32_t)handle);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000677 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700678 return NO_ERROR;
679}
680
681IPCThreadState::IPCThreadState()
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700682 : mProcess(ProcessState::self()),
Elliott Hughes07cf48a2014-08-18 10:38:38 -0700683 mMyThreadId(gettid()),
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -0700684 mStrictModePolicy(0),
685 mLastTransactionBinderFlags(0)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700686{
687 pthread_setspecific(gTLS, this);
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -0800688 clearCaller();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700689 mIn.setDataCapacity(256);
690 mOut.setDataCapacity(256);
691}
692
693IPCThreadState::~IPCThreadState()
694{
695}
696
697status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
698{
699 status_t err;
700 status_t statusBuffer;
701 err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
702 if (err < NO_ERROR) return err;
703
704 return waitForResponse(NULL, NULL);
705}
706
707status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
708{
709 int32_t cmd;
710 int32_t err;
711
712 while (1) {
713 if ((err=talkWithDriver()) < NO_ERROR) break;
714 err = mIn.errorCheck();
715 if (err < NO_ERROR) break;
716 if (mIn.dataAvail() == 0) continue;
717
718 cmd = mIn.readInt32();
719
720 IF_LOG_COMMANDS() {
721 alog << "Processing waitForResponse Command: "
722 << getReturnString(cmd) << endl;
723 }
724
725 switch (cmd) {
726 case BR_TRANSACTION_COMPLETE:
727 if (!reply && !acquireResult) goto finish;
728 break;
729
730 case BR_DEAD_REPLY:
731 err = DEAD_OBJECT;
732 goto finish;
733
734 case BR_FAILED_REPLY:
735 err = FAILED_TRANSACTION;
736 goto finish;
737
738 case BR_ACQUIRE_RESULT:
739 {
Steve Blockd0bfabc2012-01-09 18:35:44 +0000740 ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700741 const int32_t result = mIn.readInt32();
742 if (!acquireResult) continue;
743 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
744 }
745 goto finish;
746
747 case BR_REPLY:
748 {
749 binder_transaction_data tr;
750 err = mIn.read(&tr, sizeof(tr));
Steve Blockd0bfabc2012-01-09 18:35:44 +0000751 ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
Mathias Agopian7922fa22009-05-18 15:08:03 -0700752 if (err != NO_ERROR) goto finish;
753
754 if (reply) {
755 if ((tr.flags & TF_STATUS_CODE) == 0) {
756 reply->ipcSetDataReference(
757 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
758 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800759 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
760 tr.offsets_size/sizeof(binder_size_t),
Mathias Agopian7922fa22009-05-18 15:08:03 -0700761 freeBuffer, this);
762 } else {
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800763 err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700764 freeBuffer(NULL,
765 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
766 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800767 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
768 tr.offsets_size/sizeof(binder_size_t), this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700769 }
770 } else {
771 freeBuffer(NULL,
772 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
773 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800774 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
775 tr.offsets_size/sizeof(binder_size_t), this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700776 continue;
777 }
778 }
779 goto finish;
780
781 default:
782 err = executeCommand(cmd);
783 if (err != NO_ERROR) goto finish;
784 break;
785 }
786 }
787
788finish:
789 if (err != NO_ERROR) {
790 if (acquireResult) *acquireResult = err;
791 if (reply) reply->setError(err);
792 mLastError = err;
793 }
794
795 return err;
796}
797
798status_t IPCThreadState::talkWithDriver(bool doReceive)
799{
Johannes Carlsson597a3c72011-02-17 14:06:53 +0100800 if (mProcess->mDriverFD <= 0) {
801 return -EBADF;
802 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700803
804 binder_write_read bwr;
805
806 // Is the read buffer empty?
807 const bool needRead = mIn.dataPosition() >= mIn.dataSize();
808
809 // We don't want to write anything if we are still reading
810 // from data left in the input buffer and the caller
811 // has requested to read the next data.
812 const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
813
814 bwr.write_size = outAvail;
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800815 bwr.write_buffer = (uintptr_t)mOut.data();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700816
817 // This is what we'll read.
818 if (doReceive && needRead) {
819 bwr.read_size = mIn.dataCapacity();
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800820 bwr.read_buffer = (uintptr_t)mIn.data();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700821 } else {
822 bwr.read_size = 0;
Ben Cheng455a70a2011-12-01 17:11:32 -0800823 bwr.read_buffer = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700824 }
Andy McFadden457d51f2011-08-31 07:43:40 -0700825
Mathias Agopian7922fa22009-05-18 15:08:03 -0700826 IF_LOG_COMMANDS() {
827 TextOutput::Bundle _b(alog);
828 if (outAvail != 0) {
829 alog << "Sending commands to driver: " << indent;
830 const void* cmds = (const void*)bwr.write_buffer;
831 const void* end = ((const uint8_t*)cmds)+bwr.write_size;
832 alog << HexDump(cmds, bwr.write_size) << endl;
833 while (cmds < end) cmds = printCommand(alog, cmds);
834 alog << dedent;
835 }
836 alog << "Size of receive buffer: " << bwr.read_size
837 << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
838 }
839
840 // Return immediately if there is nothing to do.
841 if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
Andy McFadden457d51f2011-08-31 07:43:40 -0700842
Mathias Agopian7922fa22009-05-18 15:08:03 -0700843 bwr.write_consumed = 0;
844 bwr.read_consumed = 0;
845 status_t err;
846 do {
847 IF_LOG_COMMANDS() {
848 alog << "About to read/write, write size = " << mOut.dataSize() << endl;
849 }
850#if defined(HAVE_ANDROID_OS)
851 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
852 err = NO_ERROR;
853 else
854 err = -errno;
855#else
856 err = INVALID_OPERATION;
857#endif
Johannes Carlsson597a3c72011-02-17 14:06:53 +0100858 if (mProcess->mDriverFD <= 0) {
859 err = -EBADF;
860 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700861 IF_LOG_COMMANDS() {
862 alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
863 }
864 } while (err == -EINTR);
Andy McFadden457d51f2011-08-31 07:43:40 -0700865
Mathias Agopian7922fa22009-05-18 15:08:03 -0700866 IF_LOG_COMMANDS() {
Colin Crossf0487982014-02-05 17:42:44 -0800867 alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
Mathias Agopian7922fa22009-05-18 15:08:03 -0700868 << bwr.write_consumed << " (of " << mOut.dataSize()
Todd Poynor0646cb02013-06-25 19:12:18 -0700869 << "), read consumed: " << bwr.read_consumed << endl;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700870 }
871
872 if (err >= NO_ERROR) {
873 if (bwr.write_consumed > 0) {
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800874 if (bwr.write_consumed < mOut.dataSize())
Mathias Agopian7922fa22009-05-18 15:08:03 -0700875 mOut.remove(0, bwr.write_consumed);
876 else
877 mOut.setDataSize(0);
878 }
879 if (bwr.read_consumed > 0) {
880 mIn.setDataSize(bwr.read_consumed);
881 mIn.setDataPosition(0);
882 }
883 IF_LOG_COMMANDS() {
884 TextOutput::Bundle _b(alog);
885 alog << "Remaining data size: " << mOut.dataSize() << endl;
886 alog << "Received commands from driver: " << indent;
887 const void* cmds = mIn.data();
888 const void* end = mIn.data() + mIn.dataSize();
889 alog << HexDump(cmds, mIn.dataSize()) << endl;
890 while (cmds < end) cmds = printReturnCommand(alog, cmds);
891 alog << dedent;
892 }
893 return NO_ERROR;
894 }
895
896 return err;
897}
898
899status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
900 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
901{
902 binder_transaction_data tr;
903
Arve Hjønnevågea8e05d2014-02-18 21:10:29 -0800904 tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
Mathias Agopian7922fa22009-05-18 15:08:03 -0700905 tr.target.handle = handle;
906 tr.code = code;
907 tr.flags = binderFlags;
Evgeniy Stepanov68c8a652011-04-21 14:15:00 +0400908 tr.cookie = 0;
909 tr.sender_pid = 0;
910 tr.sender_euid = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700911
912 const status_t err = data.errorCheck();
913 if (err == NO_ERROR) {
914 tr.data_size = data.ipcDataSize();
915 tr.data.ptr.buffer = data.ipcData();
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800916 tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700917 tr.data.ptr.offsets = data.ipcObjects();
918 } else if (statusBuffer) {
919 tr.flags |= TF_STATUS_CODE;
920 *statusBuffer = err;
921 tr.data_size = sizeof(status_t);
Arve Hjønnevåg4bdf7e92014-02-18 21:04:31 -0800922 tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700923 tr.offsets_size = 0;
Arve Hjønnevåga5440702014-01-28 20:12:59 -0800924 tr.data.ptr.offsets = 0;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700925 } else {
926 return (mLastError = err);
927 }
928
929 mOut.writeInt32(cmd);
930 mOut.write(&tr, sizeof(tr));
931
932 return NO_ERROR;
933}
934
935sp<BBinder> the_context_object;
936
937void setTheContextObject(sp<BBinder> obj)
938{
939 the_context_object = obj;
940}
941
942status_t IPCThreadState::executeCommand(int32_t cmd)
943{
944 BBinder* obj;
945 RefBase::weakref_type* refs;
946 status_t result = NO_ERROR;
947
948 switch (cmd) {
949 case BR_ERROR:
950 result = mIn.readInt32();
951 break;
952
953 case BR_OK:
954 break;
955
956 case BR_ACQUIRE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000957 refs = (RefBase::weakref_type*)mIn.readPointer();
958 obj = (BBinder*)mIn.readPointer();
Steve Blockd0bfabc2012-01-09 18:35:44 +0000959 ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -0700960 "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
961 refs, obj, refs->refBase());
962 obj->incStrong(mProcess.get());
963 IF_LOG_REMOTEREFS() {
964 LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
965 obj->printRefs();
966 }
967 mOut.writeInt32(BC_ACQUIRE_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000968 mOut.writePointer((uintptr_t)refs);
969 mOut.writePointer((uintptr_t)obj);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700970 break;
971
972 case BR_RELEASE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000973 refs = (RefBase::weakref_type*)mIn.readPointer();
974 obj = (BBinder*)mIn.readPointer();
Steve Blockd0bfabc2012-01-09 18:35:44 +0000975 ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -0700976 "BR_RELEASE: object %p does not match cookie %p (expected %p)",
977 refs, obj, refs->refBase());
978 IF_LOG_REMOTEREFS() {
979 LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
980 obj->printRefs();
981 }
982 mPendingStrongDerefs.push(obj);
983 break;
984
985 case BR_INCREFS:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000986 refs = (RefBase::weakref_type*)mIn.readPointer();
987 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700988 refs->incWeak(mProcess.get());
989 mOut.writeInt32(BC_INCREFS_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000990 mOut.writePointer((uintptr_t)refs);
991 mOut.writePointer((uintptr_t)obj);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700992 break;
993
994 case BR_DECREFS:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +0000995 refs = (RefBase::weakref_type*)mIn.readPointer();
996 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -0700997 // NOTE: This assertion is not valid, because the object may no
998 // longer exist (thus the (BBinder*)cast above resulting in a different
999 // memory address).
Steve Blockd0bfabc2012-01-09 18:35:44 +00001000 //ALOG_ASSERT(refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001001 // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
1002 // refs, obj, refs->refBase());
1003 mPendingWeakDerefs.push(refs);
1004 break;
1005
1006 case BR_ATTEMPT_ACQUIRE:
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001007 refs = (RefBase::weakref_type*)mIn.readPointer();
1008 obj = (BBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001009
1010 {
1011 const bool success = refs->attemptIncStrong(mProcess.get());
Steve Blockd0bfabc2012-01-09 18:35:44 +00001012 ALOG_ASSERT(success && refs->refBase() == obj,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001013 "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
1014 refs, obj, refs->refBase());
1015
1016 mOut.writeInt32(BC_ACQUIRE_RESULT);
1017 mOut.writeInt32((int32_t)success);
1018 }
1019 break;
1020
1021 case BR_TRANSACTION:
1022 {
1023 binder_transaction_data tr;
1024 result = mIn.read(&tr, sizeof(tr));
Steve Blockd0bfabc2012-01-09 18:35:44 +00001025 ALOG_ASSERT(result == NO_ERROR,
Mathias Agopian7922fa22009-05-18 15:08:03 -07001026 "Not enough command data for brTRANSACTION");
1027 if (result != NO_ERROR) break;
1028
1029 Parcel buffer;
1030 buffer.ipcSetDataReference(
1031 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
1032 tr.data_size,
Arve Hjønnevåga5440702014-01-28 20:12:59 -08001033 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
1034 tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001035
1036 const pid_t origPid = mCallingPid;
1037 const uid_t origUid = mCallingUid;
1038
1039 mCallingPid = tr.sender_pid;
1040 mCallingUid = tr.sender_euid;
1041
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001042 int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
1043 if (gDisableBackgroundScheduling) {
1044 if (curPrio > ANDROID_PRIORITY_NORMAL) {
1045 // We have inherited a reduced priority from the caller, but do not
1046 // want to run in that state in this process. The driver set our
1047 // priority already (though not our scheduling class), so bounce
1048 // it back to the default before invoking the transaction.
1049 setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
1050 }
1051 } else {
1052 if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
1053 // We want to use the inherited priority from the caller.
1054 // Ensure this thread is in the background scheduling class,
1055 // since the driver won't modify scheduling classes for us.
1056 // The scheduling group is reset to default by the caller
1057 // once this method returns after the transaction is complete.
Glenn Kastencb5e2422012-03-16 07:15:23 -07001058 set_sched_policy(mMyThreadId, SP_BACKGROUND);
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001059 }
Dianne Hackborn5f4d7e82009-12-07 17:59:37 -08001060 }
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001061
Steve Block93cf8542012-01-04 20:05:49 +00001062 //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001063
1064 Parcel reply;
1065 IF_LOG_TRANSACTIONS() {
1066 TextOutput::Bundle _b(alog);
1067 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
1068 << " / obj " << tr.target.ptr << " / code "
1069 << TypeCode(tr.code) << ": " << indent << buffer
1070 << dedent << endl
1071 << "Data addr = "
1072 << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
1073 << ", offsets addr="
1074 << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
1075 }
1076 if (tr.target.ptr) {
1077 sp<BBinder> b((BBinder*)tr.cookie);
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -07001078 const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001079 if (error < NO_ERROR) reply.setError(error);
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -07001080
Mathias Agopian7922fa22009-05-18 15:08:03 -07001081 } else {
Brad Fitzpatrick24f8bca2010-08-30 16:01:16 -07001082 const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001083 if (error < NO_ERROR) reply.setError(error);
1084 }
1085
Steve Block93cf8542012-01-04 20:05:49 +00001086 //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
Mathias Agopian7922fa22009-05-18 15:08:03 -07001087 // mCallingPid, origPid, origUid);
1088
1089 if ((tr.flags & TF_ONE_WAY) == 0) {
1090 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
1091 sendReply(reply, 0);
1092 } else {
1093 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
1094 }
1095
1096 mCallingPid = origPid;
1097 mCallingUid = origUid;
Christopher Tate7c4dfec2010-03-18 17:55:03 -07001098
Mathias Agopian7922fa22009-05-18 15:08:03 -07001099 IF_LOG_TRANSACTIONS() {
1100 TextOutput::Bundle _b(alog);
1101 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
1102 << tr.target.ptr << ": " << indent << reply << dedent << endl;
1103 }
1104
1105 }
1106 break;
1107
1108 case BR_DEAD_BINDER:
1109 {
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001110 BpBinder *proxy = (BpBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001111 proxy->sendObituary();
1112 mOut.writeInt32(BC_DEAD_BINDER_DONE);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001113 mOut.writePointer((uintptr_t)proxy);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001114 } break;
1115
1116 case BR_CLEAR_DEATH_NOTIFICATION_DONE:
1117 {
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001118 BpBinder *proxy = (BpBinder*)mIn.readPointer();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001119 proxy->getWeakRefs()->decWeak(proxy);
1120 } break;
1121
1122 case BR_FINISHED:
1123 result = TIMED_OUT;
1124 break;
1125
1126 case BR_NOOP:
1127 break;
1128
1129 case BR_SPAWN_LOOPER:
1130 mProcess->spawnPooledThread(false);
1131 break;
1132
1133 default:
1134 printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
1135 result = UNKNOWN_ERROR;
1136 break;
1137 }
1138
1139 if (result != NO_ERROR) {
1140 mLastError = result;
1141 }
1142
1143 return result;
1144}
1145
1146void IPCThreadState::threadDestructor(void *st)
1147{
Todd Poynor0646cb02013-06-25 19:12:18 -07001148 IPCThreadState* const self = static_cast<IPCThreadState*>(st);
1149 if (self) {
1150 self->flushCommands();
Mathias Agopian7922fa22009-05-18 15:08:03 -07001151#if defined(HAVE_ANDROID_OS)
Johannes Carlsson597a3c72011-02-17 14:06:53 +01001152 if (self->mProcess->mDriverFD > 0) {
1153 ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1154 }
Mathias Agopian7922fa22009-05-18 15:08:03 -07001155#endif
Todd Poynor0646cb02013-06-25 19:12:18 -07001156 delete self;
1157 }
Mathias Agopian7922fa22009-05-18 15:08:03 -07001158}
1159
1160
Colin Crossf0487982014-02-05 17:42:44 -08001161void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
1162 size_t /*dataSize*/,
1163 const binder_size_t* /*objects*/,
1164 size_t /*objectsSize*/, void* /*cookie*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -07001165{
Steve Block93cf8542012-01-04 20:05:49 +00001166 //ALOGI("Freeing parcel %p", &parcel);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001167 IF_LOG_COMMANDS() {
1168 alog << "Writing BC_FREE_BUFFER for " << data << endl;
1169 }
Steve Blockd0bfabc2012-01-09 18:35:44 +00001170 ALOG_ASSERT(data != NULL, "Called with NULL data");
Mathias Agopian7922fa22009-05-18 15:08:03 -07001171 if (parcel != NULL) parcel->closeFileDescriptors();
1172 IPCThreadState* state = self();
1173 state->mOut.writeInt32(BC_FREE_BUFFER);
Serban Constantinescu4ca5baf2013-11-05 16:53:55 +00001174 state->mOut.writePointer((uintptr_t)data);
Mathias Agopian7922fa22009-05-18 15:08:03 -07001175}
1176
1177}; // namespace android