Merge "more test for Car" into nyc-car-dev
diff --git a/tests/android_car_api_test/AndroidManifest.xml b/tests/android_car_api_test/AndroidManifest.xml
index 2a36974..e4c5bbb 100644
--- a/tests/android_car_api_test/AndroidManifest.xml
+++ b/tests/android_car_api_test/AndroidManifest.xml
@@ -34,5 +34,7 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
+ <service android:name=".CarProjectionManagerTest$TestService"
+ android:exported="true" />
</application>
</manifest>
diff --git a/tests/android_car_api_test/src/android/car/apitest/CarProjectionManagerTest.java b/tests/android_car_api_test/src/android/car/apitest/CarProjectionManagerTest.java
new file mode 100644
index 0000000..973815b
--- /dev/null
+++ b/tests/android_car_api_test/src/android/car/apitest/CarProjectionManagerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.car.apitest;
+
+import android.app.Service;
+import android.car.Car;
+import android.car.CarProjectionManager;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.test.suitebuilder.annotation.MediumTest;
+
+@MediumTest
+public class CarProjectionManagerTest extends CarApiTestBase {
+ private static final String TAG = CarProjectionManagerTest.class.getSimpleName();
+
+ private final CarProjectionManager.CarProjectionListener mListener =
+ new CarProjectionManager.CarProjectionListener() {
+ @Override
+ public void onVoiceAssistantRequest(boolean fromLongPress) {
+ //void
+ }
+ };
+
+ private CarProjectionManager mManager;
+
+ public static class TestService extends Service {
+ public static Object mLock = new Object();
+ private static boolean sBound;
+ private final Binder mBinder = new Binder() {};
+
+ private static synchronized void setBound(boolean bound) {
+ sBound = bound;
+ }
+
+ public static synchronized boolean getBound() {
+ return sBound;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ setBound(true);
+ synchronized (mLock) {
+ mLock.notify();
+ }
+ return mBinder;
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mManager = (CarProjectionManager) getCar().getCarManager(Car.PROJECTION_SERVICE);
+ assertNotNull(mManager);
+ }
+
+ public void testSetUnsetListeners() throws Exception {
+ mManager.regsiterProjectionListener(
+ mListener, CarProjectionManager.PROJECTION_VOICE_SEARCH);
+ mManager.unregsiterProjectionListener();
+ }
+
+ public void testRegisterListenersHandleBadInput() throws Exception {
+ try {
+ mManager.regsiterProjectionListener(null, CarProjectionManager.PROJECTION_VOICE_SEARCH);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected.
+ }
+ }
+
+ public void testRegisterProjectionRunner() throws Exception {
+ Intent intent = new Intent(getContext(), TestService.class);
+ assertFalse(TestService.getBound());
+ mManager.registerProjectionRunner(intent);
+ synchronized (TestService.mLock) {
+ try {
+ TestService.mLock.wait(1000);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ }
+ assertTrue(TestService.getBound());
+ mManager.unregisterProjectionRunner(intent);
+ }
+}
diff --git a/tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java b/tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java
new file mode 100644
index 0000000..8c2f83e
--- /dev/null
+++ b/tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.test;
+
+import android.car.Car;
+import android.car.CarProjectionManager;
+import android.car.test.VehicleHalEmulator;
+import android.os.SystemClock;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.car.vehiclenetwork.VehicleNetworkConsts;
+import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
+import com.android.car.vehiclenetwork.VehiclePropConfigUtil;
+import com.android.car.vehiclenetwork.VehiclePropValueUtil;
+
+import java.util.HashMap;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@MediumTest
+public class CarProjectionManagerTest extends MockedCarTestBase {
+ private static final String TAG = CarProjectionManagerTest.class.getSimpleName();
+
+ private final Semaphore mLongAvailable = new Semaphore(0);
+ private final Semaphore mAvailable = new Semaphore(0);
+
+ private final CarProjectionManager.CarProjectionListener mListener =
+ new CarProjectionManager.CarProjectionListener() {
+ @Override
+ public void onVoiceAssistantRequest(boolean fromLongPress) {
+ if (fromLongPress) {
+ mLongAvailable.release();
+ } else {
+ mAvailable.release();
+ }
+ }
+ };
+
+ private CarProjectionManager mManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ PropertyHandler handler = new PropertyHandler();
+ getVehicleHalEmulator().addProperty(
+ VehiclePropConfigUtil.getBuilder(
+ VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT,
+ VehicleNetworkConsts.VehiclePropAccess.VEHICLE_PROP_ACCESS_READ,
+ VehicleNetworkConsts.VehiclePropChangeMode
+ .VEHICLE_PROP_CHANGE_MODE_ON_CHANGE,
+ VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4,
+ VehicleNetworkConsts.VehiclePermissionModel
+ .VEHICLE_PERMISSION_SYSTEM_APP_ONLY,
+ 0 /*configFlags*/, 0 /*sampleRateMax*/, 0 /*sampleRateMin*/).build(),
+ handler);
+ getVehicleHalEmulator().start();
+ mManager = (CarProjectionManager) getCar().getCarManager(Car.PROJECTION_SERVICE);
+ }
+
+ public void testShortPressListener() throws Exception {
+ mManager.regsiterProjectionListener(
+ mListener,
+ CarProjectionManager.PROJECTION_VOICE_SEARCH);
+ assertEquals(0, mAvailable.availablePermits());
+ assertEquals(0, mLongAvailable.availablePermits());
+ sendVoiceKey(false);
+ assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
+ assertEquals(0, mLongAvailable.availablePermits());
+ }
+
+ public void testLongPressListener() throws Exception {
+ mManager.regsiterProjectionListener(
+ mListener,
+ CarProjectionManager.PROJECTION_LONG_PRESS_VOICE_SEARCH);
+ assertEquals(0, mLongAvailable.availablePermits());
+ assertEquals(0, mAvailable.availablePermits());
+ sendVoiceKey(true);
+ assertTrue(mLongAvailable.tryAcquire(2L, TimeUnit.SECONDS));
+ assertEquals(0, mAvailable.availablePermits());
+ }
+
+ public void testMixedPressListener() throws Exception {
+ mManager.regsiterProjectionListener(
+ mListener,
+ CarProjectionManager.PROJECTION_LONG_PRESS_VOICE_SEARCH
+ | CarProjectionManager.PROJECTION_VOICE_SEARCH);
+ assertEquals(0, mLongAvailable.availablePermits());
+ assertEquals(0, mAvailable.availablePermits());
+ sendVoiceKey(true);
+ assertTrue(mLongAvailable.tryAcquire(2L, TimeUnit.SECONDS));
+ assertEquals(0, mAvailable.availablePermits());
+
+ assertEquals(0, mLongAvailable.availablePermits());
+ assertEquals(0, mAvailable.availablePermits());
+ sendVoiceKey(false);
+ assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
+ assertEquals(0, mLongAvailable.availablePermits());
+ }
+
+ public void sendVoiceKey(boolean isLong) throws InterruptedException {
+ int[] values = {
+ VehicleNetworkConsts.VehicleHwKeyInputAction.VEHICLE_HW_KEY_INPUT_ACTION_DOWN,
+ KeyEvent.KEYCODE_VOICE_ASSIST, 0, 0 };
+
+ VehiclePropValue injectValue = VehiclePropValueUtil.createIntVectorValue(
+ VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT, values,
+ SystemClock.elapsedRealtimeNanos());
+
+ getVehicleHalEmulator().injectEvent(injectValue);
+
+ if (isLong) {
+ Thread.sleep(1200); // Long press is > 1s.
+ }
+
+ int[] upValues = {
+ VehicleNetworkConsts.VehicleHwKeyInputAction.VEHICLE_HW_KEY_INPUT_ACTION_UP,
+ KeyEvent.KEYCODE_VOICE_ASSIST, 0, 0 };
+
+ injectValue = VehiclePropValueUtil.createIntVectorValue(
+ VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT, upValues,
+ SystemClock.elapsedRealtimeNanos());
+
+ getVehicleHalEmulator().injectEvent(injectValue);
+ }
+
+
+ private class PropertyHandler
+ implements VehicleHalEmulator.VehicleHalPropertyHandler {
+ HashMap<Integer, VehiclePropValue> mMap = new HashMap<>();
+
+ @Override
+ public synchronized void onPropertySet(VehiclePropValue value) {
+ Log.d(TAG, "onPropertySet:" + value);
+ mMap.put(value.getProp(), value);
+ }
+
+ @Override
+ public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
+ Log.d(TAG, "onPropertyGet:" + value);
+ VehiclePropValue currentValue = mMap.get(value.getProp());
+ // VNS will call getProperty method when subscribe is called, just return empty value.
+ return currentValue != null ? currentValue : value;
+ }
+
+ @Override
+ public synchronized void onPropertySubscribe(int property, float sampleRate, int zones) {
+ Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate);
+ }
+
+ @Override
+ public synchronized void onPropertyUnsubscribe(int property) {
+ Log.d(TAG, "onPropertyUnSubscribe property " + property);
+ }
+ }
+}