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

Commit b94da308 authored by Chavi Weingarten's avatar Chavi Weingarten
Browse files

Add native InputTransferToken

Added a native class that corresponds to the Java InputTransferToken.

Test: SurfaceControlInputReceiverTests
Test: AInputTransferTokenTest
Bug: 324271765
Change-Id: Ic5549227ad8c8ab311f8953eaf370e1a2896d8f3
parent d2a2fae7
Loading
Loading
Loading
Loading
+34 −10
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.window;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
@@ -30,6 +29,8 @@ import android.view.SurfaceControlViewHost;

import com.android.window.flags.Flags;

import libcore.util.NativeAllocationRegistry;

import java.util.Objects;

/**
@@ -51,28 +52,51 @@ import java.util.Objects;
 */
@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER)
public final class InputTransferToken implements Parcelable {
    private static native long nativeCreate();
    private static native long nativeCreate(IBinder token);
    private static native void nativeWriteToParcel(long nativeObject, Parcel out);
    private static native long nativeReadFromParcel(Parcel in);
    private static native IBinder nativeGetBinderToken(long nativeObject);
    private static native long nativeGetNativeInputTransferTokenFinalizer();
    private static native boolean nativeEquals(long nativeObject1, long nativeObject2);

    private static final NativeAllocationRegistry sRegistry =
            NativeAllocationRegistry.createMalloced(InputTransferToken.class.getClassLoader(),
                    nativeGetNativeInputTransferTokenFinalizer());

    /**
     * @hide
     */
    @NonNull
    public final IBinder mToken;
    public final long mNativeObject;

    private InputTransferToken(long nativeObject) {
        mNativeObject = nativeObject;
        sRegistry.registerNativeAllocation(this, nativeObject);
    }

    /**
     * @hide
     */
    public InputTransferToken(@NonNull IBinder token) {
        mToken = token;
        this(nativeCreate(token));
    }

    /**
     * @hide
     */
    public InputTransferToken() {
        mToken = new Binder();
        this(nativeCreate());
    }

    /**
     * @hide
     */
    public IBinder getToken() {
        return nativeGetBinderToken(mNativeObject);
    }

    private InputTransferToken(Parcel in) {
        mToken = in.readStrongBinder();
        this(nativeReadFromParcel(in));
    }

    /**
@@ -88,7 +112,7 @@ public final class InputTransferToken implements Parcelable {
     */
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeStrongBinder(mToken);
        nativeWriteToParcel(mNativeObject, dest);
    }

    public static final @NonNull Creator<InputTransferToken> CREATOR = new Creator<>() {
@@ -101,13 +125,12 @@ public final class InputTransferToken implements Parcelable {
        }
    };


    /**
     * @hide
     */
    @Override
    public int hashCode() {
        return Objects.hash(mToken);
        return Objects.hash(getToken());
    }

    /**
@@ -118,7 +141,8 @@ public final class InputTransferToken implements Parcelable {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        InputTransferToken other = (InputTransferToken) obj;
        return other.mToken == mToken;
        if (other.mNativeObject == mNativeObject) return true;
        return nativeEquals(mNativeObject, other.mNativeObject);
    }

}
+1 −0
Original line number Diff line number Diff line
@@ -265,6 +265,7 @@ cc_library_shared_for_libandroid_runtime {
                "fd_utils.cpp",
                "android_hardware_input_InputWindowHandle.cpp",
                "android_hardware_input_InputApplicationHandle.cpp",
                "android_window_InputTransferToken.cpp",
                "android_window_WindowInfosListener.cpp",
                "android_window_ScreenCapture.cpp",
                "jni_common.cpp",
+2 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ extern int register_jni_common(JNIEnv* env);
extern int register_android_tracing_PerfettoDataSource(JNIEnv* env);
extern int register_android_tracing_PerfettoDataSourceInstance(JNIEnv* env);
extern int register_android_tracing_PerfettoProducer(JNIEnv* env);
extern int register_android_window_InputTransferToken(JNIEnv* env);

// Namespace for Android Runtime flags applied during boot time.
static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
@@ -1678,6 +1679,7 @@ static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_android_tracing_PerfettoDataSource),
        REG_JNI(register_android_tracing_PerfettoDataSourceInstance),
        REG_JNI(register_android_tracing_PerfettoProducer),
        REG_JNI(register_android_window_InputTransferToken),
};

/*
+138 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "InputTransferToken"

#include <android_runtime/android_window_InputTransferToken.h>
#include <gui/InputTransferToken.h>
#include <nativehelper/JNIHelp.h>

#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "core_jni_helpers.h"

namespace android {

static struct {
    jclass clazz;
    jfieldID mNativeObject;
    jmethodID ctor;
} gInputTransferTokenClassInfo;

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make();
    inputTransferToken->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(inputTransferToken.get());
}

static jlong nativeCreateFromBinder(JNIEnv* env, jclass clazz, jobject tokenBinderObj) {
    if (tokenBinderObj == nullptr) {
        return 0;
    }
    sp<IBinder> token(ibinderForJavaObject(env, tokenBinderObj));
    if (token == nullptr) {
        return 0;
    }
    sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make(token);
    inputTransferToken->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(inputTransferToken.get());
}

static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObj, jobject parcelObj) {
    InputTransferToken* inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
    Parcel* parcel = parcelForJavaObject(env, parcelObj);
    inputTransferToken->writeToParcel(parcel);
}

static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
    sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make();
    Parcel* parcel = parcelForJavaObject(env, parcelObj);
    inputTransferToken->readFromParcel(parcel);
    inputTransferToken->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(inputTransferToken.get());
}

static jobject nativeGetBinderToken(JNIEnv* env, jclass clazz, jlong nativeObj) {
    sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
    return javaObjectForIBinder(env, inputTransferToken->mToken);
}

InputTransferToken* android_window_InputTransferToken_getNativeInputTransferToken(
        JNIEnv* env, jobject inputTransferTokenObj) {
    if (inputTransferTokenObj != nullptr &&
        env->IsInstanceOf(inputTransferTokenObj, gInputTransferTokenClassInfo.clazz)) {
        return reinterpret_cast<InputTransferToken*>(
                env->GetLongField(inputTransferTokenObj,
                                  gInputTransferTokenClassInfo.mNativeObject));
    } else {
        return nullptr;
    }
}

jobject android_window_InputTransferToken_getJavaInputTransferToken(
        JNIEnv* env, const InputTransferToken* inputTransferToken) {
    if (inputTransferToken == nullptr || env == nullptr) {
        return nullptr;
    }

    inputTransferToken->incStrong((void*)nativeCreate);
    return env->NewObject(gInputTransferTokenClassInfo.clazz, gInputTransferTokenClassInfo.ctor,
                          reinterpret_cast<jlong>(inputTransferToken));
}

static void release(InputTransferToken* inputTransferToken) {
    inputTransferToken->decStrong((void*)nativeCreate);
}

static jlong nativeGetNativeInputTransferTokenFinalizer(JNIEnv* env, jclass clazz) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&release));
}

static bool nativeEquals(JNIEnv* env, jclass clazz, jlong inputTransferTokenObj1,
                         jlong inputTransferTokenObj2) {
    sp<InputTransferToken> inputTransferToken1(
            reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1));
    sp<InputTransferToken> inputTransferToken2(
            reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2));

    return inputTransferToken1 == inputTransferToken2;
}

static const JNINativeMethod sInputTransferTokenMethods[] = {
        // clang-format off
    {"nativeCreate", "()J", (void*)nativeCreate},
    {"nativeCreate", "(Landroid/os/IBinder;)J", (void*)nativeCreateFromBinder},
    {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel},
    {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", (void*)nativeReadFromParcel},
    {"nativeGetBinderToken", "(J)Landroid/os/IBinder;", (void*)nativeGetBinderToken},
    {"nativeGetNativeInputTransferTokenFinalizer", "()J", (void*)nativeGetNativeInputTransferTokenFinalizer},
        {"nativeEquals", "(JJ)Z", (void*) nativeEquals},
        // clang-format on
};

int register_android_window_InputTransferToken(JNIEnv* env) {
    int err = RegisterMethodsOrDie(env, "android/window/InputTransferToken",
                                   sInputTransferTokenMethods, NELEM(sInputTransferTokenMethods));
    jclass inputTransferTokenClass = FindClassOrDie(env, "android/window/InputTransferToken");
    gInputTransferTokenClassInfo.clazz = MakeGlobalRefOrDie(env, inputTransferTokenClass);
    gInputTransferTokenClassInfo.mNativeObject =
            GetFieldIDOrDie(env, gInputTransferTokenClassInfo.clazz, "mNativeObject", "J");
    gInputTransferTokenClassInfo.ctor =
            GetMethodIDOrDie(env, gInputTransferTokenClassInfo.clazz, "<init>", "(J)V");
    return err;
}

} // namespace android
 No newline at end of file
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _ANDROID_WINDOW_INPUTTRANSFERTOKEN_H
#define _ANDROID_WINDOW_INPUTTRANSFERTOKEN_H

#include <gui/InputTransferToken.h>
#include <jni.h>

namespace android {

extern InputTransferToken* android_window_InputTransferToken_getNativeInputTransferToken(
        JNIEnv* env, jobject inputTransferTokenObj);

extern jobject android_window_InputTransferToken_getJavaInputTransferToken(
        JNIEnv* env, const InputTransferToken* inputTransferToken);

} // namespace android

#endif // _ANDROID_WINDOW_INPUTTRANSFERTOKEN_H
Loading