UinputBridge.java revision 492e9e851cadca62df84eaff1a3c1ba788492fba
1/*
2 * Copyright (C) 2016 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
17package com.android.server.tv;
18
19import android.os.Binder;
20import android.os.IBinder;
21
22import java.io.IOException;
23
24import dalvik.system.CloseGuard;
25
26/**
27 * Sends the input event to the linux driver.
28 */
29public final class UinputBridge {
30    private final CloseGuard mCloseGuard = CloseGuard.get();
31    private long mPtr;
32    private IBinder mToken = null;
33
34    private static native long nativeOpen(String name, String uniqueId, int width, int height,
35                                          int maxPointers);
36    private static native void nativeClose(long ptr);
37    private static native void nativeClear(long ptr);
38    private static native void nativeSendTimestamp(long ptr, long timestamp);
39    private static native void nativeSendKey(long ptr, int keyCode, boolean down);
40    private static native void nativeSendPointerDown(long ptr, int pointerId, int x, int y);
41    private static native void nativeSendPointerUp(long ptr, int pointerId);
42    private static native void nativeSendPointerSync(long ptr);
43
44    public UinputBridge(IBinder token, String name, int width, int height, int maxPointers)
45                        throws IOException {
46        if (width < 1 || height < 1) {
47            throw new IllegalArgumentException("Touchpad must be at least 1x1.");
48        }
49        if (maxPointers < 1 || maxPointers > 32) {
50            throw new IllegalArgumentException("Touchpad must support between 1 and 32 pointers.");
51        }
52        if (token == null) {
53            throw new IllegalArgumentException("Token cannot be null");
54        }
55        mPtr = nativeOpen(name, token.toString(), width, height, maxPointers);
56        if (mPtr == 0) {
57            throw new IOException("Could not open uinput device " + name);
58        }
59        mToken = token;
60        mCloseGuard.open("close");
61    }
62
63    @Override
64    protected void finalize() throws Throwable {
65        try {
66            if (mCloseGuard != null) {
67                mCloseGuard.warnIfOpen();
68            }
69            close(mToken);
70        } finally {
71            mToken = null;
72            super.finalize();
73        }
74    }
75
76    public void close(IBinder token) {
77        if (isTokenValid(token)) {
78            if (mPtr != 0) {
79                clear(token);
80                nativeClose(mPtr);
81
82                mPtr = 0;
83                mCloseGuard.close();
84            }
85        }
86    }
87
88    public IBinder getToken() {
89        return mToken;
90    }
91
92    protected boolean isTokenValid(IBinder token) {
93        return mToken.equals(token);
94    }
95
96    public void sendTimestamp(IBinder token, long timestamp) {
97        if (isTokenValid(token)) {
98            nativeSendTimestamp(mPtr, timestamp);
99        }
100    }
101
102    public void sendKeyDown(IBinder token, int keyCode) {
103        if (isTokenValid(token)) {
104            nativeSendKey(mPtr, keyCode, true /*down*/);
105        }
106    }
107
108    public void sendKeyUp(IBinder token, int keyCode) {
109        if (isTokenValid(token)) {
110            nativeSendKey(mPtr, keyCode, false /*down*/);
111        }
112    }
113
114    public void sendPointerDown(IBinder token, int pointerId, int x, int y) {
115        if (isTokenValid(token)) {
116            nativeSendPointerDown(mPtr, pointerId, x, y);
117        }
118    }
119
120    public void sendPointerUp(IBinder token, int pointerId) {
121        if (isTokenValid(token)) {
122            nativeSendPointerUp(mPtr, pointerId);
123        }
124    }
125
126    public void sendPointerSync(IBinder token) {
127        if (isTokenValid(token)) {
128            nativeSendPointerSync(mPtr);
129        }
130
131    }
132
133    public void clear(IBinder token) {
134        if (isTokenValid(token)) {
135            nativeClear(mPtr);
136        }
137    }
138
139}
140