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