Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fae6266 authored by Andreas Gampe's avatar Andreas Gampe Committed by android-build-merger
Browse files

Merge changes I119cf83a,Icc5a1e38,If07a04d3

am: 61e3189e

Change-Id: I2ef7c49b23314a5cb94671bba0d3891b6b7c3920
parents 34b5b69d 61e3189e
Loading
Loading
Loading
Loading
+97 −65
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@
#include "android_os_Parcel.h"
#include "android_util_Binder.h"

#include <nativehelper/JNIHelp.h>

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
@@ -44,8 +42,9 @@
#include <utils/SystemClock.h>
#include <utils/threads.h>

#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedUtfChars.h>

#include "core_jni_helpers.h"

@@ -133,6 +132,14 @@ static struct strict_mode_callback_offsets_t
    jmethodID mCallback;
} gStrictModeCallbackOffsets;

static struct thread_dispatch_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mDispatchUncaughtException;
    jmethodID mCurrentThread;
} gThreadDispatchOffsets;

// ****************************************************************************
// ****************************************************************************
// ****************************************************************************
@@ -166,56 +173,36 @@ static JNIEnv* javavm_to_jnienv(JavaVM* vm)
    return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
}

static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
// Report a java.lang.Error (or subclass). This will terminate the runtime by
// calling FatalError with a message derived from the given error.
static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
        const char* msg)
{
    env->ExceptionClear();

    jstring tagstr = env->NewStringUTF(LOG_TAG);
    jstring msgstr = NULL;
    if (tagstr != NULL) {
        msgstr = env->NewStringUTF(msg);
    }

    if ((tagstr == NULL) || (msgstr == NULL)) {
        env->ExceptionClear();      /* assume exception (OOM?) was thrown */
        ALOGE("Unable to call Log.e()\n");
        ALOGE("%s", msg);
        goto bail;
    }

    env->CallStaticIntMethod(
        gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
    if (env->ExceptionCheck()) {
        /* attempting to log the failure has failed */
        ALOGW("Failed trying to log exception, msg='%s'\n", msg);
        env->ExceptionClear();
    }

    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
        /*
         * It's an Error: Reraise the exception and ask the runtime to abort.
         */
    // Report an error: reraise the exception and ask the runtime to abort.

    // Try to get the exception string. Sometimes logcat isn't available,
    // so try to add it to the abort message.
    std::string exc_msg = "(Unknown exception message)";
    {
            ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(excep));
            jmethodID method_id = env->GetMethodID(exc_class.get(),
                                                   "toString",
        ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
        jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
                "()Ljava/lang/String;");
        ScopedLocalRef<jstring> jstr(
                env,
                reinterpret_cast<jstring>(
                            env->CallObjectMethod(excep, method_id)));
                        env->CallObjectMethod(error, method_id)));
        env->ExceptionClear();  // Just for good measure.
        if (jstr.get() != nullptr) {
            ScopedUtfChars jstr_utf(env, jstr.get());
            if (jstr_utf.c_str() != nullptr) {
                exc_msg = jstr_utf.c_str();
            } else {
                env->ExceptionClear();
            }
        }
    }

        env->Throw(excep);
    env->Throw(error);
    ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
    env->ExceptionDescribe();

@@ -225,10 +212,54 @@ static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
    env->FatalError(error_msg.c_str());
}

bail:
    /* discard local refs created for us by VM */
    env->DeleteLocalRef(tagstr);
    env->DeleteLocalRef(msgstr);
// Report a java.lang.Error (or subclass). This will terminate the runtime, either by
// the uncaught exception handler, or explicitly by calling
// report_java_lang_error_fatal_error.
static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
{
    // Try to run the uncaught exception machinery.
    jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
            gThreadDispatchOffsets.mCurrentThread);
    if (thread != nullptr) {
        env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
                error);
        // Should not return here, unless more errors occured.
    }
    // Some error occurred that meant that either dispatchUncaughtException could not be
    // called or that it had an error itself (as this should be unreachable under normal
    // conditions). As the binder code cannot handle Errors, attempt to log the error and
    // abort.
    env->ExceptionClear();
    report_java_lang_error_fatal_error(env, error, msg);
}

static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
{
    env->ExceptionClear();

    ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
    ScopedLocalRef<jstring> msgstr(env);
    if (tagstr != nullptr) {
        msgstr.reset(env->NewStringUTF(msg));
    }

    if ((tagstr != nullptr) && (msgstr != nullptr)) {
        env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
                tagstr.get(), msgstr.get(), excep);
        if (env->ExceptionCheck()) {
            // Attempting to log the failure has failed.
            ALOGW("Failed trying to log exception, msg='%s'\n", msg);
            env->ExceptionClear();
        }
    } else {
        env->ExceptionClear();      /* assume exception (OOM?) was thrown */
        ALOGE("Unable to call Log.e()\n");
        ALOGE("%s", msg);
    }

    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
        report_java_lang_error(env, excep, msg);
    }
}

class JavaBBinderHolder;
@@ -280,14 +311,11 @@ protected:
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

        if (env->ExceptionCheck()) {
            jthrowable excep = env->ExceptionOccurred();
            report_exception(env, excep,
            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
            report_exception(env, excep.get(),
                "*** Uncaught remote exception!  "
                "(Exceptions are not yet supported across processes.)");
            res = JNI_FALSE;

            /* clean up JNI local ref -- we don't return to Java code */
            env->DeleteLocalRef(excep);
        }

        // Check if the strict mode state changed while processing the
@@ -299,11 +327,9 @@ protected:
        }

        if (env->ExceptionCheck()) {
            jthrowable excep = env->ExceptionOccurred();
            report_exception(env, excep,
            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
            report_exception(env, excep.get(),
                "*** Uncaught exception in onBinderStrictModePolicyChange");
            /* clean up JNI local ref -- we don't return to Java code */
            env->DeleteLocalRef(excep);
        }

        // Need to always call through the native implementation of
@@ -446,9 +472,8 @@ public:
        if (mObject != NULL) {
            result = env->IsSameObject(obj, mObject);
        } else {
            jobject me = env->NewLocalRef(mObjectWeak);
            result = env->IsSameObject(obj, me);
            env->DeleteLocalRef(me);
            ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
            result = env->IsSameObject(obj, me.get());
        }
        return result;
    }
@@ -1337,5 +1362,12 @@ int register_android_os_Binder(JNIEnv* env)
    gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
            "onBinderStrictModePolicyChange", "(I)V");

    clazz = FindClassOrDie(env, "java/lang/Thread");
    gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
            "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
    gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
            "()Ljava/lang/Thread;");

    return 0;
}