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