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 package android.window;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.NonNull;
21 import android.os.IBinder;
22 import android.os.Looper;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.view.Choreographer;
26 import android.view.SurfaceControl;
27 import android.view.SurfaceControlInputReceiver;
28 import android.view.SurfaceControlViewHost;
29 
30 import com.android.window.flags.Flags;
31 
32 import libcore.util.NativeAllocationRegistry;
33 
34 import java.util.Objects;
35 
36 /**
37  * A token that can be used to request focus on or to transfer touch gesture to a
38  * {@link SurfaceControlViewHost} or {@link android.view.SurfaceControl} that has an input channel.
39  * <p>
40  * The {@link android.view.SurfaceControl} needs to have been registered for input via
41  * {@link android.view.WindowManager#registerUnbatchedSurfaceControlInputReceiver(
42  * InputTransferToken, SurfaceControl, Looper, SurfaceControlInputReceiver)} or
43  * {@link android.view.WindowManager#registerBatchedSurfaceControlInputReceiver(
44  * InputTransferToken, SurfaceControl, Choreographer, SurfaceControlInputReceiver)} and the
45  * returned token can be used to call
46  * {@link android.view.WindowManager#transferTouchGesture(InputTransferToken, InputTransferToken)}
47  * <p>
48  * For {@link SurfaceControlViewHost}, the token can be retrieved via
49  * {@link SurfaceControlViewHost.SurfacePackage#getInputTransferToken()}
50  *
51  * @see android.view.WindowManager#transferTouchGesture(InputTransferToken, InputTransferToken)
52  */
53 @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER)
54 public final class InputTransferToken implements Parcelable {
nativeCreate()55     private static native long nativeCreate();
nativeCreate(IBinder token)56     private static native long nativeCreate(IBinder token);
nativeWriteToParcel(long nativeObject, Parcel out)57     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
nativeReadFromParcel(Parcel in)58     private static native long nativeReadFromParcel(Parcel in);
nativeGetBinderToken(long nativeObject)59     private static native IBinder nativeGetBinderToken(long nativeObject);
nativeGetBinderTokenRef(long nativeObject)60     private static native long nativeGetBinderTokenRef(long nativeObject);
nativeGetNativeInputTransferTokenFinalizer()61     private static native long nativeGetNativeInputTransferTokenFinalizer();
nativeEquals(long nativeObject1, long nativeObject2)62     private static native boolean nativeEquals(long nativeObject1, long nativeObject2);
63 
64     private static final NativeAllocationRegistry sRegistry =
65             NativeAllocationRegistry.createMalloced(InputTransferToken.class.getClassLoader(),
66                     nativeGetNativeInputTransferTokenFinalizer());
67 
68     /**
69      * @hide
70      */
71     public final long mNativeObject;
72 
InputTransferToken(long nativeObject)73     private InputTransferToken(long nativeObject) {
74         mNativeObject = nativeObject;
75         sRegistry.registerNativeAllocation(this, nativeObject);
76     }
77 
78     /**
79      * @hide
80      */
InputTransferToken(@onNull IBinder token)81     public InputTransferToken(@NonNull IBinder token) {
82         this(nativeCreate(token));
83     }
84 
85     /**
86      * @hide
87      */
InputTransferToken()88     public InputTransferToken() {
89         this(nativeCreate());
90     }
91 
92     /**
93      * @hide
94      */
getToken()95     public IBinder getToken() {
96         return nativeGetBinderToken(mNativeObject);
97     }
98 
InputTransferToken(Parcel in)99     private InputTransferToken(Parcel in) {
100         this(nativeReadFromParcel(in));
101     }
102 
103     /**
104      * @hide
105      */
106     @Override
describeContents()107     public int describeContents() {
108         return 0;
109     }
110 
111     /**
112      * @hide
113      */
114     @Override
writeToParcel(@onNull Parcel dest, int flags)115     public void writeToParcel(@NonNull Parcel dest, int flags) {
116         nativeWriteToParcel(mNativeObject, dest);
117     }
118 
119     public static final @NonNull Creator<InputTransferToken> CREATOR = new Creator<>() {
120         public InputTransferToken createFromParcel(Parcel in) {
121             return new InputTransferToken(in);
122         }
123 
124         public InputTransferToken[] newArray(int size) {
125             return new InputTransferToken[size];
126         }
127     };
128 
129     /**
130      * @hide
131      */
132     @Override
hashCode()133     public int hashCode() {
134         return Objects.hash(nativeGetBinderTokenRef(mNativeObject));
135     }
136 
137     /**
138      * @hide
139      */
140     @Override
equals(Object obj)141     public boolean equals(Object obj) {
142         if (this == obj) return true;
143         if (obj == null || getClass() != obj.getClass()) return false;
144         InputTransferToken other = (InputTransferToken) obj;
145         if (other.mNativeObject == mNativeObject) return true;
146         return nativeEquals(mNativeObject, other.mNativeObject);
147     }
148 
149 }
150