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