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