xref: /aosp_15_r20/frameworks/base/core/jni/android_util_Binder.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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