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.support.car.apitest; 18 19 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; 20 21 import android.os.Looper; 22 import android.support.car.Car; 23 import android.support.car.CarConnectionCallback; 24 import android.support.car.hardware.CarSensorEvent; 25 import android.support.car.hardware.CarSensorManager; 26 import android.test.AndroidTestCase; 27 import android.test.suitebuilder.annotation.MediumTest; 28 29 import java.lang.reflect.Field; 30 import java.util.HashMap; 31 import java.util.LinkedList; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.concurrent.Semaphore; 35 import java.util.concurrent.TimeUnit; 36 37 @MediumTest 38 public class CarSensorManagerTest extends AndroidTestCase { 39 private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000; 40 41 private final Semaphore mConnectionWait = new Semaphore(0); 42 43 private Car mCar; 44 private CarSensorManager mCarSensorManager; 45 46 private final CarConnectionCallback mConnectionCallbacks = 47 new CarConnectionCallback() { 48 @Override 49 public void onDisconnected(Car car) { 50 assertMainThread(); 51 } 52 53 @Override 54 public void onConnected(Car car) { 55 assertMainThread(); 56 mConnectionWait.release(); 57 } 58 }; 59 60 private void assertMainThread() { 61 assertTrue(Looper.getMainLooper().isCurrentThread()); 62 } 63 private void waitForConnection(long timeoutMs) throws InterruptedException { 64 mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); 65 } 66 67 @Override 68 protected void setUp() throws Exception { 69 super.setUp(); 70 mCar = Car.createCar(getContext(), mConnectionCallbacks); 71 mCar.connect(); 72 waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); 73 mCarSensorManager = 74 (CarSensorManager) mCar.getCarManager(Car.SENSOR_SERVICE); 75 } 76 77 @Override 78 protected void tearDown() throws Exception { 79 super.tearDown(); 80 mCar.disconnect(); 81 } 82 83 public void testDrivingPolicy() throws Exception { 84 // Embedded does not support SENSOR_TYPE_DRIVING_STATUS. Hence this test is not run in 85 // Android Auto Embedded. 86 if (getContext().getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)) { 87 return; 88 } 89 90 int[] supportedSensors = mCarSensorManager.getSupportedSensors(); 91 assertNotNull(supportedSensors); 92 boolean found = false; 93 for (int sensor: supportedSensors) { 94 if (sensor == CarSensorManager.SENSOR_TYPE_DRIVING_STATUS) { 95 found = true; 96 break; 97 } 98 } 99 assertTrue(found); 100 assertTrue(mCarSensorManager.isSensorSupported( 101 CarSensorManager.SENSOR_TYPE_DRIVING_STATUS)); 102 CarSensorEvent lastEvent = mCarSensorManager.getLatestSensorEvent( 103 CarSensorManager.SENSOR_TYPE_DRIVING_STATUS); 104 assertNotNull(lastEvent); 105 } 106 107 public void testSensorType() throws Exception { 108 List<Field> androidCarAllIntMembers = TestUtil.getAllPublicStaticFinalMembers( 109 android.car.hardware.CarSensorManager.class, int.class); 110 List<Field> supportCarAllIntMembers = TestUtil.getAllPublicStaticFinalMembers( 111 android.support.car.hardware.CarSensorManager.class, int.class); 112 List<Field> androidCarSensorTypes = filterSensorTypes(androidCarAllIntMembers); 113 List<Field> supportCarSensorTypes = filterSensorTypes(supportCarAllIntMembers); 114 Map<Integer, Field> androidCarSensorTypeToField = new HashMap<>(); 115 for (Field androidCarSensorType : androidCarSensorTypes) { 116 androidCarSensorTypeToField.put(androidCarSensorType.getInt(null), 117 androidCarSensorType); 118 } 119 StringBuilder builder = new StringBuilder(); 120 boolean failed = false; 121 for (Field supportCarSensorType : supportCarSensorTypes) { 122 Field androidCarSensorType = androidCarSensorTypeToField.get( 123 supportCarSensorType.getInt(null)); 124 assertNotNull("Sensor type:" + supportCarSensorType.getName() + 125 " not defined in android.car", androidCarSensorType); 126 if (supportCarSensorType.getName().equals(androidCarSensorType.getName())) { 127 // match ok 128 } else if (androidCarSensorType.getName().startsWith("SENSOR_TYPE_RESERVED")) { 129 // not used in android.car, ok 130 } else if (supportCarSensorType.getName().startsWith("SENSOR_TYPE_RESERVED")) { 131 // used in android.car but reserved in support.car 132 } else { 133 failed = true; 134 builder.append("android.support sensor has name:" + supportCarSensorType.getName() + 135 " while android.car sensor has name:" + androidCarSensorType.getName() + 136 "\n"); 137 } 138 androidCarSensorTypeToField.remove(supportCarSensorType.getInt(null)); 139 } 140 assertFalse(builder.toString(), failed); 141 assertTrue("android Car sensor has additional types defined:" + androidCarSensorTypeToField, 142 androidCarSensorTypeToField.size() == 0); 143 } 144 145 public void testSensorRate() throws Exception { 146 List<Field> androidCarAllIntMembers = TestUtil.getAllPublicStaticFinalMembers( 147 android.car.hardware.CarSensorManager.class, int.class); 148 List<Field> supportCarAllIntMembers = TestUtil.getAllPublicStaticFinalMembers( 149 android.support.car.hardware.CarSensorManager.class, int.class); 150 List<Field> androidCarSensorRates = filterSensorRates(androidCarAllIntMembers); 151 List<Field> supportCarSensorRates = filterSensorRates(supportCarAllIntMembers); 152 Map<Integer, Field> androidCarSensorRateToField = new HashMap<>(); 153 for (Field androidCarSensorRate : androidCarSensorRates) { 154 androidCarSensorRateToField.put(androidCarSensorRate.getInt(null), 155 androidCarSensorRate); 156 } 157 StringBuilder builder = new StringBuilder(); 158 boolean failed = false; 159 for (Field supprotCarSensorRate : supportCarSensorRates) { 160 Field androidCarSensorRate = androidCarSensorRateToField.get( 161 supprotCarSensorRate.getInt(null)); 162 assertNotNull("Sensor rate:" + supprotCarSensorRate.getName() + 163 " not defined in android.car", androidCarSensorRate); 164 if (supprotCarSensorRate.getName().equals(androidCarSensorRate.getName())) { 165 // match ok 166 } else { 167 failed = true; 168 builder.append("android.support sensor rate has name:" + 169 supprotCarSensorRate.getName() + 170 " while android.car sensor rate has name:" + 171 androidCarSensorRate.getName()); 172 } 173 androidCarSensorRateToField.remove(supprotCarSensorRate.getInt(null)); 174 } 175 assertFalse(builder.toString(), failed); 176 assertTrue("android Car sensor has additional rates defined:" + androidCarSensorRateToField, 177 androidCarSensorRateToField.size() == 0); 178 } 179 180 private List<Field> filterSensorTypes(List<Field> fields) { 181 return filterFields(fields, "SENSOR_TYPE_"); 182 } 183 184 private List<Field> filterSensorRates(List<Field> fields) { 185 return filterFields(fields, "SENSOR_RATE_"); 186 } 187 188 private List<Field> filterFields(List<Field> fields, String prefix) { 189 List<Field> result = new LinkedList<>(); 190 for (Field f : fields) { 191 if (f.getName().startsWith(prefix)) { 192 result.add(f); 193 } 194 } 195 return result; 196 } 197 } 198