blob: 41a4b87d25a43e0fd49965be18a2c70b515799fa [file] [log] [blame]
Keun-young Parka28d7b22016-02-29 16:54:29 -08001/*
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 */
16package com.android.car.hal;
17
Pavel Maltsev338cef82016-07-26 16:04:15 -070018import android.os.SystemClock;
Keun-young Parka28d7b22016-02-29 16:54:29 -080019import android.util.Log;
Pavel Maltsev338cef82016-07-26 16:04:15 -070020import android.util.SparseLongArray;
21import android.view.InputDevice;
Keun-young Parka28d7b22016-02-29 16:54:29 -080022import android.view.KeyEvent;
23
24import com.android.car.CarLog;
25import com.android.car.vehiclenetwork.VehicleNetworkConsts;
26import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleDisplay;
27import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleHwKeyInputAction;
28import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
29import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
30
31import java.io.PrintWriter;
32import java.util.LinkedList;
33import java.util.List;
34
35public class InputHalService extends HalServiceBase {
36
37 public static final int DISPLAY_MAIN = VehicleDisplay.VEHICLE_DISPLAY_MAIN;
38 public static final int DISPLAY_INSTRUMENT_CLUSTER =
39 VehicleDisplay.VEHICLE_DISPLAY_INSTRUMENT_CLUSTER;
40
41 public interface InputListener {
42 void onKeyEvent(KeyEvent event, int targetDisplay);
43 }
44
45 private static final boolean DBG = false;
46
47 private boolean mKeyInputSupported = false;
48 private InputListener mListener;
Pavel Maltsev338cef82016-07-26 16:04:15 -070049 private final SparseLongArray mKeyDownTimes = new SparseLongArray();
Keun-young Parka28d7b22016-02-29 16:54:29 -080050
51 public void setInputListener(InputListener listener) {
52 synchronized (this) {
53 if (!mKeyInputSupported) {
54 Log.w(CarLog.TAG_INPUT, "input listener set while key input not supported");
55 return;
56 }
57 mListener = listener;
58 }
59 VehicleHal.getInstance().subscribeProperty(this,
60 VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT, 0);
61 }
62
63 public synchronized boolean isKeyInputSupported() {
64 return mKeyInputSupported;
65 }
66
67 @Override
68 public void init() {
69 }
70
71 @Override
72 public void release() {
73 synchronized (this) {
74 mListener = null;
75 mKeyInputSupported = false;
76 }
77 }
78
79 @Override
80 public List<VehiclePropConfig> takeSupportedProperties(List<VehiclePropConfig> allProperties) {
81 List<VehiclePropConfig> supported = new LinkedList<VehiclePropConfig>();
82 for (VehiclePropConfig p: allProperties) {
83 if (p.getProp() == VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT) {
84 supported.add(p);
85 synchronized (this) {
86 mKeyInputSupported = true;
87 }
88 }
89 }
90 return supported;
91 }
92
93 @Override
94 public void handleHalEvents(List<VehiclePropValue> values) {
95 InputListener listener = null;
96 synchronized (this) {
97 listener = mListener;
98 }
99 if (listener == null) {
100 Log.w(CarLog.TAG_INPUT, "Input event while listener is null");
101 return;
102 }
103 for (VehiclePropValue v : values) {
104 if (v.getProp() != VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT) {
105 Log.e(CarLog.TAG_INPUT, "Wrong event dispatched, prop:0x" +
106 Integer.toHexString(v.getProp()));
107 continue;
108 }
109 int action = (v.getInt32Values(0) ==
110 VehicleHwKeyInputAction.VEHICLE_HW_KEY_INPUT_ACTION_DOWN) ?
111 KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
112 int code = v.getInt32Values(1);
113 int display = v.getInt32Values(2);
114 if (DBG) {
115 Log.i(CarLog.TAG_INPUT, "hal event code:" + code + ",action:" + action +
116 ",display:" + display);
117 }
Pavel Maltsev338cef82016-07-26 16:04:15 -0700118
119 dispatchKeyEvent(listener, action, code, display);
Keun-young Parka28d7b22016-02-29 16:54:29 -0800120 }
121 }
122
Pavel Maltsev338cef82016-07-26 16:04:15 -0700123 private void dispatchKeyEvent(InputListener listener, int action, int code, int display) {
124 long eventTime = SystemClock.uptimeMillis();
125
126 if (action == KeyEvent.ACTION_DOWN) {
127 mKeyDownTimes.put(code, eventTime);
128 }
129
130 long downTime = action == KeyEvent.ACTION_UP
131 ? mKeyDownTimes.get(code, eventTime) : eventTime;
132
133 KeyEvent event = KeyEvent.obtain(
134 downTime,
135 eventTime,
136 action,
137 code,
138 0 /* repeat */,
139 0 /* meta state */,
140 0 /* deviceId*/,
141 0 /* scancode */,
142 0 /* flags */,
143 InputDevice.SOURCE_CLASS_BUTTON,
144 null /* characters */);
145
146 listener.onKeyEvent(event, display);
147 event.recycle();
148 }
149
Keun-young Parka28d7b22016-02-29 16:54:29 -0800150 @Override
151 public void dump(PrintWriter writer) {
152 writer.println("*Input HAL*");
153 writer.println("mKeyInputSupported:" + mKeyInputSupported);
154 }
155
156}