• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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