Home | History | Annotate | Download | only in input
      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