1 /*
2 * Copyright (C) 2024 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
17 #define LOG_TAG "InputTransferToken"
18
19 #include <android_runtime/android_window_InputTransferToken.h>
20 #include <gui/InputTransferToken.h>
21 #include <nativehelper/JNIHelp.h>
22
23 #include "android_os_Parcel.h"
24 #include "android_util_Binder.h"
25 #include "core_jni_helpers.h"
26
27 namespace android {
28
29 static struct {
30 jclass clazz;
31 jfieldID mNativeObject;
32 jmethodID ctor;
33 } gInputTransferTokenClassInfo;
34
nativeCreate(JNIEnv * env,jclass clazz)35 static jlong nativeCreate(JNIEnv* env, jclass clazz) {
36 sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make();
37 inputTransferToken->incStrong((void*)nativeCreate);
38 return reinterpret_cast<jlong>(inputTransferToken.get());
39 }
40
nativeCreateFromBinder(JNIEnv * env,jclass clazz,jobject tokenBinderObj)41 static jlong nativeCreateFromBinder(JNIEnv* env, jclass clazz, jobject tokenBinderObj) {
42 if (tokenBinderObj == nullptr) {
43 return 0;
44 }
45 sp<IBinder> token(ibinderForJavaObject(env, tokenBinderObj));
46 if (token == nullptr) {
47 return 0;
48 }
49 sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make(token);
50 inputTransferToken->incStrong((void*)nativeCreate);
51 return reinterpret_cast<jlong>(inputTransferToken.get());
52 }
53
nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativeObj,jobject parcelObj)54 static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObj, jobject parcelObj) {
55 InputTransferToken* inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
56 Parcel* parcel = parcelForJavaObject(env, parcelObj);
57 inputTransferToken->writeToParcel(parcel);
58 }
59
nativeReadFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)60 static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
61 sp<InputTransferToken> inputTransferToken = sp<InputTransferToken>::make();
62 Parcel* parcel = parcelForJavaObject(env, parcelObj);
63 inputTransferToken->readFromParcel(parcel);
64 inputTransferToken->incStrong((void*)nativeCreate);
65 return reinterpret_cast<jlong>(inputTransferToken.get());
66 }
67
nativeGetBinderToken(JNIEnv * env,jclass clazz,jlong nativeObj)68 static jobject nativeGetBinderToken(JNIEnv* env, jclass clazz, jlong nativeObj) {
69 sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
70 return javaObjectForIBinder(env, inputTransferToken->mToken);
71 }
72
nativeGetBinderTokenRef(JNIEnv *,jclass,jlong nativeObj)73 static jlong nativeGetBinderTokenRef(JNIEnv*, jclass, jlong nativeObj) {
74 sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
75 return reinterpret_cast<jlong>(inputTransferToken->mToken.get());
76 }
77
android_window_InputTransferToken_getNativeInputTransferToken(JNIEnv * env,jobject inputTransferTokenObj)78 InputTransferToken* android_window_InputTransferToken_getNativeInputTransferToken(
79 JNIEnv* env, jobject inputTransferTokenObj) {
80 if (inputTransferTokenObj != nullptr &&
81 env->IsInstanceOf(inputTransferTokenObj, gInputTransferTokenClassInfo.clazz)) {
82 return reinterpret_cast<InputTransferToken*>(
83 env->GetLongField(inputTransferTokenObj,
84 gInputTransferTokenClassInfo.mNativeObject));
85 } else {
86 return nullptr;
87 }
88 }
89
android_window_InputTransferToken_getJavaInputTransferToken(JNIEnv * env,const InputTransferToken & inputTransferToken)90 jobject android_window_InputTransferToken_getJavaInputTransferToken(
91 JNIEnv* env, const InputTransferToken& inputTransferToken) {
92 inputTransferToken.incStrong((void*)nativeCreate);
93 return env->NewObject(gInputTransferTokenClassInfo.clazz, gInputTransferTokenClassInfo.ctor,
94 reinterpret_cast<jlong>(&inputTransferToken));
95 }
96
release(InputTransferToken * inputTransferToken)97 static void release(InputTransferToken* inputTransferToken) {
98 inputTransferToken->decStrong((void*)nativeCreate);
99 }
100
nativeGetNativeInputTransferTokenFinalizer(JNIEnv * env,jclass clazz)101 static jlong nativeGetNativeInputTransferTokenFinalizer(JNIEnv* env, jclass clazz) {
102 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&release));
103 }
104
nativeEquals(JNIEnv * env,jclass clazz,jlong inputTransferTokenObj1,jlong inputTransferTokenObj2)105 static bool nativeEquals(JNIEnv* env, jclass clazz, jlong inputTransferTokenObj1,
106 jlong inputTransferTokenObj2) {
107 sp<InputTransferToken> inputTransferToken1(
108 reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1));
109 sp<InputTransferToken> inputTransferToken2(
110 reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2));
111
112 return inputTransferToken1 == inputTransferToken2;
113 }
114
115 static const JNINativeMethod sInputTransferTokenMethods[] = {
116 // clang-format off
117 {"nativeCreate", "()J", (void*)nativeCreate},
118 {"nativeCreate", "(Landroid/os/IBinder;)J", (void*)nativeCreateFromBinder},
119 {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel},
120 {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", (void*)nativeReadFromParcel},
121 {"nativeGetBinderToken", "(J)Landroid/os/IBinder;", (void*)nativeGetBinderToken},
122 {"nativeGetBinderTokenRef", "(J)J", (void*)nativeGetBinderTokenRef},
123 {"nativeGetNativeInputTransferTokenFinalizer", "()J", (void*)nativeGetNativeInputTransferTokenFinalizer},
124 {"nativeEquals", "(JJ)Z", (void*) nativeEquals},
125 // clang-format on
126 };
127
register_android_window_InputTransferToken(JNIEnv * env)128 int register_android_window_InputTransferToken(JNIEnv* env) {
129 int err = RegisterMethodsOrDie(env, "android/window/InputTransferToken",
130 sInputTransferTokenMethods, NELEM(sInputTransferTokenMethods));
131 jclass inputTransferTokenClass = FindClassOrDie(env, "android/window/InputTransferToken");
132 gInputTransferTokenClassInfo.clazz = MakeGlobalRefOrDie(env, inputTransferTokenClass);
133 gInputTransferTokenClassInfo.mNativeObject =
134 GetFieldIDOrDie(env, gInputTransferTokenClassInfo.clazz, "mNativeObject", "J");
135 gInputTransferTokenClassInfo.ctor =
136 GetMethodIDOrDie(env, gInputTransferTokenClassInfo.clazz, "<init>", "(J)V");
137 return err;
138 }
139
140 } // namespace android