blob: 6d6521fd983d97d7b71723484de2ec006957f6c6 [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 Maltsev0d07c762016-11-03 16:40:15 -070018import static android.hardware.vehicle.V2_0.VehicleProperty.HW_KEY_INPUT;
19
20import android.hardware.vehicle.V2_0.VehicleDisplay;
21import android.hardware.vehicle.V2_0.VehicleHwKeyInputAction;
22import android.hardware.vehicle.V2_0.VehiclePropConfig;
23import android.hardware.vehicle.V2_0.VehiclePropValue;
Pavel Maltsev338cef82016-07-26 16:04:15 -070024import android.os.SystemClock;
Keun-young Parka28d7b22016-02-29 16:54:29 -080025import android.util.Log;
Pavel Maltsev338cef82016-07-26 16:04:15 -070026import android.util.SparseLongArray;
27import android.view.InputDevice;
Keun-young Parka28d7b22016-02-29 16:54:29 -080028import android.view.KeyEvent;
29
30import com.android.car.CarLog;
Keun-young Parka28d7b22016-02-29 16:54:29 -080031
32import java.io.PrintWriter;
Pavel Maltsev0d07c762016-11-03 16:40:15 -070033import java.util.Collection;
Keun-young Parka28d7b22016-02-29 16:54:29 -080034import java.util.LinkedList;
35import java.util.List;
36
37public class InputHalService extends HalServiceBase {
38
Pavel Maltsev0d07c762016-11-03 16:40:15 -070039 public static final int DISPLAY_MAIN = VehicleDisplay.MAIN;
40 public static final int DISPLAY_INSTRUMENT_CLUSTER = VehicleDisplay.INSTRUMENT_CLUSTER;
41 private final VehicleHal mHal;
Keun-young Parka28d7b22016-02-29 16:54:29 -080042
43 public interface InputListener {
44 void onKeyEvent(KeyEvent event, int targetDisplay);
45 }
46
47 private static final boolean DBG = false;
48
49 private boolean mKeyInputSupported = false;
50 private InputListener mListener;
Pavel Maltsev338cef82016-07-26 16:04:15 -070051 private final SparseLongArray mKeyDownTimes = new SparseLongArray();
Keun-young Parka28d7b22016-02-29 16:54:29 -080052
Pavel Maltsev0d07c762016-11-03 16:40:15 -070053 public InputHalService(VehicleHal hal) {
54 mHal = hal;
55 }
56
Keun-young Parka28d7b22016-02-29 16:54:29 -080057 public void setInputListener(InputListener listener) {
58 synchronized (this) {
59 if (!mKeyInputSupported) {
60 Log.w(CarLog.TAG_INPUT, "input listener set while key input not supported");
61 return;
62 }
63 mListener = listener;
64 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -070065 mHal.subscribeProperty(this, HW_KEY_INPUT, 0);
Keun-young Parka28d7b22016-02-29 16:54:29 -080066 }
67
68 public synchronized boolean isKeyInputSupported() {
69 return mKeyInputSupported;
70 }
71
72 @Override
73 public void init() {
74 }
75
76 @Override
77 public void release() {
78 synchronized (this) {
79 mListener = null;
80 mKeyInputSupported = false;
81 }
82 }
83
84 @Override
Pavel Maltsev0d07c762016-11-03 16:40:15 -070085 public Collection<VehiclePropConfig> takeSupportedProperties(
86 Collection<VehiclePropConfig> allProperties) {
87 List<VehiclePropConfig> supported = new LinkedList<>();
Keun-young Parka28d7b22016-02-29 16:54:29 -080088 for (VehiclePropConfig p: allProperties) {
Pavel Maltsev0d07c762016-11-03 16:40:15 -070089 if (p.prop == HW_KEY_INPUT) {
Keun-young Parka28d7b22016-02-29 16:54:29 -080090 supported.add(p);
91 synchronized (this) {
92 mKeyInputSupported = true;
93 }
94 }
95 }
96 return supported;
97 }
98
99 @Override
100 public void handleHalEvents(List<VehiclePropValue> values) {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700101 InputListener listener;
Keun-young Parka28d7b22016-02-29 16:54:29 -0800102 synchronized (this) {
103 listener = mListener;
104 }
105 if (listener == null) {
106 Log.w(CarLog.TAG_INPUT, "Input event while listener is null");
107 return;
108 }
109 for (VehiclePropValue v : values) {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700110 if (v.prop != HW_KEY_INPUT) {
Keun-young Parka28d7b22016-02-29 16:54:29 -0800111 Log.e(CarLog.TAG_INPUT, "Wrong event dispatched, prop:0x" +
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700112 Integer.toHexString(v.prop));
Keun-young Parka28d7b22016-02-29 16:54:29 -0800113 continue;
114 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700115 int action = (v.value.int32Values.get(0) == VehicleHwKeyInputAction.ACTION_DOWN) ?
Keun-young Parka28d7b22016-02-29 16:54:29 -0800116 KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700117 int code = v.value.int32Values.get(1);
118 int display = v.value.int32Values.get(2);
Keun-young Parka28d7b22016-02-29 16:54:29 -0800119 if (DBG) {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700120 Log.i(CarLog.TAG_INPUT, "hal event code:" + code + ", action:" + action +
121 ", display:" + display);
Keun-young Parka28d7b22016-02-29 16:54:29 -0800122 }
Pavel Maltsev338cef82016-07-26 16:04:15 -0700123
124 dispatchKeyEvent(listener, action, code, display);
Keun-young Parka28d7b22016-02-29 16:54:29 -0800125 }
126 }
127
Pavel Maltsev338cef82016-07-26 16:04:15 -0700128 private void dispatchKeyEvent(InputListener listener, int action, int code, int display) {
129 long eventTime = SystemClock.uptimeMillis();
130
131 if (action == KeyEvent.ACTION_DOWN) {
132 mKeyDownTimes.put(code, eventTime);
133 }
134
135 long downTime = action == KeyEvent.ACTION_UP
136 ? mKeyDownTimes.get(code, eventTime) : eventTime;
137
138 KeyEvent event = KeyEvent.obtain(
139 downTime,
140 eventTime,
141 action,
142 code,
143 0 /* repeat */,
144 0 /* meta state */,
145 0 /* deviceId*/,
146 0 /* scancode */,
147 0 /* flags */,
148 InputDevice.SOURCE_CLASS_BUTTON,
149 null /* characters */);
150
151 listener.onKeyEvent(event, display);
152 event.recycle();
153 }
154
Keun-young Parka28d7b22016-02-29 16:54:29 -0800155 @Override
156 public void dump(PrintWriter writer) {
157 writer.println("*Input HAL*");
158 writer.println("mKeyInputSupported:" + mKeyInputSupported);
159 }
160
161}