什么是Parcel.enforceInterface?

时间:2016-04-19 03:41:05

标签: android parcelable parcel

有人能告诉我Android的Parcel类中的enforceInterface方法有什么用吗?开发者网站没有解释其目的,谷歌也没有返回任何有用的点击。

感谢。

1 个答案:

答案 0 :(得分:0)

此方法将在处理RPC调用时检查客户端和服务器端之间的接口是否相同。

详细过程:

  1. 客户端调用服务器远程方法,在调用mRemote.transact之前,此方法_data.writeInterfaceToken(DESCRIPTOR);将首先调用。
  2. 将调用服务器端onTransact,然后调用data.enforceInterface(descriptor);以检查接口是否相同,如果不匹配,则会抛出错误"Binder invocation to an incorrect interface"
  3. li>

包裹源代码:

static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const jchar* str = env->GetStringCritical(name, 0);
        if (str) {
            IPCThreadState* threadState = IPCThreadState::self();
            const int32_t oldPolicy = threadState->getStrictModePolicy();
            const bool isValid = parcel->enforceInterface(
                String16(reinterpret_cast<const char16_t*>(str),
                        env->GetStringLength(name)),
                threadState);
            env->ReleaseStringCritical(name, str);
            if (isValid) {
                const int32_t newPolicy = threadState->getStrictModePolicy();
                if (oldPolicy != newPolicy) {
                    // Need to keep the Java-level thread-local strict
                    // mode policy in sync for the libcore
                    // enforcements, which involves an upcall back
                    // into Java.  (We can't modify the
                    // Parcel.enforceInterface signature, as it's
                    // pseudo-public, and used via AIDL
                    // auto-generation...)
                    set_dalvik_blockguard_policy(env, newPolicy);
                }
                return;     // everything was correct -> return silently
            }
        }
    }

    // all error conditions wind up here
    jniThrowException(env, "java/lang/SecurityException",
            "Binder invocation to an incorrect interface");
}


bool Parcel::enforceInterface(const String16& interface,
                            IPCThreadState* threadState) const
{
    int32_t strictPolicy = readInt32();
    if (threadState == NULL) {
        threadState = IPCThreadState::self();
    }
    if ((threadState->getLastTransactionBinderFlags() &
        IBinder::FLAG_ONEWAY) != 0) {
    // For one-way calls, the callee is running entirely
    // disconnected from the caller, so disable StrictMode entirely.
    // Not only does disk/network usage not impact the caller, but
    // there's no way to commuicate back any violations anyway.
    threadState->setStrictModePolicy(0);
    } else {
    threadState->setStrictModePolicy(strictPolicy);
    }
    const String16 str(readString16());
    if (str == interface) {
        return true;
    } else {
        ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
                String8(interface).string(), String8(str).string());
        return false;
    }
}