Merge "Add test cases for CarWatchdogManager" into rvc-dev
diff --git a/computepipe/runner/engine/DefaultEngine.cpp b/computepipe/runner/engine/DefaultEngine.cpp
index d93de2e..0f7c160 100644
--- a/computepipe/runner/engine/DefaultEngine.cpp
+++ b/computepipe/runner/engine/DefaultEngine.cpp
@@ -130,8 +130,16 @@
         return Status::SUCCESS;
     }
     if (command.has_death_notification()) {
-        mCurrentPhaseError = std::make_unique<ComponentError>(
-                "ClientInterface", "Client death", mCurrentPhase, false);
+        if (mCurrentPhase == kResetPhase) {
+            /**
+             * The runner is already in reset state, no need to broadcast client death
+             * to components
+             */
+            LOG(INFO) << "client death notification with no configuration";
+            return Status::SUCCESS;
+        }
+        mCurrentPhaseError = std::make_unique<ComponentError>("ClientInterface", "Client death",
+                                                              mCurrentPhase, false);
         mWakeLooper.notify_all();
         return Status::SUCCESS;
     }
diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/evs_driver.te
index 179623d..b051569 100644
--- a/evs/sepolicy/evs_driver.te
+++ b/evs/sepolicy/evs_driver.te
@@ -23,3 +23,6 @@
 # Allow the driver to access kobject uevents
 allow hal_evs_driver self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
 
+# Allow the driver to use automotive display proxy service
+allow hal_evs_driver automotive_display_service_server:binder call;
+
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AbstractBluetoothA2dpPreferenceController.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AbstractBluetoothA2dpPreferenceController.java
index d4afe48..1451f19 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AbstractBluetoothA2dpPreferenceController.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AbstractBluetoothA2dpPreferenceController.java
@@ -83,7 +83,10 @@
         final BluetoothCodecConfig codecConfig = mBluetoothA2dpConfigStore.createCodecConfig();
         synchronized (mBluetoothA2dpConfigStore) {
             if (mBluetoothA2dp != null) {
-                setCodecConfigPreference(null, codecConfig);    // Use current active device
+                BluetoothDevice activeDevice = mBluetoothA2dp.getActiveDevice();
+                if (activeDevice != null) {
+                    setCodecConfigPreference(mBluetoothA2dp.getActiveDevice(), codecConfig);
+                }
             }
         }
         // Because the setting is not persisted into permanent storage, we cannot call update state
@@ -102,13 +105,14 @@
 
     @Override
     public void updateState(Preference preference) {
-        if (getCodecConfig(null) == null || mPreference == null) { // Use current active device
+        BluetoothDevice activeDevice = mBluetoothA2dp.getActiveDevice();
+        if (activeDevice == null || getCodecConfig(activeDevice) == null || mPreference == null) {
             return;
         }
 
         BluetoothCodecConfig codecConfig;
         synchronized (mBluetoothA2dpConfigStore) {
-            codecConfig = getCodecConfig(null);         // Use current active device
+            codecConfig = getCodecConfig(activeDevice);         // Use current active device
         }
 
         final int index = getCurrentA2dpSettingIndex(codecConfig);
@@ -178,13 +182,22 @@
     @VisibleForTesting
     void setCodecConfigPreference(BluetoothDevice device,
             BluetoothCodecConfig config) {
-        mBluetoothA2dp.setCodecConfigPreference(device, config);
+        BluetoothDevice bluetoothDevice =
+                (device != null) ? device : mBluetoothA2dp.getActiveDevice();
+        if (bluetoothDevice != null) {
+            mBluetoothA2dp.setCodecConfigPreference(bluetoothDevice, config);
+        }
     }
 
     @VisibleForTesting
     BluetoothCodecConfig getCodecConfig(BluetoothDevice device) {
         if (mBluetoothA2dp != null) {
-            BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(device);
+            BluetoothDevice bluetoothDevice =
+                    (device != null) ? device : mBluetoothA2dp.getActiveDevice();
+            if (bluetoothDevice == null) {
+                return null;
+            }
+            BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(bluetoothDevice);
             if (codecStatus != null) {
                 return codecStatus.getCodecConfig();
             }
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/BluetoothAudioCodecPreferenceController.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/BluetoothAudioCodecPreferenceController.java
index 5cf9adc..74858b6 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/BluetoothAudioCodecPreferenceController.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/BluetoothAudioCodecPreferenceController.java
@@ -17,6 +17,7 @@
 package com.android.car.developeroptions.development;
 
 import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 
 import com.android.car.developeroptions.R;
@@ -109,14 +110,20 @@
             case 6:
                 synchronized (mBluetoothA2dpConfigStore) {
                     if (mBluetoothA2dp != null) {
-                        mBluetoothA2dp.enableOptionalCodecs(null); // Use current active device
+                        BluetoothDevice activeDevice = mBluetoothA2dp.getActiveDevice();
+                        if (activeDevice != null) {
+                            mBluetoothA2dp.enableOptionalCodecs(activeDevice);
+                        }
                     }
                 }
                 return;
             case 7:
                 synchronized (mBluetoothA2dpConfigStore) {
                     if (mBluetoothA2dp != null) {
-                        mBluetoothA2dp.disableOptionalCodecs(null); // Use current active device
+                        BluetoothDevice activeDevice = mBluetoothA2dp.getActiveDevice();
+                        if (activeDevice != null) {
+                            mBluetoothA2dp.disableOptionalCodecs(activeDevice);
+                        }
                     }
                 }
                 return;
diff --git a/tests/SecurityPermissionTest/Android.bp b/tests/SecurityPermissionTest/Android.bp
index f77d151..028875e 100644
--- a/tests/SecurityPermissionTest/Android.bp
+++ b/tests/SecurityPermissionTest/Android.bp
@@ -30,6 +30,7 @@
         "androidx.test.core",
         "androidx.test.ext.junit",
         "androidx.test.rules",
+        "truth-prebuilt",
         "car-frameworks-service",
         "testng",
     ],
diff --git a/tests/SecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicTest.java b/tests/SecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicTest.java
new file mode 100644
index 0000000..111afe4
--- /dev/null
+++ b/tests/SecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 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;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.car.Car;
+import android.car.VehicleAreaType;
+import android.car.VehiclePropertyIds;
+import android.car.VehiclePropertyType;
+import android.car.hardware.property.CarPropertyManager;
+import android.os.Handler;
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+
+/**
+ * This class contains security permission tests for the {@link CarPropertyManager}'s public APIs.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CarPropertyManagerPublicTest {
+    private Car mCar = null;
+    private CarPropertyManager mPropertyManager;
+    private HashSet<Integer> mProps = new HashSet<>();
+    private static final String TAG = CarPropertyManagerPublicTest.class.getSimpleName();
+    private static final Integer DUMMY_AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
+    @Before
+    public void setUp() throws Exception  {
+        initAllPropertyIds();
+        mCar = Car.createCar(
+                InstrumentationRegistry.getInstrumentation().getTargetContext(), (Handler) null);
+        mPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);
+        assertThat(mPropertyManager).isNotNull();
+    }
+
+    private synchronized void initAllPropertyIds() {
+        mProps.add(VehiclePropertyIds.DOOR_POS);
+        mProps.add(VehiclePropertyIds.DOOR_MOVE);
+        mProps.add(VehiclePropertyIds.DOOR_LOCK);
+        mProps.add(VehiclePropertyIds.MIRROR_Z_POS);
+        mProps.add(VehiclePropertyIds.MIRROR_Z_MOVE);
+        mProps.add(VehiclePropertyIds.MIRROR_Y_POS);
+        mProps.add(VehiclePropertyIds.MIRROR_Y_MOVE);
+        mProps.add(VehiclePropertyIds.MIRROR_LOCK);
+        mProps.add(VehiclePropertyIds.MIRROR_FOLD);
+        mProps.add(VehiclePropertyIds.SEAT_MEMORY_SELECT);
+        mProps.add(VehiclePropertyIds.SEAT_MEMORY_SET);
+        mProps.add(VehiclePropertyIds.SEAT_BELT_BUCKLED);
+        mProps.add(VehiclePropertyIds.SEAT_BELT_HEIGHT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_BELT_HEIGHT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_FORE_AFT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_FORE_AFT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_1_POS);
+        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_1_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_2_POS);
+        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_2_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_HEIGHT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_HEIGHT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_DEPTH_POS);
+        mProps.add(VehiclePropertyIds.SEAT_DEPTH_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_TILT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_TILT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_FORE_AFT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_FORE_AFT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_SIDE_SUPPORT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_SIDE_SUPPORT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_HEIGHT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_HEIGHT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_ANGLE_POS);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_ANGLE_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_FORE_AFT_POS);
+        mProps.add(VehiclePropertyIds.SEAT_HEADREST_FORE_AFT_MOVE);
+        mProps.add(VehiclePropertyIds.SEAT_OCCUPANCY);
+        mProps.add(VehiclePropertyIds.WINDOW_POS);
+        mProps.add(VehiclePropertyIds.WINDOW_MOVE);
+        mProps.add(VehiclePropertyIds.WINDOW_LOCK);
+
+        // HVAC properties
+        mProps.add(VehiclePropertyIds.HVAC_FAN_SPEED);
+        mProps.add(VehiclePropertyIds.HVAC_FAN_DIRECTION);
+        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_CURRENT);
+        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_SET);
+        mProps.add(VehiclePropertyIds.HVAC_DEFROSTER);
+        mProps.add(VehiclePropertyIds.HVAC_ELECTRIC_DEFROSTER_ON);
+        mProps.add(VehiclePropertyIds.HVAC_AC_ON);
+        mProps.add(VehiclePropertyIds.HVAC_MAX_AC_ON);
+        mProps.add(VehiclePropertyIds.HVAC_MAX_DEFROST_ON);
+        mProps.add(VehiclePropertyIds.HVAC_RECIRC_ON);
+        mProps.add(VehiclePropertyIds.HVAC_DUAL_ON);
+        mProps.add(VehiclePropertyIds.HVAC_AUTO_ON);
+        mProps.add(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE);
+        mProps.add(VehiclePropertyIds.HVAC_SIDE_MIRROR_HEAT);
+        mProps.add(VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT);
+        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS);
+        mProps.add(VehiclePropertyIds.HVAC_ACTUAL_FAN_SPEED_RPM);
+        mProps.add(VehiclePropertyIds.HVAC_POWER_ON);
+        mProps.add(VehiclePropertyIds.HVAC_FAN_DIRECTION_AVAILABLE);
+        mProps.add(VehiclePropertyIds.HVAC_AUTO_RECIRC_ON);
+        mProps.add(VehiclePropertyIds.HVAC_SEAT_VENTILATION);
+
+        // Info properties
+        mProps.add(VehiclePropertyIds.INFO_VIN);
+        mProps.add(VehiclePropertyIds.INFO_MAKE);
+        mProps.add(VehiclePropertyIds.INFO_MODEL);
+        mProps.add(VehiclePropertyIds.INFO_MODEL_YEAR);
+        mProps.add(VehiclePropertyIds.INFO_FUEL_CAPACITY);
+        mProps.add(VehiclePropertyIds.INFO_FUEL_TYPE);
+        mProps.add(VehiclePropertyIds.INFO_EV_BATTERY_CAPACITY);
+        mProps.add(VehiclePropertyIds.INFO_EV_CONNECTOR_TYPE);
+        mProps.add(VehiclePropertyIds.INFO_FUEL_DOOR_LOCATION);
+        mProps.add(VehiclePropertyIds.INFO_MULTI_EV_PORT_LOCATIONS);
+        mProps.add(VehiclePropertyIds.INFO_EV_PORT_LOCATION);
+        mProps.add(VehiclePropertyIds.INFO_DRIVER_SEAT);
+        mProps.add(VehiclePropertyIds.INFO_EXTERIOR_DIMENSIONS);
+
+        // Sensor properties
+        mProps.add(VehiclePropertyIds.PERF_ODOMETER);
+        mProps.add(VehiclePropertyIds.PERF_VEHICLE_SPEED);
+        mProps.add(VehiclePropertyIds.PERF_VEHICLE_SPEED_DISPLAY);
+        mProps.add(VehiclePropertyIds.ENGINE_COOLANT_TEMP);
+        mProps.add(VehiclePropertyIds.ENGINE_OIL_LEVEL);
+        mProps.add(VehiclePropertyIds.ENGINE_OIL_TEMP);
+        mProps.add(VehiclePropertyIds.ENGINE_RPM);
+        mProps.add(VehiclePropertyIds.WHEEL_TICK);
+        mProps.add(VehiclePropertyIds.FUEL_LEVEL);
+        mProps.add(VehiclePropertyIds.FUEL_DOOR_OPEN);
+        mProps.add(VehiclePropertyIds.EV_BATTERY_LEVEL);
+        mProps.add(VehiclePropertyIds.EV_CHARGE_PORT_OPEN);
+        mProps.add(VehiclePropertyIds.EV_CHARGE_PORT_CONNECTED);
+        mProps.add(VehiclePropertyIds.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE);
+        mProps.add(VehiclePropertyIds.RANGE_REMAINING);
+        mProps.add(VehiclePropertyIds.TIRE_PRESSURE);
+        mProps.add(VehiclePropertyIds.PERF_STEERING_ANGLE);
+        mProps.add(VehiclePropertyIds.PERF_REAR_STEERING_ANGLE);
+        mProps.add(VehiclePropertyIds.GEAR_SELECTION);
+        mProps.add(VehiclePropertyIds.CURRENT_GEAR);
+        mProps.add(VehiclePropertyIds.PARKING_BRAKE_ON);
+        mProps.add(VehiclePropertyIds.PARKING_BRAKE_AUTO_APPLY);
+        mProps.add(VehiclePropertyIds.FUEL_LEVEL_LOW);
+        mProps.add(VehiclePropertyIds.NIGHT_MODE);
+        mProps.add(VehiclePropertyIds.TURN_SIGNAL_STATE);
+        mProps.add(VehiclePropertyIds.IGNITION_STATE);
+        mProps.add(VehiclePropertyIds.ABS_ACTIVE);
+        mProps.add(VehiclePropertyIds.TRACTION_CONTROL_ACTIVE);
+        mProps.add(VehiclePropertyIds.ENV_OUTSIDE_TEMPERATURE);
+        mProps.add(VehiclePropertyIds.HEADLIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.HIGH_BEAM_LIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.FOG_LIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.HAZARD_LIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.HEADLIGHTS_SWITCH);
+        mProps.add(VehiclePropertyIds.HIGH_BEAM_LIGHTS_SWITCH);
+        mProps.add(VehiclePropertyIds.FOG_LIGHTS_SWITCH);
+        mProps.add(VehiclePropertyIds.HAZARD_LIGHTS_SWITCH);
+        mProps.add(VehiclePropertyIds.READING_LIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.CABIN_LIGHTS_STATE);
+        mProps.add(VehiclePropertyIds.READING_LIGHTS_SWITCH);
+        mProps.add(VehiclePropertyIds.CABIN_LIGHTS_SWITCH);
+        // Display_Units
+        mProps.add(VehiclePropertyIds.DISTANCE_DISPLAY_UNITS);
+        mProps.add(VehiclePropertyIds.FUEL_VOLUME_DISPLAY_UNITS);
+        mProps.add(VehiclePropertyIds.TIRE_PRESSURE_DISPLAY_UNITS);
+        mProps.add(VehiclePropertyIds.EV_BATTERY_DISPLAY_UNITS);
+        mProps.add(VehiclePropertyIds.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME);
+        mProps.add(VehiclePropertyIds.VEHICLE_SPEED_DISPLAY_UNITS);
+    }
+
+    @After
+    public void tearDown() {
+        if (mCar != null) {
+            mCar.disconnect();
+        }
+    }
+
+    @Test
+    public void testCarPropertyManagerGetter() {
+        for (int propertyId : mProps) {
+            try {
+                switch (propertyId & VehiclePropertyType.MASK) {
+                    case VehiclePropertyType.BOOLEAN:
+                        // The areaId may not match with it in propertyConfig. CarService
+                        // check the permission before checking valid areaId.
+                        mPropertyManager.getBooleanProperty(propertyId, DUMMY_AREA_ID);
+                        break;
+                    case VehiclePropertyType.FLOAT:
+                        mPropertyManager.getFloatProperty(propertyId, DUMMY_AREA_ID);
+                        break;
+                    case VehiclePropertyType.INT32_VEC:
+                        mPropertyManager.getIntArrayProperty(propertyId, DUMMY_AREA_ID);
+                        break;
+                    case VehiclePropertyType.INT32:
+                        mPropertyManager.getIntProperty(propertyId, DUMMY_AREA_ID);
+                        break;
+                    default:
+                        mPropertyManager.getProperty(propertyId, DUMMY_AREA_ID);
+                }
+            } catch (Exception e) {
+                assertWithMessage("Get property: 0x" + Integer.toHexString(propertyId)
+                        + " cause an unexpected exception: " + e)
+                        .that(e).isInstanceOf(SecurityException.class);
+                continue;
+            }
+            assertPropertyNotImplementedInVhal(propertyId);
+        }
+    }
+
+    private void assertPropertyNotImplementedInVhal(int propertyId) {
+        assertWithMessage("Get property : 0x " + Integer.toHexString(propertyId)
+                + " without permission.")
+                .that(mPropertyManager.getProperty(propertyId, DUMMY_AREA_ID)).isNull();
+        Log.w(TAG, "Property id: 0x" + Integer.toHexString(propertyId)
+                + " does not exist in the VHAL implementation.");
+    }
+
+}