1 /* 2 * Copyright (C) 2010 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.view; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.os.IBinder; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.util.Slog; 24 25 /** 26 * An input channel specifies the file descriptors used to send input events to 27 * a window in another process. It is Parcelable so that it can be sent 28 * to the process that is to receive events. Only one thread should be reading 29 * from an InputChannel at a time. 30 * @hide 31 */ 32 public final class InputChannel implements Parcelable { 33 private static final String TAG = "InputChannel"; 34 35 private static final boolean DEBUG = false; 36 37 @UnsupportedAppUsage 38 public static final @android.annotation.NonNull Parcelable.Creator<InputChannel> CREATOR 39 = new Parcelable.Creator<InputChannel>() { 40 public InputChannel createFromParcel(Parcel source) { 41 InputChannel result = new InputChannel(); 42 result.readFromParcel(source); 43 return result; 44 } 45 46 public InputChannel[] newArray(int size) { 47 return new InputChannel[size]; 48 } 49 }; 50 51 @SuppressWarnings("unused") 52 @UnsupportedAppUsage 53 private long mPtr; // used by native code 54 nativeOpenInputChannelPair(String name)55 private static native InputChannel[] nativeOpenInputChannelPair(String name); 56 nativeDispose(boolean finalized)57 private native void nativeDispose(boolean finalized); nativeTransferTo(InputChannel other)58 private native void nativeTransferTo(InputChannel other); nativeReadFromParcel(Parcel parcel)59 private native void nativeReadFromParcel(Parcel parcel); nativeWriteToParcel(Parcel parcel)60 private native void nativeWriteToParcel(Parcel parcel); nativeDup(InputChannel target)61 private native void nativeDup(InputChannel target); nativeGetToken()62 private native IBinder nativeGetToken(); nativeSetToken(IBinder token)63 private native void nativeSetToken(IBinder token); 64 nativeGetName()65 private native String nativeGetName(); 66 67 /** 68 * Creates an uninitialized input channel. 69 * It can be initialized by reading from a Parcel or by transferring the state of 70 * another input channel into this one. 71 */ 72 @UnsupportedAppUsage InputChannel()73 public InputChannel() { 74 } 75 76 @Override finalize()77 protected void finalize() throws Throwable { 78 try { 79 nativeDispose(true); 80 } finally { 81 super.finalize(); 82 } 83 } 84 85 /** 86 * Creates a new input channel pair. One channel should be provided to the input 87 * dispatcher and the other to the application's input queue. 88 * @param name The descriptive (non-unique) name of the channel pair. 89 * @return A pair of input channels. The first channel is designated as the 90 * server channel and should be used to publish input events. The second channel 91 * is designated as the client channel and should be used to consume input events. 92 */ openInputChannelPair(String name)93 public static InputChannel[] openInputChannelPair(String name) { 94 if (name == null) { 95 throw new IllegalArgumentException("name must not be null"); 96 } 97 98 if (DEBUG) { 99 Slog.d(TAG, "Opening input channel pair '" + name + "'"); 100 } 101 return nativeOpenInputChannelPair(name); 102 } 103 104 /** 105 * Gets the name of the input channel. 106 * @return The input channel name. 107 */ getName()108 public String getName() { 109 String name = nativeGetName(); 110 return name != null ? name : "uninitialized"; 111 } 112 113 /** 114 * Disposes the input channel. 115 * Explicitly releases the reference this object is holding on the input channel. 116 * When all references are released, the input channel will be closed. 117 */ dispose()118 public void dispose() { 119 nativeDispose(false); 120 } 121 122 /** 123 * Transfers ownership of the internal state of the input channel to another 124 * instance and invalidates this instance. This is used to pass an input channel 125 * as an out parameter in a binder call. 126 * @param other The other input channel instance. 127 */ transferTo(InputChannel outParameter)128 public void transferTo(InputChannel outParameter) { 129 if (outParameter == null) { 130 throw new IllegalArgumentException("outParameter must not be null"); 131 } 132 133 nativeTransferTo(outParameter); 134 } 135 136 /** 137 * Duplicates the input channel. 138 */ dup()139 public InputChannel dup() { 140 InputChannel target = new InputChannel(); 141 nativeDup(target); 142 return target; 143 } 144 145 @Override describeContents()146 public int describeContents() { 147 return Parcelable.CONTENTS_FILE_DESCRIPTOR; 148 } 149 readFromParcel(Parcel in)150 public void readFromParcel(Parcel in) { 151 if (in == null) { 152 throw new IllegalArgumentException("in must not be null"); 153 } 154 155 nativeReadFromParcel(in); 156 } 157 158 @Override writeToParcel(Parcel out, int flags)159 public void writeToParcel(Parcel out, int flags) { 160 if (out == null) { 161 throw new IllegalArgumentException("out must not be null"); 162 } 163 164 nativeWriteToParcel(out); 165 166 if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) { 167 dispose(); 168 } 169 } 170 171 @Override toString()172 public String toString() { 173 return getName(); 174 } 175 getToken()176 public IBinder getToken() { 177 return nativeGetToken(); 178 } 179 setToken(IBinder token)180 public void setToken(IBinder token) { 181 nativeSetToken(token); 182 } 183 } 184