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