1 /* 2 * Copyright (C) 2019 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.cts.verifier.car; 18 19 import android.car.Car; 20 import android.car.VehicleGear; 21 import android.car.VehiclePropertyIds; 22 import android.car.hardware.CarPropertyConfig; 23 import android.car.hardware.CarPropertyValue; 24 import android.car.hardware.property.CarPropertyManager; 25 import android.os.Bundle; 26 import android.util.Log; 27 import android.widget.TextView; 28 29 import com.android.cts.verifier.PassFailButtons; 30 import com.android.cts.verifier.R; 31 32 import java.util.List; 33 import java.util.concurrent.CountDownLatch; 34 import java.util.concurrent.ExecutorService; 35 import java.util.concurrent.Executors; 36 import java.util.concurrent.TimeUnit; 37 38 /** A CTS Verifier test case to verify GEAR_SELECTION is implemented correctly.*/ 39 public final class GearSelectionTestActivity extends PassFailButtons.Activity { 40 private static final String TAG = GearSelectionTestActivity.class.getSimpleName(); 41 42 // Need to finish the test in 10 minutes. 43 private static final long TEST_TIMEOUT_MINUTES = 10; 44 45 private List<Integer> mSupportedGears; 46 private TextView mExpectedGearSelectionTextView; 47 private TextView mCurrentGearSelectionTextView; 48 private CarPropertyManager mCarPropertyManager; 49 private ExecutorService mExecutor; 50 private GearSelectionCallback mGearSelectionCallback = new GearSelectionCallback(); 51 52 @Override onCreate(Bundle savedInstanceState)53 protected void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 56 // Setup the UI. 57 setContentView(R.layout.gear_selection_test); 58 setPassFailButtonClickListeners(); 59 setInfoResources(R.string.gear_selection_test, R.string.gear_selection_test_desc, -1); 60 getPassButton().setEnabled(false); 61 62 mExpectedGearSelectionTextView = (TextView) findViewById(R.id.expected_gear_selection); 63 mCurrentGearSelectionTextView = (TextView) findViewById(R.id.current_gear_selection); 64 mExecutor = Executors.newSingleThreadExecutor(); 65 setUpTest(); 66 } 67 setUpTest()68 private void setUpTest() { 69 mCarPropertyManager = 70 (CarPropertyManager) Car.createCar(this).getCarManager(Car.PROPERTY_SERVICE); 71 if (mCarPropertyManager == null) { 72 Log.e(TAG, "Failed to get CarPropertyManager"); 73 mExpectedGearSelectionTextView.setText("CONNECTING ERROR"); 74 return; 75 } 76 77 //Verify property config 78 CarPropertyConfig<?> gearConfig = mCarPropertyManager.getCarPropertyConfig( 79 VehiclePropertyIds.GEAR_SELECTION); 80 if (gearConfig == null || gearConfig.getConfigArray().size() == 0) { 81 Log.e(TAG, "No gears specified in the config array of GEAR_SELECTION property"); 82 mExpectedGearSelectionTextView.setText("GEAR CONFIG ERROR"); 83 return; 84 } 85 86 //Register the callback for testing 87 mSupportedGears = gearConfig.getConfigArray(); 88 Log.i(TAG, "New Expected Gear: " + VehicleGear.toString(mSupportedGears.get(0))); 89 mExpectedGearSelectionTextView.setText(VehicleGear.toString(mSupportedGears.get(0))); 90 mGearSelectionCallback = new GearSelectionCallback(); 91 mGearSelectionCallback.setSupportedGearCounter(mSupportedGears.size()); 92 if (!mCarPropertyManager.registerCallback(mGearSelectionCallback, 93 VehiclePropertyIds.GEAR_SELECTION, CarPropertyManager.SENSOR_RATE_ONCHANGE)) { 94 Log.e(TAG, 95 "Failed to register callback for GEAR_SELECTION with CarPropertyManager"); 96 mExpectedGearSelectionTextView.setText("CONNECTING ERROR"); 97 return; 98 } 99 100 //Unregister if test is timeout 101 mExecutor.execute(() -> { 102 try { 103 mGearSelectionCallback.unregisterIfTimeout(); 104 } catch (InterruptedException e) { 105 Log.e(TAG, "Test is interrupted: " + e); 106 mExpectedGearSelectionTextView.setText("INTERRUPTED"); 107 Thread.currentThread().interrupt(); 108 } 109 }); 110 } 111 112 private final class GearSelectionCallback implements 113 CarPropertyManager.CarPropertyEventCallback { 114 private CountDownLatch mCountDownLatch; 115 private int mVerifyingIndex; 116 @Override onChangeEvent(CarPropertyValue value)117 public void onChangeEvent(CarPropertyValue value) { 118 if(value.getStatus() != CarPropertyValue.STATUS_AVAILABLE) { 119 Log.e(TAG, "New CarPropertyValue's status is not available - propId: " + 120 value.getPropertyId() + " status: " + value.getStatus()); 121 return; 122 } 123 Integer newGearSelection = (Integer) value.getValue(); 124 mCurrentGearSelectionTextView.setText(VehicleGear.toString(newGearSelection)); 125 Log.i(TAG, "New Gear Selection: " + VehicleGear.toString(newGearSelection)); 126 127 // Check to see if new gear matches the expected gear. 128 if (newGearSelection.equals(mSupportedGears.get(mVerifyingIndex))) { 129 mCountDownLatch.countDown(); 130 mVerifyingIndex++; 131 Log.i(TAG, "Matched gear: " + VehicleGear.toString(newGearSelection)); 132 if (mCountDownLatch.getCount() != 0) { 133 // Test is not finished so update the expected gear. 134 mExpectedGearSelectionTextView.setText( 135 VehicleGear.toString(mSupportedGears.get(mVerifyingIndex))); 136 Log.i(TAG, "New Expected Gear: " 137 + VehicleGear.toString(mSupportedGears.get(mVerifyingIndex))); 138 } else { 139 // Test is finished, unregister the callback 140 mCarPropertyManager.unregisterCallback(mGearSelectionCallback); 141 mExpectedGearSelectionTextView.setText("Finished"); 142 getPassButton().setEnabled(true); 143 Log.i(TAG, "Finished Test"); 144 } 145 } 146 } 147 148 @Override onErrorEvent(int propId, int zone)149 public void onErrorEvent(int propId, int zone) { 150 Log.e(TAG, "propId: " + propId + " zone: " + zone); 151 } 152 setSupportedGearCounter(int counter)153 public void setSupportedGearCounter(int counter) { 154 mCountDownLatch = new CountDownLatch(counter); 155 } 156 unregisterIfTimeout()157 public void unregisterIfTimeout() throws InterruptedException { 158 if (!mCountDownLatch.await(TEST_TIMEOUT_MINUTES, TimeUnit.MINUTES)) { 159 Log.e(TAG, "Failed to complete tests in 10 minutes"); 160 runOnUiThread(() -> mExpectedGearSelectionTextView.setText("Failed(Timeout)")); 161 mCarPropertyManager.unregisterCallback(mGearSelectionCallback); 162 } 163 } 164 } 165 } 166