CarProjectionManagerTest.java revision 382ceee63f079dab526fcd213dfe352124002a65
1/*
2 * Copyright (C) 2015 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
17package com.android.car;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertTrue;
21
22import android.car.Car;
23import android.car.CarProjectionManager;
24import android.hardware.automotive.vehicle.V2_0.VehicleHwKeyInputAction;
25import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
26import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
27import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
28import android.os.SystemClock;
29import android.support.test.filters.MediumTest;
30import android.support.test.runner.AndroidJUnit4;
31import android.util.Log;
32import android.view.KeyEvent;
33
34import com.android.car.vehiclehal.VehiclePropValueBuilder;
35import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
36
37import org.junit.Test;
38import org.junit.runner.RunWith;
39
40import java.util.HashMap;
41import java.util.concurrent.Semaphore;
42import java.util.concurrent.TimeUnit;
43
44@RunWith(AndroidJUnit4.class)
45@MediumTest
46public class CarProjectionManagerTest extends MockedCarTestBase {
47    private static final String TAG = CarProjectionManagerTest.class.getSimpleName();
48
49    private final Semaphore mLongAvailable = new Semaphore(0);
50    private final Semaphore mAvailable = new Semaphore(0);
51
52    private final CarProjectionManager.CarProjectionListener mListener =
53            new CarProjectionManager.CarProjectionListener() {
54                @Override
55                public void onVoiceAssistantRequest(boolean fromLongPress) {
56                    if (fromLongPress) {
57                        mLongAvailable.release();
58                    } else {
59                        mAvailable.release();
60                    }
61                }
62            };
63
64    private CarProjectionManager mManager;
65
66    @Override
67    protected synchronized void configureMockedHal() {
68        addProperty(VehicleProperty.HW_KEY_INPUT, new PropertyHandler())
69                .setAccess(VehiclePropertyAccess.READ);
70    }
71
72    @Override
73    public void setUp() throws Exception {
74        super.setUp();
75        mManager = (CarProjectionManager) getCar().getCarManager(Car.PROJECTION_SERVICE);
76    }
77
78    @Test
79    public void testShortPressListener() throws Exception {
80        mManager.registerProjectionListener(
81                mListener,
82                CarProjectionManager.PROJECTION_VOICE_SEARCH);
83        assertEquals(0, mAvailable.availablePermits());
84        assertEquals(0, mLongAvailable.availablePermits());
85        sendVoiceKey(false);
86        assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
87        assertEquals(0, mLongAvailable.availablePermits());
88    }
89
90    @Test
91    public void testLongPressListener() throws Exception {
92        mManager.registerProjectionListener(
93                mListener,
94                CarProjectionManager.PROJECTION_LONG_PRESS_VOICE_SEARCH);
95        assertEquals(0, mLongAvailable.availablePermits());
96        assertEquals(0, mAvailable.availablePermits());
97        sendVoiceKey(true);
98        assertTrue(mLongAvailable.tryAcquire(2L, TimeUnit.SECONDS));
99        assertEquals(0, mAvailable.availablePermits());
100    }
101
102    @Test
103    public void testMixedPressListener() throws Exception {
104        mManager.registerProjectionListener(
105                mListener,
106                CarProjectionManager.PROJECTION_LONG_PRESS_VOICE_SEARCH
107                | CarProjectionManager.PROJECTION_VOICE_SEARCH);
108        assertEquals(0, mLongAvailable.availablePermits());
109        assertEquals(0, mAvailable.availablePermits());
110        sendVoiceKey(true);
111        assertTrue(mLongAvailable.tryAcquire(2L, TimeUnit.SECONDS));
112        assertEquals(0, mAvailable.availablePermits());
113
114        assertEquals(0, mLongAvailable.availablePermits());
115        assertEquals(0, mAvailable.availablePermits());
116        sendVoiceKey(false);
117        assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
118        assertEquals(0, mLongAvailable.availablePermits());
119    }
120
121    public void sendVoiceKey(boolean isLong) throws InterruptedException {
122        int[] values = {VehicleHwKeyInputAction.ACTION_DOWN, KeyEvent.KEYCODE_VOICE_ASSIST, 0, 0};
123
124        VehiclePropValue injectValue =
125                VehiclePropValueBuilder.newBuilder(VehicleProperty.HW_KEY_INPUT)
126                        .setTimestamp(SystemClock.elapsedRealtimeNanos())
127                        .addIntValue(values)
128                        .build();
129
130        getMockedVehicleHal().injectEvent(injectValue);
131
132        if (isLong) {
133            Thread.sleep(1200); // Long press is > 1s.
134        }
135
136        int[] upValues = {VehicleHwKeyInputAction.ACTION_UP, KeyEvent.KEYCODE_VOICE_ASSIST, 0, 0 };
137
138        injectValue = VehiclePropValueBuilder.newBuilder(VehicleProperty.HW_KEY_INPUT)
139                .setTimestamp(SystemClock.elapsedRealtimeNanos())
140                .addIntValue(upValues)
141                .build();
142
143        getMockedVehicleHal().injectEvent(injectValue);
144    }
145
146
147    private class PropertyHandler implements VehicleHalPropertyHandler {
148        HashMap<Integer, VehiclePropValue> mMap = new HashMap<>();
149
150        @Override
151        public synchronized void onPropertySet(VehiclePropValue value) {
152            Log.d(TAG, "onPropertySet:" + value);
153            mMap.put(value.prop, value);
154        }
155
156        @Override
157        public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
158            Log.d(TAG, "onPropertyGet:" + value);
159            VehiclePropValue currentValue = mMap.get(value.prop);
160            // VNS will call get method when subscribe is called, just return empty value.
161            return currentValue != null ? currentValue : value;
162        }
163
164        @Override
165        public synchronized void onPropertySubscribe(int property, float sampleRate) {
166            Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate);
167        }
168
169        @Override
170        public synchronized void onPropertyUnsubscribe(int property) {
171            Log.d(TAG, "onPropertyUnSubscribe property " + property);
172        }
173    }
174}
175