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 package com.google.android.car.kitchensink.input; 17 18 import android.annotation.Nullable; 19 import android.annotation.StringRes; 20 import android.hardware.automotive.vehicle.V2_0.VehicleHwKeyInputAction; 21 import android.os.Bundle; 22 import android.support.v4.app.Fragment; 23 import android.util.Log; 24 import android.view.KeyEvent; 25 import android.view.LayoutInflater; 26 import android.view.MotionEvent; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import android.widget.Button; 30 import android.widget.LinearLayout; 31 32 import com.google.android.car.kitchensink.CarEmulator; 33 import com.google.android.car.kitchensink.R; 34 35 import java.util.ArrayList; 36 import java.util.Collections; 37 import java.util.List; 38 39 /** 40 * Test input event handling to system. 41 * vehicle hal should have VEHICLE_PROPERTY_HW_KEY_INPUT support for this to work. 42 */ 43 public class InputTestFragment extends Fragment { 44 45 private static final String TAG = "CAR.INPUT.KS"; 46 47 private static final Button BREAK_LINE = null; 48 49 private final List<View> mButtons = new ArrayList<>(); 50 51 private CarEmulator mCarEmulator; 52 53 @Nullable 54 @Override 55 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 56 @Nullable Bundle savedInstanceState) { 57 View view = inflater.inflate(R.layout.input_test, container, false); 58 59 Collections.addAll(mButtons, 60 BREAK_LINE, 61 createButton(R.string.home, KeyEvent.KEYCODE_HOME), 62 createButton(R.string.volume_up, KeyEvent.KEYCODE_VOLUME_UP), 63 createButton(R.string.volume_down, KeyEvent.KEYCODE_VOLUME_DOWN), 64 createButton(R.string.volume_mute, KeyEvent.KEYCODE_VOLUME_MUTE), 65 createButton(R.string.voice, KeyEvent.KEYCODE_VOICE_ASSIST), 66 BREAK_LINE, 67 createButton(R.string.music, KeyEvent.KEYCODE_MUSIC), 68 createButton(R.string.music_play, KeyEvent.KEYCODE_MEDIA_PLAY), 69 createButton(R.string.music_stop, KeyEvent.KEYCODE_MEDIA_STOP), 70 createButton(R.string.next_song, KeyEvent.KEYCODE_MEDIA_NEXT), 71 createButton(R.string.prev_song, KeyEvent.KEYCODE_MEDIA_PREVIOUS), 72 createButton(R.string.tune_right, KeyEvent.KEYCODE_CHANNEL_UP), 73 createButton(R.string.tune_left, KeyEvent.KEYCODE_CHANNEL_DOWN), 74 BREAK_LINE, 75 createButton(R.string.call_send, KeyEvent.KEYCODE_CALL), 76 createButton(R.string.call_end, KeyEvent.KEYCODE_ENDCALL) 77 ); 78 79 mCarEmulator = CarEmulator.create(getContext()); 80 addButtonsToPanel((LinearLayout) view.findViewById(R.id.input_buttons), mButtons); 81 82 return view; 83 } 84 85 private Button createButton(@StringRes int textResId, int keyCode) { 86 Button button = new Button(getContext()); 87 button.setText(getContext().getString(textResId)); 88 button.setTextSize(32f); 89 // Single touch + key event does not work as touch is happening in other window 90 // at the same time. But long press will work. 91 button.setOnTouchListener((v, event) -> { 92 handleTouchEvent(event, keyCode); 93 return true; 94 }); 95 96 return button; 97 } 98 99 private void handleTouchEvent(MotionEvent event, int keyCode) { 100 int androidAction = event.getActionMasked(); 101 Log.i(TAG, "handleTouchEvent, action:" + androidAction + ",keyCode:" + keyCode); 102 103 switch (androidAction) { 104 case MotionEvent.ACTION_DOWN: 105 mCarEmulator.injectKey(keyCode, VehicleHwKeyInputAction.ACTION_DOWN); 106 break; 107 case MotionEvent.ACTION_UP: 108 mCarEmulator.injectKey(keyCode, VehicleHwKeyInputAction.ACTION_UP); 109 break; 110 default: 111 Log.w(TAG, "Unhandled touch action: " + androidAction); 112 break; 113 } 114 } 115 116 @Override 117 public void onDestroyView() { 118 super.onDestroyView(); 119 } 120 121 private void addButtonsToPanel(LinearLayout root, List<View> buttons) { 122 LinearLayout panel = null; 123 for (View button : buttons) { 124 if (button == BREAK_LINE || panel == null) { 125 panel = new LinearLayout(getContext()); 126 panel.setOrientation(LinearLayout.HORIZONTAL); 127 root.addView(panel); 128 } else { 129 panel.addView(button); 130 } 131 } 132 } 133 } 134