diff options
author | Pavel Maltsev <pavelm@google.com> | 2018-03-29 14:04:10 -0700 |
---|---|---|
committer | Pavel Maltsev <pavelm@google.com> | 2018-03-29 14:14:58 -0700 |
commit | 31966496485e3738e6bcfe775885f5cd9b857b22 (patch) | |
tree | 639f82dad561bb07ee23af787f63b6ea7e7dcd26 /tests/EmbeddedKitchenSinkApp | |
parent | ebab4277c4926cc19768297a24d5a02663008458 (diff) | |
download | Car-31966496485e3738e6bcfe775885f5cd9b857b22.tar.gz |
Enhance test environment for input
Use real Car Service in the input fragment in KitchenSink app.
This is done through injecting events through back-door property
of emulated VHAL, in this case events tergeting cluster will be
delivered to OEM provided service
Use InputMethodManager to inject KeyEvent into sample cluster main activity
Bug: 74616964
Test: manual kitchen sink + cluster display, verify that taping on
Left/Right steering wheel buttons in kitchen sink switches facets in the
cluster
Change-Id: I09b01b3a08ce05b6c7d9e2a797cf3a5f6c42f2e0
Diffstat (limited to 'tests/EmbeddedKitchenSinkApp')
4 files changed, 86 insertions, 39 deletions
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/input_test.xml b/tests/EmbeddedKitchenSinkApp/res/layout/input_test.xml index e730b03107..1d9f3178da 100644 --- a/tests/EmbeddedKitchenSinkApp/res/layout/input_test.xml +++ b/tests/EmbeddedKitchenSinkApp/res/layout/input_test.xml @@ -16,18 +16,11 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" > - <!-- dummy one for top area --> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="50dp" - android:orientation="vertical" - android:layout_weight="1" /> + android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" - android:layout_weight="1" android:id="@+id/input_buttons"> <!-- Filled at runtime. --> </LinearLayout> diff --git a/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml b/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml index 39d862e4e2..a9e3457b43 100644 --- a/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml +++ b/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml @@ -33,6 +33,7 @@ <dimen name="car_body1_size">40sp</dimen> <dimen name="car_body2_size">32sp</dimen> <dimen name="car_action1_size">32sp</dimen> + <dimen name="car_button_text_size">32sp</dimen> <!-- Common icon size for car app --> <dimen name="car_icon_size">56dp</dimen> diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml index b917eeddf8..36854c19aa 100644 --- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml +++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml @@ -166,6 +166,13 @@ <string name="tune_left">Tune -</string> <string name="music_play">Play</string> <string name="music_stop">Stop</string> + <string name="steering_wheel">Steering Wheel Buttons:</string> + <string name="sw_left">Left</string> + <string name="sw_right">Right</string> + <string name="sw_up">Up</string> + <string name="sw_down">Down</string> + <string name="sw_center">Center</string> + <string name="sw_back">Back</string> <!-- power test --> <string name="power_get_boot_reason">Get Boot Reason</string> diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/input/InputTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/input/InputTestFragment.java index 4e222c1a32..ff6ef21c55 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/input/InputTestFragment.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/input/InputTestFragment.java @@ -15,26 +15,38 @@ */ package com.google.android.car.kitchensink.input; +import static android.hardware.automotive.vehicle.V2_0.VehicleDisplay.INSTRUMENT_CLUSTER; + import android.annotation.Nullable; import android.annotation.StringRes; -import android.hardware.automotive.vehicle.V2_0.VehicleHwKeyInputAction; +import android.hardware.automotive.vehicle.V2_0.IVehicle; +import android.hardware.automotive.vehicle.V2_0.VehicleArea; +import android.hardware.automotive.vehicle.V2_0.VehicleDisplay; +import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; +import android.hardware.automotive.vehicle.V2_0.VehicleProperty; +import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup; +import android.hardware.automotive.vehicle.V2_0.VehiclePropertyStatus; +import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType; import android.os.Bundle; +import android.os.RemoteException; import android.support.v4.app.Fragment; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; -import com.google.android.car.kitchensink.CarEmulator; import com.google.android.car.kitchensink.R; +import com.google.android.collect.Lists; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.NoSuchElementException; /** * Test input event handling to system. @@ -48,7 +60,26 @@ public class InputTestFragment extends Fragment { private final List<View> mButtons = new ArrayList<>(); - private CarEmulator mCarEmulator; + // This is special property available only in emulated VHAL implementation. + private static final int sGenerateFakeDataControllingProperty = + 0x0666 | VehiclePropertyGroup.VENDOR | VehicleArea.GLOBAL | VehiclePropertyType.MIXED; + private static final int sKeyPressCommand = 2; + + private IVehicle mVehicle; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + try { + mVehicle = IVehicle.getService(); + } catch (NoSuchElementException ex) { + throw new RuntimeException("Couldn't connect to " + IVehicle.kInterfaceName, ex); + } catch (RemoteException e) { + throw new RuntimeException("Failed to connect to IVehicle"); + } + Log.d(TAG, "Connected to IVehicle service: " + mVehicle); + } @Nullable @Override @@ -56,6 +87,10 @@ public class InputTestFragment extends Fragment { @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.input_test, container, false); + TextView steeringWheelLabel = new TextView(getActivity() /*context*/); + steeringWheelLabel.setText(R.string.steering_wheel); + steeringWheelLabel.setTextSize(getResources().getDimension(R.dimen.car_title2_size)); + Collections.addAll(mButtons, BREAK_LINE, createButton(R.string.home, KeyEvent.KEYCODE_HOME), @@ -73,49 +108,59 @@ public class InputTestFragment extends Fragment { createButton(R.string.tune_left, KeyEvent.KEYCODE_CHANNEL_DOWN), BREAK_LINE, createButton(R.string.call_send, KeyEvent.KEYCODE_CALL), - createButton(R.string.call_end, KeyEvent.KEYCODE_ENDCALL) - ); - - mCarEmulator = CarEmulator.create(getContext()); - addButtonsToPanel((LinearLayout) view.findViewById(R.id.input_buttons), mButtons); + createButton(R.string.call_end, KeyEvent.KEYCODE_ENDCALL), + BREAK_LINE, + steeringWheelLabel, + BREAK_LINE, + createButton(R.string.sw_left, KeyEvent.KEYCODE_DPAD_LEFT, INSTRUMENT_CLUSTER), + createButton(R.string.sw_right, KeyEvent.KEYCODE_DPAD_RIGHT, + INSTRUMENT_CLUSTER), + createButton(R.string.sw_up, KeyEvent.KEYCODE_DPAD_UP, INSTRUMENT_CLUSTER), + createButton(R.string.sw_down, KeyEvent.KEYCODE_DPAD_DOWN, INSTRUMENT_CLUSTER), + createButton(R.string.sw_center, KeyEvent.KEYCODE_DPAD_CENTER, + INSTRUMENT_CLUSTER), + createButton(R.string.sw_back, KeyEvent.KEYCODE_BACK, INSTRUMENT_CLUSTER) + ); + + addButtonsToPanel(view.findViewById(R.id.input_buttons), mButtons); return view; } private Button createButton(@StringRes int textResId, int keyCode) { + return createButton(textResId, keyCode, VehicleDisplay.MAIN); + } + + private Button createButton(@StringRes int textResId, int keyCode, int targetDisplay) { Button button = new Button(getContext()); button.setText(getContext().getString(textResId)); - button.setTextSize(32f); - // Single touch + key event does not work as touch is happening in other window - // at the same time. But long press will work. - button.setOnTouchListener((v, event) -> { - handleTouchEvent(event, keyCode); - return true; - }); - + button.setTextSize(getResources().getDimension(R.dimen.car_button_text_size)); + button.setOnClickListener(v -> onButtonClick(keyCode, targetDisplay)); return button; } - private void handleTouchEvent(MotionEvent event, int keyCode) { - int androidAction = event.getActionMasked(); - Log.i(TAG, "handleTouchEvent, action:" + androidAction + ",keyCode:" + keyCode); - - switch (androidAction) { - case MotionEvent.ACTION_DOWN: - mCarEmulator.injectKey(keyCode, VehicleHwKeyInputAction.ACTION_DOWN); - break; - case MotionEvent.ACTION_UP: - mCarEmulator.injectKey(keyCode, VehicleHwKeyInputAction.ACTION_UP); - break; - default: - Log.w(TAG, "Unhandled touch action: " + androidAction); - break; + private void onButtonClick(int keyCode, int targetDisplay) { + VehiclePropValue prop = new VehiclePropValue(); + prop.prop = sGenerateFakeDataControllingProperty; + prop.value.int32Values.addAll(Lists.newArrayList( + sKeyPressCommand, VehicleProperty.HW_KEY_INPUT, keyCode, targetDisplay)); + int status; + try { + status = mVehicle.set(prop); + } catch (RemoteException e) { + throw new RuntimeException("Failed to inject key press"); + } + + if (VehiclePropertyStatus.AVAILABLE != status) { + Toast.makeText(getContext(), "Failed to inject key event, status:" + status, + Toast.LENGTH_LONG).show(); } } @Override public void onDestroyView() { super.onDestroyView(); + mButtons.clear(); } private void addButtonsToPanel(LinearLayout root, List<View> buttons) { @@ -127,6 +172,7 @@ public class InputTestFragment extends Fragment { root.addView(panel); } else { panel.addView(button); + panel.setPadding(0, 10, 10, 0); } } } |