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

Commit c62e38d5 authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk
Browse files

Use ParcelableException to carry RuntimeException over AIDL.

Test: instrumentation
Bug: b/36863239
Change-Id: Iff55c0d188c360c8bf8ec74de560c42af6fa998d
parent bad4cd2b
Loading
Loading
Loading
Loading
+40 −7
Original line number Diff line number Diff line
@@ -79,13 +79,22 @@ static struct {
        jmethodID putBitmapFromNative;
        jmethodID putClockFromNative;
    } RadioMetadata;

    struct {
        jclass clazz;
        jmethodID cstor;
    } RuntimeException;

    struct {
        jclass clazz;
        jmethodID cstor;
    } ParcelableException;
} gjni;

bool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
    if (hidlResult.isOk()) return false;

    jniThrowExceptionFmt(env, "java/lang/RuntimeException",
            "HIDL call failed: %s", hidlResult.description().c_str());
    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
    return true;
}

@@ -94,7 +103,7 @@ bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
        case Result::OK:
            return false;
        case Result::NOT_INITIALIZED:
            jniThrowRuntimeException(env, "Result::NOT_INITIALIZED");
            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
            return true;
        case Result::INVALID_ARGUMENTS:
            jniThrowException(env, "java/lang/IllegalArgumentException",
@@ -104,11 +113,11 @@ bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
            return true;
        case Result::TIMEOUT:
            jniThrowRuntimeException(env, "Result::TIMEOUT (unexpected here)");
            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
            return true;
        default:
            jniThrowExceptionFmt(env, "java/lang/RuntimeException",
                    "Unknown failure, result: %d", halResult);
            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
                    + std::to_string(static_cast<int32_t>(halResult)));
            return true;
    }
}
@@ -122,13 +131,27 @@ bool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
            return true;
        case ProgramListResult::UNAVAILABLE:
            jniThrowRuntimeException(env, "ProgramListResult::UNAVAILABLE (unexpected here)");
            ThrowParcelableRuntimeException(env,
                    "ProgramListResult::UNAVAILABLE (unexpected here)");
            return true;
        default:
            return __ThrowIfFailed(env, static_cast<Result>(halResult));
    }
}

void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
    EnvWrapper wrap(env);

    auto jMsg = wrap(env->NewStringUTF(msg.c_str()));
    auto runtimeExc = wrap(env->NewObject(gjni.RuntimeException.clazz,
            gjni.RuntimeException.cstor, jMsg.get()));
    auto parcelableExc = wrap(env->NewObject(gjni.ParcelableException.clazz,
            gjni.ParcelableException.cstor, runtimeExc.get()));

    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
}

static Rds RdsForRegion(bool rds, Region region) {
    if (!rds) return Rds::NONE;

@@ -359,6 +382,16 @@ void register_android_server_radio_convert(JNIEnv *env) {
            "putBitmapFromNative", "(I[B)I");
    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
            "putClockFromNative", "(IJI)I");

    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
            "(Ljava/lang/String;)V");

    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
            "(Ljava/lang/Throwable;)V");
}

} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info);
JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);


void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg);

// These three are only for internal use by template functions below.
bool __ThrowIfFailedHidl(JNIEnv *env,
        const hardware::details::return_status &hidlResult);