146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/*
246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2010 The Android Open Source Project
346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License.
646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at
746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software
1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and
1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License.
1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */
1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownpackage android.view;
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.os.Parcel;
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.os.Parcelable;
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.util.Slog;
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/**
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * An input channel specifies the file descriptors used to send input events to
25a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn * a window in another process.  It is Parcelable so that it can be sent
26a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn * to the process that is to receive events.  Only one thread should be reading
27a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn * from an InputChannel at a time.
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * @hide
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */
307fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownpublic final class InputChannel implements Parcelable {
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private static final String TAG = "InputChannel";
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
33c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    private static final boolean DEBUG = false;
34c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public static final Parcelable.Creator<InputChannel> CREATOR
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            = new Parcelable.Creator<InputChannel>() {
3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        public InputChannel createFromParcel(Parcel source) {
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            InputChannel result = new InputChannel();
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            result.readFromParcel(source);
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return result;
4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        public InputChannel[] newArray(int size) {
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return new InputChannel[size];
4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    };
4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    @SuppressWarnings("unused")
49a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat    private long mPtr; // used by native code
5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private static native InputChannel[] nativeOpenInputChannelPair(String name);
5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private native void nativeDispose(boolean finalized);
5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private native void nativeTransferTo(InputChannel other);
5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private native void nativeReadFromParcel(Parcel parcel);
5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private native void nativeWriteToParcel(Parcel parcel);
571951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown    private native void nativeDup(InputChannel target);
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private native String nativeGetName();
6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Creates an uninitialized input channel.
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * It can be initialized by reading from a Parcel or by transferring the state of
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * another input channel into this one.
6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
6646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public InputChannel() {
6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
681951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown
6946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    @Override
7046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    protected void finalize() throws Throwable {
7146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        try {
7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            nativeDispose(true);
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        } finally {
7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            super.finalize();
7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Creates a new input channel pair.  One channel should be provided to the input
8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * dispatcher and the other to the application's input queue.
8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param name The descriptive (non-unique) name of the channel pair.
82c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown     * @return A pair of input channels.  The first channel is designated as the
83c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown     * server channel and should be used to publish input events.  The second channel
84c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown     * is designated as the client channel and should be used to consume input events.
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public static InputChannel[] openInputChannelPair(String name) {
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (name == null) {
8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            throw new IllegalArgumentException("name must not be null");
8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
90c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
91c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        if (DEBUG) {
92c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            Slog.d(TAG, "Opening input channel pair '" + name + "'");
93c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        }
9446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return nativeOpenInputChannelPair(name);
9546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Gets the name of the input channel.
9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @return The input channel name.
10046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
10146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public String getName() {
10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        String name = nativeGetName();
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return name != null ? name : "uninitialized";
10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Disposes the input channel.
10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Explicitly releases the reference this object is holding on the input channel.
10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * When all references are released, the input channel will be closed.
11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void dispose() {
11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeDispose(false);
11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Transfers ownership of the internal state of the input channel to another
11746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * instance and invalidates this instance.  This is used to pass an input channel
11846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * as an out parameter in a binder call.
11946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param other The other input channel instance.
12046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
1210a0ab128a65900a23f1018a14f5cbecec6443dd3Jeff Brown    public void transferTo(InputChannel outParameter) {
12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (outParameter == null) {
12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            throw new IllegalArgumentException("outParameter must not be null");
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeTransferTo(outParameter);
12746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1291951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown    /**
1301951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown     * Duplicates the input channel.
1311951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown     */
1321951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown    public InputChannel dup() {
1331951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown        InputChannel target = new InputChannel();
1341951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown        nativeDup(target);
1351951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown        return target;
1361951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown    }
1371951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown
138c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public int describeContents() {
14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
14146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
142c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void readFromParcel(Parcel in) {
14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (in == null) {
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            throw new IllegalArgumentException("in must not be null");
14646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
14746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeReadFromParcel(in);
14946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
150c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
151c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void writeToParcel(Parcel out, int flags) {
15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (out == null) {
15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            throw new IllegalArgumentException("out must not be null");
15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeWriteToParcel(out);
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1590a0ab128a65900a23f1018a14f5cbecec6443dd3Jeff Brown        if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            dispose();
16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    @Override
16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public String toString() {
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return getName();
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
169