1 /*
2 * Copyright (C) 2006 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
17 #define LOG_TAG "JavaBinder"
18 //#define LOG_NDEBUG 0
19
20 #include "android_os_Parcel.h"
21 #include "android_util_Binder.h"
22
23 #include <atomic>
24 #include <fcntl.h>
25 #include <inttypes.h>
26 #include <stdio.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30
31 #include <android-base/stringprintf.h>
32 #include <binder/IInterface.h>
33 #include <binder/IServiceManager.h>
34 #include <binder/IPCThreadState.h>
35 #include <binder/Parcel.h>
36 #include <binder/BpBinder.h>
37 #include <binder/ProcessState.h>
38 #include <cutils/atomic.h>
39 #include <log/log.h>
40 #include <utils/KeyedVector.h>
41 #include <utils/List.h>
42 #include <utils/Log.h>
43 #include <utils/String8.h>
44 #include <utils/SystemClock.h>
45 #include <utils/threads.h>
46
47 #include <nativehelper/JNIHelp.h>
48 #include <nativehelper/ScopedLocalRef.h>
49 #include <nativehelper/ScopedUtfChars.h>
50
51 #include "core_jni_helpers.h"
52
53 //#undef ALOGV
54 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
55
56 #define DEBUG_DEATH 0
57 #if DEBUG_DEATH
58 #define LOGDEATH ALOGD
59 #else
60 #define LOGDEATH ALOGV
61 #endif
62
63 using namespace android;
64
65 // ----------------------------------------------------------------------------
66
67 static struct bindernative_offsets_t
68 {
69 // Class state.
70 jclass mClass;
71 jmethodID mExecTransact;
72
73 // Object state.
74 jfieldID mObject;
75
76 } gBinderOffsets;
77
78 // ----------------------------------------------------------------------------
79
80 static struct binderinternal_offsets_t
81 {
82 // Class state.
83 jclass mClass;
84 jmethodID mForceGc;
85 jmethodID mProxyLimitCallback;
86
87 } gBinderInternalOffsets;
88
89 static struct sparseintarray_offsets_t
90 {
91 jclass classObject;
92 jmethodID constructor;
93 jmethodID put;
94 } gSparseIntArrayOffsets;
95
96 // ----------------------------------------------------------------------------
97
98 static struct error_offsets_t
99 {
100 jclass mClass;
101 } gErrorOffsets;
102
103 // ----------------------------------------------------------------------------
104
105 static struct binderproxy_offsets_t
106 {
107 // Class state.
108 jclass mClass;
109 jmethodID mGetInstance;
110 jmethodID mSendDeathNotice;
111 jmethodID mDumpProxyDebugInfo;
112
113 // Object state.
114 jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
115 } gBinderProxyOffsets;
116
117 static struct class_offsets_t
118 {
119 jmethodID mGetName;
120 } gClassOffsets;
121
122 // ----------------------------------------------------------------------------
123
124 static struct log_offsets_t
125 {
126 // Class state.
127 jclass mClass;
128 jmethodID mLogE;
129 } gLogOffsets;
130
131 static struct parcel_file_descriptor_offsets_t
132 {
133 jclass mClass;
134 jmethodID mConstructor;
135 } gParcelFileDescriptorOffsets;
136
137 static struct strict_mode_callback_offsets_t
138 {
139 jclass mClass;
140 jmethodID mCallback;
141 } gStrictModeCallbackOffsets;
142
143 static struct thread_dispatch_offsets_t
144 {
145 // Class state.
146 jclass mClass;
147 jmethodID mDispatchUncaughtException;
148 jmethodID mCurrentThread;
149 } gThreadDispatchOffsets;
150
151 // ****************************************************************************
152 // ****************************************************************************
153 // ****************************************************************************
154
155 static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
156 static constexpr uint32_t GC_INTERVAL = 1000;
157
158 // Protected by gProxyLock. We warn if this gets too large.
159 static int32_t gNumProxies = 0;
160 static int32_t gProxiesWarned = 0;
161
162 // Number of GlobalRefs held by JavaBBinders.
163 static std::atomic<uint32_t> gNumLocalRefsCreated(0);
164 static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
165 // Number of GlobalRefs held by JavaDeathRecipients.
166 static std::atomic<uint32_t> gNumDeathRefsCreated(0);
167 static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
168
169 // We collected after creating this many refs.
170 static std::atomic<uint32_t> gCollectedAtRefs(0);
171
172 // Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
173 // TODO: Consider removing this completely. We should no longer be generating GlobalRefs
174 // that are reclaimed as a result of GC action.
175 __attribute__((no_sanitize("unsigned-integer-overflow")))
gcIfManyNewRefs(JNIEnv * env)176 static void gcIfManyNewRefs(JNIEnv* env)
177 {
178 uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
179 + gNumDeathRefsCreated.load(std::memory_order_relaxed);
180 uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
181 // A bound on the number of threads that can have incremented gNum...RefsCreated before the
182 // following check is executed. Effectively a bound on #threads. Almost any value will do.
183 static constexpr uint32_t MAX_RACING = 100000;
184
185 if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
186 // Recently passed next GC interval.
187 if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
188 collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
189 ALOGV("Binder forcing GC at %u created refs", totalRefs);
190 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
191 gBinderInternalOffsets.mForceGc);
192 } // otherwise somebody else beat us to it.
193 } else {
194 ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
195 }
196 }
197
jnienv_to_javavm(JNIEnv * env)198 static JavaVM* jnienv_to_javavm(JNIEnv* env)
199 {
200 JavaVM* vm;
201 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
202 }
203
javavm_to_jnienv(JavaVM * vm)204 static JNIEnv* javavm_to_jnienv(JavaVM* vm)
205 {
206 JNIEnv* env;
207 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
208 }
209
210 // Report a java.lang.Error (or subclass). This will terminate the runtime by
211 // calling FatalError with a message derived from the given error.
report_java_lang_error_fatal_error(JNIEnv * env,jthrowable error,const char * msg)212 static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
213 const char* msg)
214 {
215 // Report an error: reraise the exception and ask the runtime to abort.
216
217 // Try to get the exception string. Sometimes logcat isn't available,
218 // so try to add it to the abort message.
219 std::string exc_msg = "(Unknown exception message)";
220 {
221 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
222 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
223 "()Ljava/lang/String;");
224 ScopedLocalRef<jstring> jstr(
225 env,
226 reinterpret_cast<jstring>(
227 env->CallObjectMethod(error, method_id)));
228 env->ExceptionClear(); // Just for good measure.
229 if (jstr.get() != nullptr) {
230 ScopedUtfChars jstr_utf(env, jstr.get());
231 if (jstr_utf.c_str() != nullptr) {
232 exc_msg = jstr_utf.c_str();
233 } else {
234 env->ExceptionClear();
235 }
236 }
237 }
238
239 env->Throw(error);
240 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
241 env->ExceptionDescribe();
242
243 std::string error_msg = base::StringPrintf(
244 "java.lang.Error thrown during binder transaction: %s",
245 exc_msg.c_str());
246 env->FatalError(error_msg.c_str());
247 }
248
249 // Report a java.lang.Error (or subclass). This will terminate the runtime, either by
250 // the uncaught exception handler, or explicitly by calling
251 // report_java_lang_error_fatal_error.
report_java_lang_error(JNIEnv * env,jthrowable error,const char * msg)252 static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
253 {
254 // Try to run the uncaught exception machinery.
255 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
256 gThreadDispatchOffsets.mCurrentThread);
257 if (thread != nullptr) {
258 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
259 error);
260 // Should not return here, unless more errors occured.
261 }
262 // Some error occurred that meant that either dispatchUncaughtException could not be
263 // called or that it had an error itself (as this should be unreachable under normal
264 // conditions). As the binder code cannot handle Errors, attempt to log the error and
265 // abort.
266 env->ExceptionClear();
267 report_java_lang_error_fatal_error(env, error, msg);
268 }
269
report_exception(JNIEnv * env,jthrowable excep,const char * msg)270 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
271 {
272 env->ExceptionClear();
273
274 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
275 ScopedLocalRef<jstring> msgstr(env);
276 if (tagstr != nullptr) {
277 msgstr.reset(env->NewStringUTF(msg));
278 }
279
280 if ((tagstr != nullptr) && (msgstr != nullptr)) {
281 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
282 tagstr.get(), msgstr.get(), excep);
283 if (env->ExceptionCheck()) {
284 // Attempting to log the failure has failed.
285 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
286 env->ExceptionClear();
287 }
288 } else {
289 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
290 ALOGE("Unable to call Log.e()\n");
291 ALOGE("%s", msg);
292 }
293
294 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
295 report_java_lang_error(env, excep, msg);
296 }
297 }
298
299 class JavaBBinderHolder;
300
301 class JavaBBinder : public BBinder
302 {
303 public:
JavaBBinder(JNIEnv * env,jobject object)304 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
305 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
306 {
307 ALOGV("Creating JavaBBinder %p\n", this);
308 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
309 gcIfManyNewRefs(env);
310 }
311
checkSubclass(const void * subclassID) const312 bool checkSubclass(const void* subclassID) const
313 {
314 return subclassID == &gBinderOffsets;
315 }
316
object() const317 jobject object() const
318 {
319 return mObject;
320 }
321
322 protected:
~JavaBBinder()323 virtual ~JavaBBinder()
324 {
325 ALOGV("Destroying JavaBBinder %p\n", this);
326 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
327 JNIEnv* env = javavm_to_jnienv(mVM);
328 env->DeleteGlobalRef(mObject);
329 }
330
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)331 virtual status_t onTransact(
332 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
333 {
334 JNIEnv* env = javavm_to_jnienv(mVM);
335
336 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
337
338 IPCThreadState* thread_state = IPCThreadState::self();
339 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
340
341 //printf("Transact from %p to Java code sending: ", this);
342 //data.print();
343 //printf("\n");
344 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
345 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
346
347 if (env->ExceptionCheck()) {
348 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
349 report_exception(env, excep.get(),
350 "*** Uncaught remote exception! "
351 "(Exceptions are not yet supported across processes.)");
352 res = JNI_FALSE;
353 }
354
355 // Check if the strict mode state changed while processing the
356 // call. The Binder state will be restored by the underlying
357 // Binder system in IPCThreadState, however we need to take care
358 // of the parallel Java state as well.
359 if (thread_state->getStrictModePolicy() != strict_policy_before) {
360 set_dalvik_blockguard_policy(env, strict_policy_before);
361 }
362
363 if (env->ExceptionCheck()) {
364 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
365 report_exception(env, excep.get(),
366 "*** Uncaught exception in onBinderStrictModePolicyChange");
367 }
368
369 // Need to always call through the native implementation of
370 // SYSPROPS_TRANSACTION.
371 if (code == SYSPROPS_TRANSACTION) {
372 BBinder::onTransact(code, data, reply, flags);
373 }
374
375 //aout << "onTransact to Java code; result=" << res << endl
376 // << "Transact from " << this << " to Java code returning "
377 // << reply << ": " << *reply << endl;
378 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
379 }
380
dump(int fd,const Vector<String16> & args)381 virtual status_t dump(int fd, const Vector<String16>& args)
382 {
383 return 0;
384 }
385
386 private:
387 JavaVM* const mVM;
388 jobject const mObject; // GlobalRef to Java Binder
389 };
390
391 // ----------------------------------------------------------------------------
392
393 class JavaBBinderHolder
394 {
395 public:
get(JNIEnv * env,jobject obj)396 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
397 {
398 AutoMutex _l(mLock);
399 sp<JavaBBinder> b = mBinder.promote();
400 if (b == NULL) {
401 b = new JavaBBinder(env, obj);
402 mBinder = b;
403 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
404 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
405 }
406
407 return b;
408 }
409
getExisting()410 sp<JavaBBinder> getExisting()
411 {
412 AutoMutex _l(mLock);
413 return mBinder.promote();
414 }
415
416 private:
417 Mutex mLock;
418 wp<JavaBBinder> mBinder;
419 };
420
421 // ----------------------------------------------------------------------------
422
423 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
424 // death recipient references passed in through JNI with the permanent corresponding
425 // JavaDeathRecipient objects.
426
427 class JavaDeathRecipient;
428
429 class DeathRecipientList : public RefBase {
430 List< sp<JavaDeathRecipient> > mList;
431 Mutex mLock;
432
433 public:
434 DeathRecipientList();
435 ~DeathRecipientList();
436
437 void add(const sp<JavaDeathRecipient>& recipient);
438 void remove(const sp<JavaDeathRecipient>& recipient);
439 sp<JavaDeathRecipient> find(jobject recipient);
440
441 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
442 };
443
444 // ----------------------------------------------------------------------------
445
446 class JavaDeathRecipient : public IBinder::DeathRecipient
447 {
448 public:
JavaDeathRecipient(JNIEnv * env,jobject object,const sp<DeathRecipientList> & list)449 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
450 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
451 mObjectWeak(NULL), mList(list)
452 {
453 // These objects manage their own lifetimes so are responsible for final bookkeeping.
454 // The list holds a strong reference to this object.
455 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
456 list->add(this);
457
458 gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
459 gcIfManyNewRefs(env);
460 }
461
binderDied(const wp<IBinder> & who)462 void binderDied(const wp<IBinder>& who)
463 {
464 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
465 if (mObject != NULL) {
466 JNIEnv* env = javavm_to_jnienv(mVM);
467
468 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
469 gBinderProxyOffsets.mSendDeathNotice, mObject);
470 if (env->ExceptionCheck()) {
471 jthrowable excep = env->ExceptionOccurred();
472 report_exception(env, excep,
473 "*** Uncaught exception returned from death notification!");
474 }
475
476 // Serialize with our containing DeathRecipientList so that we can't
477 // delete the global ref on mObject while the list is being iterated.
478 sp<DeathRecipientList> list = mList.promote();
479 if (list != NULL) {
480 AutoMutex _l(list->lock());
481
482 // Demote from strong ref to weak after binderDied() has been delivered,
483 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
484 mObjectWeak = env->NewWeakGlobalRef(mObject);
485 env->DeleteGlobalRef(mObject);
486 mObject = NULL;
487 }
488 }
489 }
490
clearReference()491 void clearReference()
492 {
493 sp<DeathRecipientList> list = mList.promote();
494 if (list != NULL) {
495 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
496 list->remove(this);
497 } else {
498 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
499 }
500 }
501
matches(jobject obj)502 bool matches(jobject obj) {
503 bool result;
504 JNIEnv* env = javavm_to_jnienv(mVM);
505
506 if (mObject != NULL) {
507 result = env->IsSameObject(obj, mObject);
508 } else {
509 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
510 result = env->IsSameObject(obj, me.get());
511 }
512 return result;
513 }
514
warnIfStillLive()515 void warnIfStillLive() {
516 if (mObject != NULL) {
517 // Okay, something is wrong -- we have a hard reference to a live death
518 // recipient on the VM side, but the list is being torn down.
519 JNIEnv* env = javavm_to_jnienv(mVM);
520 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
521 ScopedLocalRef<jstring> nameRef(env,
522 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
523 ScopedUtfChars nameUtf(env, nameRef.get());
524 if (nameUtf.c_str() != NULL) {
525 ALOGW("BinderProxy is being destroyed but the application did not call "
526 "unlinkToDeath to unlink all of its death recipients beforehand. "
527 "Releasing leaked death recipient: %s", nameUtf.c_str());
528 } else {
529 ALOGW("BinderProxy being destroyed; unable to get DR object name");
530 env->ExceptionClear();
531 }
532 }
533 }
534
535 protected:
~JavaDeathRecipient()536 virtual ~JavaDeathRecipient()
537 {
538 //ALOGI("Removing death ref: recipient=%p\n", mObject);
539 gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
540 JNIEnv* env = javavm_to_jnienv(mVM);
541 if (mObject != NULL) {
542 env->DeleteGlobalRef(mObject);
543 } else {
544 env->DeleteWeakGlobalRef(mObjectWeak);
545 }
546 }
547
548 private:
549 JavaVM* const mVM;
550 jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
551 jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
552 wp<DeathRecipientList> mList;
553 };
554
555 // ----------------------------------------------------------------------------
556
DeathRecipientList()557 DeathRecipientList::DeathRecipientList() {
558 LOGDEATH("New DRL @ %p", this);
559 }
560
~DeathRecipientList()561 DeathRecipientList::~DeathRecipientList() {
562 LOGDEATH("Destroy DRL @ %p", this);
563 AutoMutex _l(mLock);
564
565 // Should never happen -- the JavaDeathRecipient objects that have added themselves
566 // to the list are holding references on the list object. Only when they are torn
567 // down can the list header be destroyed.
568 if (mList.size() > 0) {
569 List< sp<JavaDeathRecipient> >::iterator iter;
570 for (iter = mList.begin(); iter != mList.end(); iter++) {
571 (*iter)->warnIfStillLive();
572 }
573 }
574 }
575
add(const sp<JavaDeathRecipient> & recipient)576 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
577 AutoMutex _l(mLock);
578
579 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
580 mList.push_back(recipient);
581 }
582
remove(const sp<JavaDeathRecipient> & recipient)583 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
584 AutoMutex _l(mLock);
585
586 List< sp<JavaDeathRecipient> >::iterator iter;
587 for (iter = mList.begin(); iter != mList.end(); iter++) {
588 if (*iter == recipient) {
589 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
590 mList.erase(iter);
591 return;
592 }
593 }
594 }
595
find(jobject recipient)596 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
597 AutoMutex _l(mLock);
598
599 List< sp<JavaDeathRecipient> >::iterator iter;
600 for (iter = mList.begin(); iter != mList.end(); iter++) {
601 if ((*iter)->matches(recipient)) {
602 return *iter;
603 }
604 }
605 return NULL;
606 }
607
lock()608 Mutex& DeathRecipientList::lock() {
609 return mLock;
610 }
611
612 // ----------------------------------------------------------------------------
613
614 namespace android {
615
616 // We aggregate native pointer fields for BinderProxy in a single object to allow
617 // management with a single NativeAllocationRegistry, and to reduce the number of JNI
618 // Java field accesses. This costs us some extra indirections here.
619 struct BinderProxyNativeData {
620 // Both fields are constant and not null once javaObjectForIBinder returns this as
621 // part of a BinderProxy.
622
623 // The native IBinder proxied by this BinderProxy.
624 sp<IBinder> mObject;
625
626 // Death recipients for mObject. Reference counted only because DeathRecipients
627 // hold a weak reference that can be temporarily promoted.
628 sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
629 };
630
getBPNativeData(JNIEnv * env,jobject obj)631 BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
632 return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
633 }
634
635 static Mutex gProxyLock;
636
637 // We may cache a single BinderProxyNativeData node to avoid repeat allocation.
638 // All fields are null. Protected by gProxyLock.
639 static BinderProxyNativeData *gNativeDataCache;
640
641 // If the argument is a JavaBBinder, return the Java object that was used to create it.
642 // Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
643 // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
javaObjectForIBinder(JNIEnv * env,const sp<IBinder> & val)644 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
645 {
646 if (val == NULL) return NULL;
647
648 if (val->checkSubclass(&gBinderOffsets)) {
649 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
650 jobject object = static_cast<JavaBBinder*>(val.get())->object();
651 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
652 return object;
653 }
654
655 // For the rest of the function we will hold this lock, to serialize
656 // looking/creation/destruction of Java proxies for native Binder proxies.
657 AutoMutex _l(gProxyLock);
658
659 BinderProxyNativeData* nativeData = gNativeDataCache;
660 if (nativeData == nullptr) {
661 nativeData = new BinderProxyNativeData();
662 }
663 // gNativeDataCache is now logically empty.
664 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
665 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
666 if (env->ExceptionCheck()) {
667 // In the exception case, getInstance still took ownership of nativeData.
668 gNativeDataCache = nullptr;
669 return NULL;
670 }
671 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
672 if (actualNativeData == nativeData) {
673 // New BinderProxy; we still have exclusive access.
674 nativeData->mOrgue = new DeathRecipientList;
675 nativeData->mObject = val;
676 gNativeDataCache = nullptr;
677 ++gNumProxies;
678 if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
679 ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
680 gProxiesWarned = gNumProxies;
681 }
682 } else {
683 // nativeData wasn't used. Reuse it the next time.
684 gNativeDataCache = nativeData;
685 }
686
687 return object;
688 }
689
ibinderForJavaObject(JNIEnv * env,jobject obj)690 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
691 {
692 if (obj == NULL) return NULL;
693
694 // Instance of Binder?
695 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
696 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
697 env->GetLongField(obj, gBinderOffsets.mObject);
698 return jbh->get(env, obj);
699 }
700
701 // Instance of BinderProxy?
702 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
703 return getBPNativeData(env, obj)->mObject;
704 }
705
706 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
707 return NULL;
708 }
709
newParcelFileDescriptor(JNIEnv * env,jobject fileDesc)710 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
711 {
712 return env->NewObject(
713 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
714 }
715
set_dalvik_blockguard_policy(JNIEnv * env,jint strict_policy)716 void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
717 {
718 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
719 // to sync our state back to it. See the comments in StrictMode.java.
720 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
721 gStrictModeCallbackOffsets.mCallback,
722 strict_policy);
723 }
724
signalExceptionForError(JNIEnv * env,jobject obj,status_t err,bool canThrowRemoteException,int parcelSize)725 void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
726 bool canThrowRemoteException, int parcelSize)
727 {
728 switch (err) {
729 case UNKNOWN_ERROR:
730 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
731 break;
732 case NO_MEMORY:
733 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
734 break;
735 case INVALID_OPERATION:
736 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
737 break;
738 case BAD_VALUE:
739 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
740 break;
741 case BAD_INDEX:
742 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
743 break;
744 case BAD_TYPE:
745 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
746 break;
747 case NAME_NOT_FOUND:
748 jniThrowException(env, "java/util/NoSuchElementException", NULL);
749 break;
750 case PERMISSION_DENIED:
751 jniThrowException(env, "java/lang/SecurityException", NULL);
752 break;
753 case NOT_ENOUGH_DATA:
754 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
755 break;
756 case NO_INIT:
757 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
758 break;
759 case ALREADY_EXISTS:
760 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
761 break;
762 case DEAD_OBJECT:
763 // DeadObjectException is a checked exception, only throw from certain methods.
764 jniThrowException(env, canThrowRemoteException
765 ? "android/os/DeadObjectException"
766 : "java/lang/RuntimeException", NULL);
767 break;
768 case UNKNOWN_TRANSACTION:
769 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
770 break;
771 case FAILED_TRANSACTION: {
772 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
773 const char* exceptionToThrow;
774 char msg[128];
775 // TransactionTooLargeException is a checked exception, only throw from certain methods.
776 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
777 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
778 // for other reasons also, such as if the transaction is malformed or
779 // refers to an FD that has been closed. We should change the driver
780 // to enable us to distinguish these cases in the future.
781 if (canThrowRemoteException && parcelSize > 200*1024) {
782 // bona fide large payload
783 exceptionToThrow = "android/os/TransactionTooLargeException";
784 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
785 } else {
786 // Heuristic: a payload smaller than this threshold "shouldn't" be too
787 // big, so it's probably some other, more subtle problem. In practice
788 // it seems to always mean that the remote process died while the binder
789 // transaction was already in flight.
790 exceptionToThrow = (canThrowRemoteException)
791 ? "android/os/DeadObjectException"
792 : "java/lang/RuntimeException";
793 snprintf(msg, sizeof(msg)-1,
794 "Transaction failed on small parcel; remote process probably died");
795 }
796 jniThrowException(env, exceptionToThrow, msg);
797 } break;
798 case FDS_NOT_ALLOWED:
799 jniThrowException(env, "java/lang/RuntimeException",
800 "Not allowed to write file descriptors here");
801 break;
802 case UNEXPECTED_NULL:
803 jniThrowNullPointerException(env, NULL);
804 break;
805 case -EBADF:
806 jniThrowException(env, "java/lang/RuntimeException",
807 "Bad file descriptor");
808 break;
809 case -ENFILE:
810 jniThrowException(env, "java/lang/RuntimeException",
811 "File table overflow");
812 break;
813 case -EMFILE:
814 jniThrowException(env, "java/lang/RuntimeException",
815 "Too many open files");
816 break;
817 case -EFBIG:
818 jniThrowException(env, "java/lang/RuntimeException",
819 "File too large");
820 break;
821 case -ENOSPC:
822 jniThrowException(env, "java/lang/RuntimeException",
823 "No space left on device");
824 break;
825 case -ESPIPE:
826 jniThrowException(env, "java/lang/RuntimeException",
827 "Illegal seek");
828 break;
829 case -EROFS:
830 jniThrowException(env, "java/lang/RuntimeException",
831 "Read-only file system");
832 break;
833 case -EMLINK:
834 jniThrowException(env, "java/lang/RuntimeException",
835 "Too many links");
836 break;
837 default:
838 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
839 String8 msg;
840 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
841 // RemoteException is a checked exception, only throw from certain methods.
842 jniThrowException(env, canThrowRemoteException
843 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
844 break;
845 }
846 }
847
848 }
849
850 // ----------------------------------------------------------------------------
851
android_os_Binder_getCallingPid(JNIEnv * env,jobject clazz)852 static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
853 {
854 return IPCThreadState::self()->getCallingPid();
855 }
856
android_os_Binder_getCallingUid(JNIEnv * env,jobject clazz)857 static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
858 {
859 return IPCThreadState::self()->getCallingUid();
860 }
861
android_os_Binder_clearCallingIdentity(JNIEnv * env,jobject clazz)862 static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
863 {
864 return IPCThreadState::self()->clearCallingIdentity();
865 }
866
android_os_Binder_restoreCallingIdentity(JNIEnv * env,jobject clazz,jlong token)867 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
868 {
869 // XXX temporary sanity check to debug crashes.
870 int uid = (int)(token>>32);
871 if (uid > 0 && uid < 999) {
872 // In Android currently there are no uids in this range.
873 char buf[128];
874 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
875 jniThrowException(env, "java/lang/IllegalStateException", buf);
876 return;
877 }
878 IPCThreadState::self()->restoreCallingIdentity(token);
879 }
880
android_os_Binder_setThreadStrictModePolicy(JNIEnv * env,jobject clazz,jint policyMask)881 static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
882 {
883 IPCThreadState::self()->setStrictModePolicy(policyMask);
884 }
885
android_os_Binder_getThreadStrictModePolicy(JNIEnv * env,jobject clazz)886 static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
887 {
888 return IPCThreadState::self()->getStrictModePolicy();
889 }
890
android_os_Binder_flushPendingCommands(JNIEnv * env,jobject clazz)891 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
892 {
893 IPCThreadState::self()->flushCommands();
894 }
895
android_os_Binder_getNativeBBinderHolder(JNIEnv * env,jobject clazz)896 static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
897 {
898 JavaBBinderHolder* jbh = new JavaBBinderHolder();
899 return (jlong) jbh;
900 }
901
Binder_destroy(void * rawJbh)902 static void Binder_destroy(void* rawJbh)
903 {
904 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
905 ALOGV("Java Binder: deleting holder %p", jbh);
906 delete jbh;
907 }
908
android_os_Binder_getNativeFinalizer(JNIEnv *,jclass)909 JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
910 return (jlong) Binder_destroy;
911 }
912
android_os_Binder_blockUntilThreadAvailable(JNIEnv * env,jobject clazz)913 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
914 {
915 return IPCThreadState::self()->blockUntilThreadAvailable();
916 }
917
918 // ----------------------------------------------------------------------------
919
920 static const JNINativeMethod gBinderMethods[] = {
921 /* name, signature, funcPtr */
922 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
923 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
924 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
925 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
926 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
927 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
928 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
929 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
930 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
931 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
932 };
933
934 const char* const kBinderPathName = "android/os/Binder";
935
int_register_android_os_Binder(JNIEnv * env)936 static int int_register_android_os_Binder(JNIEnv* env)
937 {
938 jclass clazz = FindClassOrDie(env, kBinderPathName);
939
940 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
941 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
942 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
943
944 return RegisterMethodsOrDie(
945 env, kBinderPathName,
946 gBinderMethods, NELEM(gBinderMethods));
947 }
948
949 // ****************************************************************************
950 // ****************************************************************************
951 // ****************************************************************************
952
953 namespace android {
954
android_os_Debug_getLocalObjectCount(JNIEnv * env,jobject clazz)955 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
956 {
957 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
958 }
959
android_os_Debug_getProxyObjectCount(JNIEnv * env,jobject clazz)960 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
961 {
962 AutoMutex _l(gProxyLock);
963 return gNumProxies;
964 }
965
android_os_Debug_getDeathObjectCount(JNIEnv * env,jobject clazz)966 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
967 {
968 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
969 }
970
971 }
972
973 // ****************************************************************************
974 // ****************************************************************************
975 // ****************************************************************************
976
android_os_BinderInternal_getContextObject(JNIEnv * env,jobject clazz)977 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
978 {
979 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
980 return javaObjectForIBinder(env, b);
981 }
982
android_os_BinderInternal_joinThreadPool(JNIEnv * env,jobject clazz)983 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
984 {
985 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
986 android::IPCThreadState::self()->joinThreadPool();
987 }
988
android_os_BinderInternal_disableBackgroundScheduling(JNIEnv * env,jobject clazz,jboolean disable)989 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
990 jobject clazz, jboolean disable)
991 {
992 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
993 }
994
android_os_BinderInternal_setMaxThreads(JNIEnv * env,jobject clazz,jint maxThreads)995 static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
996 jobject clazz, jint maxThreads)
997 {
998 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
999 }
1000
android_os_BinderInternal_handleGc(JNIEnv * env,jobject clazz)1001 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1002 {
1003 ALOGV("Gc has executed, updating Refs count at GC");
1004 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
1005 }
1006
android_os_BinderInternal_proxyLimitcallback(int uid)1007 static void android_os_BinderInternal_proxyLimitcallback(int uid)
1008 {
1009 JNIEnv *env = AndroidRuntime::getJNIEnv();
1010 {
1011 // Calls into BinderProxy must be serialized
1012 AutoMutex _l(gProxyLock);
1013 env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
1014 gBinderProxyOffsets.mDumpProxyDebugInfo);
1015 }
1016 if (env->ExceptionCheck()) {
1017 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1018 report_exception(env, excep.get(),
1019 "*** Uncaught exception in dumpProxyDebugInfo");
1020 }
1021
1022 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1023 gBinderInternalOffsets.mProxyLimitCallback,
1024 uid);
1025
1026 if (env->ExceptionCheck()) {
1027 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1028 report_exception(env, excep.get(),
1029 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1030 }
1031 }
1032
android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv * env,jobject clazz,jboolean enable)1033 static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1034 jboolean enable)
1035 {
1036 BpBinder::setCountByUidEnabled((bool) enable);
1037 }
1038
android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv * env,jclass clazz)1039 static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1040 {
1041 Vector<uint32_t> uids, counts;
1042 BpBinder::getCountByUid(uids, counts);
1043 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1044 gSparseIntArrayOffsets.constructor);
1045 for (size_t i = 0; i < uids.size(); i++) {
1046 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1047 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1048 }
1049 return sparseIntArray;
1050 }
1051
android_os_BinderInternal_getBinderProxyCount(JNIEnv * env,jobject clazz,jint uid)1052 static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1053 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1054 }
1055
android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv * env,jobject clazz,jint high,jint low)1056 static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1057 jint high, jint low)
1058 {
1059 BpBinder::setBinderProxyCountWatermarks(high, low);
1060 }
1061
1062 // ----------------------------------------------------------------------------
1063
1064 static const JNINativeMethod gBinderInternalMethods[] = {
1065 /* name, signature, funcPtr */
1066 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1067 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
1068 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
1069 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
1070 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1071 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1072 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1073 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1074 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
1075 };
1076
1077 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1078
int_register_android_os_BinderInternal(JNIEnv * env)1079 static int int_register_android_os_BinderInternal(JNIEnv* env)
1080 {
1081 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
1082
1083 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1084 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
1085 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1086
1087 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1088 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1089 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1090 "<init>", "()V");
1091 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1092 "(II)V");
1093
1094 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
1095
1096 return RegisterMethodsOrDie(
1097 env, kBinderInternalPathName,
1098 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1099 }
1100
1101 // ****************************************************************************
1102 // ****************************************************************************
1103 // ****************************************************************************
1104
android_os_BinderProxy_pingBinder(JNIEnv * env,jobject obj)1105 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1106 {
1107 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1108 if (target == NULL) {
1109 return JNI_FALSE;
1110 }
1111 status_t err = target->pingBinder();
1112 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1113 }
1114
android_os_BinderProxy_getInterfaceDescriptor(JNIEnv * env,jobject obj)1115 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1116 {
1117 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1118 if (target != NULL) {
1119 const String16& desc = target->getInterfaceDescriptor();
1120 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1121 desc.size());
1122 }
1123 jniThrowException(env, "java/lang/RuntimeException",
1124 "No binder found for object");
1125 return NULL;
1126 }
1127
android_os_BinderProxy_isBinderAlive(JNIEnv * env,jobject obj)1128 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1129 {
1130 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1131 if (target == NULL) {
1132 return JNI_FALSE;
1133 }
1134 bool alive = target->isBinderAlive();
1135 return alive ? JNI_TRUE : JNI_FALSE;
1136 }
1137
getprocname(pid_t pid,char * buf,size_t len)1138 static int getprocname(pid_t pid, char *buf, size_t len) {
1139 char filename[32];
1140 FILE *f;
1141
1142 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
1143 f = fopen(filename, "r");
1144 if (!f) {
1145 *buf = '\0';
1146 return 1;
1147 }
1148 if (!fgets(buf, len, f)) {
1149 *buf = '\0';
1150 fclose(f);
1151 return 2;
1152 }
1153 fclose(f);
1154 return 0;
1155 }
1156
push_eventlog_string(char ** pos,const char * end,const char * str)1157 static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1158 jint len = strlen(str);
1159 int space_needed = 1 + sizeof(len) + len;
1160 if (end - *pos < space_needed) {
1161 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
1162 end - *pos, space_needed);
1163 return false;
1164 }
1165 **pos = EVENT_TYPE_STRING;
1166 (*pos)++;
1167 memcpy(*pos, &len, sizeof(len));
1168 *pos += sizeof(len);
1169 memcpy(*pos, str, len);
1170 *pos += len;
1171 return true;
1172 }
1173
push_eventlog_int(char ** pos,const char * end,jint val)1174 static bool push_eventlog_int(char** pos, const char* end, jint val) {
1175 int space_needed = 1 + sizeof(val);
1176 if (end - *pos < space_needed) {
1177 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
1178 end - *pos, space_needed);
1179 return false;
1180 }
1181 **pos = EVENT_TYPE_INT;
1182 (*pos)++;
1183 memcpy(*pos, &val, sizeof(val));
1184 *pos += sizeof(val);
1185 return true;
1186 }
1187
1188 // From frameworks/base/core/java/android/content/EventLogTags.logtags:
1189
1190 static const bool kEnableBinderSample = false;
1191
1192 #define LOGTAG_BINDER_OPERATION 52004
1193
conditionally_log_binder_call(int64_t start_millis,IBinder * target,jint code)1194 static void conditionally_log_binder_call(int64_t start_millis,
1195 IBinder* target, jint code) {
1196 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1197
1198 int sample_percent;
1199 if (duration_ms >= 500) {
1200 sample_percent = 100;
1201 } else {
1202 sample_percent = 100 * duration_ms / 500;
1203 if (sample_percent == 0) {
1204 return;
1205 }
1206 if (sample_percent < (random() % 100 + 1)) {
1207 return;
1208 }
1209 }
1210
1211 char process_name[40];
1212 getprocname(getpid(), process_name, sizeof(process_name));
1213 String8 desc(target->getInterfaceDescriptor());
1214
1215 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1216 buf[0] = EVENT_TYPE_LIST;
1217 buf[1] = 5;
1218 char* pos = &buf[2];
1219 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1220 if (!push_eventlog_string(&pos, end, desc.string())) return;
1221 if (!push_eventlog_int(&pos, end, code)) return;
1222 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1223 if (!push_eventlog_string(&pos, end, process_name)) return;
1224 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1225 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1226 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1227 }
1228
1229 // We only measure binder call durations to potentially log them if
1230 // we're on the main thread.
should_time_binder_calls()1231 static bool should_time_binder_calls() {
1232 return (getpid() == gettid());
1233 }
1234
android_os_BinderProxy_transact(JNIEnv * env,jobject obj,jint code,jobject dataObj,jobject replyObj,jint flags)1235 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1236 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1237 {
1238 if (dataObj == NULL) {
1239 jniThrowNullPointerException(env, NULL);
1240 return JNI_FALSE;
1241 }
1242
1243 Parcel* data = parcelForJavaObject(env, dataObj);
1244 if (data == NULL) {
1245 return JNI_FALSE;
1246 }
1247 Parcel* reply = parcelForJavaObject(env, replyObj);
1248 if (reply == NULL && replyObj != NULL) {
1249 return JNI_FALSE;
1250 }
1251
1252 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1253 if (target == NULL) {
1254 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1255 return JNI_FALSE;
1256 }
1257
1258 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1259 target, obj, code);
1260
1261
1262 bool time_binder_calls;
1263 int64_t start_millis;
1264 if (kEnableBinderSample) {
1265 // Only log the binder call duration for things on the Java-level main thread.
1266 // But if we don't
1267 time_binder_calls = should_time_binder_calls();
1268
1269 if (time_binder_calls) {
1270 start_millis = uptimeMillis();
1271 }
1272 }
1273
1274 //printf("Transact from Java code to %p sending: ", target); data->print();
1275 status_t err = target->transact(code, *data, reply, flags);
1276 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1277
1278 if (kEnableBinderSample) {
1279 if (time_binder_calls) {
1280 conditionally_log_binder_call(start_millis, target, code);
1281 }
1282 }
1283
1284 if (err == NO_ERROR) {
1285 return JNI_TRUE;
1286 } else if (err == UNKNOWN_TRANSACTION) {
1287 return JNI_FALSE;
1288 }
1289
1290 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1291 return JNI_FALSE;
1292 }
1293
android_os_BinderProxy_linkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1294 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1295 jobject recipient, jint flags) // throws RemoteException
1296 {
1297 if (recipient == NULL) {
1298 jniThrowNullPointerException(env, NULL);
1299 return;
1300 }
1301
1302 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1303 IBinder* target = nd->mObject.get();
1304
1305 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1306
1307 if (!target->localBinder()) {
1308 DeathRecipientList* list = nd->mOrgue.get();
1309 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1310 status_t err = target->linkToDeath(jdr, NULL, flags);
1311 if (err != NO_ERROR) {
1312 // Failure adding the death recipient, so clear its reference
1313 // now.
1314 jdr->clearReference();
1315 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1316 }
1317 }
1318 }
1319
android_os_BinderProxy_unlinkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1320 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1321 jobject recipient, jint flags)
1322 {
1323 jboolean res = JNI_FALSE;
1324 if (recipient == NULL) {
1325 jniThrowNullPointerException(env, NULL);
1326 return res;
1327 }
1328
1329 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1330 IBinder* target = nd->mObject.get();
1331 if (target == NULL) {
1332 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1333 return JNI_FALSE;
1334 }
1335
1336 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1337
1338 if (!target->localBinder()) {
1339 status_t err = NAME_NOT_FOUND;
1340
1341 // If we find the matching recipient, proceed to unlink using that
1342 DeathRecipientList* list = nd->mOrgue.get();
1343 sp<JavaDeathRecipient> origJDR = list->find(recipient);
1344 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
1345 if (origJDR != NULL) {
1346 wp<IBinder::DeathRecipient> dr;
1347 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1348 if (err == NO_ERROR && dr != NULL) {
1349 sp<IBinder::DeathRecipient> sdr = dr.promote();
1350 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1351 if (jdr != NULL) {
1352 jdr->clearReference();
1353 }
1354 }
1355 }
1356
1357 if (err == NO_ERROR || err == DEAD_OBJECT) {
1358 res = JNI_TRUE;
1359 } else {
1360 jniThrowException(env, "java/util/NoSuchElementException",
1361 "Death link does not exist");
1362 }
1363 }
1364
1365 return res;
1366 }
1367
BinderProxy_destroy(void * rawNativeData)1368 static void BinderProxy_destroy(void* rawNativeData)
1369 {
1370 // Don't race with construction/initialization
1371 AutoMutex _l(gProxyLock);
1372
1373 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1374 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1375 nativeData->mObject.get(), nativeData->mOrgue.get());
1376 delete nativeData;
1377 IPCThreadState::self()->flushCommands();
1378 --gNumProxies;
1379 }
1380
android_os_BinderProxy_getNativeFinalizer(JNIEnv *,jclass)1381 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1382 return (jlong) BinderProxy_destroy;
1383 }
1384
1385 // ----------------------------------------------------------------------------
1386
1387 static const JNINativeMethod gBinderProxyMethods[] = {
1388 /* name, signature, funcPtr */
1389 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1390 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1391 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1392 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1393 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1394 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1395 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
1396 };
1397
1398 const char* const kBinderProxyPathName = "android/os/BinderProxy";
1399
int_register_android_os_BinderProxy(JNIEnv * env)1400 static int int_register_android_os_BinderProxy(JNIEnv* env)
1401 {
1402 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1403 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1404
1405 clazz = FindClassOrDie(env, kBinderProxyPathName);
1406 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1407 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1408 "(JJ)Landroid/os/BinderProxy;");
1409 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1410 "(Landroid/os/IBinder$DeathRecipient;)V");
1411 gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo",
1412 "()V");
1413 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
1414
1415 clazz = FindClassOrDie(env, "java/lang/Class");
1416 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1417
1418 return RegisterMethodsOrDie(
1419 env, kBinderProxyPathName,
1420 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1421 }
1422
1423 // ****************************************************************************
1424 // ****************************************************************************
1425 // ****************************************************************************
1426
register_android_os_Binder(JNIEnv * env)1427 int register_android_os_Binder(JNIEnv* env)
1428 {
1429 if (int_register_android_os_Binder(env) < 0)
1430 return -1;
1431 if (int_register_android_os_BinderInternal(env) < 0)
1432 return -1;
1433 if (int_register_android_os_BinderProxy(env) < 0)
1434 return -1;
1435
1436 jclass clazz = FindClassOrDie(env, "android/util/Log");
1437 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1438 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1439 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1440
1441 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1442 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1443 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1444 "(Ljava/io/FileDescriptor;)V");
1445
1446 clazz = FindClassOrDie(env, "android/os/StrictMode");
1447 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1448 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1449 "onBinderStrictModePolicyChange", "(I)V");
1450
1451 clazz = FindClassOrDie(env, "java/lang/Thread");
1452 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1453 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1454 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1455 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1456 "()Ljava/lang/Thread;");
1457
1458 return 0;
1459 }
1460