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); nativeRelease()58 private native void nativeRelease(); nativeTransferTo(InputChannel other)59 private native void nativeTransferTo(InputChannel other); nativeReadFromParcel(Parcel parcel)60 private native void nativeReadFromParcel(Parcel parcel); nativeWriteToParcel(Parcel parcel)61 private native void nativeWriteToParcel(Parcel parcel); nativeDup(InputChannel target)62 private native void nativeDup(InputChannel target); nativeGetToken()63 private native IBinder nativeGetToken(); 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 * Release the Java objects hold over the native InputChannel. If other references 124 * still exist in native-land, then the channel may continue to exist. 125 */ release()126 public void release() { 127 nativeRelease(); 128 } 129 130 /** 131 * Transfers ownership of the internal state of the input channel to another 132 * instance and invalidates this instance. This is used to pass an input channel 133 * as an out parameter in a binder call. 134 * @param other The other input channel instance. 135 */ transferTo(InputChannel outParameter)136 public void transferTo(InputChannel outParameter) { 137 if (outParameter == null) { 138 throw new IllegalArgumentException("outParameter must not be null"); 139 } 140 141 nativeTransferTo(outParameter); 142 } 143 144 /** 145 * Duplicates the input channel. 146 */ dup()147 public InputChannel dup() { 148 InputChannel target = new InputChannel(); 149 nativeDup(target); 150 return target; 151 } 152 153 @Override describeContents()154 public int describeContents() { 155 return Parcelable.CONTENTS_FILE_DESCRIPTOR; 156 } 157 readFromParcel(Parcel in)158 public void readFromParcel(Parcel in) { 159 if (in == null) { 160 throw new IllegalArgumentException("in must not be null"); 161 } 162 163 nativeReadFromParcel(in); 164 } 165 166 @Override writeToParcel(Parcel out, int flags)167 public void writeToParcel(Parcel out, int flags) { 168 if (out == null) { 169 throw new IllegalArgumentException("out must not be null"); 170 } 171 172 nativeWriteToParcel(out); 173 174 if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) { 175 dispose(); 176 } 177 } 178 179 @Override toString()180 public String toString() { 181 return getName(); 182 } 183 getToken()184 public IBinder getToken() { 185 return nativeGetToken(); 186 } 187 } 188