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 #define LOG_TAG "JavaBinder"
17 // #define LOG_NDEBUG 0
18
19 #include "android_util_Binder.h"
20
21 #include <android-base/stringprintf.h>
22 #include <binder/BpBinder.h>
23 #include <binder/IInterface.h>
24 #include <binder/IPCThreadState.h>
25 #include <binder/IServiceManager.h>
26 #include <binder/Parcel.h>
27 #include <binder/ProcessState.h>
28 #include <binder/Stability.h>
29 #include <binderthreadstate/CallerUtils.h>
30 #include <cutils/atomic.h>
31 #include <fcntl.h>
32 #include <inttypes.h>
33 #include <log/log.h>
34 #include <nativehelper/JNIHelp.h>
35 #include <nativehelper/ScopedLocalRef.h>
36 #include <nativehelper/ScopedUtfChars.h>
37 #include <stdio.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #include <utils/KeyedVector.h>
42 #include <utils/List.h>
43 #include <utils/Log.h>
44 #include <utils/String8.h>
45 #include <utils/SystemClock.h>
46 #include <utils/threads.h>
47
48 #include <atomic>
49 #include <mutex>
50 #include <string>
51
52 #include "android_os_Parcel.h"
53 #include "core_jni_helpers.h"
54
55 //#undef ALOGV
56 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
57
58 #define DEBUG_DEATH_FREEZE 0
59 #if DEBUG_DEATH_FREEZE
60 #define LOG_DEATH_FREEZE ALOGD
61 #else
62 #define LOG_DEATH_FREEZE ALOGV
63 #endif
64
65 using namespace android;
66
67 // ----------------------------------------------------------------------------
68
69 static struct bindernative_offsets_t
70 {
71 // Class state.
72 jclass mClass;
73 jmethodID mExecTransact;
74 jmethodID mGetInterfaceDescriptor;
75 jmethodID mTransactionCallback;
76 jmethodID mGetExtension;
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 = sp<JavaBBinder>::make(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 (mSetExtensionCalled) {
493 jobject javaIBinderObject = env->CallObjectMethod(obj, gBinderOffsets.mGetExtension);
494 sp<IBinder> extensionFromJava = ibinderForJavaObject(env, javaIBinderObject);
495 if (extensionFromJava != nullptr) {
496 b.get()->setExtension(extensionFromJava);
497 }
498 }
499 mBinder = b;
500 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
501 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
502 }
503
504 return b;
505 }
506
getExisting()507 sp<JavaBBinder> getExisting()
508 {
509 AutoMutex _l(mLock);
510 return mBinder.promote();
511 }
512
markVintf()513 void markVintf() {
514 AutoMutex _l(mLock);
515 mVintf = true;
516 }
517
forceDowngradeToSystemStability()518 void forceDowngradeToSystemStability() {
519 AutoMutex _l(mLock);
520 mVintf = false;
521 }
522
setExtension(const sp<IBinder> & extension)523 void setExtension(const sp<IBinder>& extension) {
524 AutoMutex _l(mLock);
525 mSetExtensionCalled = true;
526 sp<JavaBBinder> b = mBinder.promote();
527 if (b != nullptr) {
528 b.get()->setExtension(extension);
529 }
530 }
531
532 private:
533 Mutex mLock;
534 wp<JavaBBinder> mBinder;
535
536 // in the future, we might condense this into int32_t stability, or if there
537 // is too much binder state here, we can think about making JavaBBinder an
538 // sp here (avoid recreating it)
539 bool mVintf = false;
540 bool mSetExtensionCalled = false;
541 };
542
543 // ----------------------------------------------------------------------------
544
545 // A JavaRecipient receives either death notifications or frozen state change
546 // callbacks from natve code (IBinder) and dispatch the notifications to its
547 // corresponding Java listener object.
548 //
549 // A RecipientList keeps tracks of all JavaRecipients for an IBinder. This way
550 // we can find a JavaRecipient given a Java listener object.
551 //
552 // The implementation is shared between death recipients and frozen state change
553 // callbacks via template. For death recipients the template is instantiated as
554 // follows:
555 //
556 // IBinder::DeathRecipient
557 // ^
558 // |
559 // (inherits)
560 // |
561 // JavaRecipient<IBinder::DeathRecipient> <----> RecipientList<IBinder::DeathRecipient>
562 // ^
563 // |
564 // (inherits)
565 // |
566 // JavaDeathRecipient
567 //
568 //
569 // The instantiation for frozen state change callbacks are:
570 //
571 // IBinder::FrozenStateChangeCallback
572 // ^
573 // |
574 // (inherits)
575 // |
576 // JavaRecipient<IBinder::FrozenStateChangeCallback>
577 // ^ ^
578 // | |
579 // (inherits) +--> RecipientList<IBinder::FrozenStateChangeCallback>
580 // |
581 // JavaFrozenStateChangeCallback
582
583 template <typename T>
584 class JavaRecipient;
585
586 template <typename T>
587 class RecipientList : public RefBase {
588 List<sp<JavaRecipient<T> > > mList;
589 Mutex mLock;
590
591 public:
592 RecipientList();
593 ~RecipientList();
594
595 void add(const sp<JavaRecipient<T> >& recipient);
596 void remove(const sp<JavaRecipient<T> >& recipient);
597 sp<JavaRecipient<T> > find(jobject recipient);
598
599 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
600 };
601
602 // ----------------------------------------------------------------------------
603 #ifdef BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
604 #if __BIONIC__
605 #include <android/api-level.h>
target_sdk_is_at_least_vic()606 static bool target_sdk_is_at_least_vic() {
607 return android_get_application_target_sdk_version() >= __ANDROID_API_V__;
608 }
609 #else
target_sdk_is_at_least_vic()610 static constexpr bool target_sdk_is_at_least_vic() {
611 // If not built for Android (i.e. glibc host), follow the latest behavior as there's no compat
612 // requirement there.
613 return true;
614 }
615 #endif // __BIONIC__
616 #endif // BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
617
618 template <typename T>
619 constexpr const char* logPrefix();
620
621 template <>
logPrefix()622 constexpr const char* logPrefix<IBinder::DeathRecipient>() {
623 return "[DEATH]";
624 }
625
626 template <>
logPrefix()627 constexpr const char* logPrefix<IBinder::FrozenStateChangeCallback>() {
628 return "[FREEZE]";
629 }
630
631 template <typename T>
632 class JavaRecipient : public T {
633 public:
JavaRecipient(JNIEnv * env,jobject object,const sp<RecipientList<T>> & list,bool useWeakReference)634 JavaRecipient(JNIEnv* env, jobject object, const sp<RecipientList<T> >& list,
635 bool useWeakReference)
636 : mVM(jnienv_to_javavm(env)), mObject(NULL), mObjectWeak(NULL), mList(list) {
637 if (useWeakReference) {
638 mObjectWeak = env->NewWeakGlobalRef(object);
639 } else {
640 mObject = env->NewGlobalRef(object);
641 }
642 }
643
onFirstRef()644 void onFirstRef() override {
645 T::onFirstRef();
646
647 sp<RecipientList<T>> list = mList.promote();
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(sp<JavaRecipient>::fromExisting(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(sp<JavaRecipient>::fromExisting(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> mFrozenStateChangeCallbackList;
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 = sp<DeathRecipientList>::make();
968 nativeData->mFrozenStateChangeCallbackList = sp<FrozenStateChangeCallbackList>::make();
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
1252
android_os_Binder_setExtension(JNIEnv * env,jobject obj,jobject extensionObject)1253 static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) {
1254 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
1255 sp<IBinder> extension = ibinderForJavaObject(env, extensionObject);
1256 jbh->setExtension(extension);
1257 }
1258
1259 // ----------------------------------------------------------------------------
1260
1261 // clang-format off
1262 static const JNINativeMethod gBinderMethods[] = {
1263 /* name, signature, funcPtr */
1264 // @CriticalNative
getCallingPid()1265 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
1266 // @CriticalNative
getCallingUid()1267 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
1268 // @CriticalNative
isDirectlyHandlingTransactionNative()1269 { "isDirectlyHandlingTransactionNative", "()Z",
1270 (void*)android_os_Binder_isDirectlyHandlingTransactionNative },
1271 // @CriticalNative
clearCallingIdentity()1272 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
1273 // @CriticalNative
restoreCallingIdentity(J)1274 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
1275 // @CriticalNative
hasExplicitIdentity()1276 { "hasExplicitIdentity", "()Z", (void*)android_os_Binder_hasExplicitIdentity },
1277 // @CriticalNative
setThreadStrictModePolicy(I)1278 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
1279 // @CriticalNative
getThreadStrictModePolicy()1280 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
1281 // @CriticalNative
setCallingWorkSourceUid(I)1282 { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
1283 // @CriticalNative
getCallingWorkSourceUid()1284 { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
1285 // @CriticalNative
clearCallingWorkSource()1286 { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
restoreCallingWorkSource(J)1287 { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
markVintfStability()1288 { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability},
forceDowngradeToSystemStability()1289 { "forceDowngradeToSystemStability", "()V", (void*)android_os_Binder_forceDowngradeToSystemStability},
flushPendingCommands()1290 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
getNativeBBinderHolder()1291 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
getNativeFinalizer()1292 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
blockUntilThreadAvailable()1293 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
setExtensionNative(Landroid/os/IBinder;)1294 { "setExtensionNative", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
1295 };
1296 // clang-format on
1297
1298 const char* const kBinderPathName = "android/os/Binder";
1299
int_register_android_os_Binder(JNIEnv * env)1300 static int int_register_android_os_Binder(JNIEnv* env)
1301 {
1302 jclass clazz = FindClassOrDie(env, kBinderPathName);
1303
1304 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1305 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
1306 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
1307 "()Ljava/lang/String;");
1308 gBinderOffsets.mTransactionCallback =
1309 GetStaticMethodIDOrDie(env, clazz, "transactionCallback", "(IIII)V");
1310 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1311 gBinderOffsets.mGetExtension = GetMethodIDOrDie(env, clazz, "getExtension",
1312 "()Landroid/os/IBinder;");
1313
1314 return RegisterMethodsOrDie(
1315 env, kBinderPathName,
1316 gBinderMethods, NELEM(gBinderMethods));
1317 }
1318
1319 // ****************************************************************************
1320 // ****************************************************************************
1321 // ****************************************************************************
1322
1323 namespace android {
1324
android_os_Debug_getLocalObjectCount(JNIEnv * env,jobject clazz)1325 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
1326 {
1327 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
1328 }
1329
android_os_Debug_getProxyObjectCount(JNIEnv * env,jobject clazz)1330 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
1331 {
1332 return BpBinder::getBinderProxyCount();
1333 }
1334
android_os_Debug_getDeathObjectCount(JNIEnv * env,jobject clazz)1335 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
1336 {
1337 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
1338 }
1339
1340 }
1341
1342 // ****************************************************************************
1343 // ****************************************************************************
1344 // ****************************************************************************
1345
android_os_BinderInternal_getContextObject(JNIEnv * env,jobject clazz)1346 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1347 {
1348 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1349 return javaObjectForIBinder(env, b);
1350 }
1351
android_os_BinderInternal_joinThreadPool(JNIEnv * env,jobject clazz)1352 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1353 {
1354 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1355 android::IPCThreadState::self()->joinThreadPool();
1356 }
1357
android_os_BinderInternal_disableBackgroundScheduling(JNIEnv * env,jobject clazz,jboolean disable)1358 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1359 jobject clazz, jboolean disable)
1360 {
1361 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1362 }
1363
android_os_BinderInternal_setMaxThreads(JNIEnv * env,jobject clazz,jint maxThreads)1364 static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1365 jobject clazz, jint maxThreads)
1366 {
1367 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1368 }
1369
android_os_BinderInternal_handleGc(JNIEnv * env,jobject clazz)1370 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1371 {
1372 ALOGV("Gc has executed, updating Refs count at GC");
1373 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
1374 }
1375
android_os_BinderInternal_proxyLimitCallback(int uid)1376 static void android_os_BinderInternal_proxyLimitCallback(int uid)
1377 {
1378 JNIEnv *env = AndroidRuntime::getJNIEnv();
1379 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1380 gBinderInternalOffsets.mProxyLimitCallback,
1381 uid);
1382
1383 if (env->ExceptionCheck()) {
1384 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1385 binder_report_exception(env, excep.get(),
1386 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1387 }
1388 }
1389
android_os_BinderInternal_proxyWarningCallback(int uid)1390 static void android_os_BinderInternal_proxyWarningCallback(int uid)
1391 {
1392 JNIEnv *env = AndroidRuntime::getJNIEnv();
1393 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1394 gBinderInternalOffsets.mProxyWarningCallback,
1395 uid);
1396
1397 if (env->ExceptionCheck()) {
1398 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1399 binder_report_exception(env, excep.get(),
1400 "*** Uncaught exception in binderProxyWarningCallbackFromNative");
1401 }
1402 }
1403
android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv * env,jobject clazz,jboolean enable)1404 static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1405 jboolean enable)
1406 {
1407 BpBinder::setCountByUidEnabled((bool) enable);
1408 }
1409
android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv * env,jclass clazz)1410 static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1411 {
1412 Vector<uint32_t> uids, counts;
1413 BpBinder::getCountByUid(uids, counts);
1414 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1415 gSparseIntArrayOffsets.constructor);
1416 for (size_t i = 0; i < uids.size(); i++) {
1417 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1418 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1419 }
1420 return sparseIntArray;
1421 }
1422
android_os_BinderInternal_getBinderProxyCount(JNIEnv * env,jobject clazz,jint uid)1423 static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1424 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1425 }
1426
android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv * env,jobject clazz,jint high,jint low,jint warning)1427 static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1428 jint high, jint low,
1429 jint warning)
1430 {
1431 BpBinder::setBinderProxyCountWatermarks(high, low, warning);
1432 }
1433
1434 // ----------------------------------------------------------------------------
1435
1436 static const JNINativeMethod gBinderInternalMethods[] = {
1437 /* name, signature, funcPtr */
getContextObject()1438 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
joinThreadPool()1439 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
disableBackgroundScheduling(Z)1440 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
setMaxThreads(I)1441 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
handleGc()1442 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
nSetBinderProxyCountEnabled(Z)1443 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
nGetBinderProxyPerUidCounts()1444 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
nGetBinderProxyCount(I)1445 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
nSetBinderProxyCountWatermarks(III)1446 { "nSetBinderProxyCountWatermarks", "(III)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
1447 };
1448
1449 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1450
int_register_android_os_BinderInternal(JNIEnv * env)1451 static int int_register_android_os_BinderInternal(JNIEnv* env)
1452 {
1453 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
1454
1455 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1456 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
1457 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1458 gBinderInternalOffsets.mProxyWarningCallback =
1459 GetStaticMethodIDOrDie(env, clazz, "binderProxyWarningCallbackFromNative", "(I)V");
1460
1461 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1462 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1463 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1464 "<init>", "()V");
1465 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1466 "(II)V");
1467
1468 BpBinder::setBinderProxyCountEventCallback(android_os_BinderInternal_proxyLimitCallback,
1469 android_os_BinderInternal_proxyWarningCallback);
1470
1471 return RegisterMethodsOrDie(
1472 env, kBinderInternalPathName,
1473 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1474 }
1475
1476 // ****************************************************************************
1477 // ****************************************************************************
1478 // ****************************************************************************
1479
android_os_BinderProxy_pingBinder(JNIEnv * env,jobject obj)1480 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1481 {
1482 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1483 if (target == NULL) {
1484 return JNI_FALSE;
1485 }
1486 status_t err = target->pingBinder();
1487 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1488 }
1489
android_os_BinderProxy_getInterfaceDescriptor(JNIEnv * env,jobject obj)1490 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1491 {
1492 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1493 if (target != NULL) {
1494 const String16& desc = target->getInterfaceDescriptor();
1495 return env->NewString(reinterpret_cast<const jchar*>(desc.c_str()), desc.size());
1496 }
1497 jniThrowException(env, "java/lang/RuntimeException",
1498 "No binder found for object");
1499 return NULL;
1500 }
1501
android_os_BinderProxy_isBinderAlive(JNIEnv * env,jobject obj)1502 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1503 {
1504 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1505 if (target == NULL) {
1506 return JNI_FALSE;
1507 }
1508 bool alive = target->isBinderAlive();
1509 return alive ? JNI_TRUE : JNI_FALSE;
1510 }
1511
android_os_BinderProxy_transact(JNIEnv * env,jobject obj,jint code,jobject dataObj,jobject replyObj,jint flags)1512 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1513 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1514 {
1515 if (dataObj == NULL) {
1516 jniThrowNullPointerException(env, NULL);
1517 return JNI_FALSE;
1518 }
1519
1520 Parcel* data = parcelForJavaObject(env, dataObj);
1521 if (data == NULL) {
1522 return JNI_FALSE;
1523 }
1524 Parcel* reply = parcelForJavaObject(env, replyObj);
1525 if (reply == NULL && replyObj != NULL) {
1526 return JNI_FALSE;
1527 }
1528
1529 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1530 if (target == NULL) {
1531 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1532 return JNI_FALSE;
1533 }
1534
1535 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1536 target, obj, code);
1537
1538 //printf("Transact from Java code to %p sending: ", target); data->print();
1539 status_t err = target->transact(code, *data, reply, flags);
1540 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1541
1542 if (err == NO_ERROR) {
1543 return JNI_TRUE;
1544 }
1545
1546 env->CallStaticVoidMethod(gBinderOffsets.mClass, gBinderOffsets.mTransactionCallback, getpid(),
1547 code, flags, err);
1548
1549 if (err == UNKNOWN_TRANSACTION) {
1550 return JNI_FALSE;
1551 }
1552
1553 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1554 return JNI_FALSE;
1555 }
1556
android_os_BinderProxy_linkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1557 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1558 jobject recipient, jint flags) // throws RemoteException
1559 {
1560 if (recipient == NULL) {
1561 jniThrowNullPointerException(env, NULL);
1562 return;
1563 }
1564
1565 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1566 IBinder* target = nd->mObject.get();
1567
1568 LOG_DEATH_FREEZE("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1569
1570 if (!target->localBinder()) {
1571 sp<DeathRecipientList> list = nd->mOrgue;
1572 sp<JavaDeathRecipient> jdr = sp<JavaDeathRecipient>::make(env, recipient, list);
1573 status_t err = target->linkToDeath(jdr, NULL, flags);
1574 if (err != NO_ERROR) {
1575 // Failure adding the death recipient, so clear its reference
1576 // now.
1577 jdr->clearReference();
1578 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1579 }
1580 }
1581 }
1582
android_os_BinderProxy_unlinkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1583 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1584 jobject recipient, jint flags)
1585 {
1586 jboolean res = JNI_FALSE;
1587 if (recipient == NULL) {
1588 jniThrowNullPointerException(env, NULL);
1589 return res;
1590 }
1591
1592 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1593 IBinder* target = nd->mObject.get();
1594 if (target == NULL) {
1595 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1596 return JNI_FALSE;
1597 }
1598
1599 LOG_DEATH_FREEZE("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1600
1601 if (!target->localBinder()) {
1602 status_t err = NAME_NOT_FOUND;
1603
1604 // If we find the matching recipient, proceed to unlink using that
1605 DeathRecipientList* list = nd->mOrgue.get();
1606 sp<JavaRecipient<IBinder::DeathRecipient> > origJDR = list->find(recipient);
1607 LOG_DEATH_FREEZE(" unlink found list %p and JDR %p", list, origJDR.get());
1608 if (origJDR != NULL) {
1609 wp<IBinder::DeathRecipient> dr;
1610 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1611 if (err == NO_ERROR && dr != NULL) {
1612 sp<IBinder::DeathRecipient> sdr = dr.promote();
1613 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1614 if (jdr != NULL) {
1615 jdr->clearReference();
1616 }
1617 }
1618 }
1619
1620 if (err == NO_ERROR || err == DEAD_OBJECT) {
1621 res = JNI_TRUE;
1622 } else {
1623 jniThrowException(env, "java/util/NoSuchElementException",
1624 base::StringPrintf("Death link does not exist (%s)",
1625 statusToString(err).c_str())
1626 .c_str());
1627 }
1628 }
1629
1630 return res;
1631 }
1632
android_os_BinderProxy_addFrozenStateChangeCallback(JNIEnv * env,jobject obj,jobject callback)1633 static void android_os_BinderProxy_addFrozenStateChangeCallback(
1634 JNIEnv* env, jobject obj,
1635 jobject callback) // throws RemoteException
1636 {
1637 if (callback == NULL) {
1638 jniThrowNullPointerException(env, NULL);
1639 return;
1640 }
1641
1642 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1643 IBinder* target = nd->mObject.get();
1644
1645 LOG_DEATH_FREEZE("addFrozenStateChangeCallback: binder=%p callback=%p\n", target, callback);
1646
1647 if (!target->localBinder()) {
1648 sp<FrozenStateChangeCallbackList> list = nd->mFrozenStateChangeCallbackList;
1649 auto jfscc = sp<JavaFrozenStateChangeCallback>::make(env, callback, list);
1650 status_t err = target->addFrozenStateChangeCallback(jfscc);
1651 if (err != NO_ERROR) {
1652 // Failure adding the callback, so clear its reference now.
1653 jfscc->clearReference();
1654 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1655 }
1656 }
1657 }
1658
android_os_BinderProxy_removeFrozenStateChangeCallback(JNIEnv * env,jobject obj,jobject callback)1659 static jboolean android_os_BinderProxy_removeFrozenStateChangeCallback(JNIEnv* env, jobject obj,
1660 jobject callback) {
1661 jboolean res = JNI_FALSE;
1662 if (callback == NULL) {
1663 jniThrowNullPointerException(env, NULL);
1664 return res;
1665 }
1666
1667 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1668 IBinder* target = nd->mObject.get();
1669 if (target == NULL) {
1670 ALOGW("Binder has been finalized when calling removeFrozenStateChangeCallback() with "
1671 "callback=%p)\n",
1672 callback);
1673 return JNI_FALSE;
1674 }
1675
1676 LOG_DEATH_FREEZE("removeFrozenStateChangeCallback: binder=%p callback=%p\n", target, callback);
1677
1678 if (!target->localBinder()) {
1679 status_t err = NAME_NOT_FOUND;
1680
1681 // If we find the matching callback, proceed to unlink using that
1682 FrozenStateChangeCallbackList* list = nd->mFrozenStateChangeCallbackList.get();
1683 sp<JavaRecipient<IBinder::FrozenStateChangeCallback> > origJFSCC = list->find(callback);
1684 LOG_DEATH_FREEZE(" removeFrozenStateChangeCallback found list %p and JFSCC %p", list,
1685 origJFSCC.get());
1686 if (origJFSCC != NULL) {
1687 err = target->removeFrozenStateChangeCallback(origJFSCC);
1688 if (err == NO_ERROR) {
1689 origJFSCC->clearReference();
1690 }
1691 }
1692
1693 if (err == NO_ERROR || err == DEAD_OBJECT) {
1694 res = JNI_TRUE;
1695 } else {
1696 jniThrowException(env, "java/util/NoSuchElementException",
1697 base::StringPrintf("Frozen state change callback does not exist (%s)",
1698 statusToString(err).c_str())
1699 .c_str());
1700 }
1701 }
1702
1703 return res;
1704 }
1705
android_os_BinderProxy_frozenStateChangeCallbackSupported(JNIEnv *,jclass *)1706 static jboolean android_os_BinderProxy_frozenStateChangeCallbackSupported(JNIEnv*, jclass*) {
1707 return ProcessState::isDriverFeatureEnabled(ProcessState::DriverFeature::FREEZE_NOTIFICATION);
1708 }
1709
BinderProxy_destroy(void * rawNativeData)1710 static void BinderProxy_destroy(void* rawNativeData)
1711 {
1712 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1713 LOG_DEATH_FREEZE("Destroying BinderProxy: binder=%p drl=%p fsccl=%p\n",
1714 nativeData->mObject.get(), nativeData->mOrgue.get(),
1715 nativeData->mFrozenStateChangeCallbackList.get());
1716 delete nativeData;
1717 IPCThreadState::self()->flushCommands();
1718 }
1719
android_os_BinderProxy_getNativeFinalizer(JNIEnv *,jclass)1720 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1721 return (jlong) BinderProxy_destroy;
1722 }
1723
android_os_BinderProxy_getExtension(JNIEnv * env,jobject obj)1724 static jobject android_os_BinderProxy_getExtension(JNIEnv* env, jobject obj) {
1725 IBinder* binder = getBPNativeData(env, obj)->mObject.get();
1726 if (binder == nullptr) {
1727 jniThrowException(env, "java/lang/IllegalStateException", "Native IBinder is null");
1728 return nullptr;
1729 }
1730 sp<IBinder> extension;
1731 status_t err = binder->getExtension(&extension);
1732 if (err != OK) {
1733 signalExceptionForError(env, obj, err, true /* canThrowRemoteException */);
1734 return nullptr;
1735 }
1736 return javaObjectForIBinder(env, extension);
1737 }
1738
1739 // ----------------------------------------------------------------------------
1740
1741 // clang-format off
1742 static const JNINativeMethod gBinderProxyMethods[] = {
1743 /* name, signature, funcPtr */
pingBinder()1744 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
isBinderAlive()1745 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
getInterfaceDescriptor()1746 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
transactNative(ILandroid/os/Parcel;Landroid/os/Parcel;I)1747 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
linkToDeathNative(Landroid/os/IBinder$DeathRecipient;I)1748 {"linkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
unlinkToDeathNative(Landroid/os/IBinder$DeathRecipient;I)1749 {"unlinkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
addFrozenStateChangeCallbackNative(Landroid/os/IBinder$FrozenStateChangeCallback;)1750 {"addFrozenStateChangeCallbackNative",
1751 "(Landroid/os/IBinder$FrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback},
removeFrozenStateChangeCallbackNative(Landroid/os/IBinder$FrozenStateChangeCallback;)1752 {"removeFrozenStateChangeCallbackNative",
1753 "(Landroid/os/IBinder$FrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback},
isFrozenStateChangeCallbackSupportedNative()1754 {"isFrozenStateChangeCallbackSupportedNative",
1755 "()Z", (void*)android_os_BinderProxy_frozenStateChangeCallbackSupported},
getNativeFinalizer()1756 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
getExtension()1757 {"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
1758 };
1759 // clang-format on
1760
1761 const char* const kBinderProxyPathName = "android/os/BinderProxy";
1762
int_register_android_os_BinderProxy(JNIEnv * env)1763 static int int_register_android_os_BinderProxy(JNIEnv* env)
1764 {
1765 gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
1766 gErrorOffsets.mOutOfMemory =
1767 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
1768 gErrorOffsets.mStackOverflow =
1769 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
1770
1771 jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
1772 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1773 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1774 "(JJ)Landroid/os/BinderProxy;");
1775 gBinderProxyOffsets.mSendDeathNotice =
1776 GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1777 "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
1778 gBinderProxyOffsets.mInvokeFrozenStateChangeCallback =
1779 GetStaticMethodIDOrDie(env, clazz, "invokeFrozenStateChangeCallback",
1780 "(Landroid/os/IBinder$FrozenStateChangeCallback;Landroid/os/"
1781 "IBinder;I)V");
1782 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
1783
1784 clazz = FindClassOrDie(env, "java/lang/Class");
1785 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1786
1787 return RegisterMethodsOrDie(
1788 env, kBinderProxyPathName,
1789 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1790 }
1791
1792 // ****************************************************************************
1793 // ****************************************************************************
1794 // ****************************************************************************
1795
register_android_os_Binder(JNIEnv * env)1796 int register_android_os_Binder(JNIEnv* env)
1797 {
1798 if (int_register_android_os_Binder(env) < 0)
1799 return -1;
1800 if (int_register_android_os_BinderInternal(env) < 0)
1801 return -1;
1802 if (int_register_android_os_BinderProxy(env) < 0)
1803 return -1;
1804
1805 jclass clazz = FindClassOrDie(env, "android/util/Log");
1806 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1807 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1808 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1809
1810 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1811 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1812 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1813 "(Ljava/io/FileDescriptor;)V");
1814
1815 clazz = FindClassOrDie(env, "android/os/StrictMode");
1816 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1817 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1818 "onBinderStrictModePolicyChange", "(I)V");
1819
1820 clazz = FindClassOrDie(env, "java/lang/Thread");
1821 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1822 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1823 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1824 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1825 "()Ljava/lang/Thread;");
1826
1827 return 0;
1828 }
1829