[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 6235661a18 -s ours am: 3347b854a8 -s ours
am skip reason: subject contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Car/+/12949932
Change-Id: Iac62badc93452d4b5f166c645936cf474b562c4a
diff --git a/FrameworkPackageStubs/AndroidManifest.xml b/FrameworkPackageStubs/AndroidManifest.xml
index ac674cb..4e51f13 100644
--- a/FrameworkPackageStubs/AndroidManifest.xml
+++ b/FrameworkPackageStubs/AndroidManifest.xml
@@ -59,11 +59,26 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
<data android:scheme="content" />
<data android:scheme="file" />
<data android:mimeType="video/*" />
<data android:mimeType="image/*" />
</intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.PICK" />
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/image" />
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.PICK" />
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/video"/>
+ </intent-filter>
</activity>
<!-- Settings package stubs -->
diff --git a/car-lib/Android.bp b/car-lib/Android.bp
index 932b6af..1978ba3 100644
--- a/car-lib/Android.bp
+++ b/car-lib/Android.bp
@@ -80,7 +80,6 @@
aidl: {
include_dirs: [
"system/bt/binder",
- "packages/services/Car/watchdog/aidl",
],
},
exclude_srcs: [
@@ -89,7 +88,6 @@
],
static_libs: [
"android.car.internal.event-log-tags",
- "carwatchdog_aidl_interface-java",
],
product_variables: {
pdk: {
diff --git a/car-lib/src/android/car/VehiclePropertyIds.java b/car-lib/src/android/car/VehiclePropertyIds.java
index a9945da..644ea1e 100644
--- a/car-lib/src/android/car/VehiclePropertyIds.java
+++ b/car-lib/src/android/car/VehiclePropertyIds.java
@@ -129,7 +129,7 @@
public static final int INFO_EXTERIOR_DIMENSIONS = 289472779;
/**
* Current odometer value of the vehicle
- * Requires permission: {@link Car#PERMISSION_MILEAGE}.
+ * The property is protected by the signature permission: android.car.permission.CAR_MILEAGE.
*/
@RequiresPermission(Car.PERMISSION_MILEAGE)
public static final int PERF_ODOMETER = 291504644;
@@ -166,25 +166,29 @@
public static final int PERF_REAR_STEERING_ANGLE = 291504656;
/**
* Temperature of engine coolant
- * Requires permission: {@link Car#PERMISSION_CAR_ENGINE_DETAILED}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_ENGINE_DETAILED.
*/
@RequiresPermission(Car.PERMISSION_CAR_ENGINE_DETAILED)
public static final int ENGINE_COOLANT_TEMP = 291504897;
/**
* Engine oil level
- * Requires permission: {@link Car#PERMISSION_CAR_ENGINE_DETAILED}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_ENGINE_DETAILED.
*/
@RequiresPermission(Car.PERMISSION_CAR_ENGINE_DETAILED)
public static final int ENGINE_OIL_LEVEL = 289407747;
/**
* Temperature of engine oil
- * Requires permission: {@link Car#PERMISSION_CAR_ENGINE_DETAILED}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_ENGINE_DETAILED.
*/
@RequiresPermission(Car.PERMISSION_CAR_ENGINE_DETAILED)
public static final int ENGINE_OIL_TEMP = 291504900;
/**
* Engine rpm
- * Requires permission: {@link Car#PERMISSION_CAR_ENGINE_DETAILED}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_ENGINE_DETAILED.
*/
@RequiresPermission(Car.PERMISSION_CAR_ENGINE_DETAILED)
public static final int ENGINE_RPM = 291504901;
@@ -203,7 +207,8 @@
/**
* Fuel door open
* Requires permission: {@link Car#PERMISSION_ENERGY_PORTS} to read the property.
- * Requires permission: {@link Car#PERMISSION_CONTROL_ENERGY_PORTS} to control the property.
+ * Requires the signature permission: android.car.permission.CONTROL_CAR_ENERGY_PORTS to write
+ * the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_ENERGY_PORTS))
@RequiresPermission.Write(@RequiresPermission(Car.PERMISSION_CONTROL_ENERGY_PORTS))
@@ -217,7 +222,8 @@
/**
* EV charge port open
* Requires permission: {@link Car#PERMISSION_ENERGY_PORTS} to read the property.
- * Requires permission: {@link Car#PERMISSION_CONTROL_ENERGY_PORTS} to control the property.
+ * Requires the signature permission: android.car.permission.CONTROL_CAR_ENERGY_PORTS to write
+ * the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_ENERGY_PORTS))
@RequiresPermission.Write(@RequiresPermission(Car.PERMISSION_CONTROL_ENERGY_PORTS))
@@ -241,7 +247,8 @@
* all energy sources in a vehicle. For example, a hybrid car's range will
* be the sum of the ranges based on fuel and battery.
* Requires permission: {@link Car#PERMISSION_ENERGY} to read the property.
- * Requires permission: {@link Car#PERMISSION_ADJUST_RANGE_REMAINING} to write the property.
+ * Requires the signature permission: android.car.permission.ADJUST_RANGE_REMAINING to write
+ * the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_ENERGY))
@RequiresPermission.Write(@RequiresPermission(Car.PERMISSION_ADJUST_RANGE_REMAINING))
@@ -251,7 +258,7 @@
*
* min/max value indicates tire pressure sensor range. Each tire will have a separate min/max
* value denoted by its areaConfig.areaId.
- * Requires permission: {@link Car#PERMISSION_TIRES}.
+ * The property is protected by the signature permission: android.car.permission.CAR_TIRES.
*/
@RequiresPermission(Car.PERMISSION_TIRES)
public static final int TIRE_PRESSURE = 392168201;
@@ -298,7 +305,8 @@
public static final int NIGHT_MODE = 287310855;
/**
* State of the vehicles turn signals
- * Requires permission: {@link Car#PERMISSION_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS .
*/
@RequiresPermission(Car.PERMISSION_EXTERIOR_LIGHTS)
public static final int TURN_SIGNAL_STATE = 289408008;
@@ -310,109 +318,127 @@
public static final int IGNITION_STATE = 289408009;
/**
* ABS is active
- * Requires permission: {@link Car#PERMISSION_CAR_DYNAMICS_STATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_DYNAMICS_STATE.
*/
@RequiresPermission(Car.PERMISSION_CAR_DYNAMICS_STATE)
public static final int ABS_ACTIVE = 287310858;
/**
* Traction Control is active
- * Requires permission: {@link Car#PERMISSION_CAR_DYNAMICS_STATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_DYNAMICS_STATE.
*/
@RequiresPermission(Car.PERMISSION_CAR_DYNAMICS_STATE)
public static final int TRACTION_CONTROL_ACTIVE = 287310859;
/**
* Fan speed setting
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_FAN_SPEED = 356517120;
/**
* Fan direction setting
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_FAN_DIRECTION = 356517121;
/**
* HVAC current temperature.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_TEMPERATURE_CURRENT = 358614274;
/**
* HVAC, target temperature set.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_TEMPERATURE_SET = 358614275;
/**
* On/off defrost for designated window
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_DEFROSTER = 320865540;
/**
* On/off AC for designated areaId
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_AC_ON = 354419973;
/**
* On/off max AC
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_MAX_AC_ON = 354419974;
/**
* On/off max defrost
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_MAX_DEFROST_ON = 354419975;
/**
* Recirculation on/off
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_RECIRC_ON = 354419976;
/**
* Enable temperature coupling between areas.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_DUAL_ON = 354419977;
/**
* On/off automatic mode
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_AUTO_ON = 354419978;
/**
* Seat heating/cooling
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_SEAT_TEMPERATURE = 356517131;
/**
* Side Mirror Heat
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_SIDE_MIRROR_HEAT = 339739916;
/**
* Steering Wheel Heating/Cooling
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_STEERING_WHEEL_HEAT = 289408269;
/**
* Temperature units for display
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_TEMPERATURE_DISPLAY_UNITS = 289408270;
/**
* Actual fan speed
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_ACTUAL_FAN_SPEED_RPM = 356517135;
@@ -423,31 +449,36 @@
* properties that control individual HVAC features/subsystems to AVAILABLE
* state (unless any/all of them are UNAVAILABLE on their own individual
* merits).
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_POWER_ON = 354419984;
/**
* Fan Positions Available
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_FAN_DIRECTION_AVAILABLE = 356582673;
/**
* Automatic recirculation on/off
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_AUTO_RECIRC_ON = 354419986;
/**
* Seat ventilation
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
public static final int HVAC_SEAT_VENTILATION = 356517139;
/**
* ELECTRIC DEFROSTER
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_CLIMATE}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_CLIMATE.
* @hide
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE)
@@ -455,8 +486,8 @@
/**
* Distance units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS} and
- * {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@RequiresPermission.Write(@RequiresPermission(allOf = {Car.PERMISSION_CONTROL_DISPLAY_UNITS,
@@ -465,8 +496,8 @@
/**
* Fuel volume units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS}
- * and {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@RequiresPermission.Write(@RequiresPermission(allOf = {Car.PERMISSION_CONTROL_DISPLAY_UNITS,
@@ -475,8 +506,8 @@
/**
* Tire pressure units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS} and
- * {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@RequiresPermission.Write(@RequiresPermission(allOf = {Car.PERMISSION_CONTROL_DISPLAY_UNITS,
@@ -485,8 +516,8 @@
/**
* EV battery units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS} and
- * {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@RequiresPermission.Write(@RequiresPermission(allOf = {Car.PERMISSION_CONTROL_DISPLAY_UNITS,
@@ -495,8 +526,8 @@
/**
* Speed Units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS} and
- * {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
* @hide
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@@ -506,8 +537,8 @@
/**
* Fuel consumption units for display
* Requires permission {@link Car#PERMISSION_READ_DISPLAY_UNITS} to read the property.
- * Requires permission {@link Car#PERMISSION_CONTROL_DISPLAY_UNITS} and
- * {@link Car#PERMISSION_VENDOR_EXTENSION}to write the property.
+ * Requires two signature permissions: android.car.permission.CONTROL_CAR_DISPLAY_UNITS and
+ * android.car.permission.CAR_VENDOR_EXTENSION to write the property.
*/
@RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_DISPLAY_UNITS))
@RequiresPermission.Write(@RequiresPermission(allOf = {Car.PERMISSION_CONTROL_DISPLAY_UNITS,
@@ -524,7 +555,7 @@
*
* It is assumed that AP's power state is controller by separate power
* controller.
- * Requires permission: {@link Car#PERMISSION_CAR_POWER}.
+ * The property is protected by the signature permission: android.car.permission.CAR_POWER.
*/
@RequiresPermission(Car.PERMISSION_CAR_POWER)
public static final int AP_POWER_STATE_REQ = 289475072;
@@ -533,7 +564,7 @@
*
* It is assumed that AP's power state is controller by separate power
* controller.
- * Requires permission: {@link Car#PERMISSION_CAR_POWER}.
+ * The property is protected by the signature permission: android.car.permission.CAR_POWER.
*/
@RequiresPermission(Car.PERMISSION_CAR_POWER)
public static final int AP_POWER_STATE_REPORT = 289475073;
@@ -543,7 +574,7 @@
* off. For example, even if user presses power on button after automatic
* power on with door unlock, bootup reason must stay with
* VehicleApPowerBootupReason#USER_UNLOCK.
- * Requires permission: {@link Car#PERMISSION_CAR_POWER}.
+ * The property is protected by the signature permission: android.car.permission.CAR_POWER.
*/
@RequiresPermission(Car.PERMISSION_CAR_POWER)
public static final int AP_POWER_BOOTUP_REASON = 289409538;
@@ -551,7 +582,7 @@
* Property to represent brightness of the display. Some cars have single
* control for the brightness of all displays and this property is to share
* change in that control.
- * Requires permission: {@link Car#PERMISSION_CAR_POWER}.
+ * The property is protected by the signature permission: android.car.permission.CAR_POWER.
*/
@RequiresPermission(Car.PERMISSION_CAR_POWER)
public static final int DISPLAY_BRIGHTNESS = 289409539;
@@ -564,55 +595,64 @@
*
* This is an integer in case a door may be set to a particular position.
* Max value indicates fully open, min value (0) indicates fully closed.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_DOORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_DOORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_DOORS)
public static final int DOOR_POS = 373295872;
/**
* Door move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_DOORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_DOORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_DOORS)
public static final int DOOR_MOVE = 373295873;
/**
* Door lock
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_DOORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_DOORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_DOORS)
public static final int DOOR_LOCK = 371198722;
/**
* Mirror Z Position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_Z_POS = 339741504;
/**
* Mirror Z Move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_Z_MOVE = 339741505;
/**
* Mirror Y Position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_Y_POS = 339741506;
/**
* Mirror Y Move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_Y_MOVE = 339741507;
/**
* Mirror Lock
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_LOCK = 287312708;
/**
* Mirror Fold
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_MIRRORS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_MIRRORS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_MIRRORS)
public static final int MIRROR_FOLD = 287312709;
@@ -622,7 +662,8 @@
* This parameter selects the memory preset to use to select the seat
* position. The minValue is always 0, and the maxValue determines the
* number of seat positions available.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_MEMORY_SELECT = 356518784;
@@ -632,7 +673,8 @@
* This setting allows the user to save the current seat position settings
* into the selected preset slot. The maxValue for each seat position
* must match the maxValue for SEAT_MEMORY_SELECT.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_MEMORY_SET = 356518785;
@@ -640,37 +682,43 @@
* Seatbelt buckled
*
* True indicates belt is buckled.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BELT_BUCKLED = 354421634;
/**
* Seatbelt height position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BELT_HEIGHT_POS = 356518787;
/**
* Seatbelt height move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BELT_HEIGHT_MOVE = 356518788;
/**
* Seat fore/aft position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_FORE_AFT_POS = 356518789;
/**
* Seat fore/aft move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_FORE_AFT_MOVE = 356518790;
/**
* Seat backrest angle 1 position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BACKREST_ANGLE_1_POS = 356518791;
@@ -678,146 +726,169 @@
* Seat backrest angle 1 move
*
* Moves the backrest forward or recline.
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BACKREST_ANGLE_1_MOVE = 356518792;
/**
* Seat backrest angle 2 position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BACKREST_ANGLE_2_POS = 356518793;
/**
* Seat backrest angle 2 move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_BACKREST_ANGLE_2_MOVE = 356518794;
/**
* Seat height position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEIGHT_POS = 356518795;
/**
* Seat height move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEIGHT_MOVE = 356518796;
/**
* Seat depth position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_DEPTH_POS = 356518797;
/**
* Seat depth move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_DEPTH_MOVE = 356518798;
/**
* Seat tilt position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_TILT_POS = 356518799;
/**
* Seat tilt move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_TILT_MOVE = 356518800;
/**
* Lumber fore/aft position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_LUMBAR_FORE_AFT_POS = 356518801;
/**
* Lumbar fore/aft move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_LUMBAR_FORE_AFT_MOVE = 356518802;
/**
* Lumbar side support position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_LUMBAR_SIDE_SUPPORT_POS = 356518803;
/**
* Lumbar side support move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 356518804;
/**
* Headrest height position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_HEIGHT_POS = 289409941;
/**
* Headrest height move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_HEIGHT_MOVE = 356518806;
/**
* Headrest angle position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_ANGLE_POS = 356518807;
/**
* Headrest angle move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_ANGLE_MOVE = 356518808;
/**
* Headrest fore/aft position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_FORE_AFT_POS = 356518809;
/**
* Headrest fore/aft move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_HEADREST_FORE_AFT_MOVE = 356518810;
/**
* Seat Occupancy
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_SEATS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_SEATS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_SEATS)
public static final int SEAT_OCCUPANCY = 356518832;
/**
* Window Position
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_WINDOWS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_WINDOWS
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_WINDOWS)
public static final int WINDOW_POS = 322964416;
/**
* Window Move
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_WINDOWS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_WINDOWS
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_WINDOWS)
public static final int WINDOW_MOVE = 322964417;
/**
* Window Lock
- * Requires permission: {@link Car#PERMISSION_CONTROL_CAR_WINDOWS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CONTROL_CAR_WINDOWS
*/
@RequiresPermission(Car.PERMISSION_CONTROL_CAR_WINDOWS)
public static final int WINDOW_LOCK = 320867268;
/**
* Vehicle Maps Service (VMS) message
- * Requires one of permissions in {@link Car#PERMISSION_VMS_PUBLISHER},
- * {@link Car#PERMISSION_VMS_SUBSCRIBER}.
+ * The property is protected by the signature permissions:
+ * android.car.permission.VMS_PUBLISHER and android.car.permission.VMS_SUBSCRIBER.
*/
@RequiresPermission(anyOf = {Car.PERMISSION_VMS_PUBLISHER, Car.PERMISSION_VMS_SUBSCRIBER})
public static final int VEHICLE_MAP_SERVICE = 299895808;
@@ -825,7 +896,8 @@
* OBD2 Live Sensor Data
*
* Reports a snapshot of the current (live) values of the OBD2 sensors available.
- * Requires permission: {@link Car#PERMISSION_CAR_DIAGNOSTIC_READ_ALL}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_DIAGNOSTICS.
*/
@RequiresPermission(Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL)
public static final int OBD2_LIVE_FRAME = 299896064;
@@ -834,13 +906,15 @@
*
* Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
* occurred and was detected.
- * Requires permission: {@link Car#PERMISSION_CAR_DIAGNOSTIC_READ_ALL}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_DIAGNOSTICS.
*/
@RequiresPermission(Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL)
public static final int OBD2_FREEZE_FRAME = 299896065;
/**
* OBD2 Freeze Frame Information
- * Requires permission: {@link Car#PERMISSION_CAR_DIAGNOSTIC_READ_ALL}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_DIAGNOSTICS.
*/
@RequiresPermission(Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL)
public static final int OBD2_FREEZE_FRAME_INFO = 299896066;
@@ -849,55 +923,64 @@
*
* This property allows deletion of any of the freeze frames stored in
* vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
- * Requires permission: {@link Car#PERMISSION_CAR_DIAGNOSTIC_CLEAR}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CLEAR_CAR_DIAGNOSTICS.
*/
@RequiresPermission(Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR)
public static final int OBD2_FREEZE_FRAME_CLEAR = 299896067;
/**
* Headlights State
- * Requires permission: {@link Car#PERMISSION_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_EXTERIOR_LIGHTS)
public static final int HEADLIGHTS_STATE = 289410560;
/**
* High beam lights state
- * Requires permission: {@link Car#PERMISSION_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_EXTERIOR_LIGHTS)
public static final int HIGH_BEAM_LIGHTS_STATE = 289410561;
/**
* Fog light state
- * Requires permission: {@link Car#PERMISSION_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_EXTERIOR_LIGHTS)
public static final int FOG_LIGHTS_STATE = 289410562;
/**
* Hazard light status
- * Requires permission: {@link Car#PERMISSION_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_EXTERIOR_LIGHTS)
public static final int HAZARD_LIGHTS_STATE = 289410563;
/**
* Headlight switch
- * Requires permission: {@link Car#PERMISSION_CONTROL_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_EXTERIOR_LIGHTS)
public static final int HEADLIGHTS_SWITCH = 289410576;
/**
* High beam light switch
- * Requires permission: {@link Car#PERMISSION_CONTROL_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_EXTERIOR_LIGHTS)
public static final int HIGH_BEAM_LIGHTS_SWITCH = 289410577;
/**
* Fog light switch
- * Requires permission: {@link Car#PERMISSION_CONTROL_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_EXTERIOR_LIGHTS)
public static final int FOG_LIGHTS_SWITCH = 289410578;
/**
* Hazard light switch
- * Requires permission: {@link Car#PERMISSION_CONTROL_EXTERIOR_LIGHTS}.
+ * The property is protected by the signature permission:
+ * android.car.permission.CAR_EXTERIOR_LIGHTS.
*/
@RequiresPermission(Car.PERMISSION_CONTROL_EXTERIOR_LIGHTS)
public static final int HAZARD_LIGHTS_SWITCH = 289410579;
diff --git a/car-lib/src/android/car/hardware/CarPropertyConfig.java b/car-lib/src/android/car/hardware/CarPropertyConfig.java
index df7ac5f..96b0aa8 100644
--- a/car-lib/src/android/car/hardware/CarPropertyConfig.java
+++ b/car-lib/src/android/car/hardware/CarPropertyConfig.java
@@ -38,8 +38,6 @@
* Represents general information about car property such as data type and min/max ranges for car
* areas (if applicable). This class supposed to be immutable, parcelable and could be passed over.
*
- * <p>Use {@link CarPropertyConfig#newBuilder} to create an instance of this class.
- *
* @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
* should be visible to framework as default class loader is being used here.
*
diff --git a/car-lib/src/android/car/hardware/CarSensorEvent.java b/car-lib/src/android/car/hardware/CarSensorEvent.java
index 3f33a8d..68ba9f5 100644
--- a/car-lib/src/android/car/hardware/CarSensorEvent.java
+++ b/car-lib/src/android/car/hardware/CarSensorEvent.java
@@ -24,13 +24,14 @@
* data is stored in a sensor-type specific format in the object's float and byte arrays.
*
* To aid unmarshalling the object's data arrays, this class provides static nested classes and
- * conversion methods, for example {@link EnvironmentData} and {@link #getEnvironmentData}. The
- * conversion methods each have an optional data parameter which, if not null, will be used and
- * returned. This parameter should be used to avoid unnecessary object churn whenever possible.
- * Additionally, calling a conversion method on a CarSensorEvent object with an inappropriate type
- * will result in an {@code UnsupportedOperationException} being thrown.
+ * conversion methods. The conversion methods each have an optional data parameter which,
+ * if not null, will be used and returned. This parameter should be used to avoid unnecessary
+ * object churn whenever possible. Additionally, calling a conversion method on a CarSensorEvent
+ * object with an inappropriate type will result in an {@code UnsupportedOperationException}
+ * being thrown.
*
- * @deprecated consider using {@link android.car.hardware.property.CarPropertyEvent} instead.
+ * @deprecated consider using {@link CarPropertyValue} and
+ * {@link android.car.hardware.property.CarPropertyManager} instead.
*/
@Deprecated
public class CarSensorEvent implements Parcelable {
diff --git a/car-lib/src/android/car/hardware/CarSensorManager.java b/car-lib/src/android/car/hardware/CarSensorManager.java
index d047aa1..b34e171 100644
--- a/car-lib/src/android/car/hardware/CarSensorManager.java
+++ b/car-lib/src/android/car/hardware/CarSensorManager.java
@@ -52,17 +52,14 @@
/**
* This sensor represents vehicle speed in m/s.
* Sensor data in {@link CarSensorEvent} is a float which will be >= 0.
- * This requires {@link Car#PERMISSION_SPEED} permission.
*/
public static final int SENSOR_TYPE_CAR_SPEED = 0x11600207;
/**
* Represents engine RPM of the car. Sensor data in {@link CarSensorEvent} is a float.
- * This requires {@link Car#PERMISSION_CAR_ENGINE_DETAILED} permission.
*/
public static final int SENSOR_TYPE_RPM = 0x11600305;
/**
* Total travel distance of the car in Kilometer. Sensor data is a float.
- * This requires {@link Car#PERMISSION_MILEAGE} permission.
*/
public static final int SENSOR_TYPE_ODOMETER = 0x11600204;
/**
@@ -138,12 +135,10 @@
public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 0x11510306;
/**
* Set to true when ABS is active. This sensor is event driven.
- * This requires {@link Car#PERMISSION_CAR_DYNAMICS_STATE} permission.
*/
public static final int SENSOR_TYPE_ABS_ACTIVE = 0x1120040a;
/**
* Set to true when traction control is active. This sensor is event driven.
- * This requires {@link Car#PERMISSION_CAR_DYNAMICS_STATE} permission.
*/
public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 0x1120040b;
/** @hide */
@@ -156,8 +151,8 @@
/**
* Indicates battery level of the car.
- * In {@link CarSensorEvent}, represents battery level in WH. floatValues[{@link
- * CarSensorEvent#INDEX_EV_BATTERY_CAPACITY_ACTUAL}] represents the actual battery capacity in
+ * In {@link CarSensorEvent}, represents battery level in WH. floatValues of
+ * INDEX_EV_BATTERY_CAPACITY_ACTUAL property represents the actual battery capacity in
* WH. The battery degrades over time, so this value is expected to drop slowly over the life
* of the vehicle.
* This requires {@link Car#PERMISSION_ENERGY} permission.
@@ -180,7 +175,6 @@
public static final int SENSOR_TYPE_EV_BATTERY_CHARGE_RATE = 0x1160030c;
/**
* Oil level sensor.
- * This requires {@link Car#PERMISSION_CAR_ENGINE_DETAILED} permission
*/
public static final int SENSOR_TYPE_ENGINE_OIL_LEVEL = 0x11400303;
diff --git a/car-lib/src/android/car/user/UserRemovalResult.java b/car-lib/src/android/car/user/UserRemovalResult.java
index dbfd8a6..e76528b 100644
--- a/car-lib/src/android/car/user/UserRemovalResult.java
+++ b/car-lib/src/android/car/user/UserRemovalResult.java
@@ -72,11 +72,11 @@
public static final int STATUS_USER_DOES_NOT_EXIST = CommonResults.LAST_COMMON_STATUS + 2;
/**
- * When user to remove is last admin user.
+ * When last admin user successfully removed.
*
* @hide
*/
- public static final int STATUS_TARGET_USER_IS_LAST_ADMIN_USER =
+ public static final int STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED =
CommonResults.LAST_COMMON_STATUS + 3;
/**
@@ -87,12 +87,12 @@
* {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
* {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
* {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
- * {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+ * {@link UserRemovalResult#STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED}.
*/
private final @Status int mStatus;
public boolean isSuccess() {
- return mStatus == STATUS_SUCCESSFUL;
+ return mStatus == STATUS_SUCCESSFUL || mStatus == STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED;
}
// TODO(b/158195639): if you change any status constant, you need to manually assign its values
@@ -119,7 +119,7 @@
STATUS_HAL_INTERNAL_FAILURE,
STATUS_TARGET_USER_IS_CURRENT_USER,
STATUS_USER_DOES_NOT_EXIST,
- STATUS_TARGET_USER_IS_LAST_ADMIN_USER
+ STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED
})
@Retention(RetentionPolicy.SOURCE)
@DataClass.Generated.Member
@@ -139,8 +139,8 @@
return "STATUS_TARGET_USER_IS_CURRENT_USER";
case STATUS_USER_DOES_NOT_EXIST:
return "STATUS_USER_DOES_NOT_EXIST";
- case STATUS_TARGET_USER_IS_LAST_ADMIN_USER:
- return "STATUS_TARGET_USER_IS_LAST_ADMIN_USER";
+ case STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED:
+ return "STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED";
default: return Integer.toHexString(value);
}
}
@@ -156,14 +156,31 @@
* {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
* {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
* {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
- * {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+ * {@link UserRemovalResult#STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED}.
* @hide
*/
@DataClass.Generated.Member
public UserRemovalResult(
- int status) {
+ @Status int status) {
this.mStatus = status;
+ if (!(mStatus == STATUS_SUCCESSFUL)
+ && !(mStatus == STATUS_ANDROID_FAILURE)
+ && !(mStatus == STATUS_HAL_INTERNAL_FAILURE)
+ && !(mStatus == STATUS_TARGET_USER_IS_CURRENT_USER)
+ && !(mStatus == STATUS_USER_DOES_NOT_EXIST)
+ && !(mStatus == STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED)) {
+ throw new java.lang.IllegalArgumentException(
+ "status was " + mStatus + " but must be one of: "
+ + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+ + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+ + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), "
+ + "STATUS_TARGET_USER_IS_CURRENT_USER(" + STATUS_TARGET_USER_IS_CURRENT_USER + "), "
+ + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + "), "
+ + "STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED(" + STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED + ")");
+ }
+
+
// onConstructed(); // You can define this method to get a callback
}
@@ -175,10 +192,10 @@
* {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
* {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
* {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
- * {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+ * {@link UserRemovalResult#STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED}.
*/
@DataClass.Generated.Member
- public int getStatus() {
+ public @Status int getStatus() {
return mStatus;
}
@@ -189,7 +206,7 @@
// String fieldNameToString() { ... }
return "UserRemovalResult { " +
- "status = " + mStatus +
+ "status = " + statusToString(mStatus) +
" }";
}
@@ -217,6 +234,23 @@
this.mStatus = status;
+ if (!(mStatus == STATUS_SUCCESSFUL)
+ && !(mStatus == STATUS_ANDROID_FAILURE)
+ && !(mStatus == STATUS_HAL_INTERNAL_FAILURE)
+ && !(mStatus == STATUS_TARGET_USER_IS_CURRENT_USER)
+ && !(mStatus == STATUS_USER_DOES_NOT_EXIST)
+ && !(mStatus == STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED)) {
+ throw new java.lang.IllegalArgumentException(
+ "status was " + mStatus + " but must be one of: "
+ + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+ + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+ + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), "
+ + "STATUS_TARGET_USER_IS_CURRENT_USER(" + STATUS_TARGET_USER_IS_CURRENT_USER + "), "
+ + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + "), "
+ + "STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED(" + STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED + ")");
+ }
+
+
// onConstructed(); // You can define this method to get a callback
}
@@ -235,10 +269,10 @@
};
@DataClass.Generated(
- time = 1591259644931L,
+ time = 1600198487158L,
codegenVersion = "1.0.15",
sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserRemovalResult.java",
- inputSignatures = "public static final int STATUS_SUCCESSFUL\npublic static final int STATUS_ANDROID_FAILURE\npublic static final int STATUS_HAL_INTERNAL_FAILURE\npublic static final int STATUS_TARGET_USER_IS_CURRENT_USER\npublic static final int STATUS_USER_DOES_NOT_EXIST\npublic static final int STATUS_TARGET_USER_IS_LAST_ADMIN_USER\nprivate final int mStatus\npublic boolean isSuccess()\nclass UserRemovalResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+ inputSignatures = "public static final int STATUS_SUCCESSFUL\npublic static final int STATUS_ANDROID_FAILURE\npublic static final int STATUS_HAL_INTERNAL_FAILURE\npublic static final int STATUS_TARGET_USER_IS_CURRENT_USER\npublic static final int STATUS_USER_DOES_NOT_EXIST\npublic static final int STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED\nprivate final @android.car.user.UserRemovalResult.Status int mStatus\npublic boolean isSuccess()\nclass UserRemovalResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
@Deprecated
private void __metadata() {}
diff --git a/car-lib/src/android/car/watchdog/CarWatchdogManager.java b/car-lib/src/android/car/watchdog/CarWatchdogManager.java
index d8fb7d9..301e3b6 100644
--- a/car-lib/src/android/car/watchdog/CarWatchdogManager.java
+++ b/car-lib/src/android/car/watchdog/CarWatchdogManager.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.automotive.watchdog.ICarWatchdogClient;
import android.car.Car;
import android.car.CarManagerBase;
import android.os.Handler;
@@ -318,7 +317,7 @@
}
/** @hide */
- private static final class ICarWatchdogClientImpl extends ICarWatchdogClient.Stub {
+ private static final class ICarWatchdogClientImpl extends ICarWatchdogServiceCallback.Stub {
private final WeakReference<CarWatchdogManager> mManager;
private ICarWatchdogClientImpl(CarWatchdogManager manager) {
@@ -326,7 +325,7 @@
}
@Override
- public void checkIfAlive(int sessionId, int timeout) {
+ public void onCheckHealthStatus(int sessionId, int timeout) {
CarWatchdogManager manager = mManager.get();
if (manager != null) {
manager.checkClientStatus(sessionId, timeout);
@@ -334,22 +333,12 @@
}
@Override
- public void prepareProcessTermination() {
+ public void onPrepareProcessTermination() {
CarWatchdogManager manager = mManager.get();
if (manager != null) {
manager.notifyProcessTermination();
}
}
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
}
private final class SessionInfo {
diff --git a/car-lib/src/android/car/watchdog/ICarWatchdogService.aidl b/car-lib/src/android/car/watchdog/ICarWatchdogService.aidl
index 017e0e1..358e5e4 100644
--- a/car-lib/src/android/car/watchdog/ICarWatchdogService.aidl
+++ b/car-lib/src/android/car/watchdog/ICarWatchdogService.aidl
@@ -16,13 +16,12 @@
package android.car.watchdog;
-import android.automotive.watchdog.ICarWatchdogClient;
-import android.automotive.watchdog.TimeoutLength;
+import android.car.watchdog.ICarWatchdogServiceCallback;
/** @hide */
interface ICarWatchdogService {
// registerClient needs to get callingPid, so cannot be oneway.
- void registerClient(in ICarWatchdogClient client, in TimeoutLength timeout);
- void unregisterClient(in ICarWatchdogClient client);
- void tellClientAlive(in ICarWatchdogClient client, in int sessionId);
+ void registerClient(in ICarWatchdogServiceCallback client, in int timeout);
+ void unregisterClient(in ICarWatchdogServiceCallback client);
+ void tellClientAlive(in ICarWatchdogServiceCallback client, in int sessionId);
}
diff --git a/car-lib/src/android/car/watchdog/ICarWatchdogServiceCallback.aidl b/car-lib/src/android/car/watchdog/ICarWatchdogServiceCallback.aidl
new file mode 100644
index 0000000..9d1fd8a
--- /dev/null
+++ b/car-lib/src/android/car/watchdog/ICarWatchdogServiceCallback.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 android.car.watchdog;
+
+/** @hide */
+oneway interface ICarWatchdogServiceCallback {
+ void onCheckHealthStatus(in int sessionId, in int timeout);
+ void onPrepareProcessTermination();
+}
diff --git a/car-usb-handler/src/android/car/usb/handler/AoapServiceManager.java b/car-usb-handler/src/android/car/usb/handler/AoapServiceManager.java
index 04bef87..f0656aa 100644
--- a/car-usb-handler/src/android/car/usb/handler/AoapServiceManager.java
+++ b/car-usb-handler/src/android/car/usb/handler/AoapServiceManager.java
@@ -55,9 +55,7 @@
private static final int MSG_DISCONNECT = 1;
private static final int DISCONNECT_DELAY_MS = 30000;
-
- private static final int INVOCATION_TIMEOUT_MS = 5000;
-
+ private static final int INVOCATION_TIMEOUT_MS = 20000;
private final HashMap<ComponentName, AoapServiceConnection> mConnections = new HashMap<>();
private Context mContext;
diff --git a/car_product/build/car.mk b/car_product/build/car.mk
index 657bad9..67674ab 100644
--- a/car_product/build/car.mk
+++ b/car_product/build/car.mk
@@ -43,7 +43,6 @@
DirectRenderingCluster \
GarageModeTestApp \
ExperimentalCarService \
- RotaryPlayground \
BugReportApp \
# SEPolicy for test apps / services
@@ -86,6 +85,7 @@
PRODUCT_PACKAGES += \
CarFrameworkPackageStubs \
CarService \
+ CarShell \
CarDialerApp \
CarRadioApp \
OverviewApp \
diff --git a/car_product/build/car_base.mk b/car_product/build/car_base.mk
index a1b6534..531aa1e 100644
--- a/car_product/build/car_base.mk
+++ b/car_product/build/car_base.mk
@@ -17,7 +17,16 @@
# Base platform for car builds
# car packages should be added to car.mk instead of here
+ifeq ($(DISABLE_CAR_PRODUCT_CONFIG_OVERLAY),)
PRODUCT_PACKAGE_OVERLAYS += packages/services/Car/car_product/overlay
+endif
+
+ifeq ($(DISABLE_CAR_PRODUCT_VISUAL_OVERLAY),)
+PRODUCT_PACKAGE_OVERLAYS += packages/services/Car/car_product/overlay-visual
+endif
+
+PRODUCT_COPY_FILES += \
+ packages/services/Car/car_product/build/component-overrides.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sysconfig/component-overrides.xml \
PRODUCT_PACKAGES += \
com.android.wifi \
@@ -43,7 +52,6 @@
MmsService \
ExternalStorageProvider \
atrace \
- cameraserver \
libandroidfw \
libaudioutils \
libmdnssd \
@@ -57,12 +65,16 @@
car-bugreportd \
# EVS resources
-PRODUCT_PACKAGES += android.automotive.evs.manager@1.0
+PRODUCT_PACKAGES += android.automotive.evs.manager@1.1
# The following packages, or their vendor specific equivalents should be include in the device.mk
#PRODUCT_PACKAGES += evs_app
#PRODUCT_PACKAGES += evs_app_default_resources
#PRODUCT_PACKAGES += android.hardware.automotive.evs@1.0-service
+# EVS manager overrides cameraserver on automotive implementations so
+# we need to configure Camera API to not connect to it
+PRODUCT_PROPERTY_OVERRIDES += config.disable_cameraservice=true
+
# Device running Android is a car
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.type.automotive.xml:system/etc/permissions/android.hardware.type.automotive.xml
diff --git a/car_product/build/component-overrides.xml b/car_product/build/component-overrides.xml
new file mode 100644
index 0000000..510b2be
--- /dev/null
+++ b/car_product/build/component-overrides.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!--
+ This component-overrides.xml is used to enable the service by default
+ on car devices. Since Runtime Resource Overlays (RROs) can no longer change
+ the value of resources in manifest when read during PackagerParser.
+-->
+<config>
+<!--
+ The components mentioned under bluetooth are based on
+ packages/services/Car/car_product/overlay/packages/apps/Bluetooth/res/values/config.xml
+ and packages/apps/Bluetooth/AndroidManifest.xml
+-->
+ <component-override package="com.android.bluetooth" >
+ <!-- Disable source profiles (typically used in phone) -->
+ <!-- Controlled by profile_supported_a2dp -->
+ <component class=".a2dp.A2dpService" enabled="false" />
+
+ <!-- Controlled by profile_supported_avrcp_target -->
+ <component class=".avrcp.AvrcpTargetService" enabled="false" />
+
+ <!-- Controlled by profile_supported_hs_hfp -->
+ <component class=".hfp.HeadsetService" enabled="false" />
+
+ <!-- Controlled by profile_supported_hid_device -->
+ <component class=".hid.HidDeviceService" enabled="false" />
+
+ <!-- Controlled by profile_supported_hid_host -->
+ <component class=".hid.HidHostService" enabled="false" />
+
+ <!-- Controlled by profile_supported_pbap -->
+ <component class=".pbap.BluetoothPbapActivity" enabled="false" />
+ <component class=".pbap.BluetoothPbapService" enabled="false" />
+
+ <!-- Controlled by profile_supported_map -->
+ <component class=".map.BluetoothMapService" enabled="false" />
+ <component class=".map.BluetoothMapSettings" enabled="false" />
+
+ <!-- Controlled by profile_supported_opp -->
+ <component class=".opp.BluetoothOppService" enabled="false" />
+ <component class=".opp.BluetoothOppReceiver" enabled="false" />
+ <component class=".opp.BluetoothOppLauncherActivity" enabled="false" />
+ <component class=".opp.BluetoothOppBtEnableActivity" enabled="false" />
+ <component class=".opp.BluetoothOppBtEnablingActivity" enabled="false" />
+ <component class=".opp.BluetoothOppIncomingFileConfirmActivity" enabled="false" />
+ <component class=".opp.BluetoothOppTransferActivity" enabled="false" />
+ <component class=".opp.BluetoothOppTransferHistory" enabled="false" />
+
+ <!-- Controlled by profile_supported_sap -->
+ <component class=".sap.SapService" enabled="false" />
+ <!-- End for disabling-->
+
+ <!-- Enable sink profiles (typically used on a CarKitt) -->
+ <!-- Controlled by profile_supported_hfpclient -->
+ <component class=".hfpclient.HeadsetClientService" enabled="true" />
+
+ <!-- Controlled by hfp_client_connection_service_enabled -->
+ <component class=".hfpclient.connserv.HfpClientConnectionService" enabled="true" />
+
+ <!-- Controlled by profile_supported_avrcp_controller -->
+ <component class=".avrcpcontroller.AvrcpControllerService" enabled="true" />
+
+ <!-- Controlled by avrcp_controller_enable_cover_art -->
+ <component class=".avrcpcontroller.AvrcpCoverArtProvider" enabled="true" />
+
+ <!-- Controlled by profile_supported_a2dp_sink -->
+ <component class=".a2dpsink.A2dpSinkService" enabled="true" />
+ <component class=".avrcpcontroller.BluetoothMediaBrowserService" enabled="true" />
+ <component class=".BluetoothPrefs" enabled="true" />
+
+ <!-- Controlled by profile_supported_pbapclient -->
+ <component class=".pbapclient.PbapClientService" enabled="true" />
+ <component class=".pbapclient.AuthenticationService" enabled="true" />
+
+ <!-- Controlled by profile_supported_pan -->
+ <component class=".pan.PanService" enabled="true" />
+
+ <!-- Controlled by profile_supported_mapmce -->
+ <component class=".mapclient.MapClientService" enabled="true" />
+ <!-- End for enabling-->
+ </component-override>
+</config>
diff --git a/car_product/build/preinstalled-packages-product-car-base.xml b/car_product/build/preinstalled-packages-product-car-base.xml
index 0ed7b7f..bf62fa1 100644
--- a/car_product/build/preinstalled-packages-product-car-base.xml
+++ b/car_product/build/preinstalled-packages-product-car-base.xml
@@ -26,6 +26,12 @@
<install-in user-type="SYSTEM" />
</install-in-user-type>
+ <!-- Failed to complete CtsShortcutHostTestCases if LocalTransport is not
+ installed for system user -->
+ <install-in-user-type package="com.android.localtransport">
+ <install-in user-type="SYSTEM" />
+ </install-in-user-type>
+
<!--
Apps that need to run on SYSTEM and evaluated by package owner.
Here the apps will have FULL and SYSTEM.
@@ -42,6 +48,10 @@
<install-in user-type="FULL" />
<install-in user-type="SYSTEM" />
</install-in-user-type>
+ <install-in-user-type package="com.android.car.shell">
+ <install-in user-type="FULL" />
+ <install-in user-type="SYSTEM" />
+ </install-in-user-type>
<install-in-user-type package="com.android.car.frameworkpackagestubs">
<install-in user-type="FULL" />
<install-in user-type="SYSTEM" />
diff --git a/car_product/init/init.car.rc b/car_product/init/init.car.rc
index d255942..a4880ab 100644
--- a/car_product/init/init.car.rc
+++ b/car_product/init/init.car.rc
@@ -6,11 +6,11 @@
on property:persist.automotive.evs.mode=0
# stop EVS and automotive display services
stop automotive_display
- stop evs_driver
+ stop evs_sample_driver
stop evs_manager
on property:persist.automotive.evs.mode=1
# start EVS and automotive display services
start automotive_display
- start evs_driver
+ start evs_sample_driver
start evs_manager
diff --git a/car_product/overlay/frameworks/base/core/res/res/anim/fade_in.xml b/car_product/overlay-visual/frameworks/base/core/res/res/anim/fade_in.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/anim/fade_in.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/anim/fade_in.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/anim/fade_out.xml b/car_product/overlay-visual/frameworks/base/core/res/res/anim/fade_out.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/anim/fade_out.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/anim/fade_out.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-night-nodpi/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-night-nodpi/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-night-nodpi/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-night-nodpi/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-sw600dp-night/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw600dp-night/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-sw600dp-night/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw600dp-night/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-sw720dp-night/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw720dp-night/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-sw720dp-night/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw720dp-night/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png b/car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable/ic_account_circle.xml b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_account_circle.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable/ic_account_circle.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_account_circle.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable/ic_collapse_notification.xml b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_collapse_notification.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable/ic_collapse_notification.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_collapse_notification.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable/ic_expand_notification.xml b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_expand_notification.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable/ic_expand_notification.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable/ic_expand_notification.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable/item_background.xml b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/item_background.xml
similarity index 70%
rename from car_product/overlay/frameworks/base/core/res/res/drawable/item_background.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable/item_background.xml
index b95802f..51a1d58 100644
--- a/car_product/overlay/frameworks/base/core/res/res/drawable/item_background.xml
+++ b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/item_background.xml
@@ -15,12 +15,18 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_pressed="true">
+ <shape android:shape="rectangle">
+ <solid android:color="#8A94CBFF"/>
+ <stroke android:width="4dp"
+ android:color="#94CBFF"/>
+ </shape>
+ </item>
<item android:state_focused="true">
- <ripple android:color="#4b9eff">
- <item android:id="@android:id/mask">
- <color android:color="@android:color/white" />
- </item>
- </ripple>
+ <shape android:shape="rectangle">
+ <solid android:color="#3D94CBFF"/>
+ <stroke android:width="8dp" android:color="#94CBFF"/>
+ </shape>
</item>
<item>
<ripple android:color="?android:attr/colorControlHighlight">
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable/toast_frame.xml b/car_product/overlay-visual/frameworks/base/core/res/res/drawable/toast_frame.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/drawable/toast_frame.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/drawable/toast_frame.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/notification_template_right_icon.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/notification_template_right_icon.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/notification_template_right_icon.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/notification_template_right_icon.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolve_list_item.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/resolve_list_item.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/resolve_list_item.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/resolve_list_item.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_different_item_header.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_different_item_header.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/resolver_different_item_header.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_different_item_header.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_list.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_list.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/transient_notification.xml b/car_product/overlay-visual/frameworks/base/core/res/res/layout/transient_notification.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/layout/transient_notification.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/layout/transient_notification.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-h1752dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-h1752dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-h1752dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-h1752dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-h600dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-h600dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-h600dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-h600dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-night/colors_car.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-night/colors_car.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-night/colors_car.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-night/colors_car.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-night/colors_device_defaults.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-night/colors_device_defaults.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-night/colors_device_defaults.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-night/colors_device_defaults.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-w1280dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-w1280dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-w1280dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-w1280dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-w1920dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-w1920dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-w1920dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-w1920dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-w690dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-w690dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-w690dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-w690dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-w840dp/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values-w840dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values-w840dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values-w840dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/colors.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/colors.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/colors.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/colors.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/colors_device_defaults.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/colors_device_defaults.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/colors_device_defaults.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/colors_device_defaults.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/dimens.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/dimens.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/dimens.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/styles.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/styles.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/styles.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/styles.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/styles_device_default.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/styles_device_default.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/styles_device_default.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/styles_device_default.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml b/car_product/overlay-visual/frameworks/base/core/res/res/values/themes_device_defaults.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml
rename to car_product/overlay-visual/frameworks/base/core/res/res/values/themes_device_defaults.xml
diff --git a/car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-h600dp/dimens.xml b/car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-h600dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-h600dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-h600dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-sw600dp/dimens.xml b/car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-sw600dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-sw600dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-sw600dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-w1024dp/dimens.xml b/car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-w1024dp/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-w1024dp/dimens.xml
rename to car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-w1024dp/dimens.xml
diff --git a/car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-w550dp-land/dimens.xml b/car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-w550dp-land/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/CarSystemUI/res/values-w550dp-land/dimens.xml
rename to car_product/overlay-visual/frameworks/base/packages/CarSystemUI/res/values-w550dp-land/dimens.xml
diff --git a/car_product/overlay/frameworks/base/packages/SettingsLib/res/values/dimens.xml b/car_product/overlay-visual/frameworks/base/packages/SettingsLib/res/values/dimens.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/SettingsLib/res/values/dimens.xml
rename to car_product/overlay-visual/frameworks/base/packages/SettingsLib/res/values/dimens.xml
diff --git a/car_product/overlay/frameworks/base/packages/SettingsLib/res/values/styles.xml b/car_product/overlay-visual/frameworks/base/packages/SettingsLib/res/values/styles.xml
similarity index 100%
rename from car_product/overlay/frameworks/base/packages/SettingsLib/res/values/styles.xml
rename to car_product/overlay-visual/frameworks/base/packages/SettingsLib/res/values/styles.xml
diff --git a/car_product/overlay/frameworks/base/core/res/res/drawable-night/item_background.xml b/car_product/overlay/frameworks/base/core/res/res/drawable-night/item_background.xml
deleted file mode 100644
index cfab8bd..0000000
--- a/car_product/overlay/frameworks/base/core/res/res/drawable-night/item_background.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true">
- <ripple android:color="#2371cd">
- <item android:id="@android:id/mask">
- <color android:color="@android:color/white" />
- </item>
- </ripple>
- </item>
- <item>
- <ripple android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <color android:color="@android:color/white" />
- </item>
- </ripple>
- </item>
-</selector>
diff --git a/car_product/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/car_product/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
index 81a9a3d..5b53dcf 100644
--- a/car_product/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
+++ b/car_product/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
@@ -26,4 +26,7 @@
<!-- Disable system heads-up notifications -->
<integer name="def_heads_up_enabled">0</integer>
+
+ <!-- Default for UI touch sounds disabled -->
+ <bool name="def_sound_effects_enabled">false</bool>
</resources>
diff --git a/car_product/sepolicy/private/carservice_app.te b/car_product/sepolicy/private/carservice_app.te
index 49a3c6f..2fd2095 100644
--- a/car_product/sepolicy/private/carservice_app.te
+++ b/car_product/sepolicy/private/carservice_app.te
@@ -66,8 +66,9 @@
allow carservice_app statsd:binder call;
# To access /sys/fs/<type>/<partition>/lifetime_write_kbytes
-r_dir_file(carservice_app, sysfs_fs_ext4)
-r_dir_file(carservice_app, sysfs_fs_f2fs)
+allow carservice_app sysfs:dir { open read search };
+allow carservice_app sysfs_fs_ext4_features:dir { open read search};
+allow carservice_app sysfs_fs_f2fs:dir { open read search };
set_prop(carservice_app, ctl_start_prop)
set_prop(carservice_app, ctl_stop_prop)
diff --git a/car_product/sepolicy/private/genfs_contexts b/car_product/sepolicy/private/genfs_contexts
deleted file mode 100644
index e8e6e9f..0000000
--- a/car_product/sepolicy/private/genfs_contexts
+++ /dev/null
@@ -1 +0,0 @@
-genfscon sysfs /fs/ext4 u:object_r:sysfs_fs_ext4:s0
diff --git a/car_product/sepolicy/public/file.te b/car_product/sepolicy/public/file.te
index 8703f35..11bf839 100644
--- a/car_product/sepolicy/public/file.te
+++ b/car_product/sepolicy/public/file.te
@@ -1,4 +1,8 @@
+# This type for lifetime_write_kbytes files which resides in
+# /sys/fs/<filesystem>/<partition>/lifetime_writes_kbytes
+# Vendors are supposed to extend genfs_contexts with the
+# partition names for their devices.
+type sysfs_fs_lifetime_write, sysfs_type, fs_type;
+
# /data/system/car
type system_car_data_file, file_type, data_file_type, core_data_file_type;
-# /sys/fs/ext4
-type sysfs_fs_ext4, sysfs_type, fs_type;
diff --git a/computepipe/tests/PipeQueryTest.cpp b/computepipe/tests/PipeQueryTest.cpp
index 634ebd0..c3c614a 100644
--- a/computepipe/tests/PipeQueryTest.cpp
+++ b/computepipe/tests/PipeQueryTest.cpp
@@ -100,30 +100,30 @@
// Check retrieval of inserted entries
TEST_F(PipeQueryTest, GetGraphListTest) {
- std::shared_ptr<IPipeRunner> dummy1 = ndk::SharedRefBase::make<FakeRunner>();
- addFakeRunner("dummy1", dummy1);
- std::shared_ptr<IPipeRunner> dummy2 = ndk::SharedRefBase::make<FakeRunner>();
- addFakeRunner("dummy2", dummy2);
+ std::shared_ptr<IPipeRunner> stub1 = ndk::SharedRefBase::make<FakeRunner>();
+ addFakeRunner("stub1", stub1);
+ std::shared_ptr<IPipeRunner> stub2 = ndk::SharedRefBase::make<FakeRunner>();
+ addFakeRunner("stub2", stub2);
std::vector<std::string>* outNames = new std::vector<std::string>();
std::shared_ptr<PipeQuery> qIface = ndk::SharedRefBase::make<PipeQuery>(mRegistry);
ASSERT_TRUE(qIface->getGraphList(outNames).isOk());
ASSERT_NE(outNames->size(), 0);
- EXPECT_THAT(std::find(outNames->begin(), outNames->end(), "dummy1"),
+ EXPECT_THAT(std::find(outNames->begin(), outNames->end(), "stub1"),
testing::Ne(outNames->end()));
- EXPECT_THAT(std::find(outNames->begin(), outNames->end(), "dummy2"),
+ EXPECT_THAT(std::find(outNames->begin(), outNames->end(), "stub2"),
testing::Ne(outNames->end()));
}
// Check successful retrieval of runner
TEST_F(PipeQueryTest, GetRunnerTest) {
- std::shared_ptr<IPipeRunner> dummy1 = ndk::SharedRefBase::make<FakeRunner>();
- addFakeRunner("dummy1", dummy1);
+ std::shared_ptr<IPipeRunner> stub1 = ndk::SharedRefBase::make<FakeRunner>();
+ addFakeRunner("stub1", stub1);
std::shared_ptr<PipeQuery> qIface = ndk::SharedRefBase::make<PipeQuery>(mRegistry);
std::shared_ptr<IClientInfo> info = ndk::SharedRefBase::make<FakeClientInfo>();
std::shared_ptr<IPipeRunner> runner;
- ASSERT_TRUE(qIface->getPipeRunner("dummy1", info, &runner).isOk());
+ ASSERT_TRUE(qIface->getPipeRunner("stub1", info, &runner).isOk());
EXPECT_THAT(runner, testing::NotNull());
}
diff --git a/computepipe/tests/PipeRegistrationTest.cpp b/computepipe/tests/PipeRegistrationTest.cpp
index 1caf07b..4af8440 100644
--- a/computepipe/tests/PipeRegistrationTest.cpp
+++ b/computepipe/tests/PipeRegistrationTest.cpp
@@ -50,17 +50,17 @@
// Valid registration succeeds
TEST_F(PipeRegistrationTest, RegisterFakeRunner) {
- std::shared_ptr<IPipeRunner> dummy = ndk::SharedRefBase::make<FakeRunner>();
+ std::shared_ptr<IPipeRunner> fake = ndk::SharedRefBase::make<FakeRunner>();
std::shared_ptr<IPipeRegistration> rIface =
ndk::SharedRefBase::make<PipeRegistration>(this->mRegistry);
- EXPECT_TRUE(rIface->registerPipeRunner("dummy", dummy).isOk());
+ EXPECT_TRUE(rIface->registerPipeRunner("fake", fake).isOk());
}
// Duplicate registration fails
TEST_F(PipeRegistrationTest, RegisterDuplicateRunner) {
- std::shared_ptr<IPipeRunner> dummy = ndk::SharedRefBase::make<FakeRunner>();
+ std::shared_ptr<IPipeRunner> fake = ndk::SharedRefBase::make<FakeRunner>();
std::shared_ptr<IPipeRegistration> rIface =
ndk::SharedRefBase::make<PipeRegistration>(this->mRegistry);
- ASSERT_TRUE(rIface->registerPipeRunner("dummy", dummy).isOk());
- EXPECT_FALSE(rIface->registerPipeRunner("dummy", dummy).isOk());
+ ASSERT_TRUE(rIface->registerPipeRunner("fake", fake).isOk());
+ EXPECT_FALSE(rIface->registerPipeRunner("fake", fake).isOk());
}
diff --git a/computepipe/tests/runner/graph/GrpcGraphTest.cpp b/computepipe/tests/runner/graph/GrpcGraphTest.cpp
index 883ef6f..2effb00 100644
--- a/computepipe/tests/runner/graph/GrpcGraphTest.cpp
+++ b/computepipe/tests/runner/graph/GrpcGraphTest.cpp
@@ -44,12 +44,12 @@
namespace graph {
namespace {
-constexpr char kGraphName[] = "Dummy graph name";
-constexpr char kSetGraphConfigMessage[] = "Dummy set config message";
-constexpr char kSetDebugOptionMessage[] = "Dummy set debug option message";
-constexpr char kStartGraphMessage[] = "Dummy start graph message";
-constexpr char kStopGraphMessage[] = "Dummy stop graph message";
-constexpr char kOutputStreamPacket[] = "Dummy output stream packet";
+constexpr char kGraphName[] = "Stub graph name";
+constexpr char kSetGraphConfigMessage[] = "Stub set config message";
+constexpr char kSetDebugOptionMessage[] = "Stub set debug option message";
+constexpr char kStartGraphMessage[] = "Stub start graph message";
+constexpr char kStopGraphMessage[] = "Stub stop graph message";
+constexpr char kOutputStreamPacket[] = "Stub output stream packet";
constexpr char kResetGraphMessage[] = "ResetGraphMessage";
// This is a barebones synchronous server implementation. A better implementation would be an
diff --git a/evs/apps/default/ConfigManager.cpp b/evs/apps/default/ConfigManager.cpp
index 76c142c..cc55518 100644
--- a/evs/apps/default/ConfigManager.cpp
+++ b/evs/apps/default/ConfigManager.cpp
@@ -142,8 +142,11 @@
float yaw = node.get("yaw", 0).asFloat();
float pitch = node.get("pitch", 0).asFloat();
+ float roll = node.get("roll", 0).asFloat();
float hfov = node.get("hfov", 0).asFloat();
float vfov = node.get("vfov", 0).asFloat();
+ bool hflip = node.get("hflip", false).asBool();
+ bool vflip = node.get("vflip", false).asBool();
// Wrap the direction angles to be in the 180deg to -180deg range
// Rotate 180 in yaw if necessary to flip the pitch into the +/-90degree range
@@ -157,6 +160,7 @@
pitch = -180.0f + pitch;
}
yaw = normalizeToPlusMinus180degrees(yaw);
+ roll = normalizeToPlusMinus180degrees(roll);
// Range check the FOV values to ensure they are postive and less than 180degrees
if (hfov > 179.0f) {
@@ -183,8 +187,11 @@
info.position[2] = node.get("z", 0).asFloat();
info.yaw = yaw * kDegreesToRadians;
info.pitch = pitch * kDegreesToRadians;
+ info.roll = roll * kDegreesToRadians;
info.hfov = hfov * kDegreesToRadians;
info.vfov = vfov * kDegreesToRadians;
+ info.hflip = hflip;
+ info.vflip = vflip;
info.cameraId = cameraId;
info.function = function;
diff --git a/evs/apps/default/ConfigManager.h b/evs/apps/default/ConfigManager.h
index 7c2186d..bf22d0c 100644
--- a/evs/apps/default/ConfigManager.h
+++ b/evs/apps/default/ConfigManager.h
@@ -31,8 +31,11 @@
float position[3] = {0}; // x, y, z -> right, fwd, up in the units of car space
float yaw = 0; // radians positive to the left (right hand rule about global z axis)
float pitch = 0; // positive upward (ie: right hand rule about local x axis)
+ float roll = 0; // radians positively increasing clockwisely around the optical axis
float hfov = 0; // radians
float vfov = 0; // radians
+ bool hflip = false;// boolean to flip the preview horizontally
+ bool vflip = false;// boolean to flip the preview vertically
};
struct DisplayInfo {
@@ -111,6 +114,8 @@
android_pixel_format_t getExternalMemoryFormat() const {
return mExternalMemoryFormat;
}
+ void setMockGearSignal(int32_t signal) { mMockGearSignal = signal; }
+ int32_t getMockGearSignal() const { return mMockGearSignal; }
private:
// Camera information
@@ -126,6 +131,9 @@
// Format of external memory
android_pixel_format_t mExternalMemoryFormat;
+ // Gear signal to simulate in test mode
+ int32_t mMockGearSignal;
+
// Car body information (assumes front wheel steering and origin at center of rear axel)
// Note that units aren't specified and don't matter as long as all length units are consistent
// within the JSON file from which we parse. That is, if everything is in meters, that's fine.
diff --git a/evs/apps/default/EvsStateControl.cpp b/evs/apps/default/EvsStateControl.cpp
index 06af502..5e81022 100644
--- a/evs/apps/default/EvsStateControl.cpp
+++ b/evs/apps/default/EvsStateControl.cpp
@@ -219,7 +219,7 @@
bool EvsStateControl::selectStateForCurrentConditions() {
- static int32_t sDummyGear = int32_t(VehicleGear::GEAR_REVERSE);
+ static int32_t sDummyGear = mConfig.getMockGearSignal();
static int32_t sDummySignal = int32_t(VehicleTurnSignal::NONE);
if (mVehicle != nullptr) {
@@ -245,7 +245,7 @@
sDummyGear = int32_t(VehicleGear::GEAR_DRIVE);
}
- // Build the dummy vehicle state values (treating single values as 1 element vectors)
+ // Build the placeholder vehicle state values (treating single values as 1 element vectors)
mGearValue.value.int32Values.setToExternal(&sDummyGear, 1);
mTurnSignalValue.value.int32Values.setToExternal(&sDummySignal, 1);
}
diff --git a/evs/apps/default/RenderDirectView.cpp b/evs/apps/default/RenderDirectView.cpp
index 68b731e..c2263ce 100644
--- a/evs/apps/default/RenderDirectView.cpp
+++ b/evs/apps/default/RenderDirectView.cpp
@@ -15,15 +15,16 @@
*/
#include "RenderDirectView.h"
+
#include "VideoTex.h"
#include "glError.h"
#include "shader.h"
#include "shader_simpleTex.h"
+#include <android-base/logging.h>
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
#include <math/mat4.h>
#include <system/camera_metadata.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-#include <android-base/logging.h>
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -38,7 +39,7 @@
int32_t framerate;
} RawStreamConfig;
-const size_t kStreamCfgSz = sizeof(RawStreamConfig);
+const size_t kStreamCfgSz = sizeof(RawStreamConfig) / sizeof(int32_t);
RenderDirectView::RenderDirectView(sp<IEvsEnumerator> enumerator,
@@ -47,7 +48,21 @@
mEnumerator(enumerator),
mCameraDesc(camDesc),
mConfig(config) {
- /* Nothing to do */
+ // Find and store the target camera configuration
+ const auto& camList = mConfig.getCameras();
+ const auto target = std::find_if(camList.begin(), camList.end(),
+ [this](const ConfigManager::CameraInfo& info) {
+ return info.cameraId == mCameraDesc.v1.cameraId;
+ });
+ if (target != camList.end()) {
+ // Store the info
+ mCameraInfo = *target;
+
+ // Calculate a rotation matrix
+ float sinRoll, cosRoll;
+ sincosf(mCameraInfo.roll, &sinRoll, &cosRoll);
+ mRotationMat = {cosRoll, -sinRoll, sinRoll, cosRoll};
+ }
}
@@ -148,6 +163,10 @@
glUseProgram(mShaderProgram);
// Set up the model to clip space transform (identity matrix if we're modeling in screen space)
+ android::vec2 leftTop = {-0.5f, 0.5f};
+ android::vec2 rightTop = {0.5f, 0.5f};
+ android::vec2 leftBottom = {-0.5f, -0.5f};
+ android::vec2 rightBottom = {0.5f, -0.5f};
GLint loc = glGetUniformLocation(mShaderProgram, "cameraMat");
if (loc < 0) {
LOG(ERROR) << "Couldn't set shader parameter 'cameraMat'";
@@ -155,8 +174,13 @@
} else {
const android::mat4 identityMatrix;
glUniformMatrix4fv(loc, 1, false, identityMatrix.asArray());
- }
+ // Rotate the preview
+ leftTop = mRotationMat * leftTop;
+ leftBottom = mRotationMat * leftBottom;
+ rightTop = mRotationMat * rightTop;
+ rightBottom = mRotationMat * rightBottom;
+ }
// Bind the texture and assign it to the shader's sampler
mTexture->refresh();
@@ -183,11 +207,22 @@
-1.0, -1.0, 0.0f, // left bottom
1.0, -1.0, 0.0f // right bottom
};
- // TODO: We're flipping horizontally here, but should do it only for specified cameras!
- GLfloat vertsCarTex[] = { 1.0f, 1.0f, // left top
- 0.0f, 1.0f, // right top
- 1.0f, 0.0f, // left bottom
- 0.0f, 0.0f // right bottom
+
+ // Flip the preview if needed
+ if (mCameraInfo.hflip) {
+ std::swap(leftTop.x, rightTop.x);
+ std::swap(leftBottom.x, rightBottom.x);
+ }
+
+ if (mCameraInfo.vflip) {
+ std::swap(leftTop.y, leftBottom.y);
+ std::swap(rightTop.y, rightBottom.y);
+ }
+
+ GLfloat vertsCarTex[] = { leftTop.x + 0.5f, leftTop.y + 0.5f,
+ rightTop.x + 0.5f, rightTop.y + 0.5f,
+ leftBottom.x + 0.5f, leftBottom.y + 0.5f,
+ rightBottom.x + 0.5f, rightBottom.y + 0.5f
};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
diff --git a/evs/apps/default/RenderDirectView.h b/evs/apps/default/RenderDirectView.h
index 65a94e2..2f9c11e 100644
--- a/evs/apps/default/RenderDirectView.h
+++ b/evs/apps/default/RenderDirectView.h
@@ -17,13 +17,12 @@
#ifndef CAR_EVS_APP_RENDERDIRECTVIEW_H
#define CAR_EVS_APP_RENDERDIRECTVIEW_H
-
-#include "RenderBase.h"
-
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include "ConfigManager.h"
+#include "RenderBase.h"
#include "VideoTex.h"
+#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
+#include <math/mat2.h>
using namespace ::android::hardware::automotive::evs::V1_1;
using ::android::hardware::camera::device::V3_2::Stream;
@@ -52,6 +51,8 @@
std::unique_ptr<VideoTex> mTexture;
GLuint mShaderProgram = 0;
+
+ android::mat2 mRotationMat;
};
diff --git a/evs/apps/default/config.json b/evs/apps/default/config.json
index 1762e86..16148a7 100644
--- a/evs/apps/default/config.json
+++ b/evs/apps/default/config.json
@@ -8,31 +8,76 @@
},
"displays" : [
{
- "displayPort" : 1,
+ "displayPort" : 136,
"frontRange" : 100,
"rearRange" : 100
},
{
- "displayPort" : 2,
+ "displayPort" : 130,
"frontRange" : 100,
"rearRange" : 100
}
],
"graphic" : {
- "frontPixel" : 23,
- "rearPixel" : 223
+ "frontPixel" : -20,
+ "rearPixel" : 260
},
"cameras" : [
{
- "cameraId" : "/dev/video3",
- "function" : "reverse, park",
+ "cameraId" : "/dev/video10",
+ "function" : "reverse,park",
"x" : 0.0,
- "y" : -40.0,
+ "y" : 20.0,
"z" : 48,
"yaw" : 180,
- "pitch" : -30,
- "hfov" : 125,
- "vfov" : 103
+ "pitch" : -10,
+ "roll" : 0,
+ "hfov" : 115,
+ "vfov" : 80,
+ "hflip" : true,
+ "vflip" : false
+ },
+ {
+ "cameraId" : "/dev/video11",
+ "function" : "front,park",
+ "x" : 0.0,
+ "y" : 100.0,
+ "z" : 48,
+ "yaw" : 0,
+ "pitch" : -10,
+ "roll" : 0,
+ "hfov" : 115,
+ "vfov" : 80,
+ "hflip" : false,
+ "vflip" : false
+ },
+ {
+ "cameraId" : "/dev/video12",
+ "function" : "right,park",
+ "x" : -25.0,
+ "y" : 60.0,
+ "z" : 88,
+ "yaw" : -90,
+ "pitch" : -10,
+ "roll" : 0,
+ "hfov" : 60,
+ "vfov" : 62,
+ "hflip" : false,
+ "vflip" : false
+ },
+ {
+ "cameraId" : "/dev/video13",
+ "function" : "left, park",
+ "x" : 20.0,
+ "y" : 60.0,
+ "z" : 88,
+ "yaw" : 90,
+ "pitch" : -10,
+ "roll" : 0,
+ "hfov" : 60,
+ "vfov" : 62,
+ "hflip" : false,
+ "vflip" : false
}
]
}
diff --git a/evs/apps/default/config.json.readme b/evs/apps/default/config.json.readme
index 561adcc..893eb86 100644
--- a/evs/apps/default/config.json.readme
+++ b/evs/apps/default/config.json.readme
@@ -38,8 +38,11 @@
"z" : 48, // Optical center distance above ground
"yaw" : 180, // Optical axis degrees to the left of straight ahead
"pitch" : -30, // Optical axis degrees above the horizon
+ "roll" : 0, // Rotation degrees around the optical axis
"hfov" : 125, // Horizontal field of view in degrees
- "vfov" :103 // Vertical field of view in degrees
+ "vfov" :103, // Vertical field of view in degrees
+ "hflip" : true, // Flip the view horizontally
+ "vflip" : true, // Flip the view vertically
}
]
}
diff --git a/evs/apps/default/evs_app.cpp b/evs/apps/default/evs_app.cpp
index 92d4b7a..877304e 100644
--- a/evs/apps/default/evs_app.cpp
+++ b/evs/apps/default/evs_app.cpp
@@ -133,6 +133,7 @@
int displayId = -1;
bool useExternalMemory = false;
android_pixel_format_t extMemoryFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ int32_t mockGearSignal = static_cast<int32_t>(VehicleGear::GEAR_REVERSE);
for (int i=1; i< argc; i++) {
if (strcmp(argv[i], "--test") == 0) {
useVehicleHal = false;
@@ -159,6 +160,15 @@
++i;
}
}
+ } else if (strcmp(argv[i], "--gear") == 0) {
+ // Gear signal to simulate
+ i += 1; // increase an index to next argument
+ if (strcasecmp(argv[i], "Park") == 0) {
+ mockGearSignal = static_cast<int32_t>(VehicleGear::GEAR_PARK);
+ } else if (strcasecmp(argv[i], "Reverse") != 0) {
+ LOG(WARNING) << "Unknown gear signal, " << argv[i] << ", is ignored "
+ << "and the reverse signal will be used instead";
+ }
} else {
printf("Ignoring unrecognized command line arg '%s'\n", argv[i]);
printHelp = true;
@@ -166,7 +176,10 @@
}
if (printHelp) {
printf("Options include:\n");
- printf(" --test\n\tDo not talk to Vehicle Hal, but simulate 'reverse' instead\n");
+ printf(" --test\n\tDo not talk to Vehicle Hal, "
+ "but simulate a given mock gear signal instead\n");
+ printf(" --gear\n\tMock gear signal for the test mode.");
+ printf(" Available options are Reverse and Park (case insensitive)\n");
printf(" --hw\n\tBypass EvsManager by connecting directly to EvsEnumeratorHw\n");
printf(" --mock\n\tConnect directly to EvsEnumeratorHw-Mock\n");
printf(" --display\n\tSpecify the display to use. If this is not set, the first"
@@ -230,6 +243,9 @@
config.useExternalMemory(useExternalMemory);
config.setExternalMemoryFormat(extMemoryFormat);
+ // Set a mock gear signal for the test mode
+ config.setMockGearSignal(mockGearSignal);
+
// Connect to the Vehicle HAL so we can monitor state
sp<IVehicle> pVnet;
if (useVehicleHal) {
diff --git a/evs/manager/1.1/Android.bp b/evs/manager/1.1/Android.bp
index 891d615..d9c7d33 100644
--- a/evs/manager/1.1/Android.bp
+++ b/evs/manager/1.1/Android.bp
@@ -14,6 +14,65 @@
//
//
+cc_library {
+ name: "android.automotive.evs.manager.fuzzlib",
+
+ srcs: [
+ "Enumerator.cpp",
+ "HalCamera.cpp",
+ "HalDisplay.cpp",
+ "VirtualCamera.cpp",
+ "stats/CameraUsageStats.cpp",
+ "stats/LooperWrapper.cpp",
+ "stats/StatsCollector.cpp",
+ "sync/unique_fd.cpp",
+ "sync/unique_fence.cpp",
+ "sync/unique_timeline.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.automotive.evs@1.0",
+ "android.hardware.automotive.evs@1.1",
+ "libbase",
+ "libcamera_metadata",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libprocessgroup",
+ "libstatslog",
+ "libsync",
+ "libui",
+ "libutils",
+ ],
+
+ cflags: ["-DLOG_TAG=\"EvsManagerFuzzlibV1_1\""] + [
+ "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
+ "-Wall",
+ "-Werror",
+ "-Wunused",
+ "-Wunreachable-code",
+ "-Wthread-safety",
+ ],
+
+ include_dirs: [
+ "system/core/libsync",
+ ],
+
+ export_include_dirs: [
+ "./",
+ "stats/",
+ "sync/",
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: [
+ "-DEVS_DEBUG",
+ ]
+ }
+ },
+}
+
//#################################
cc_binary {
diff --git a/evs/manager/1.1/Enumerator.cpp b/evs/manager/1.1/Enumerator.cpp
index fdf3500..61cfec9 100644
--- a/evs/manager/1.1/Enumerator.cpp
+++ b/evs/manager/1.1/Enumerator.cpp
@@ -61,6 +61,12 @@
using CameraDesc_1_0 = ::android::hardware::automotive::evs::V1_0::CameraDesc;
using CameraDesc_1_1 = ::android::hardware::automotive::evs::V1_1::CameraDesc;
+Enumerator::~Enumerator() {
+ if (mClientsMonitor != nullptr) {
+ mClientsMonitor->stopCollection();
+ }
+}
+
bool Enumerator::init(const char* hardwareServiceName) {
LOG(DEBUG) << "init";
diff --git a/evs/manager/1.1/Enumerator.h b/evs/manager/1.1/Enumerator.h
index 7708295..3d3a253 100644
--- a/evs/manager/1.1/Enumerator.h
+++ b/evs/manager/1.1/Enumerator.h
@@ -78,6 +78,9 @@
// Implementation details
bool init(const char* hardwareServiceName);
+ // Destructor
+ virtual ~Enumerator();
+
private:
bool inline checkPermission();
bool isLogicalCamera(const camera_metadata_t *metadata);
diff --git a/evs/manager/1.1/HalCamera.cpp b/evs/manager/1.1/HalCamera.cpp
index 38297bb..f4d2c49 100644
--- a/evs/manager/1.1/HalCamera.cpp
+++ b/evs/manager/1.1/HalCamera.cpp
@@ -236,6 +236,12 @@
std::lock_guard<std::mutex> lock(mFrameMutex);
+ if (mTimelines.find(id) == mTimelines.end()) {
+ // Timeline for this client either does not exist or is deleted.
+ LOG(ERROR) << "Timeline for this client does not exist.";
+ return {};
+ }
+
mTimelines[id]->BumpFenceEventCounter();
UniqueFence fence = mTimelines[id]->CreateFence("FrameFence");
diff --git a/evs/manager/1.1/VirtualCamera.cpp b/evs/manager/1.1/VirtualCamera.cpp
index 6204a78..fda58d1 100644
--- a/evs/manager/1.1/VirtualCamera.cpp
+++ b/evs/manager/1.1/VirtualCamera.cpp
@@ -180,10 +180,13 @@
// Warn if we got an unexpected stream termination
LOG(WARNING) << "Stream unexpectedly stopped, current status "
<< mStreamState;
- }
- // Mark the stream as stopped.
- mStreamState = STOPPED;
+ // Clean up the resource and forward an event to the client
+ stopVideoStream();
+
+ // This event is handled properly.
+ return true;
+ }
if (mStream_1_1 == nullptr) {
// Send a null frame instead, for v1.0 client
diff --git a/evs/manager/1.1/android.automotive.evs.manager@1.1.rc b/evs/manager/1.1/android.automotive.evs.manager@1.1.rc
index 41212e2..5223822 100644
--- a/evs/manager/1.1/android.automotive.evs.manager@1.1.rc
+++ b/evs/manager/1.1/android.automotive.evs.manager@1.1.rc
@@ -3,5 +3,4 @@
priority -20
user automotive_evs
group automotive_evs system
- onrestart restart evs_app
disabled # will not automatically start with its class; must be explictly started.
diff --git a/evs/manager/1.1/stats/StatsCollector.cpp b/evs/manager/1.1/stats/StatsCollector.cpp
index b57f928..4733871 100644
--- a/evs/manager/1.1/stats/StatsCollector.cpp
+++ b/evs/manager/1.1/stats/StatsCollector.cpp
@@ -107,9 +107,15 @@
CollectionInfo* info) {
AutoMutex lock(mMutex);
if (mCurrentCollectionEvent != event) {
- LOG(WARNING) << "Skipping " << toString(event) << " collection event "
- << "on collection event " << toString(mCurrentCollectionEvent);
- return {};
+ if (mCurrentCollectionEvent != CollectionEvent::TERMINATED) {
+ LOG(WARNING) << "Skipping " << toString(event) << " collection event "
+ << "on collection event " << toString(mCurrentCollectionEvent);
+
+ return {};
+ } else {
+ return Error() << "A collection has been terminated "
+ << "while a current event was pending in the message queue.";
+ }
}
if (info->maxCacheSize < 1) {
diff --git a/evs/manager/1.1/test/fuzzer/Android.bp b/evs/manager/1.1/test/fuzzer/Android.bp
new file mode 100644
index 0000000..b2ca44c
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/Android.bp
@@ -0,0 +1,77 @@
+// Copyright 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.
+
+cc_defaults {
+ name: "evs_fuzz_default",
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ ],
+
+ shared_libs: [
+ "android.automotive.evs.manager.fuzzlib",
+ "android.hardware.automotive.evs@1.0",
+ "android.hardware.automotive.evs@1.1",
+ "libbase",
+ "libcamera_metadata",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libprocessgroup",
+ "libstatslog",
+ "libsync",
+ "libui",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Wno-unused-parameter",
+ ],
+
+ include_dirs: [
+ "system/core/libsync",
+ ],
+}
+
+cc_fuzz {
+ name: "evs_halcamera_fuzzer",
+ srcs: [
+ "HalCameraFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
+
+cc_fuzz {
+ name: "evs_virtual_camera_fuzzer",
+ srcs: [
+ "VirtualCameraFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
+
+cc_fuzz {
+ name: "evs_haldisplay_fuzzer",
+ srcs: [
+ "HalDisplayFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
+
+cc_fuzz {
+ name: "evs_enumerator_fuzzer",
+ srcs: [
+ "EnumeratorFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
\ No newline at end of file
diff --git a/evs/manager/1.1/test/fuzzer/Common.h b/evs/manager/1.1/test/fuzzer/Common.h
new file mode 100644
index 0000000..5a619f6
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/Common.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
+#define EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+#define EVS_FUZZ_BASE_ENUM \
+ EVS_FUZZ_NOTIFY, /*verify notify*/ \
+ EVS_FUZZ_GET_HW_CAMERA, /*verify getHalCameras*/ \
+ EVS_FUZZ_DELIVER_FRAME, /* verify deliverFrame */ \
+ EVS_FUZZ_DONE_WITH_FRAME_1_0, /* verify doneWithFrame */ \
+ EVS_FUZZ_DONE_WITH_FRAME_1_1, /* verify doneWithFrame_1_1 */ \
+ EVS_FUZZ_SET_PRIMARY, /* verify setPrimary */ \
+ EVS_FUZZ_FORCE_PRIMARY, /* verify forcePrimary */ \
+ EVS_FUZZ_UNSET_PRIMARY, /* verify unsetPrimary */ \
+ EVS_FUZZ_SET_PARAMETER, /* verify setIntParameter */ \
+ EVS_FUZZ_GET_PARAMETER, /* verify getIntParameter */ \
+ EVS_FUZZ_API_SUM
+
+const char* kMockHWEnumeratorName = "hw/fuzzEVSMock";
+const uint64_t startMockHWCameraId = 1024;
+const uint64_t endMockHWCameraId = 1028;
+const uint64_t startMockHWDisplayId = 256;
+const uint64_t endMockHWDisplayId = 258;
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
+
+#endif // EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
diff --git a/evs/manager/1.1/test/fuzzer/EnumeratorFuzzer.cpp b/evs/manager/1.1/test/fuzzer/EnumeratorFuzzer.cpp
new file mode 100644
index 0000000..d0bfebf
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/EnumeratorFuzzer.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright 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.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <hidl/HidlTransportSupport.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <iostream>
+#include "Common.h"
+#include "Enumerator.h"
+#include "HalDisplay.h"
+#include "MockHWEnumerator.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+namespace {
+
+enum EvsFuzzFuncs {
+ EVS_FUZZ_GET_CAMERA_LIST, // verify getCameraList
+ EVS_FUZZ_OPEN_CAMERA, // verify openCamera
+ EVS_FUZZ_CLOSE_CAMERA, // verify closeCamera
+ EVS_FUZZ_OPEN_DISPLAY, // verify openDisplay
+ EVS_FUZZ_CLOSE_DISPLAY, // verify closeDisplay
+ EVS_FUZZ_GET_DISPLAY_STATE, // verify getDisplayState
+ EVS_FUZZ_GET_CAMERA_LIST_1_1, // verify getCameraList_1_1
+ EVS_FUZZ_OPEN_CAMERA_1_1, // verify openCamera_1_1
+ EVS_FUZZ_IS_HARDWARE, // verify isHardware
+ EVS_FUZZ_GET_DISPLAY_LIST, // verify getDisplayIdList
+ EVS_FUZZ_OPEN_DISPLAY_1_1, // verify openDisplay_1_1
+ EVS_FUZZ_GET_ULTRASONICS_ARRAY_LIST, // verify getUltrasonicsArrayList
+ EVS_FUZZ_OPEN_ULTRASONICS_ARRAY, // verify openUltrasonicsArray
+ EVS_FUZZ_CLOSE_ULTRASONICS_ARRAY, // verify closeUltrasonicsArray
+ EVS_FUZZ_API_SUM
+};
+
+const int kMaxFuzzerConsumedBytes = 12;
+
+
+static sp<IEvsEnumerator_1_1> sMockHWEnumerator;
+static sp<Enumerator> sEnumerator;
+
+static vector<sp<IEvsCamera_1_0>> sVirtualCameras;
+static vector<sp<IEvsDisplay_1_0>> sDisplays;
+
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+ configureRpcThreadpool(2, false /* callerWillNotJoin */);
+
+ // Prepare for the HWEnumerator service
+ sMockHWEnumerator = new MockHWEnumerator();
+ status_t status = sMockHWEnumerator->registerAsService(kMockHWEnumeratorName);
+ if (status != OK) {
+ std::cerr << "Could not register service " << kMockHWEnumeratorName
+ << " status = " << status
+ << " - quitting from LLVMFuzzerInitialize" << std::endl;
+ exit(2);
+ }
+
+ // Inititialize the enumerator that we are going to test
+ // TODO(b/162631113) if we place the initialization of enumerator inside
+ // LLVMFuzzerTestOneInput, there will be issues in destruction.
+ sEnumerator = new Enumerator();
+ if (!sEnumerator->init(kMockHWEnumeratorName)) {
+ std::cerr << "Failed to connect to hardware service"
+ << "- quitting from LLVMFuzzerInitialize" << std::endl;
+ exit(1);
+ }
+
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+
+ while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
+ switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
+ case EVS_FUZZ_GET_CAMERA_LIST: {
+ sEnumerator->getCameraList([](auto list){});
+ break;
+ }
+ case EVS_FUZZ_OPEN_CAMERA: {
+ uint64_t whichCam =
+ fdp.ConsumeIntegralInRange<uint64_t>(startMockHWCameraId,
+ endMockHWCameraId-1);
+ hidl_string camStr = to_string(whichCam);
+ sp<IEvsCamera_1_0> virtualCam = sEnumerator->openCamera(camStr);
+ if (virtualCam != nullptr) {
+ sVirtualCameras.emplace_back(virtualCam);
+ }
+ break;
+ }
+ case EVS_FUZZ_CLOSE_CAMERA: {
+ if (!sVirtualCameras.empty()) {
+ sp<IEvsCamera_1_0> cam = sVirtualCameras.back();
+ sEnumerator->closeCamera(cam);
+ sVirtualCameras.pop_back();
+ }
+ break;
+ }
+ case EVS_FUZZ_OPEN_DISPLAY: {
+ sp<IEvsDisplay_1_0> display = sEnumerator->openDisplay();
+ if (display != nullptr) {
+ sDisplays.emplace_back(display);
+ }
+ break;
+ }
+ case EVS_FUZZ_CLOSE_DISPLAY: {
+ if (!sDisplays.empty()) {
+ sp<IEvsDisplay_1_0> display = sDisplays.back();
+ sEnumerator->closeDisplay(display);
+ sDisplays.pop_back();
+ }
+ break;
+ }
+ case EVS_FUZZ_GET_DISPLAY_STATE: {
+ sEnumerator->getDisplayState();
+ break;
+ }
+ case EVS_FUZZ_GET_CAMERA_LIST_1_1: {
+ sEnumerator->getCameraList_1_1([](auto cams){});
+ break;
+ }
+ case EVS_FUZZ_OPEN_CAMERA_1_1: {
+ uint64_t whichCam =
+ fdp.ConsumeIntegralInRange<uint64_t>(startMockHWCameraId,
+ endMockHWCameraId-1);
+ hidl_string camStr = to_string(whichCam);
+ Stream streamCfg = {};
+ sp<IEvsCamera_1_1> virtualCam = sEnumerator->openCamera_1_1(camStr, streamCfg);
+ if (virtualCam != nullptr) {
+ sVirtualCameras.emplace_back(virtualCam);
+ }
+ break;
+ }
+ case EVS_FUZZ_IS_HARDWARE: {
+ sEnumerator->isHardware();
+ break;
+ }
+ case EVS_FUZZ_GET_DISPLAY_LIST: {
+ sEnumerator->getDisplayIdList([](auto list){});
+ break;
+ }
+ case EVS_FUZZ_OPEN_DISPLAY_1_1: {
+ uint64_t whichDisp =
+ fdp.ConsumeIntegralInRange<uint64_t>(startMockHWDisplayId,
+ endMockHWDisplayId-1);
+ // port is the same as display in this test
+ sp<IEvsDisplay_1_1> display = sEnumerator->openDisplay_1_1(
+ static_cast<uint8_t>(whichDisp));
+ if (display != nullptr) {
+ sDisplays.emplace_back(display);
+ }
+ break;
+ }
+ case EVS_FUZZ_GET_ULTRASONICS_ARRAY_LIST: {
+ sEnumerator->getUltrasonicsArrayList([](auto list) {});
+ break;
+ }
+ case EVS_FUZZ_OPEN_ULTRASONICS_ARRAY: {
+ // TODO(b/162465548) replace this once implementation is ready
+ sEnumerator->openUltrasonicsArray("");
+ break;
+ }
+ case EVS_FUZZ_CLOSE_ULTRASONICS_ARRAY: {
+ // TODO(b/162465548) replace this once implementation is ready
+ sEnumerator->closeUltrasonicsArray(nullptr);
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unexpected option, aborting...";
+ break;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
diff --git a/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp b/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp
new file mode 100644
index 0000000..4660182
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright 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.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <iostream>
+#include "Common.h"
+#include "Enumerator.h"
+#include "HalCamera.h"
+#include "MockHWCamera.h"
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+namespace {
+
+enum EvsFuzzFuncs {
+ EVS_FUZZ_MAKE_VIRTUAL_CAMERA = 0, // verify makeVirtualCamera
+ EVS_FUZZ_OWN_VIRTUAL_CAMERA, // verify ownVirtualCamera
+ EVS_FUZZ_DISOWN_VIRTUAL_CAMERA, // verify disownVirtualCamera
+ EVS_FUZZ_GET_CLIENT_COUNT, // verify getClientCount
+ EVS_FUZZ_GET_ID, // verify getId
+ EVS_FUZZ_GET_STREAM_CONFIG, // verify getStreamConfig
+ EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT, // verify changeFramesInFlight
+ EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT_1, // verify overloaded changeFramesInFlight
+ EVS_FUZZ_REQUEST_NEW_FRAME, // verify requestNewFrame
+ EVS_FUZZ_CLIENT_STREAM_STARTING, // verify clientStreamStarting
+ EVS_FUZZ_CLIENT_STREAM_ENDING, // verify clientStreamEnding
+ EVS_FUZZ_GET_STATS, // verify getStats
+ EVS_FUZZ_GET_STREAM_CONFIGURATION, // verify getStreamConfiguration
+ EVS_FUZZ_DELIVER_FRAME_1_1, // verify deliverFrame_1_1
+ EVS_FUZZ_BASE_ENUM // verify common functions
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ sp<IEvsCamera_1_1> mockHWCamera = new MockHWCamera();
+ sp<HalCamera> halCamera = new HalCamera(mockHWCamera);
+ std::vector<sp<VirtualCamera>> virtualCameras;
+
+ while (fdp.remaining_bytes() > 4) {
+ switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
+ case EVS_FUZZ_MAKE_VIRTUAL_CAMERA: {
+ sp<VirtualCamera> virtualCamera = halCamera->makeVirtualCamera();
+ virtualCameras.emplace_back(virtualCamera);
+ break;
+ }
+ case EVS_FUZZ_OWN_VIRTUAL_CAMERA: {
+ if (!virtualCameras.empty()) {
+ uint32_t whichCam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
+ halCamera->ownVirtualCamera(virtualCameras[whichCam]);
+ }
+ break;
+ }
+ case EVS_FUZZ_DISOWN_VIRTUAL_CAMERA: {
+ if (!virtualCameras.empty()) {
+ uint32_t whichCam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
+ halCamera->disownVirtualCamera(virtualCameras[whichCam]);
+ }
+ break;
+ }
+ case EVS_FUZZ_GET_HW_CAMERA: {
+ halCamera->getHwCamera();
+ break;
+ }
+ case EVS_FUZZ_GET_CLIENT_COUNT: {
+ halCamera->getClientCount();
+ break;
+ }
+ case EVS_FUZZ_GET_ID: {
+ halCamera->getId();
+ break;
+ }
+ case EVS_FUZZ_GET_STREAM_CONFIG: {
+ halCamera->getStreamConfig();
+ break;
+ }
+ case EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT: {
+ uint32_t delta = fdp.ConsumeIntegral<int32_t>();
+ halCamera->changeFramesInFlight(delta);
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unexpected option, aborting...";
+ break;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
diff --git a/evs/manager/1.1/test/fuzzer/HalDisplayFuzzer.cpp b/evs/manager/1.1/test/fuzzer/HalDisplayFuzzer.cpp
new file mode 100644
index 0000000..8ccc057
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/HalDisplayFuzzer.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright 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.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <sys/time.h>
+#include <iostream>
+#include "Common.h"
+#include "Enumerator.h"
+#include "HalDisplay.h"
+#include "MockHWDisplay.h"
+
+using DisplayDesc = ::android::hardware::automotive::evs::V1_0::DisplayDesc;
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+namespace {
+
+enum EvsFuzzFuncs {
+ EVS_FUZZ_GET_HW_DISPLAY = 0, // verify getHwDisplay
+ EVS_FUZZ_GET_DISPLAY_INFO, // verify getDisplayInfo
+ EVS_FUZZ_SET_DISPLAY_STATE, // verify setDisplayState
+ EVS_FUZZ_GET_DISPLAY_STATE, // verify getDisplayState
+ EVS_FUZZ_GET_TARGET_BUFFER, // verify getTargetBuffer
+ EVS_FUZZ_RTN_TGT_BUF_FOR_DISPLAY, // verify returnTargetBufferForDisplay
+ EVS_FUZZ_GET_DISPLAY_INFO_1_1, // verify getDisplayInfo_1_1
+ EVS_FUZZ_TO_STRING, // verify toString
+ EVS_FUZZ_API_SUM
+};
+
+const int kMaxFuzzerConsumedBytes = 12;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ sp<IEvsDisplay_1_0> mockHWDisplay = new MockHWDisplay();
+ sp<HalDisplay> halDisplay = new HalDisplay(mockHWDisplay);
+
+ while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
+ switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
+ case EVS_FUZZ_GET_HW_DISPLAY: {
+ halDisplay->getHwDisplay();
+ break;
+ }
+ case EVS_FUZZ_GET_DISPLAY_INFO: {
+ halDisplay->getDisplayInfo([](DisplayDesc desc) {});
+ break;
+ }
+ case EVS_FUZZ_SET_DISPLAY_STATE: {
+ uint32_t state =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ EvsDisplayState::NUM_STATES) -
+ 1);
+ halDisplay->setDisplayState(static_cast<EvsDisplayState>(state));
+ break;
+ }
+ case EVS_FUZZ_GET_DISPLAY_STATE: {
+ halDisplay->getDisplayState();
+ break;
+ }
+ case EVS_FUZZ_GET_TARGET_BUFFER: {
+ halDisplay->getTargetBuffer([](const BufferDesc_1_0& buff) {});
+ break;
+ }
+ case EVS_FUZZ_RTN_TGT_BUF_FOR_DISPLAY: {
+ BufferDesc_1_0 buffer;
+ buffer.bufferId = fdp.ConsumeIntegral<int32_t>();
+ halDisplay->returnTargetBufferForDisplay(buffer);
+ break;
+ }
+ case EVS_FUZZ_GET_DISPLAY_INFO_1_1: {
+ halDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {});
+ break;
+ }
+ case EVS_FUZZ_TO_STRING: {
+ std::string indent = fdp.ConsumeRandomLengthString(kMaxFuzzerConsumedBytes);
+ halDisplay->toString(indent.c_str());
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unexpected option, aborting...";
+ break;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
diff --git a/evs/manager/1.1/test/fuzzer/MockHWCamera.h b/evs/manager/1.1/test/fuzzer/MockHWCamera.h
new file mode 100644
index 0000000..a4e0638
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/MockHWCamera.h
@@ -0,0 +1,109 @@
+// Copyright 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.
+
+#ifndef EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWCAMERA_H_
+#define EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWCAMERA_H_
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+class MockHWCamera : public IEvsCamera_1_1 {
+public:
+ MockHWCamera() = default;
+
+ // v1.0 methods
+ Return<void> getCameraInfo(getCameraInfo_cb _hidl_cb) override { return {}; }
+ Return<EvsResult> setMaxFramesInFlight(uint32_t bufferCount) override {
+ if (bufferCount > 1024) {
+ return EvsResult::INVALID_ARG;
+ }
+ return EvsResult::OK;
+ }
+ Return<EvsResult> startVideoStream(const ::android::sp<IEvsCameraStream_1_0>& stream) override {
+ return EvsResult::OK;
+ }
+ Return<void> doneWithFrame(const BufferDesc_1_0& buffer) override { return {}; }
+ Return<void> stopVideoStream() override { return {}; }
+ Return<int32_t> getExtendedInfo(uint32_t opaqueIdentifier) override {
+ if (mExtendedInfo.find(opaqueIdentifier) != mExtendedInfo.end()) {
+ return mExtendedInfo[opaqueIdentifier];
+ }
+ return 0;
+ }
+ Return<EvsResult> setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue) override {
+ mExtendedInfo[opaqueIdentifier] = opaqueValue;
+ return EvsResult::OK;
+ }
+
+ // v1.1 methods
+ Return<void> getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) override { return {}; }
+ MOCK_METHOD(Return<void>, getPhysicalCameraInfo,
+ (const hidl_string& deviceId, getPhysicalCameraInfo_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<EvsResult>, pauseVideoStream, (), (override));
+ MOCK_METHOD(Return<EvsResult>, resumeVideoStream, (), (override));
+ MOCK_METHOD(Return<EvsResult>, doneWithFrame_1_1,
+ (const hardware::hidl_vec<BufferDesc_1_1>& buffer), (override));
+ MOCK_METHOD(Return<EvsResult>, setMaster, (), (override));
+ MOCK_METHOD(Return<EvsResult>, forceMaster, (const sp<IEvsDisplay_1_0>& display), (override));
+ MOCK_METHOD(Return<EvsResult>, unsetMaster, (), (override));
+ Return<void> getParameterList(getParameterList_cb _hidl_cb) override { return {}; }
+ Return<void> getIntParameterRange(CameraParam id, getIntParameterRange_cb _hidl_cb) override {
+ return {};
+ }
+ Return<void> setIntParameter(CameraParam id, int32_t value,
+ setIntParameter_cb _hidl_cb) override {
+ // FIXME in default implementation, it's _hidl_cb(EvsResult::INVALID_ARG, 0); which will
+ // always cause a segfault what's the predefined behavior of _hidl_cb?
+ std::vector<int32_t> vec;
+ vec.push_back(0);
+ _hidl_cb(EvsResult::INVALID_ARG, vec);
+ return {};
+ }
+
+ Return<void> getIntParameter(CameraParam id, getIntParameter_cb _hidl_cb) {
+ _hidl_cb(EvsResult::INVALID_ARG, 0);
+ return {};
+ }
+
+ Return<void> getExtendedInfo_1_1(uint32_t opaqueIdentifier,
+ getExtendedInfo_1_1_cb _hidl_cb) override {
+ return {};
+ }
+ Return<EvsResult> setExtendedInfo_1_1(uint32_t opaqueIdentifier,
+ const hidl_vec<uint8_t>& opaqueValue) override {
+ return EvsResult::OK;
+ }
+ Return<void> importExternalBuffers(const hidl_vec<BufferDesc_1_1>& buffers,
+ importExternalBuffers_cb _hidl_cb) override {
+ return {};
+ }
+
+private:
+ std::map<uint32_t, int32_t> mExtendedInfo;
+ std::map<uint32_t, int32_t> mExtendedInfo_1_1;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
+
+#endif // EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWCAMERA_H_
diff --git a/evs/manager/1.1/test/fuzzer/MockHWDisplay.h b/evs/manager/1.1/test/fuzzer/MockHWDisplay.h
new file mode 100644
index 0000000..59d352a
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/MockHWDisplay.h
@@ -0,0 +1,49 @@
+// Copyright 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.
+
+#ifndef EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWDISPLAY_H_
+#define EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWDISPLAY_H_
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+class MockHWDisplay : public IEvsDisplay_1_1 {
+public:
+ MockHWDisplay() = default;
+
+ Return<void> getDisplayInfo(getDisplayInfo_cb _hidl_cb) override { return {}; }
+ Return<EvsResult> setDisplayState(EvsDisplayState state) override { return EvsResult::OK; }
+ Return<EvsDisplayState> getDisplayState() override { return EvsDisplayState::VISIBLE; }
+ Return<void> getTargetBuffer(getTargetBuffer_cb _hidl_cb) override { return {}; }
+ Return<EvsResult> returnTargetBufferForDisplay(const BufferDesc_1_0& buffer) override {
+ return EvsResult::OK;
+ }
+ Return<void> getDisplayInfo_1_1(getDisplayInfo_1_1_cb _info_cb) override {
+ return {};
+ }
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
+
+#endif // EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWDISPLAY_H_
diff --git a/evs/manager/1.1/test/fuzzer/MockHWEnumerator.h b/evs/manager/1.1/test/fuzzer/MockHWEnumerator.h
new file mode 100644
index 0000000..38241c7
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/MockHWEnumerator.h
@@ -0,0 +1,124 @@
+// Copyright 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.
+
+#ifndef EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWENUMERATOR_H_
+#define EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWENUMERATOR_H_
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "MockHWDisplay.h"
+#include "MockHWCamera.h"
+
+using ::android::hardware::automotive::evs::V1_0::DisplayState;
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+class MockHWEnumerator : public IEvsEnumerator_1_1 {
+public:
+ MockHWEnumerator() {
+ // four cameras
+ for (uint64_t i = startMockHWCameraId; i < endMockHWCameraId; i++) {
+ sp<MockHWCamera> camera = new MockHWCamera();
+ mHWCameras[i] = camera;
+ }
+
+ // two displays
+ for (uint8_t i = static_cast<uint8_t>(startMockHWDisplayId);
+ i < static_cast<uint8_t>(endMockHWDisplayId); i++) {
+ sp<MockHWDisplay> display = new MockHWDisplay();
+ mHWDisplays[i] = display;
+ mDisplayPortList[i] = i;
+ }
+ }
+
+ // Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow.
+ MOCK_METHOD(Return<void>, getCameraList, (getCameraList_cb _hidl_cb), (override));
+ Return<sp<IEvsCamera_1_0>> openCamera(const hidl_string& cameraId) override {
+ uint64_t idx = stoi(cameraId);
+ if (mHWCameras.find(idx) != mHWCameras.end()) {
+ return mHWCameras[idx];
+ }
+ return nullptr;
+ }
+ MOCK_METHOD(Return<void>, closeCamera, (const sp<IEvsCamera_1_0>& carCamera), (override));
+ Return<sp<IEvsDisplay_1_0>> openDisplay() override {
+ return mHWDisplays.begin()->second;
+ }
+ Return<void> closeDisplay(const sp<IEvsDisplay_1_0>& display) override {
+ return {};
+ }
+ MOCK_METHOD(Return<DisplayState>, getDisplayState, (), (override));
+
+ // Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow.
+ Return<void> getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
+ return {};
+ }
+ Return<sp<IEvsCamera_1_1>> openCamera_1_1(const hidl_string& cameraId,
+ const Stream& streamCfg) override {
+ uint64_t idx = stoi(cameraId);
+ if (mHWCameras.find(idx) != mHWCameras.end()) {
+ return mHWCameras[idx];
+ }
+ return nullptr;
+ }
+ MOCK_METHOD(Return<bool>, isHardware, (), (override));
+ Return<void> getDisplayIdList(getDisplayIdList_cb _list_cb) override {
+ vector<uint8_t> ids;
+
+ ids.resize(mDisplayPortList.size());
+ unsigned i = 0;
+ for (const auto& [port, id] : mDisplayPortList) {
+ ids[i++] = port;
+ }
+
+ _list_cb(ids);
+ return {};
+ }
+ Return<sp<IEvsDisplay_1_1>> openDisplay_1_1(uint8_t port) override {
+ auto iter = mDisplayPortList.find(port);
+ if (iter != mDisplayPortList.end()) {
+ uint64_t id = iter->second;
+ auto it = mHWDisplays.find(id);
+ if (it != mHWDisplays.end()) {
+ return it->second;
+ }
+ return nullptr;
+ }
+ return nullptr;
+ }
+ MOCK_METHOD(Return<void>, getUltrasonicsArrayList, (getUltrasonicsArrayList_cb _hidl_cb),
+ (override));
+ MOCK_METHOD(Return<sp<IEvsUltrasonicsArray>>, openUltrasonicsArray,
+ (const hidl_string& ultrasonicsArrayId), (override));
+ MOCK_METHOD(Return<void>, closeUltrasonicsArray,
+ (const sp<IEvsUltrasonicsArray>& evsUltrasonicsArray), (override));
+
+private:
+ std::map<uint64_t, sp<MockHWDisplay>> mHWDisplays;
+ std::map<uint64_t, sp<MockHWCamera>> mHWCameras;
+ std::map<uint8_t, uint64_t> mDisplayPortList;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
+
+#endif // EVS_MANAGER_1_1_TEST_FUZZER_MOCKHWENUMERATOR_H_
diff --git a/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp b/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp
new file mode 100644
index 0000000..3776f4b
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 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.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <iostream>
+#include "Common.h"
+#include "Enumerator.h"
+#include "MockHWCamera.h"
+#include "VirtualCamera.h"
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+namespace {
+
+using CameraDesc_1_0 = ::android::hardware::automotive::evs::V1_0::CameraDesc;
+
+enum EvsFuzzFuncs {
+ EVS_FUZZ_GET_ALLOWED_BUFFERS, // verify getAllowedBuffers
+ EVS_FUZZ_IS_STREAMING, // verify isStreaming
+ EVS_FUZZ_GET_VERSION, // verify getVersion
+ EVS_FUZZ_SET_DESCRIPTOR, // verify setDescriptor
+ EVS_FUZZ_GET_CAMERA_INFO, // verify getCameraInfo
+ EVS_FUZZ_SETMAX_FRAMES_IN_FLIGHT, // verify setMaxFramesInFlight
+ EVS_FUZZ_START_VIDEO_STREAM, // verify startVideoStream
+ EVS_FUZZ_STOP_VIDEO_STREAM, // verify stopVideoStream
+ EVS_FUZZ_GET_EXTENDED_INFO, // verify getExtendedInfo
+ EVS_FUZZ_SET_EXTENDED_INFO, // verify setExtendedInfo
+ EVS_FUZZ_GET_CAMERA_INFO_1_1, // verify getCameraInfo_1_1
+ EVS_FUZZ_GET_PHYSICAL_CAMERA_INFO, // verify getPhysicalCameraInfo
+ EVS_FUZZ_PAUSE_VIDEO_STREAM, // verify pauseVideoStream
+ EVS_FUZZ_RESUME_VIDEO_STREAM, // verify resumeVideoStream
+ EVS_FUZZ_GET_PARAMETER_LIST, // verify getParameterList
+ EVS_FUZZ_GET_INT_PARAMETER_RANGE, // verify getIntParameterRange
+ EVS_FUZZ_SET_EXTENDED_INFO_1_1, // verify setExtendedInfo_1_1
+ EVS_FUZZ_GET_EXTENDED_INFO_1_1, // verify getExtendedInfo_1_1
+ EVS_FUZZ_IMPORT_EXTERNAL_BUFFERS, // verify importExternalBuffers
+ EVS_FUZZ_BASE_ENUM // verify common functions
+};
+
+const int kMaxFuzzerConsumedBytes = 12;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ sp<IEvsCamera_1_1> mockHWCamera = new MockHWCamera();
+ sp<HalCamera> halCamera = new HalCamera(mockHWCamera);
+ sp<VirtualCamera> virtualCamera = halCamera->makeVirtualCamera();
+
+ std::vector<BufferDesc_1_0> vBufferDesc_1_0;
+ std::vector<BufferDesc_1_1> vBufferDesc_1_1;
+
+ bool videoStarted = false;
+
+ while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
+ switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
+ case EVS_FUZZ_GET_ALLOWED_BUFFERS: {
+ virtualCamera->getAllowedBuffers();
+ break;
+ }
+ case EVS_FUZZ_IS_STREAMING: {
+ virtualCamera->isStreaming();
+ break;
+ }
+ case EVS_FUZZ_GET_VERSION: {
+ virtualCamera->getVersion();
+ break;
+ }
+ case EVS_FUZZ_GET_HW_CAMERA: {
+ virtualCamera->getHalCameras();
+ break;
+ }
+ case EVS_FUZZ_SET_DESCRIPTOR: {
+ CameraDesc* desc = new CameraDesc();
+ virtualCamera->setDescriptor(desc);
+ break;
+ }
+ case EVS_FUZZ_NOTIFY: {
+ if (videoStarted) {
+ EvsEventDesc event;
+ uint32_t type = fdp.ConsumeIntegralInRange<
+ uint32_t>(0, static_cast<uint32_t>(EvsEventType::STREAM_ERROR));
+ event.aType = static_cast<EvsEventType>(type);
+ virtualCamera->notify(event);
+ }
+ break;
+ }
+ case EVS_FUZZ_DELIVER_FRAME: {
+ BufferDesc buffer;
+ buffer.bufferId = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->deliverFrame(buffer);
+ vBufferDesc_1_1.emplace_back(buffer);
+ break;
+ }
+ case EVS_FUZZ_GET_CAMERA_INFO: {
+ virtualCamera->getCameraInfo([](CameraDesc_1_0 desc) {});
+ break;
+ }
+ case EVS_FUZZ_SETMAX_FRAMES_IN_FLIGHT: {
+ uint32_t delta = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->setMaxFramesInFlight(delta);
+ break;
+ }
+ case EVS_FUZZ_START_VIDEO_STREAM: {
+ if (!videoStarted) {
+ sp<IEvsCamera_1_1> mockHWCamera1 = new MockHWCamera();
+ sp<HalCamera> halCamera1 = new HalCamera(mockHWCamera1);
+ virtualCamera->startVideoStream(halCamera1);
+ videoStarted = true;
+ }
+ break;
+ }
+ case EVS_FUZZ_DONE_WITH_FRAME_1_0: {
+ if (!vBufferDesc_1_0.empty()) {
+ uint32_t whichBuffer =
+ fdp.ConsumeIntegralInRange<uint32_t>(0, vBufferDesc_1_0.size() - 1);
+ virtualCamera->doneWithFrame(vBufferDesc_1_0[whichBuffer]);
+ }
+ break;
+ }
+ case EVS_FUZZ_STOP_VIDEO_STREAM: {
+ virtualCamera->stopVideoStream();
+ videoStarted = false;
+ break;
+ }
+ case EVS_FUZZ_GET_EXTENDED_INFO: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->getExtendedInfo(opaqueIdentifier);
+ break;
+ }
+ case EVS_FUZZ_SET_EXTENDED_INFO: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ int32_t opaqueValue = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->setExtendedInfo(opaqueIdentifier, opaqueValue);
+ break;
+ }
+ case EVS_FUZZ_GET_CAMERA_INFO_1_1: {
+ virtualCamera->getCameraInfo_1_1([](CameraDesc desc) {});
+ break;
+ }
+ case EVS_FUZZ_GET_PHYSICAL_CAMERA_INFO: {
+ hidl_string deviceId("");
+ virtualCamera->getPhysicalCameraInfo(deviceId, [](const CameraDesc& info) {});
+ break;
+ }
+ case EVS_FUZZ_DONE_WITH_FRAME_1_1: {
+ if (!vBufferDesc_1_1.empty()) {
+ hidl_vec<BufferDesc_1_1> buffers(vBufferDesc_1_1);
+ virtualCamera->doneWithFrame_1_1(buffers);
+ }
+ break;
+ }
+ case EVS_FUZZ_PAUSE_VIDEO_STREAM: {
+ virtualCamera->pauseVideoStream();
+ break;
+ }
+ case EVS_FUZZ_RESUME_VIDEO_STREAM: {
+ virtualCamera->resumeVideoStream();
+ break;
+ }
+ case EVS_FUZZ_SET_PRIMARY: {
+ virtualCamera->setMaster();
+ break;
+ }
+ case EVS_FUZZ_FORCE_PRIMARY: {
+ // TODO(161388489) skip this until we finished fuzzing evs display
+ break;
+ }
+ case EVS_FUZZ_UNSET_PRIMARY: {
+ virtualCamera->unsetMaster();
+ break;
+ }
+ case EVS_FUZZ_GET_PARAMETER_LIST: {
+ virtualCamera->getParameterList([](hidl_vec<CameraParam> cmdList) {});
+ break;
+ }
+ case EVS_FUZZ_GET_INT_PARAMETER_RANGE: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ virtualCamera->getIntParameterRange(static_cast<CameraParam>(whichParam),
+ [](int32_t val0, int32_t val1, int32_t val2) {
+ });
+ break;
+ }
+ case EVS_FUZZ_SET_PARAMETER: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ int32_t val = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->setIntParameter(static_cast<CameraParam>(whichParam), val,
+ [](auto status, auto effectiveValues) {});
+ break;
+ }
+ case EVS_FUZZ_GET_PARAMETER: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ virtualCamera->getIntParameter(static_cast<CameraParam>(whichParam),
+ [](auto status, auto effectiveValues) {});
+ break;
+ }
+ case EVS_FUZZ_SET_EXTENDED_INFO_1_1: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ uint8_t opaqueValue = fdp.ConsumeIntegral<uint8_t>();
+ vector<uint8_t> v;
+ v.push_back(opaqueValue);
+ hidl_vec<uint8_t> vec(v);
+ virtualCamera->setExtendedInfo_1_1(opaqueIdentifier, vec);
+ break;
+ }
+ case EVS_FUZZ_GET_EXTENDED_INFO_1_1: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->getExtendedInfo_1_1(opaqueIdentifier,
+ [](const auto& result, const auto& data) {});
+ break;
+ }
+ case EVS_FUZZ_IMPORT_EXTERNAL_BUFFERS: {
+ if (!vBufferDesc_1_1.empty()) {
+ hidl_vec<BufferDesc_1_1> buffers(vBufferDesc_1_1);
+ virtualCamera->importExternalBuffers(buffers, [](auto _result, auto _delta) {});
+ }
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unexpected option, aborting...";
+ break;
+ }
+ }
+
+ if (videoStarted) {
+ // TODO(b/161762538) if we do not stop video stream manually here,
+ // there will be crash at VirtualCamera.cpp::pHwCamera->unsetMaster(this);
+ virtualCamera->stopVideoStream();
+ }
+ return 0;
+}
+
+} // namespace
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
diff --git a/evs/sampleDriver/EvsEnumerator.cpp b/evs/sampleDriver/EvsEnumerator.cpp
index 2dbedb4..731d14b 100644
--- a/evs/sampleDriver/EvsEnumerator.cpp
+++ b/evs/sampleDriver/EvsEnumerator.cpp
@@ -220,7 +220,7 @@
if (displayIds.size() > 0) {
sInternalDisplayId = displayIds[0];
for (const auto& id : displayIds) {
- const auto port = id & 0xF;
+ const auto port = id & 0xFF;
LOG(INFO) << "Display " << std::hex << id
<< " is detected on the port, " << port;
sDisplayPortList.insert_or_assign(port, id);
@@ -510,7 +510,7 @@
if (sDisplayPortList.size() > 0) {
ids.resize(sDisplayPortList.size());
unsigned i = 0;
- ids[i++] = sInternalDisplayId & 0xF;
+ ids[i++] = sInternalDisplayId & 0xFF;
for (const auto& [port, id] : sDisplayPortList) {
if (sInternalDisplayId != id) {
ids[i++] = port;
diff --git a/evs/sampleDriver/EvsV4lCamera.cpp b/evs/sampleDriver/EvsV4lCamera.cpp
index cd2a3a4..a46a80b 100644
--- a/evs/sampleDriver/EvsV4lCamera.cpp
+++ b/evs/sampleDriver/EvsV4lCamera.cpp
@@ -728,7 +728,7 @@
if (!readyForFrame) {
// We need to return the video buffer so it can capture a new frame
- mVideo.markFrameConsumed();
+ mVideo.markFrameConsumed(pV4lBuff->index);
} else {
// Assemble the buffer description we'll transmit below
BufferDesc_1_1 bufDesc_1_1 = {};
@@ -779,7 +779,7 @@
// Give the video frame back to the underlying device for reuse
// Note that we do this before making the client callback to give the
// underlying camera more time to capture the next frame
- mVideo.markFrameConsumed();
+ mVideo.markFrameConsumed(pV4lBuff->index);
// Issue the (asynchronous) callback to the client -- can't be holding
// the lock
diff --git a/evs/sampleDriver/VideoCapture.cpp b/evs/sampleDriver/VideoCapture.cpp
index 9663bf6..accee26 100644
--- a/evs/sampleDriver/VideoCapture.cpp
+++ b/evs/sampleDriver/VideoCapture.cpp
@@ -91,7 +91,7 @@
// Set our desired output format
v4l2_format format;
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- format.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
format.fmt.pix.width = width;
format.fmt.pix.height = height;
LOG(INFO) << "Requesting format: "
@@ -125,7 +125,7 @@
// Make sure we're initialized to the STOPPED state
mRunMode = STOPPED;
- mFrameReady = false;
+ mFrames.clear();
// Ready to go!
return true;
@@ -164,45 +164,54 @@
return false;
}
- // Get the information on the buffer that was created for us
- memset(&mBufferInfo, 0, sizeof(mBufferInfo));
- mBufferInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mBufferInfo.memory = V4L2_MEMORY_MMAP;
- mBufferInfo.index = 0;
- if (ioctl(mDeviceFd, VIDIOC_QUERYBUF, &mBufferInfo) < 0) {
- PLOG(ERROR) << "VIDIOC_QUERYBUF failed";
- return false;
- }
+ mNumBuffers = bufrequest.count;
+ mBufferInfos = std::make_unique<v4l2_buffer[]>(mNumBuffers);
+ mPixelBuffers = std::make_unique<void *[]>(mNumBuffers);
- LOG(INFO) << "Buffer description:";
- LOG(INFO) << " offset: " << mBufferInfo.m.offset;
- LOG(INFO) << " length: " << mBufferInfo.length;
- LOG(INFO) << " flags : " << std::hex << mBufferInfo.flags;
+ for (int i = 0; i < mNumBuffers; ++i) {
+ // Get the information on the buffer that was created for us
+ memset(&mBufferInfos[i], 0, sizeof(v4l2_buffer));
+ mBufferInfos[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mBufferInfos[i].memory = V4L2_MEMORY_MMAP;
+ mBufferInfos[i].index = i;
- // Get a pointer to the buffer contents by mapping into our address space
- mPixelBuffer = mmap(
- NULL,
- mBufferInfo.length,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- mDeviceFd,
- mBufferInfo.m.offset
- );
- if( mPixelBuffer == MAP_FAILED) {
- PLOG(ERROR) << "mmap() failed";
- return false;
- }
- memset(mPixelBuffer, 0, mBufferInfo.length);
- LOG(INFO) << "Buffer mapped at " << mPixelBuffer;
+ if (ioctl(mDeviceFd, VIDIOC_QUERYBUF, &mBufferInfos[i]) < 0) {
+ PLOG(ERROR) << "VIDIOC_QUERYBUF failed";
+ return false;
+ }
- // Queue the first capture buffer
- if (ioctl(mDeviceFd, VIDIOC_QBUF, &mBufferInfo) < 0) {
- PLOG(ERROR) << "VIDIOC_QBUF failed";
- return false;
+ LOG(INFO) << "Buffer description:";
+ LOG(INFO) << " offset: " << mBufferInfos[i].m.offset;
+ LOG(INFO) << " length: " << mBufferInfos[i].length;
+ LOG(INFO) << " flags : " << std::hex << mBufferInfos[i].flags;
+
+ // Get a pointer to the buffer contents by mapping into our address space
+ mPixelBuffers[i] = mmap(
+ NULL,
+ mBufferInfos[i].length,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ mDeviceFd,
+ mBufferInfos[i].m.offset
+ );
+
+ if(mPixelBuffers[i] == MAP_FAILED) {
+ PLOG(ERROR) << "mmap() failed";
+ return false;
+ }
+
+ memset(mPixelBuffers[i], 0, mBufferInfos[i].length);
+ LOG(INFO) << "Buffer mapped at " << mPixelBuffers[i];
+
+ // Queue the first capture buffer
+ if (ioctl(mDeviceFd, VIDIOC_QBUF, &mBufferInfos[i]) < 0) {
+ PLOG(ERROR) << "VIDIOC_QBUF failed";
+ return false;
+ }
}
// Start the video stream
- int type = mBufferInfo.type;
+ const int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(mDeviceFd, VIDIOC_STREAMON, &type) < 0) {
PLOG(ERROR) << "VIDIOC_STREAMON failed";
return false;
@@ -236,7 +245,7 @@
}
// Stop the underlying video stream (automatically empties the buffer queue)
- int type = mBufferInfo.type;
+ const int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(mDeviceFd, VIDIOC_STREAMOFF, &type) < 0) {
PLOG(ERROR) << "VIDIOC_STREAMOFF failed";
}
@@ -244,8 +253,10 @@
LOG(DEBUG) << "Capture thread stopped.";
}
- // Unmap the buffers we allocated
- munmap(mPixelBuffer, mBufferInfo.length);
+ for (int i = 0; i < mNumBuffers; ++i) {
+ // Unmap the buffers we allocated
+ munmap(mPixelBuffers[i], mBufferInfos[i].length);
+ }
// Tell the L4V2 driver to release our streaming buffers
v4l2_requestbuffers bufrequest;
@@ -256,24 +267,29 @@
// Drop our reference to the frame delivery callback interface
mCallback = nullptr;
+
+ // Release capture buffers
+ mNumBuffers = 0;
+ mBufferInfos = nullptr;
+ mPixelBuffers = nullptr;
}
-void VideoCapture::markFrameReady() {
- mFrameReady = true;
-};
-
-
-bool VideoCapture::returnFrame() {
- // We're giving the frame back to the system, so clear the "ready" flag
- mFrameReady = false;
+bool VideoCapture::returnFrame(int id) {
+ if (mFrames.find(id) == mFrames.end()) {
+ LOG(WARNING) << "Invalid request to return a buffer " << id << " is ignored.";
+ return false;
+ }
// Requeue the buffer to capture the next available frame
- if (ioctl(mDeviceFd, VIDIOC_QBUF, &mBufferInfo) < 0) {
+ if (ioctl(mDeviceFd, VIDIOC_QBUF, &mBufferInfos[id]) < 0) {
PLOG(ERROR) << "VIDIOC_QBUF failed";
return false;
}
+ // Remove ID of returned buffer from the set
+ mFrames.erase(id);
+
return true;
}
@@ -282,17 +298,25 @@
void VideoCapture::collectFrames() {
// Run until our atomic signal is cleared
while (mRunMode == RUN) {
+ struct v4l2_buffer buf = {
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .memory = V4L2_MEMORY_MMAP
+ };
+
// Wait for a buffer to be ready
- if (ioctl(mDeviceFd, VIDIOC_DQBUF, &mBufferInfo) < 0) {
+ if (ioctl(mDeviceFd, VIDIOC_DQBUF, &buf) < 0) {
PLOG(ERROR) << "VIDIOC_DQBUF failed";
break;
}
- markFrameReady();
+ mFrames.insert(buf.index);
+
+ // Update a frame metadata
+ mBufferInfos[buf.index] = buf;
// If a callback was requested per frame, do that now
if (mCallback) {
- mCallback(this, &mBufferInfo, mPixelBuffer);
+ mCallback(this, &mBufferInfos[buf.index], mPixelBuffers[buf.index]);
}
}
diff --git a/evs/sampleDriver/VideoCapture.h b/evs/sampleDriver/VideoCapture.h
index 42a5ef4..d298d41 100644
--- a/evs/sampleDriver/VideoCapture.h
+++ b/evs/sampleDriver/VideoCapture.h
@@ -41,12 +41,21 @@
__u32 getV4LFormat() { return mFormat; };
// NULL until stream is started
- void* getLatestData() { return mPixelBuffer; };
+ void* getLatestData() {
+ if (mFrames.empty()) {
+ // No frame is available
+ return nullptr;
+ }
- bool isFrameReady() { return mFrameReady; };
- void markFrameConsumed() { returnFrame(); };
+ // Return a pointer to the buffer captured most recently
+ const int latestBufferId = *mFrames.end();
+ return mPixelBuffers[latestBufferId];
+ }
- bool isOpen() { return mDeviceFd >= 0; };
+ bool isFrameReady() { return !mFrames.empty(); }
+ void markFrameConsumed(int id) { returnFrame(id); }
+
+ bool isOpen() { return mDeviceFd >= 0; }
int setParameter(struct v4l2_control& control);
int getParameter(struct v4l2_control& control);
@@ -54,13 +63,13 @@
private:
void collectFrames();
- void markFrameReady();
- bool returnFrame();
+ bool returnFrame(int id);
int mDeviceFd = -1;
- v4l2_buffer mBufferInfo = {};
- void* mPixelBuffer = nullptr;
+ int mNumBuffers = 0;
+ std::unique_ptr<v4l2_buffer[]> mBufferInfos = nullptr;
+ std::unique_ptr<void*[]> mPixelBuffers = nullptr;
__u32 mFormat = 0;
__u32 mWidth = 0;
@@ -71,7 +80,7 @@
std::thread mCaptureThread; // The thread we'll use to dispatch frames
std::atomic<int> mRunMode; // Used to signal the frame loop (see RunModes below)
- std::atomic<bool> mFrameReady; // Set when a frame has been delivered
+ std::set<int> mFrames; // Set of available frame buffers
// Careful changing these -- we're using bit-wise ops to manipulate these
enum RunModes {
diff --git a/evs/sampleDriver/android.hardware.automotive.evs@1.1-sample.rc b/evs/sampleDriver/android.hardware.automotive.evs@1.1-sample.rc
index 324a949..e7d7217 100644
--- a/evs/sampleDriver/android.hardware.automotive.evs@1.1-sample.rc
+++ b/evs/sampleDriver/android.hardware.automotive.evs@1.1-sample.rc
@@ -1,4 +1,4 @@
-service evs_driver /vendor/bin/android.hardware.automotive.evs@1.1-sample
+service evs_sample_driver /vendor/bin/android.hardware.automotive.evs@1.1-sample
class hal
priority -20
user graphics
diff --git a/evs/sampleDriver/resources/evs_sample_configuration.xml b/evs/sampleDriver/resources/evs_sample_configuration.xml
index f81b922..8b9007f 100644
--- a/evs/sampleDriver/resources/evs_sample_configuration.xml
+++ b/evs/sampleDriver/resources/evs_sample_configuration.xml
@@ -55,7 +55,7 @@
name='LOGICAL_MULTI_CAMERA_PHYSICAL_IDS'
type='byte[]'
size='2'
- value='/dev/video3,/dev/video4'
+ value='/dev/video10,/dev/video11'
/>
</characteristics>
</group>
@@ -198,7 +198,105 @@
</characteristics>
</device>
- <!-- camera device information for v4l2loopback devices -->
+ <!-- vivid emulated video devices -->
+ <device id='/dev/video10' position='rear'>
+ <caps>
+ <!-- list of supported controls -->
+ <supported_controls>
+ <control name='BRIGHTNESS' min='0' max='255'/>
+ <control name='CONTRAST' min='0' max='255'/>
+ <control name='AUTO_WHITE_BALANCE' min='0' max='1'/>
+ <control name='WHITE_BALANCE_TEMPERATURE' min='2000' max='7500'/>
+ <control name='SHARPNESS' min='0' max='255'/>
+ <control name='AUTO_FOCUS' min='0' max='1'/>
+ <control name='ABSOLUTE_FOCUS' min='0' max='255' step='5'/>
+ <control name='ABSOLUTE_ZOOM' min='100' max='400'/>
+ </supported_controls>
+
+ <!-- list of supported stream configurations -->
+ <!-- vivid webcam input support below three resolutions -->
+ <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='5'/>
+ <stream id='1' width='640' height='360' format='RGBA_8888' framerate='15'/>
+ <stream id='2' width='360' height='180' format='RGBA_8888' framerate='30'/>
+ </caps>
+
+ <!-- list of parameters -->
+ <characteristics/>
+ </device>
+ <device id='/dev/video11' position='left'>
+ <caps>
+ <!-- list of supported controls -->
+ <supported_controls>
+ <control name='BRIGHTNESS' min='0' max='255'/>
+ <control name='CONTRAST' min='0' max='255'/>
+ <control name='AUTO_WHITE_BALANCE' min='0' max='1'/>
+ <control name='WHITE_BALANCE_TEMPERATURE' min='2000' max='7500'/>
+ <control name='SHARPNESS' min='0' max='255'/>
+ <control name='AUTO_FOCUS' min='0' max='1'/>
+ <control name='ABSOLUTE_FOCUS' min='0' max='255' step='5'/>
+ <control name='ABSOLUTE_ZOOM' min='100' max='400'/>
+ </supported_controls>
+
+ <!-- list of supported stream configurations -->
+ <!-- vivid webcam input support below three resolutions -->
+ <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='5'/>
+ <stream id='1' width='640' height='360' format='RGBA_8888' framerate='15'/>
+ <stream id='2' width='360' height='180' format='RGBA_8888' framerate='30'/>
+ </caps>
+
+ <!-- list of parameters -->
+ <characteristics/>
+ </device>
+ <device id='/dev/video12' position='right'>
+ <caps>
+ <!-- list of supported controls -->
+ <supported_controls>
+ <control name='BRIGHTNESS' min='0' max='255'/>
+ <control name='CONTRAST' min='0' max='255'/>
+ <control name='AUTO_WHITE_BALANCE' min='0' max='1'/>
+ <control name='WHITE_BALANCE_TEMPERATURE' min='2000' max='7500'/>
+ <control name='SHARPNESS' min='0' max='255'/>
+ <control name='AUTO_FOCUS' min='0' max='1'/>
+ <control name='ABSOLUTE_FOCUS' min='0' max='255' step='5'/>
+ <control name='ABSOLUTE_ZOOM' min='100' max='400'/>
+ </supported_controls>
+
+ <!-- list of supported stream configurations -->
+ <!-- vivid webcam input support below three resolutions -->
+ <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='5'/>
+ <stream id='1' width='640' height='360' format='RGBA_8888' framerate='15'/>
+ <stream id='2' width='360' height='180' format='RGBA_8888' framerate='30'/>
+ </caps>
+
+ <!-- list of parameters -->
+ <characteristics/>
+ </device>
+ <device id='/dev/video13' position='front'>
+ <caps>
+ <!-- list of supported controls -->
+ <supported_controls>
+ <control name='BRIGHTNESS' min='0' max='255'/>
+ <control name='CONTRAST' min='0' max='255'/>
+ <control name='AUTO_WHITE_BALANCE' min='0' max='1'/>
+ <control name='WHITE_BALANCE_TEMPERATURE' min='2000' max='7500'/>
+ <control name='SHARPNESS' min='0' max='255'/>
+ <control name='AUTO_FOCUS' min='0' max='1'/>
+ <control name='ABSOLUTE_FOCUS' min='0' max='255' step='5'/>
+ <control name='ABSOLUTE_ZOOM' min='100' max='400'/>
+ </supported_controls>
+
+ <!-- list of supported stream configurations -->
+ <!-- vivid webcam input support below three resolutions -->
+ <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='5'/>
+ <stream id='1' width='640' height='360' format='RGBA_8888' framerate='15'/>
+ <stream id='2' width='360' height='180' format='RGBA_8888' framerate='30'/>
+ </caps>
+
+ <!-- list of parameters -->
+ <characteristics/>
+ </device>
+
+ <!-- camera device information for v4l2loopback devices -->
<!-- camera group v4l2loopback_group0 -->
<group id='v4l2loopback_group0' synchronized='CALIBRATED'>
<caps>
diff --git a/evs/sepolicy/evs.mk b/evs/sepolicy/evs.mk
new file mode 100644
index 0000000..aee4003
--- /dev/null
+++ b/evs/sepolicy/evs.mk
@@ -0,0 +1,3 @@
+# Extended View System Selinux Policies
+PRODUCT_PUBLIC_SEPOLICY_DIRS += packages/services/Car/evs/sepolicy/public
+PRODUCT_PRIVATE_SEPOLICY_DIRS += packages/services/Car/evs/sepolicy/private
diff --git a/evs/sepolicy/private/automotive_display_service.te b/evs/sepolicy/private/automotive_display_service.te
new file mode 100644
index 0000000..cd42ed6
--- /dev/null
+++ b/evs/sepolicy/private/automotive_display_service.te
@@ -0,0 +1,2 @@
+allow automotive_display_service hal_evs_driver:binder transfer;
+allow automotive_display_service hal_evs_driver:fd use;
diff --git a/evs/sepolicy/evs_app.te b/evs/sepolicy/private/evs_app.te
similarity index 100%
rename from evs/sepolicy/evs_app.te
rename to evs/sepolicy/private/evs_app.te
diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/private/evs_driver.te
similarity index 94%
rename from evs/sepolicy/evs_driver.te
rename to evs/sepolicy/private/evs_driver.te
index 9bb7b97..5b847fa 100644
--- a/evs/sepolicy/evs_driver.te
+++ b/evs/sepolicy/private/evs_driver.te
@@ -1,5 +1,4 @@
-# evs_mock mock hardware driver service
-type hal_evs_driver, domain;
+# evs reference hardware driver service
hal_server_domain(hal_evs_driver, hal_evs)
hal_client_domain(hal_evs_driver, hal_evs)
diff --git a/evs/sepolicy/evs_manager.te b/evs/sepolicy/private/evs_manager.te
similarity index 74%
rename from evs/sepolicy/evs_manager.te
rename to evs/sepolicy/private/evs_manager.te
index cf649bb..32bbc32 100644
--- a/evs/sepolicy/evs_manager.te
+++ b/evs/sepolicy/private/evs_manager.te
@@ -1,5 +1,4 @@
# evs manager
-type evs_manager, domain, coredomain;
hal_server_domain(evs_manager, hal_evs)
hal_client_domain(evs_manager, hal_evs)
@@ -7,10 +6,7 @@
type evs_manager_exec, exec_type, file_type, system_file_type;
init_daemon_domain(evs_manager)
-# allow use of hwservices
-allow evs_manager hal_graphics_allocator_default:fd use;
-
-# allow write to fd
+# allow write messages to the shell
allow evs_manager shell:fd use;
allow evs_manager shell:fifo_file write;
diff --git a/evs/sepolicy/file_contexts b/evs/sepolicy/private/file_contexts
similarity index 100%
rename from evs/sepolicy/file_contexts
rename to evs/sepolicy/private/file_contexts
diff --git a/evs/sepolicy/servicemanager.te b/evs/sepolicy/private/servicemanager.te
similarity index 100%
rename from evs/sepolicy/servicemanager.te
rename to evs/sepolicy/private/servicemanager.te
diff --git a/evs/sepolicy/surfaceflinger.te b/evs/sepolicy/private/surfaceflinger.te
similarity index 100%
rename from evs/sepolicy/surfaceflinger.te
rename to evs/sepolicy/private/surfaceflinger.te
diff --git a/evs/sepolicy/public/evs_driver.te b/evs/sepolicy/public/evs_driver.te
new file mode 100644
index 0000000..9f72441
--- /dev/null
+++ b/evs/sepolicy/public/evs_driver.te
@@ -0,0 +1,2 @@
+# reference evs hardware driver service
+type hal_evs_driver, domain;
diff --git a/evs/sepolicy/public/evs_manager.te b/evs/sepolicy/public/evs_manager.te
new file mode 100644
index 0000000..24f3e6c
--- /dev/null
+++ b/evs/sepolicy/public/evs_manager.te
@@ -0,0 +1,2 @@
+# evs manager
+type evs_manager, domain, coredomain;
diff --git a/packages/CarShell/Android.bp b/packages/CarShell/Android.bp
new file mode 100644
index 0000000..545a2c5
--- /dev/null
+++ b/packages/CarShell/Android.bp
@@ -0,0 +1,7 @@
+android_app {
+ name: "CarShell",
+ srcs: ["src/**/*.java"],
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+}
diff --git a/packages/CarShell/AndroidManifest.xml b/packages/CarShell/AndroidManifest.xml
new file mode 100644
index 0000000..c947a59
--- /dev/null
+++ b/packages/CarShell/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.car.shell"
+ coreApp="true"
+ android:sharedUserId="android.uid.shell"
+ >
+ <!-- Permission required for ATS tests - AtsCarHostTestCases, AtsCarDeviceApp -->
+ <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE" />
+ <!-- Permission required for ATS tests - AtsDeviceInfo, AtsAudioDeviceTestCases -->
+ <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
+ <!-- Permissions required for ATS tests - AtsDeviceInfo -->
+ <uses-permission android:name="android.car.permission.CAR_DIAGNOSTICS" />
+</manifest>
diff --git a/service/res/values-ca/strings.xml b/service/res/values-ca/strings.xml
index 6bf7504..cb1b4ee 100644
--- a/service/res/values-ca/strings.xml
+++ b/service/res/values-ca/strings.xml
@@ -24,8 +24,8 @@
<string name="car_permission_desc_energy" msgid="3392963810053235407">"Accedir a la informació sobre l\'energia del cotxe"</string>
<string name="car_permission_label_adjust_range_remaining" msgid="839033553999920138">"ajustar l\'autonomia restant del cotxe"</string>
<string name="car_permission_desc_adjust_range_remaining" msgid="2369321650437370673">"Ajustar el valor de l\'autonomia restant del cotxe."</string>
- <string name="car_permission_label_hvac" msgid="1499454192558727843">"accedir al sistema de calefacció, ventilació i aire condicionat del cotxe"</string>
- <string name="car_permission_desc_hvac" msgid="3754229695589774195">"Accedir al sistema de calefacció, ventilació i aire condicionat del cotxe"</string>
+ <string name="car_permission_label_hvac" msgid="1499454192558727843">"accedir al sistema de climatització del cotxe"</string>
+ <string name="car_permission_desc_hvac" msgid="3754229695589774195">"Accedir al sistema de climatització del cotxe"</string>
<string name="car_permission_label_mileage" msgid="4661317074631150551">"accedeix a la informació sobre el quilometratge del cotxe"</string>
<string name="car_permission_desc_mileage" msgid="7179735693278681090">"Accedir a la informació sobre el quilometratge del cotxe"</string>
<string name="car_permission_label_speed" msgid="1149027717860529745">"llegeix la velocitat del cotxe"</string>
diff --git a/service/src/com/android/car/CarMediaService.java b/service/src/com/android/car/CarMediaService.java
index 9501c89..c35578b 100644
--- a/service/src/com/android/car/CarMediaService.java
+++ b/service/src/com/android/car/CarMediaService.java
@@ -210,10 +210,14 @@
if (Log.isLoggable(CarLog.TAG_MEDIA, Log.DEBUG)) {
Log.d(CarLog.TAG_MEDIA, "CarMediaService.onEvent(" + event + ")");
}
- if (CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING == event.getEventType()) {
- maybeInitUser(event.getUserId());
- } else if (CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING == event.getEventType()) {
- onUserUnlock(event.getUserId());
+
+ switch (event.getEventType()) {
+ case CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING:
+ maybeInitUser(event.getUserId());
+ break;
+ case CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED:
+ onUserUnlock(event.getUserId());
+ break;
}
};
@@ -409,7 +413,7 @@
@Override
public List<ComponentName> getLastMediaSources(@CarMediaManager.MediaSourceMode int mode) {
String key = getMediaSourceKey(mode);
- String serialized = mSharedPrefs.getString(key, null);
+ String serialized = mSharedPrefs.getString(key, "");
return getComponentNameList(serialized).stream()
.map(name -> ComponentName.unflattenFromString(name)).collect(Collectors.toList());
}
@@ -814,7 +818,7 @@
private @NonNull ComponentName getLastMediaSource(int mode) {
if (sharedPrefsInitialized()) {
String key = getMediaSourceKey(mode);
- String serialized = mSharedPrefs.getString(key, null);
+ String serialized = mSharedPrefs.getString(key, "");
if (!TextUtils.isEmpty(serialized)) {
for (String name : getComponentNameList(serialized)) {
ComponentName componentName = ComponentName.unflattenFromString(name);
@@ -840,7 +844,7 @@
return componentNames.stream().collect(Collectors.joining(COMPONENT_NAME_SEPARATOR));
}
- private List<String> getComponentNameList(String serialized) {
+ private List<String> getComponentNameList(@NonNull String serialized) {
String[] componentNames = serialized.split(COMPONENT_NAME_SEPARATOR);
return (Arrays.asList(componentNames));
}
diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java
index da88468..df647bb 100644
--- a/service/src/com/android/car/CarPowerManagementService.java
+++ b/service/src/com/android/car/CarPowerManagementService.java
@@ -35,6 +35,7 @@
import android.hardware.automotive.vehicle.V2_0.InitialUserInfoRequestType;
import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq;
+import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -50,7 +51,8 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.sysprop.CarProperties;
-import android.util.Log;
+import android.util.AtomicFile;
+import android.util.Slog;
import com.android.car.am.ContinuousBlankActivity;
import com.android.car.hal.PowerHalService;
@@ -62,8 +64,16 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractionManagerService;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
+import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
@@ -79,6 +89,13 @@
// TODO: replace all usage
private static final String TAG = CarLog.TAG_POWER;
+ private static final String WIFI_STATE_FILENAME = "wifi_state";
+ private static final String WIFI_STATE_MODIFIED = "forcibly_disabled";
+ private static final String WIFI_STATE_ORIGINAL = "original";
+ // If Suspend to RAM fails, we retry with an exponential back-off:
+ // 10 msec, 20 msec, ..., 1280 msec, for a maximum of about 2.5 seconds.
+ private static final int MAX_SUSPEND_TRIES = 9; // Initial + 8 retries
+ private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10;
private final Object mLock = new Object();
private final Object mSimulationWaitObject = new Object();
@@ -141,6 +158,9 @@
private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
+ private final WifiManager mWifiManager;
+ private final AtomicFile mWifiStateFile;
+
// TODO: Make this OEM configurable.
private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000;
private static final int SHUTDOWN_EXTEND_MAX_MS = 5000;
@@ -162,7 +182,7 @@
*/
@Override
public void onCallbackDied(ICarPowerStateListener listener) {
- Log.i(CarLog.TAG_POWER, "binderDied " + listener.asBinder());
+ Slog.i(TAG, "binderDied " + listener.asBinder());
CarPowerManagementService.this.doUnregisterListener(listener);
}
}
@@ -193,7 +213,7 @@
mSwitchGuestUserBeforeSleep = resources.getBoolean(
R.bool.config_switchGuestUserBeforeGoingSleep);
if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) {
- Log.w(CarLog.TAG_POWER,
+ Slog.w(TAG,
"maxGarageModeRunningDurationInSecs smaller than minimum required, resource:"
+ mShutdownPrepareTimeMs + "(ms) while should exceed:"
+ MIN_MAX_GARAGE_MODE_DURATION_MS + "(ms), Ignore resource.");
@@ -202,6 +222,9 @@
mUserService = carUserService;
mInitialUserSetter = initialUserSetter;
mVoiceInteractionManagerService = voiceInteractionService;
+ mWifiManager = context.getSystemService(WifiManager.class);
+ mWifiStateFile = new AtomicFile(
+ new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME));
}
@VisibleForTesting
@@ -228,7 +251,7 @@
// Initialize CPMS in WAIT_FOR_VHAL state
onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerStateListener.WAIT_FOR_VHAL);
} else {
- Log.w(CarLog.TAG_POWER, "Vehicle hal does not support power state yet.");
+ Slog.w(TAG, "Vehicle hal does not support power state yet.");
onApPowerStateChange(CpmsState.ON, CarPowerStateListener.ON);
}
mSystemInterface.startDisplayStateMonitoring(this);
@@ -272,6 +295,7 @@
public void onApPowerStateChange(PowerState state) {
synchronized (mLock) {
mPendingPowerStates.addFirst(new CpmsState(state));
+ mLock.notify();
}
mHandler.handlePowerStateChange();
}
@@ -279,7 +303,7 @@
@VisibleForTesting
void setStateForTesting(boolean isBooting, boolean isResuming) {
synchronized (mLock) {
- Log.d(CarLog.TAG_POWER, "setStateForTesting():"
+ Slog.d(TAG, "setStateForTesting():"
+ " booting(" + mIsBooting + ">" + isBooting + ")"
+ " resuming(" + mIsResuming + ">" + isResuming + ")");
mIsBooting = isBooting;
@@ -294,6 +318,7 @@
CpmsState newState = new CpmsState(apState, carPowerStateListenerState);
synchronized (mLock) {
mPendingPowerStates.addFirst(newState);
+ mLock.notify();
}
mHandler.handlePowerStateChange();
}
@@ -304,10 +329,10 @@
state = mPendingPowerStates.peekFirst();
mPendingPowerStates.clear();
if (state == null) {
- Log.e(CarLog.TAG_POWER, "Null power state was requested");
+ Slog.e(TAG, "Null power state was requested");
return;
}
- Log.i(CarLog.TAG_POWER, "doHandlePowerStateChange: newState=" + state.name());
+ Slog.i(TAG, "doHandlePowerStateChange: newState=" + state.name());
if (!needPowerStateChangeLocked(state)) {
return;
}
@@ -315,7 +340,7 @@
releaseTimerLocked();
}
mHandler.cancelProcessingComplete();
- Log.i(CarLog.TAG_POWER, "setCurrentState " + state.toString());
+ Slog.i(TAG, "setCurrentState " + state.toString());
CarStatsLogHelper.logPowerState(state.mState);
mCurrentState = state;
switch (state.mState) {
@@ -361,6 +386,7 @@
mHal.sendSleepExit();
break;
}
+ restoreWifi();
}
private void updateCarUserNoticeServiceIfNecessary() {
@@ -371,8 +397,7 @@
CarLocalServices.getService(CarUserNoticeService.class);
if (currentUserInfo != null && currentUserInfo.isGuest()
&& carUserNoticeService != null) {
- Log.i(CarLog.TAG_POWER,
- "Car user notice service will ignore all messages before user switch.");
+ Slog.i(TAG, "Car user notice service will ignore all messages before user switch.");
Intent intent = new Intent();
intent.setComponent(new ComponentName(mContext.getPackageName(),
ContinuousBlankActivity.class.getName()));
@@ -381,7 +406,7 @@
carUserNoticeService.ignoreUserNotice(currentUserId);
}
} catch (Exception e) {
- Log.w(CarLog.TAG_POWER, "Cannot ignore user notice for current user", e);
+ Slog.w(TAG, "Cannot ignore user notice for current user", e);
}
}
@@ -402,14 +427,14 @@
allowUserSwitch = false;
mIsBooting = false;
mIsResuming = false;
- Log.i(CarLog.TAG_POWER, "User switch disallowed while booting");
+ Slog.i(TAG, "User switch disallowed while booting");
} else {
// The system is resuming after a suspension. Optionally disable user switching.
allowUserSwitch = !mDisableUserSwitchDuringResume;
mIsBooting = false;
mIsResuming = false;
if (!allowUserSwitch) {
- Log.i(CarLog.TAG_POWER, "User switch disallowed while resuming");
+ Slog.i(TAG, "User switch disallowed while resuming");
}
}
}
@@ -422,7 +447,7 @@
try {
switchUserOnResumeIfNecessary(allowUserSwitch);
} catch (Exception e) {
- Log.e(CarLog.TAG_POWER, "Could not switch user on resume", e);
+ Slog.e(TAG, "Could not switch user on resume", e);
}
setVoiceInteractionDisabled(false);
@@ -430,7 +455,7 @@
@VisibleForTesting // Ideally it should not be exposed, but it speeds up the unit tests
void switchUserOnResumeIfNecessary(boolean allowSwitching) {
- Log.d(TAG, "switchUserOnResumeIfNecessary(): allowSwitching=" + allowSwitching
+ Slog.d(TAG, "switchUserOnResumeIfNecessary(): allowSwitching=" + allowSwitching
+ ", mSwitchGuestUserBeforeSleep=" + mSwitchGuestUserBeforeSleep);
if (!allowSwitching) {
if (mSwitchGuestUserBeforeSleep) { // already handled
@@ -461,16 +486,10 @@
int currentUserId = ActivityManager.getCurrentUser();
UserInfo currentUser = mUserManager.getUserInfo(currentUserId);
- UserInfo newUser = mInitialUserSetter.replaceGuestIfNeeded(currentUser);
- if (newUser == currentUser) return; // Not a guest
+ if (!mInitialUserSetter.canReplaceGuestUser(currentUser)) return; // Not a guest
- boolean replaceGuest = !mSwitchGuestUserBeforeSleep;
- if (newUser == null) {
- Log.w(TAG, "Failed to replace guest; falling back to default behavior");
- executeDefaultInitialUserBehavior(replaceGuest);
- return;
- }
- switchUser(newUser.id, replaceGuest);
+ mInitialUserSetter.set(newInitialUserInfoBuilder(InitialUserSetter.TYPE_REPLACE_GUEST)
+ .build());
}
private void switchUser(@UserIdInt int userId, boolean replaceGuest) {
@@ -499,7 +518,7 @@
* Switches the initial user by calling the User HAL to define the behavior.
*/
private void switchUserOnResumeIfNecessaryUsingHal() {
- Log.i(TAG, "Using User HAL to define initial user behavior");
+ Slog.i(TAG, "Using User HAL to define initial user behavior");
mUserService.getInitialUserInfo(InitialUserInfoRequestType.RESUME, (status, response) -> {
switch (status) {
case HalCallback.STATUS_HAL_RESPONSE_TIMEOUT:
@@ -523,12 +542,12 @@
boolean replaceGuest = !mSwitchGuestUserBeforeSleep;
switch (response.action) {
case InitialUserInfoResponseAction.DEFAULT:
- Log.i(TAG, "HAL requested default initial user behavior");
+ Slog.i(TAG, "HAL requested default initial user behavior");
executeDefaultInitialUserBehavior(replaceGuest);
return;
case InitialUserInfoResponseAction.SWITCH:
int userId = response.userToSwitchOrCreate.userId;
- Log.i(TAG, "HAL requested switch to user " + userId);
+ Slog.i(TAG, "HAL requested switch to user " + userId);
// If guest was replaced on shutdown, it doesn't need to be replaced
// again
switchUser(userId, replaceGuest);
@@ -536,7 +555,7 @@
case InitialUserInfoResponseAction.CREATE:
int halFlags = response.userToSwitchOrCreate.flags;
String name = response.userNameToCreate;
- Log.i(TAG, "HAL requested new user (name="
+ Slog.i(TAG, "HAL requested new user (name="
+ UserHelper.safeName(name) + ", flags="
+ UserHalHelper.userFlagsToString(halFlags) + ")");
mInitialUserSetter
@@ -560,7 +579,7 @@
* Switches the initial user directly when the User HAL call failed.
*/
private void switchUserOnResumeUserHalFallback(String reason) {
- Log.w(TAG, "Failed to set initial user based on User Hal (" + reason
+ Slog.w(TAG, "Failed to set initial user based on User Hal (" + reason
+ "); falling back to default behavior");
executeDefaultInitialUserBehavior(!mSwitchGuestUserBeforeSleep);
}
@@ -576,7 +595,7 @@
|| !newState.mCanSleep;
mGarageModeShouldExitImmediately = !newState.mCanPostpone;
}
- Log.i(CarLog.TAG_POWER,
+ Slog.i(TAG,
(newState.mCanPostpone
? "starting shutdown prepare with Garage Mode"
: "starting shutdown prepare without Garage Mode"));
@@ -588,7 +607,7 @@
// Simulate system shutdown to Deep Sleep
private void simulateShutdownPrepare() {
mSystemInterface.setDisplayState(false);
- Log.i(CarLog.TAG_POWER, "starting shutdown prepare");
+ Slog.i(TAG, "starting shutdown prepare");
sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE);
mHal.sendShutdownPrepare();
doHandlePreprocessing();
@@ -627,15 +646,18 @@
if (forceReboot) {
PowerManager powerManager = mContext.getSystemService(PowerManager.class);
if (powerManager == null) {
- Log.wtf(CarLog.TAG_POWER, "No PowerManager. Cannot reboot.");
+ Slog.wtf(TAG, "No PowerManager. Cannot reboot.");
} else {
- Log.i(CarLog.TAG_POWER, "GarageMode has completed. Forcing reboot.");
+ Slog.i(TAG, "GarageMode has completed. Forcing reboot.");
powerManager.reboot("GarageModeReboot");
throw new AssertionError("Should not return from PowerManager.reboot()");
}
}
setVoiceInteractionDisabled(true);
+ // To make Kernel implementation simpler when going into sleep.
+ disableWifi();
+
if (mustShutDown) {
// shutdown HU
mSystemInterface.shutdown();
@@ -649,10 +671,83 @@
try {
mVoiceInteractionManagerService.setDisabled(disabled);
} catch (RemoteException e) {
- Log.w(TAG, "setVoiceIntefactionDisabled(" + disabled + ") failed", e);
+ Slog.w(TAG, "setVoiceIntefactionDisabled(" + disabled + ") failed", e);
}
}
+ private void restoreWifi() {
+ boolean needToRestore = readWifiModifiedState();
+ if (needToRestore) {
+ if (!mWifiManager.isWifiEnabled()) {
+ Slog.i(TAG, "Wifi has been enabled to restore the last setting");
+ mWifiManager.setWifiEnabled(true);
+ }
+ // Update the persistent data as wifi is not modified by car framework.
+ saveWifiModifiedState(false);
+ }
+ }
+
+ private void disableWifi() {
+ boolean wifiEnabled = mWifiManager.isWifiEnabled();
+ boolean wifiModifiedState = readWifiModifiedState();
+ if (wifiEnabled != wifiModifiedState) {
+ saveWifiModifiedState(wifiEnabled);
+ }
+ if (!wifiEnabled) return;
+
+ mWifiManager.setWifiEnabled(false);
+ wifiEnabled = mWifiManager.isWifiEnabled();
+ Slog.i(TAG, "Wifi has been disabled and the last setting was saved");
+ }
+
+ private void saveWifiModifiedState(boolean forciblyDisabled) {
+ FileOutputStream fos;
+ try {
+ fos = mWifiStateFile.startWrite();
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot create " + WIFI_STATE_FILENAME, e);
+ return;
+ }
+
+ try (BufferedWriter writer = new BufferedWriter(
+ new OutputStreamWriter(fos, StandardCharsets.UTF_8))) {
+ writer.write(forciblyDisabled ? WIFI_STATE_MODIFIED : WIFI_STATE_ORIGINAL);
+ writer.newLine();
+ writer.flush();
+ mWifiStateFile.finishWrite(fos);
+ } catch (IOException e) {
+ mWifiStateFile.failWrite(fos);
+ Slog.e(TAG, "Writing " + WIFI_STATE_FILENAME + " failed", e);
+ }
+ }
+
+ private boolean readWifiModifiedState() {
+ boolean needToRestore = false;
+ boolean invalidState = false;
+
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(mWifiStateFile.openRead(), StandardCharsets.UTF_8))) {
+ String line = reader.readLine();
+ if (line == null) {
+ needToRestore = false;
+ invalidState = true;
+ } else {
+ line = line.trim();
+ needToRestore = WIFI_STATE_MODIFIED.equals(line);
+ invalidState = !(needToRestore || WIFI_STATE_ORIGINAL.equals(line));
+ }
+ } catch (IOException e) {
+ // If a file named wifi_state doesn't exist, we will not modify Wifi at system start.
+ Slog.w(TAG, "Failed to read " + WIFI_STATE_FILENAME + ": " + e);
+ return false;
+ }
+ if (invalidState) {
+ mWifiStateFile.delete();
+ }
+
+ return needToRestore;
+ }
+
@GuardedBy("mLock")
private void releaseTimerLocked() {
if (mTimer != null) {
@@ -676,12 +771,11 @@
pollingCount =
(shutdownPrepareTimeOverrideInSecs * 1000 / intervalMs)
+ 1;
- Log.i(CarLog.TAG_POWER,
- "Garage mode duration overridden secs:"
- + shutdownPrepareTimeOverrideInSecs);
+ Slog.i(TAG, "Garage mode duration overridden secs:"
+ + shutdownPrepareTimeOverrideInSecs);
}
}
- Log.i(CarLog.TAG_POWER, "processing before shutdown expected for: "
+ Slog.i(TAG, "processing before shutdown expected for: "
+ mShutdownPrepareTimeMs + " ms, adding polling:" + pollingCount);
synchronized (mLock) {
mProcessingStartTime = SystemClock.elapsedRealtime();
@@ -743,7 +837,7 @@
listener.onStateChanged(newState);
} catch (RemoteException e) {
// It's likely the connection snapped. Let binder death handle the situation.
- Log.e(CarLog.TAG_POWER, "onStateChanged() call failed", e);
+ Slog.e(TAG, "onStateChanged() call failed", e);
}
}
listenerList.finishBroadcast();
@@ -776,7 +870,7 @@
// Any wakeup time from before is no longer valid.
mNextWakeupSec = 0;
}
- Log.i(CarLog.TAG_POWER, "Resuming after suspending");
+ Slog.i(TAG, "Resuming after suspending");
mSystemInterface.refreshDisplayBrightness();
onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState);
}
@@ -785,8 +879,7 @@
if (mCurrentState == null) {
return true;
} else if (mCurrentState.equals(newState)) {
- Log.d(CarLog.TAG_POWER, "Requested state is already in effect: "
- + newState.name());
+ Slog.d(TAG, "Requested state is already in effect: " + newState.name());
return false;
}
@@ -820,12 +913,12 @@
|| newState.mState == CpmsState.WAIT_FOR_VHAL);
break;
default:
- Log.e(CarLog.TAG_POWER, "Unexpected current state: currentState="
+ Slog.e(TAG, "Unexpected current state: currentState="
+ mCurrentState.name() + ", newState=" + newState.name());
transitionAllowed = true;
}
if (!transitionAllowed) {
- Log.e(CarLog.TAG_POWER, "Requested power transition is not allowed: "
+ Slog.e(TAG, "Requested power transition is not allowed: "
+ mCurrentState.name() + " --> " + newState.name());
}
return transitionAllowed;
@@ -837,7 +930,7 @@
releaseTimerLocked();
if (!mShutdownOnFinish && mLastSleepEntryTime > mProcessingStartTime) {
// entered sleep after processing start. So this could be duplicate request.
- Log.w(CarLog.TAG_POWER, "Duplicate sleep entry request, ignore");
+ Slog.w(TAG, "Duplicate sleep entry request, ignore");
return;
}
listenerState = mShutdownOnFinish
@@ -857,7 +950,7 @@
}
private void doHandleMainDisplayStateChange(boolean on) {
- Log.w(CarLog.TAG_POWER, "Unimplemented: doHandleMainDisplayStateChange() - on = " + on);
+ Slog.w(TAG, "Unimplemented: doHandleMainDisplayStateChange() - on = " + on);
}
public void handleMainDisplayChanged(boolean on) {
@@ -934,13 +1027,13 @@
public void scheduleNextWakeupTime(int seconds) {
ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
if (seconds < 0) {
- Log.w(CarLog.TAG_POWER, "Next wake up time is negative. Ignoring!");
+ Slog.w(TAG, "Next wake up time is negative. Ignoring!");
return;
}
boolean timedWakeupAllowed = mHal.isTimedWakeupAllowed();
synchronized (mLock) {
if (!timedWakeupAllowed) {
- Log.w(CarLog.TAG_POWER, "Setting timed wakeups are disabled in HAL. Skipping");
+ Slog.w(TAG, "Setting timed wakeups are disabled in HAL. Skipping");
mNextWakeupSec = 0;
return;
}
@@ -948,7 +1041,7 @@
// The new value is sooner than the old value. Take the new value.
mNextWakeupSec = seconds;
} else {
- Log.d(CarLog.TAG_POWER, "Tried to schedule next wake up, but already had shorter "
+ Slog.d(TAG, "Tried to schedule next wake up, but already had shorter "
+ "scheduled time");
}
}
@@ -983,13 +1076,13 @@
if (!mShutdownOnFinish) {
if (mLastSleepEntryTime > mProcessingStartTime
&& mLastSleepEntryTime < SystemClock.elapsedRealtime()) {
- Log.i(CarLog.TAG_POWER, "signalComplete: Already slept!");
+ Slog.i(TAG, "signalComplete: Already slept!");
return;
}
}
powerHandler = mHandler;
}
- Log.i(CarLog.TAG_POWER, "Apps are finished, call handleProcessingComplete()");
+ Slog.i(TAG, "Apps are finished, call handleProcessingComplete()");
powerHandler.handleProcessingComplete();
}
}
@@ -1050,7 +1143,7 @@
public void handleMessage(Message msg) {
CarPowerManagementService service = mService.get();
if (service == null) {
- Log.i(TAG, "handleMessage null service");
+ Slog.i(TAG, "handleMessage null service");
return;
}
switch (msg.what) {
@@ -1100,32 +1193,44 @@
}
// Send the command to enter Suspend to RAM.
- // If the command is not successful, try again.
+ // If the command is not successful, try again with an exponential back-off.
// If it fails repeatedly, send the command to shut down.
+ // If we decide to go to a different power state, abort this retry mechanism.
// Returns true if we successfully suspended.
private boolean suspendWithRetries() {
- final int maxTries = 3;
- final long retryIntervalMs = 10;
+ long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS;
int tryCount = 0;
while (true) {
- Log.i(CarLog.TAG_POWER, "Entering Suspend to RAM");
+ Slog.i(TAG, "Entering Suspend to RAM");
boolean suspendSucceeded = mSystemInterface.enterDeepSleep();
if (suspendSucceeded) {
return true;
}
tryCount++;
- if (tryCount >= maxTries) {
+ if (tryCount >= MAX_SUSPEND_TRIES) {
break;
}
// We failed to suspend. Block the thread briefly and try again.
- Log.w(CarLog.TAG_POWER, "Failed to Suspend; will retry later.");
- try {
- Thread.sleep(retryIntervalMs);
- } catch (InterruptedException ignored) { }
+ synchronized (mLock) {
+ if (mPendingPowerStates.isEmpty()) {
+ Slog.w(TAG, "Failed to Suspend; will retry later.");
+ try {
+ mLock.wait(retryIntervalMs);
+ } catch (InterruptedException ignored) {
+ Thread.currentThread().interrupt();
+ }
+ retryIntervalMs *= 2;
+ }
+ // Check for a new power state now, before going around the loop again
+ if (!mPendingPowerStates.isEmpty()) {
+ Slog.i(TAG, "Terminating the attempt to Suspend to RAM");
+ return false;
+ }
+ }
}
// Too many failures trying to suspend. Shut down.
- Log.w(CarLog.TAG_POWER, "Could not Suspend to RAM. Shutting down.");
+ Slog.w(TAG, "Could not Suspend to RAM. Shutting down.");
mSystemInterface.shutdown();
return false;
}
@@ -1270,6 +1375,7 @@
// Cancel Garage Mode in case it's running
mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL,
CarPowerStateListener.SHUTDOWN_CANCELLED));
+ mLock.notify();
handler = mHandler;
}
handler.handlePowerStateChange();
@@ -1312,7 +1418,7 @@
// We simulate this behavior by calling wait().
// We continue from wait() when forceSimulatedResume() is called.
private void simulateSleepByWaiting() {
- Log.i(CarLog.TAG_POWER, "Starting to simulate Deep Sleep by waiting");
+ Slog.i(TAG, "Starting to simulate Deep Sleep by waiting");
synchronized (mSimulationWaitObject) {
while (!mWakeFromSimulatedSleep) {
try {
@@ -1323,6 +1429,6 @@
}
mInSimulatedDeepSleepMode = false;
}
- Log.i(CarLog.TAG_POWER, "Exit Deep Sleep simulation");
+ Slog.i(TAG, "Exit Deep Sleep simulation");
}
}
diff --git a/service/src/com/android/car/CarShellCommand.java b/service/src/com/android/car/CarShellCommand.java
index e1282ab..2ccf858 100644
--- a/service/src/com/android/car/CarShellCommand.java
+++ b/service/src/com/android/car/CarShellCommand.java
@@ -348,12 +348,13 @@
pw.println("\tdisable-feature featureName");
pw.println("\t Disable the requested feature. Change will happen after reboot");
pw.println("\t This requires root/su.");
- pw.println("\tinject-key [-d display] [-t down_delay_ms] key_code");
- pw.println("\t inject key down / up event to car service");
+ pw.println("\tinject-key [-d display] [-t down_delay_ms | -a down|up] key_code");
+ pw.println("\t inject key down and/or up event to car service");
pw.println("\t display: 0 for main, 1 for cluster. If not specified, it will be 0.");
pw.println("\t down_delay_ms: delay from down to up key event. If not specified,");
pw.println("\t it will be 0");
pw.println("\t key_code: int key code defined in android KeyEvent");
+ pw.println("\t If -a isn't specified, both down and up will be injected.");
pw.println("\tinject-rotary [-d display] [-i input_type] [-c clockwise]");
pw.println("\t [-dt delta_times_ms]");
pw.println("\t inject rotary input event to car service.");
@@ -557,7 +558,7 @@
break;
case COMMAND_SUSPEND:
mCarPowerManagementService.forceSuspendAndMaybeReboot(false);
- writer.println("Resume: Simulating powering down to Deep Sleep");
+ writer.println("Suspend: Simulating powering down to Deep Sleep");
break;
case COMMAND_ENABLE_TRUSTED_DEVICE:
if (args.length != 2) {
@@ -740,6 +741,7 @@
int display = InputHalService.DISPLAY_MAIN;
int delayMs = 0;
int keyCode = KeyEvent.KEYCODE_UNKNOWN;
+ int action = -1;
try {
while (i < args.length) {
switch (args[i]) {
@@ -751,6 +753,16 @@
i++;
delayMs = Integer.parseInt(args[i]);
break;
+ case "-a":
+ i++;
+ if (args[i].equalsIgnoreCase("down")) {
+ action = KeyEvent.ACTION_DOWN;
+ } else if (args[i].equalsIgnoreCase("up")) {
+ action = KeyEvent.ACTION_UP;
+ } else {
+ throw new IllegalArgumentException("Invalid action: " + args[i]);
+ }
+ break;
default:
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
throw new IllegalArgumentException("key_code already set:"
@@ -782,14 +794,20 @@
return;
}
- KeyEvent keyDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
- mCarInputService.onKeyEvent(keyDown, display);
- SystemClock.sleep(delayMs);
- KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
- mCarInputService.onKeyEvent(keyUp, display);
+ if (action == -1) {
+ injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, display);
+ SystemClock.sleep(delayMs);
+ injectKeyEvent(KeyEvent.ACTION_UP, keyCode, display);
+ } else {
+ injectKeyEvent(action, keyCode, display);
+ }
writer.println("Succeeded");
}
+ private void injectKeyEvent(int action, int keyCode, int display) {
+ mCarInputService.onKeyEvent(new KeyEvent(action, keyCode), display);
+ }
+
private void injectRotary(String[] args, PrintWriter writer) {
int i = 1; // 0 is command itself
int display = InputHalService.DISPLAY_MAIN;
diff --git a/service/src/com/android/car/am/FixedActivityService.java b/service/src/com/android/car/am/FixedActivityService.java
index 38e31d1..81bc470 100644
--- a/service/src/com/android/car/am/FixedActivityService.java
+++ b/service/src/com/android/car/am/FixedActivityService.java
@@ -17,6 +17,7 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.os.Process.INVALID_UID;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static com.android.car.CarLog.TAG_AM;
@@ -26,7 +27,9 @@
import android.app.ActivityManager;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.IProcessObserver;
import android.app.Presentation;
import android.app.TaskStackListener;
@@ -58,6 +61,7 @@
import com.android.car.R;
import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
import java.util.List;
@@ -127,6 +131,7 @@
private final Context mContext;
private final IActivityManager mAm;
+ private final IActivityTaskManager mAtm;
private final DisplayManager mDm;
@@ -148,8 +153,9 @@
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
- || Intent.ACTION_PACKAGE_REPLACED.equals(
- action)) {
+ || Intent.ACTION_PACKAGE_REPLACED.equals(action)
+ || Intent.ACTION_PACKAGE_ADDED.equals(action)
+ || Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
Uri packageData = intent.getData();
if (packageData == null) {
Log.w(TAG_AM, "null packageData");
@@ -166,15 +172,15 @@
synchronized (mLock) {
for (int i = 0; i < mRunningActivities.size(); i++) {
RunningActivityInfo info = mRunningActivities.valueAt(i);
- ComponentName component = info.intent.getComponent();
- // should do this for all activities as the same package can cover multiple
- // displays.
- if (packageName.equals(component.getPackageName())
- && info.userId == userId) {
- Log.i(TAG_AM, "Package updated:" + packageName
- + ",user:" + userId);
+ // Should do this for all activities as it can happen for multiple
+ // displays. Package name is ignored as one package can affect
+ // others.
+ if (info.userId == userId) {
+ Log.i(TAG_AM, "Package changed:" + packageName
+ + ",user:" + userId + ",action:" + action);
info.resetCrashCounterLocked();
tryLaunch = true;
+ break;
}
}
}
@@ -211,8 +217,47 @@
public void onTaskRemovalStarted(int taskId) {
launchIfNecessary();
}
+
+ @Override
+ public void onTaskFocusChanged(int taskId, boolean focused) {
+ handleTaskFocusChanged(taskId, focused);
+ }
};
+ @VisibleForTesting
+ void handleTaskFocusChanged(int taskId, boolean focused) {
+ if (DBG) Log.d(TAG_AM, "handleTaskFocusChanged taskId=" + taskId + ", focused=" + focused);
+ if (!focused) {
+ return; // We don't care the focus losing events.
+ }
+ synchronized (mLock) {
+ for (int i = mRunningActivities.size() - 1; i >= 0; i--) {
+ RunningActivityInfo info = mRunningActivities.valueAt(i);
+ if (DBG) Log.d(TAG_AM, "Checking " + info);
+ if (info.taskId == taskId) {
+ moveFocusBackToDefaultDisplay(taskId);
+ return;
+ }
+ }
+ }
+ }
+
+ private void moveFocusBackToDefaultDisplay(int taskId) {
+ try {
+ List<StackInfo> tasks = mAtm.getAllStackInfosOnDisplay(Display.DEFAULT_DISPLAY);
+ if (tasks.size() == 0) return;
+ StackInfo topStack = tasks.get(0);
+ int topTaskIdInDefaultDisplay = topStack.taskIds[topStack.taskIds.length - 1];
+ if (DBG) {
+ Log.d(TAG_AM, "FixedActivity #" + taskId + " got the focus, return back to #"
+ + topTaskIdInDefaultDisplay);
+ }
+ mAtm.setFocusedTask(topTaskIdInDefaultDisplay);
+ } catch (RemoteException e) {
+ Log.e(TAG_AM, "remote exception from ATM", e);
+ }
+ }
+
private final IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
@Override
public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
@@ -266,14 +311,17 @@
};
public FixedActivityService(Context context) {
- this(context, ActivityManager.getService(), context.getSystemService(UserManager.class),
+ this(context, ActivityManager.getService(), ActivityTaskManager.getService(),
+ context.getSystemService(UserManager.class),
context.getSystemService(DisplayManager.class));
}
FixedActivityService(Context context, IActivityManager activityManager,
+ IActivityTaskManager activityTaskManager,
UserManager userManager, DisplayManager displayManager) {
mContext = context;
mAm = activityManager;
+ mAtm = activityTaskManager;
mUm = userManager;
mDm = displayManager;
mHandlerThread = CarServiceUtils.getHandlerThread(
@@ -337,6 +385,8 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
/* broadcastPermission= */ null, /* scheduler= */ null);
@@ -444,12 +494,23 @@
}
mBlockingPresentations.append(displayIdForActivity, p);
}
+ // Change the window type, since we can't show the Presentation window
+ // in the internal display.
+ p.getWindow().setType(TYPE_SYSTEM_DIALOG);
p.show();
});
}
mRunningActivities.removeAt(i);
}
+ int previousDisplayId = Display.INVALID_DISPLAY;
for (StackInfo stackInfo : infos) {
+ // In the current ATMS implementation which enumerates the display first, then
+ // enumerates the stack/task, so the tasks in the same display come consecutively.
+ if (stackInfo.displayId == previousDisplayId) {
+ // 2nd+ tasks, skip it.
+ continue;
+ }
+ previousDisplayId = stackInfo.displayId;
RunningActivityInfo activityInfo = mRunningActivities.get(stackInfo.displayId);
if (activityInfo == null) {
continue;
diff --git a/service/src/com/android/car/audio/CarAudioService.java b/service/src/com/android/car/audio/CarAudioService.java
index db081eb..bc67085 100644
--- a/service/src/com/android/car/audio/CarAudioService.java
+++ b/service/src/com/android/car/audio/CarAudioService.java
@@ -892,6 +892,10 @@
*
* @param zoneId The audio zone id
* @param uid The uid to map
+ *
+ * <p><b>Note:</b> Will throw if occupant zone mapping exist, as uid and occupant zone mapping
+ * do not work in conjunction.
+ *
* @return true if the device affinities, for devices in zone, are successfully set
*/
@Override
@@ -905,6 +909,9 @@
+ uid + " mapped to : "
+ zoneId);
+ // If occupant mapping exist uid routing can not be used
+ requiredOccupantZoneMappingDisabledLocked();
+
// Figure out if anything is currently holding focus,
// This will change the focus to transient loss while we are switching zones
Integer currentZoneId = mUidToZoneMap.get(uid);
@@ -985,6 +992,10 @@
/**
* Removes the current mapping of the uid, focus will be lost in zone
* @param uid The uid to remove
+ *
+ * <p><b>Note:</b> Will throw if occupant zone mapping exist, as uid and occupant zone mapping
+ * do not work in conjunction.
+ *
* return true if all the devices affinities currently
* mapped to uid are successfully removed
*/
@@ -993,6 +1004,10 @@
enforcePermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS);
requireDynamicRouting();
synchronized (mImplLock) {
+ // Throw so as to not set the wrong expectation,
+ // that routing will be changed if clearZoneIdForUid is called.
+ requiredOccupantZoneMappingDisabledLocked();
+
return checkAndRemoveUidLocked(uid);
}
}
@@ -1083,6 +1098,13 @@
Preconditions.checkState(mUseDynamicRouting, "Dynamic routing is required");
}
+ private void requiredOccupantZoneMappingDisabledLocked() {
+ if (isOccupantZoneMappingAvailableLocked()) {
+ throw new IllegalStateException(
+ "UID based routing is not supported while using occupant zone mapping");
+ }
+ }
+
/**
* @return {@link AudioDevicePort} that handles the given car audio usage.
* Multiple usages may share one {@link AudioDevicePort}
@@ -1123,7 +1145,7 @@
private void handleOccupantZoneUserChanged() {
int driverUserId = mOccupantZoneService.getDriverUserId();
synchronized (mImplLock) {
- if (!isOccupantZoneMappingAvailable()) {
+ if (!isOccupantZoneMappingAvailableLocked()) {
//No occupant zone to audio zone mapping, re-adjust to settings driver.
for (int index = 0; index < mCarAudioZones.length; index++) {
CarAudioZone zone = mCarAudioZones[index];
@@ -1142,7 +1164,7 @@
}
}
- private boolean isOccupantZoneMappingAvailable() {
+ private boolean isOccupantZoneMappingAvailableLocked() {
return mAudioZoneIdToOccupantZoneIdMapping.size() > 0;
}
diff --git a/service/src/com/android/car/hal/InputHalService.java b/service/src/com/android/car/hal/InputHalService.java
index d6e3750..c39ba51 100644
--- a/service/src/com/android/car/hal/InputHalService.java
+++ b/service/src/com/android/car/hal/InputHalService.java
@@ -29,6 +29,7 @@
import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
+import android.view.Display;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -341,6 +342,9 @@
0 /* flags */,
InputDevice.SOURCE_CLASS_BUTTON);
+ if (display == DISPLAY_MAIN) {
+ event.setDisplayId(Display.DEFAULT_DISPLAY);
+ }
listener.onKeyEvent(event, display);
}
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index e4aeea8..1883a8a 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -942,7 +942,8 @@
halUser.flags = UserHalHelper.convertFlags(userInfo);
UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
- // Do not delete last admin user.
+ // check if the user is last admin user.
+ boolean isLastAdmin = false;
if (UserHalHelper.isAdmin(halUser.flags)) {
int size = usersInfo.existingUsers.size();
int totalAdminUsers = 0;
@@ -952,8 +953,7 @@
}
}
if (totalAdminUsers == 1) {
- return logAndGetResults(userId,
- UserRemovalResult.STATUS_TARGET_USER_IS_LAST_ADMIN_USER);
+ isLastAdmin = true;
}
}
@@ -970,7 +970,13 @@
mHal.removeUser(request);
}
- return logAndGetResults(userId, UserRemovalResult.STATUS_SUCCESSFUL);
+ if (isLastAdmin) {
+ Log.w(TAG_USER, "Last admin user successfully removed. UserId: " + userId);
+ }
+
+ return logAndGetResults(userId,
+ isLastAdmin ? UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED
+ : UserRemovalResult.STATUS_SUCCESSFUL);
}
private UserRemovalResult logAndGetResults(@UserIdInt int userId,
diff --git a/service/src/com/android/car/user/UserMetrics.java b/service/src/com/android/car/user/UserMetrics.java
index 62b9755..cd139cc 100644
--- a/service/src/com/android/car/user/UserMetrics.java
+++ b/service/src/com/android/car/user/UserMetrics.java
@@ -125,7 +125,6 @@
synchronized (mLock) {
mHalResponseTime = halResponseTime;
mFirstUserUnlockDuration.put(userId, duration);
- onUserUnlockedEventLocked(timestampMs, userId);
}
}
diff --git a/service/src/com/android/car/watchdog/CarWatchdogService.java b/service/src/com/android/car/watchdog/CarWatchdogService.java
index 8a1ebc7..488165f 100644
--- a/service/src/com/android/car/watchdog/CarWatchdogService.java
+++ b/service/src/com/android/car/watchdog/CarWatchdogService.java
@@ -34,6 +34,7 @@
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
import android.car.hardware.power.ICarPowerStateListener;
import android.car.watchdog.ICarWatchdogService;
+import android.car.watchdog.ICarWatchdogServiceCallback;
import android.car.watchdoglib.CarWatchdogDaemonHelper;
import android.content.Context;
import android.content.pm.UserInfo;
@@ -172,11 +173,11 @@
}
/**
- * Registers {@link android.automotive.watchdog. ICarWatchdogClient} to
+ * Registers {@link android.car.watchdog.ICarWatchdogServiceCallback} to
* {@link CarWatchdogService}.
*/
@Override
- public void registerClient(ICarWatchdogClient client, int timeout) {
+ public void registerClient(ICarWatchdogServiceCallback client, int timeout) {
ArrayList<ClientInfo> clients = mClientMap.get(timeout);
if (clients == null) {
Log.w(TAG, "Cannot register the client: invalid timeout");
@@ -210,11 +211,11 @@
}
/**
- * Unregisters {@link android.automotive.watchdog. ICarWatchdogClient} from
+ * Unregisters {@link android.car.watchdog.ICarWatchdogServiceCallback} from
* {@link CarWatchdogService}.
*/
@Override
- public void unregisterClient(ICarWatchdogClient client) {
+ public void unregisterClient(ICarWatchdogServiceCallback client) {
synchronized (mLock) {
IBinder binder = client.asBinder();
for (int timeout : ALL_TIMEOUTS) {
@@ -241,7 +242,7 @@
* Tells {@link CarWatchdogService} that the client is alive.
*/
@Override
- public void tellClientAlive(ICarWatchdogClient client, int sessionId) {
+ public void tellClientAlive(ICarWatchdogServiceCallback client, int sessionId) {
synchronized (mLock) {
for (int timeout : ALL_TIMEOUTS) {
if (!mClientCheckInProgress.get(timeout)) {
@@ -305,7 +306,7 @@
}
}
- private void onClientDeath(ICarWatchdogClient client, int timeout) {
+ private void onClientDeath(ICarWatchdogServiceCallback client, int timeout) {
synchronized (mLock) {
removeClientLocked(client.asBinder(), timeout);
}
@@ -363,7 +364,7 @@
for (int i = 0; i < clientsToCheck.size(); i++) {
ClientInfo clientInfo = clientsToCheck.get(i);
try {
- clientInfo.client.checkIfAlive(clientInfo.sessionId, timeout);
+ clientInfo.client.onCheckHealthStatus(clientInfo.sessionId, timeout);
} catch (RemoteException e) {
Log.w(TAG, "Sending a ping message to client(pid: " + clientInfo.pid
+ ") failed: " + e);
@@ -414,9 +415,9 @@
for (int i = 0; i < clientsToNotify.size(); i++) {
ClientInfo clientInfo = clientsToNotify.get(i);
try {
- clientInfo.client.prepareProcessTermination();
+ clientInfo.client.onPrepareProcessTermination();
} catch (RemoteException e) {
- Log.w(TAG, "Notifying prepareProcessTermination to client(pid: " + clientInfo.pid
+ Log.w(TAG, "Notifying onPrepareProcessTermination to client(pid: " + clientInfo.pid
+ ") failed: " + e);
}
}
@@ -589,13 +590,14 @@
}
private final class ClientInfo implements IBinder.DeathRecipient {
- public final ICarWatchdogClient client;
+ public final ICarWatchdogServiceCallback client;
public final int pid;
@UserIdInt public final int userId;
public final int timeout;
public volatile int sessionId;
- private ClientInfo(ICarWatchdogClient client, int pid, @UserIdInt int userId, int timeout) {
+ private ClientInfo(ICarWatchdogServiceCallback client, int pid, @UserIdInt int userId,
+ int timeout) {
this.client = client;
this.pid = pid;
this.userId = userId;
diff --git a/surround_view/app/sv_app.cpp b/surround_view/app/sv_app.cpp
index 2fe0c86..43369c2 100644
--- a/surround_view/app/sv_app.cpp
+++ b/surround_view/app/sv_app.cpp
@@ -50,6 +50,53 @@
DEMO_3D,
};
+const float kHorizontalFov = 90;
+
+// Number of views to generate.
+const uint32_t kPoseCount = 16;
+
+// Set of pose rotations expressed in quaternions.
+// Views are generated about a circle at a height about the car, point towards the center.
+const float kPoseRot[kPoseCount][4] = {
+ {-0.251292, -0.251292, -0.660948, 0.660948},
+ {0.197439, 0.295488, 0.777193, -0.519304},
+ {0.135998, 0.328329, 0.86357, -0.357702},
+ {0.0693313, 0.348552, 0.916761, -0.182355},
+ {-7.76709e-09, 0.355381, 0.934722, 2.0429e-08},
+ {-0.0693313, 0.348552, 0.916761, 0.182355},
+ {-0.135998, 0.328329, 0.86357, 0.357702},
+ {-0.197439, 0.295488, 0.777193, 0.519304},
+ {-0.251292, 0.251292, 0.660948, 0.660948},
+ {-0.295488, 0.197439, 0.519304, 0.777193},
+ {-0.328329, 0.135998, 0.357702, 0.86357},
+ {-0.348552, 0.0693313, 0.182355, 0.916761},
+ {-0.355381, -2.11894e-09, -5.57322e-09, 0.934722},
+ {-0.348552, -0.0693313, -0.182355, 0.916761},
+ {-0.328329, -0.135998, -0.357702, 0.86357},
+ {-0.295488, -0.197439, -0.519304, 0.777193}
+};
+
+// Set of pose translations i.e. positions of the views.
+// Views are generated about a circle at a height about the car, point towards the center.
+const float kPoseTrans[kPoseCount][4] = {
+ {4, 0, 2.5},
+ {3.69552, 1.53073, 2.5},
+ {2.82843, 2.82843, 2.5},
+ {1.53073, 3.69552, 2.5},
+ {-1.74846e-07, 4, 2.5},
+ {-1.53073, 3.69552, 2.5},
+ {-2.82843, 2.82843, 2.5},
+ {-3.69552, 1.53073, 2.5},
+ {-4, -3.49691e-07, 2.5},
+ {-3.69552, -1.53073, 2.5},
+ {-2.82843, -2.82843, 2.5},
+ {-1.53073, -3.69552, 2.5},
+ {4.76995e-08, -4, 2.5},
+ {1.53073, -3.69552, 2.5},
+ {2.82843, -2.82843, 2.5},
+ {3.69552, -1.53073, 2.5}
+};
+
bool run2dSurroundView(sp<ISurroundViewService> pSurroundViewService,
sp<IEvsDisplay> pDisplay) {
LOG(INFO) << "Run 2d Surround View demo";
@@ -108,6 +155,28 @@
return true;
};
+// Given a valid sv 3d session and pose, viewid and hfov parameters, sets the view.
+bool setView(sp<ISurroundView3dSession> surroundView3dSession, uint32_t viewId,
+ uint32_t poseIndex, float hfov)
+{
+ const View3d view3d = {
+ .viewId = viewId,
+ .pose = {
+ .rotation = {.x=kPoseRot[poseIndex][0], .y=kPoseRot[poseIndex][1],
+ .z=kPoseRot[poseIndex][2], .w=kPoseRot[poseIndex][3]},
+ .translation = {.x=kPoseTrans[poseIndex][0], .y=kPoseTrans[poseIndex][1],
+ .z=kPoseTrans[poseIndex][2]},
+ },
+ .horizontalFov = hfov,
+ };
+
+ const std::vector<View3d> views = {view3d};
+ if (surroundView3dSession->setViews(views) != SvResult::OK) {
+ return false;
+ }
+ return true;
+}
+
bool run3dSurroundView(sp<ISurroundViewService> pSurroundViewService,
sp<IEvsDisplay> pDisplay) {
LOG(INFO) << "Run 3d Surround View demo";
@@ -130,19 +199,15 @@
LOG(INFO) << "start3dSession succeeded";
}
- // TODO(b/150412555): now we have the dummy view here since the views are
- // set in service. This should be fixed.
- std::vector<View3d> singleView(1);
- surroundView3dSession->setViews(singleView);
-
- if (surroundView3dSession->setViews(singleView) != SvResult::OK) {
- LOG(ERROR) << "Failed to setViews";
- return false;
- }
-
sp<SurroundViewServiceCallback> sv3dCallback
= new SurroundViewServiceCallback(pDisplay, surroundView3dSession);
+ // A view must be set before the 3d stream is started.
+ if (!setView(surroundView3dSession, 0, 0, kHorizontalFov)) {
+ LOG(ERROR) << "Failed to setView of pose index :" << 0;
+ return false;
+ }
+
// Start 3d stream with callback
if (surroundView3dSession->startStream(sv3dCallback) != SvResult::OK) {
LOG(ERROR) << "Failed to start 3d stream";
@@ -150,7 +215,15 @@
}
// Let the SV algorithm run for 10 seconds for HIGH_QUALITY
- std::this_thread::sleep_for(std::chrono::seconds(10));
+ const int totalViewingTimeSecs = 10;
+ const std::chrono::milliseconds
+ perPoseSleepTimeMs(totalViewingTimeSecs * 1000 / kPoseCount);
+ for(uint32_t i = 1; i < kPoseCount; i++) {
+ if (!setView(surroundView3dSession, i, i, kHorizontalFov)) {
+ LOG(WARNING) << "Failed to setView of pose index :" << i;
+ }
+ std::this_thread::sleep_for(perPoseSleepTimeMs);
+ }
// Switch to low quality and lower resolution
Sv3dConfig config;
@@ -163,7 +236,12 @@
}
// Let the SV algorithm run for 10 seconds for LOW_QUALITY
- std::this_thread::sleep_for(std::chrono::seconds(10));
+ for(uint32_t i = 0; i < kPoseCount; i++) {
+ if(!setView(surroundView3dSession, i + kPoseCount, i, kHorizontalFov)) {
+ LOG(WARNING) << "Failed to setView of pose index :" << i;
+ }
+ std::this_thread::sleep_for(perPoseSleepTimeMs);
+ }
// TODO(b/150412555): wait for the last frame
// Stop the 3d stream and session
diff --git a/surround_view/service-impl/Android.bp b/surround_view/service-impl/Android.bp
index 7580795..d05c4d8 100644
--- a/surround_view/service-impl/Android.bp
+++ b/surround_view/service-impl/Android.bp
@@ -156,7 +156,6 @@
vendor : true,
srcs : [
"CameraUtils.cpp",
- "CoreLibSetupHelper.cpp",
"SurroundView2dSession.cpp",
"SurroundView3dSession.cpp",
],
diff --git a/surround_view/service-impl/CoreLibSetupHelper.cpp b/surround_view/service-impl/CoreLibSetupHelper.cpp
deleted file mode 100644
index 4812efe..0000000
--- a/surround_view/service-impl/CoreLibSetupHelper.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "CoreLibSetupHelper.h"
-
-using namespace android_auto::surround_view;
-
-namespace android_auto {
-namespace surround_view {
-
-vector<SurroundViewCameraParams> GetCameras() {
- std::vector<android_auto::surround_view::SurroundViewCameraParams> cameras;
-
- // Camera 1.
- {
- android_auto::surround_view::SurroundViewCameraParams camera_params;
-
- camera_params.intrinsics[0] = 608.0026093794693;
- camera_params.intrinsics[1] = 0.0;
- camera_params.intrinsics[2] = 968.699544102168;
- camera_params.intrinsics[3] = 0.0;
- camera_params.intrinsics[4] = 608.205469489769;
- camera_params.intrinsics[5] = 476.38843298898996;
- camera_params.intrinsics[6] = 0.0;
- camera_params.intrinsics[7] = 0.0;
- camera_params.intrinsics[8] = 1.0;
-
- camera_params.distorion[0] = -0.03711481733589263;
- camera_params.distorion[1] = -0.0014805627895442888;
- camera_params.distorion[2] = -0.00030212056866592464;
- camera_params.distorion[3] = -0.00020149538570397933;
-
- camera_params.rvec[0] = 2.26308;
- camera_params.rvec[1] = 0.0382788;
- camera_params.rvec[2] = -0.0220549;
-
- camera_params.tvec[0] = -7.8028875403817685e-02;
- camera_params.tvec[1] = 1.4537396465103221e+00;
- camera_params.tvec[2] = -8.4197165554645001e-02;
-
- camera_params.size.width = 1920;
- camera_params.size.height = 1024;
-
- camera_params.circular_fov = 179;
-
- cameras.push_back(camera_params);
- }
-
- // Camera 2.
- {
- android_auto::surround_view::SurroundViewCameraParams camera_params;
-
- camera_params.intrinsics[0] = 607.8691721095306;
- camera_params.intrinsics[1] = 0.0;
- camera_params.intrinsics[2] = 975.5686146375716;
- camera_params.intrinsics[3] = 0.0;
- camera_params.intrinsics[4] = 608.0112887189435;
- camera_params.intrinsics[5] = 481.1938786570715;
- camera_params.intrinsics[6] = 0.0;
- camera_params.intrinsics[7] = 0.0;
- camera_params.intrinsics[8] = 1.0;
-
- camera_params.distorion[0] = -0.040116809827977926;
- camera_params.distorion[1] = 0.0028769489398543014;
- camera_params.distorion[2] = -0.002651039958977229;
- camera_params.distorion[3] = 0.00024260630476736675;
-
- camera_params.rvec[0] = 1.67415;
- camera_params.rvec[1] = -1.74075;
- camera_params.rvec[2] = 0.789399;
-
- camera_params.tvec[0] = 2.9715052384687407e-01;
- camera_params.tvec[1] = 1.1407102692699396e+00;
- camera_params.tvec[2] = 3.0074545273489206e-01;
-
- camera_params.size.width = 1920;
- camera_params.size.height = 1024;
-
- camera_params.circular_fov = 179;
-
- cameras.push_back(camera_params);
- }
-
- // Camera 3.
- {
- android_auto::surround_view::SurroundViewCameraParams camera_params;
-
- camera_params.intrinsics[0] = 608.557299289448;
- camera_params.intrinsics[1] = 0.0;
- camera_params.intrinsics[2] = 960.1949354417656;
- camera_params.intrinsics[3] = 0.0;
- camera_params.intrinsics[4] = 608.8093878512448;
- camera_params.intrinsics[5] = 474.74744054048256;
- camera_params.intrinsics[6] = 0.0;
- camera_params.intrinsics[7] = 0.0;
- camera_params.intrinsics[8] = 1.0;
-
- camera_params.distorion[0] = -0.03998488563470043;
- camera_params.distorion[1] = 0.0024786686909103388;
- camera_params.distorion[2] = -0.002354736769480817;
- camera_params.distorion[3] = 0.00018369619088506146;
-
- camera_params.rvec[0] = -0.106409;
- camera_params.rvec[1] = -2.83697;
- camera_params.rvec[2] = 1.28629;
-
- camera_params.tvec[0] = 1.7115269161259747e-01;
- camera_params.tvec[1] = 1.4376160762596599e+00;
- camera_params.tvec[2] = -1.9028844233159006e-02;
-
- camera_params.size.width = 1920;
- camera_params.size.height = 1024;
-
- camera_params.circular_fov = 179;
-
- cameras.push_back(camera_params);
- }
-
- // Camera 4.
- {
- android_auto::surround_view::SurroundViewCameraParams camera_params;
-
- camera_params.intrinsics[0] = 608.1221963545495;
- camera_params.intrinsics[1] = 0.0;
- camera_params.intrinsics[2] = 943.6280444638576;
- camera_params.intrinsics[3] = 0.0;
- camera_params.intrinsics[4] = 608.0523818661524;
- camera_params.intrinsics[5] = 474.8564698210861;
- camera_params.intrinsics[6] = 0.0;
- camera_params.intrinsics[7] = 0.0;
- camera_params.intrinsics[8] = 1.0;
-
- camera_params.distorion[0] = -0.038096507459563965;
- camera_params.distorion[1] = 0.0004008114278766646;
- camera_params.distorion[2] = -0.0013549275607082035;
- camera_params.distorion[3] = -5.9961182248325556e-06;
-
- camera_params.rvec[0] = 1.63019;
- camera_params.rvec[1] = 1.76475;
- camera_params.rvec[2] = -0.827941;
-
- camera_params.tvec[0] = -3.0842691427126512e-01;
- camera_params.tvec[1] = 1.0884122033556984e+00;
- camera_params.tvec[2] = 3.4419058255954926e-01;
-
- camera_params.size.width = 1920;
- camera_params.size.height = 1024;
-
- camera_params.circular_fov = 179;
-
- cameras.push_back(camera_params);
- }
- return cameras;
-
-}
-
-SurroundView2dParams Get2dParams() {
- android_auto::surround_view::Size2dInteger
- resolution{ /*width=*/ 1024, /*height*/ 768};
- // make sure resolution has the same ratio with physical_size.
- // {480 *360 }
- android_auto::surround_view::Size2dFloat physical_size{8.0, 6.0};
- android_auto::surround_view::Coordinate2dFloat physical_center{0, 0};
-
- return android_auto::surround_view::SurroundView2dParams(
- resolution, physical_size, physical_center);
-}
-
-SurroundView3dParams Get3dParams() {
- return android_auto::surround_view::SurroundView3dParams(
- /*plane_radius=*/ 8.0f,
- /*plane_divisions=*/ 50,
- /*curve_height=*/ 6.0f,
- /*curve_divisions=*/ 50,
- /*angular_divisions=*/ 90,
- /*curve_coefficient=*/ 3.0f,
- /*resolution=*/ Size2dInteger(1024, 768));
-}
-
-BoundingBox GetBoundingBox() {
- return android_auto::surround_view::BoundingBox(
- /*x=*/ -0.01f,
- /*y=*/ 0.01f,
- /*width=*/ 0.01f,
- /*height=*/ 0.01f);
-}
-
-vector<float> GetUndistortionScales() {
- return vector<float>{1.0f, 1.0f, 1.0f, 1.0f};
-}
-
-
-} // namespace surround_view
-} // namespace audroid_auto
-
diff --git a/surround_view/service-impl/CoreLibSetupHelper.h b/surround_view/service-impl/CoreLibSetupHelper.h
deleted file mode 100644
index 889ebf2..0000000
--- a/surround_view/service-impl/CoreLibSetupHelper.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include "core_lib.h"
-
-using namespace std;
-
-// TODO(b/150412555): The helper method should only be used for testing
-// purposes once EVS camera is used.
-namespace android_auto {
-namespace surround_view {
-
-vector<SurroundViewCameraParams> GetCameras();
-
-SurroundView2dParams Get2dParams();
-
-SurroundView3dParams Get3dParams();
-
-BoundingBox GetBoundingBox();
-
-vector<float> GetUndistortionScales();
-
-} // namespace surround_view
-} // namespace android_auto
-
diff --git a/surround_view/service-impl/README b/surround_view/service-impl/README
deleted file mode 100644
index d7b5e7c..0000000
--- a/surround_view/service-impl/README
+++ /dev/null
@@ -1 +0,0 @@
-The core_lib.h and the .so files are copied from google3 at Mar 19, 2020.
diff --git a/surround_view/service-impl/SurroundView2dSession.cpp b/surround_view/service-impl/SurroundView2dSession.cpp
index b50049c..cbf652e 100644
--- a/surround_view/service-impl/SurroundView2dSession.cpp
+++ b/surround_view/service-impl/SurroundView2dSession.cpp
@@ -27,6 +27,18 @@
#include "CameraUtils.h"
+using ::std::adopt_lock;
+using ::std::lock;
+using ::std::lock_guard;
+using ::std::map;
+using ::std::mutex;
+using ::std::scoped_lock;
+using ::std::string;
+using ::std::thread;
+using ::std::unique_lock;
+using ::std::unique_ptr;
+using ::std::vector;
+
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using ::android::hardware::camera::device::V3_2::Stream;
@@ -50,11 +62,13 @@
int32_t framerate;
} RawStreamConfig;
-static const size_t kStreamCfgSz = sizeof(RawStreamConfig);
+static const size_t kStreamCfgSz = sizeof(RawStreamConfig) / sizeof(int32_t);
static const uint8_t kGrayColor = 128;
-static const int kNumChannels = 3;
+static const int kInputNumChannels = 4;
+static const int kOutputNumChannels = 3;
static const int kNumFrames = 4;
static const int kSv2dViewId = 0;
+static const float kUndistortionScales[4] = {1.0f, 1.0f, 1.0f, 1.0f};
SurroundView2dSession::FramesHandler::FramesHandler(
sp<IEvsCamera> pCamera, sp<SurroundView2dSession> pSession)
@@ -77,25 +91,52 @@
{
scoped_lock<mutex> lock(mSession->mAccessLock);
if (mSession->mProcessingEvsFrames) {
- LOG(WARNING) << "EVS frames are being processed. Skip frames:" << mSession->mSequenceId;
+ LOG(WARNING) << "EVS frames are being processed. Skip frames:"
+ << mSession->mSequenceId;
mCamera->doneWithFrame_1_1(buffers);
return {};
+ } else {
+ // Sets the flag to true immediately so the new coming frames will
+ // be skipped.
+ mSession->mProcessingEvsFrames = true;
}
}
if (buffers.size() != kNumFrames) {
+ scoped_lock<mutex> lock(mSession->mAccessLock);
LOG(ERROR) << "The number of incoming frames is " << buffers.size()
<< ", which is different from the number " << kNumFrames
<< ", specified in config file";
+ mSession->mProcessingEvsFrames = false;
+ mCamera->doneWithFrame_1_1(buffers);
return {};
}
{
scoped_lock<mutex> lock(mSession->mAccessLock);
+ vector<int> indices;
+ for (const auto& id
+ : mSession->mIOModuleConfig->cameraConfig.evsCameraIds) {
+ for (int i = 0; i < kNumFrames; i++) {
+ if (buffers[i].deviceId == id) {
+ indices.emplace_back(i);
+ break;
+ }
+ }
+ }
+
+ if (indices.size() != kNumFrames) {
+ LOG(ERROR) << "The frames are not from the cameras we expected!";
+ mSession->mProcessingEvsFrames = false;
+ mCamera->doneWithFrame_1_1(buffers);
+ return {};
+ }
+
for (int i = 0; i < kNumFrames; i++) {
- LOG(DEBUG) << "Copying buffer No." << i
- << " to Surround View Service";
- mSession->copyFromBufferToPointers(buffers[i],
+ LOG(DEBUG) << "Copying buffer from camera ["
+ << buffers[indices[i]].deviceId
+ << "] to Surround View Service";
+ mSession->copyFromBufferToPointers(buffers[indices[i]],
mSession->mInputPointers[i]);
}
}
@@ -103,10 +144,6 @@
mCamera->doneWithFrame_1_1(buffers);
// Notify the session that a new set of frames is ready
- {
- scoped_lock<mutex> lock(mSession->mAccessLock);
- mSession->mProcessingEvsFrames = true;
- }
mSession->mFramesSignal.notify_all();
return {};
@@ -115,15 +152,11 @@
Return<void> SurroundView2dSession::FramesHandler::notify(const EvsEventDesc& event) {
switch(event.aType) {
case EvsEventType::STREAM_STOPPED:
- {
+ // The Surround View STREAM_STOPPED event is generated when the
+ // service finished processing the queued frames. So it does not
+ // rely on the Evs STREAM_STOPPED event.
LOG(INFO) << "Received a STREAM_STOPPED event from Evs.";
-
- // TODO(b/158339680): There is currently an issue in EVS reference
- // implementation that causes STREAM_STOPPED event to be delivered
- // properly. When the bug is fixed, we should deal with this event
- // properly in case the EVS stream is stopped unexpectly.
break;
- }
case EvsEventType::PARAMETER_CHANGED:
LOG(INFO) << "Camera parameter " << std::hex << event.payload[0]
@@ -187,24 +220,10 @@
LOG(INFO) << "Managed to get read access to GraphicBuffer";
}
- int stride = pDesc->stride;
-
- // readPtr comes from EVS, and it is with 4 channels
- uint8_t* readPtr = static_cast<uint8_t*>(inputDataPtr);
-
- // writePtr comes from CV imread, and it is with 3 channels
- uint8_t* writePtr = static_cast<uint8_t*>(pointers.cpu_data_pointer);
-
- for (int i=0; i<pDesc->width; i++)
- for (int j=0; j<pDesc->height; j++) {
- writePtr[(i + j * stride) * 3 + 0] =
- readPtr[(i + j * stride) * 4 + 0];
- writePtr[(i + j * stride) * 3 + 1] =
- readPtr[(i + j * stride) * 4 + 1];
- writePtr[(i + j * stride) * 3 + 2] =
- readPtr[(i + j * stride) * 4 + 2];
- }
- LOG(INFO) << "Brute force copying finished";
+ // Both source and destination are with 4 channels
+ memcpy(pointers.cpu_data_pointer, inputDataPtr,
+ pDesc->height * pDesc->width * kInputNumChannels);
+ LOG(DEBUG) << "Buffer copying finished";
return true;
}
@@ -460,7 +479,7 @@
mOutputPointer.width = mOutputWidth;
mOutputPointer.format = Format::RGB;
mOutputPointer.data_pointer =
- new char[mOutputHeight * mOutputWidth * kNumChannels];
+ new char[mOutputHeight * mOutputWidth * kOutputNumChannels];
if (!mOutputPointer.data_pointer) {
LOG(ERROR) << "Memory allocation failed. Exiting.";
@@ -484,13 +503,14 @@
}
}
+ LOG(INFO) << "Output Pointer data format: " << mOutputPointer.format;
if (mSurroundView->Get2dSurroundView(mInputPointers, &mOutputPointer)) {
LOG(INFO) << "Get2dSurroundView succeeded";
} else {
LOG(ERROR) << "Get2dSurroundView failed. "
<< "Using memset to initialize to gray";
memset(mOutputPointer.data_pointer, kGrayColor,
- mOutputHeight * mOutputWidth * kNumChannels);
+ mOutputHeight * mOutputWidth * kOutputNumChannels);
}
void* textureDataPtr = nullptr;
@@ -508,8 +528,8 @@
// by line, instead of single memcpy.
uint8_t* writePtr = static_cast<uint8_t*>(textureDataPtr);
uint8_t* readPtr = static_cast<uint8_t*>(mOutputPointer.data_pointer);
- const int readStride = mOutputWidth * kNumChannels;
- const int writeStride = mSvTexture->getStride() * kNumChannels;
+ const int readStride = mOutputWidth * kOutputNumChannels;
+ const int writeStride = mSvTexture->getStride() * kOutputNumChannels;
if (readStride == writeStride) {
memcpy(writePtr, readPtr, readStride * mSvTexture->getHeight());
} else {
@@ -571,7 +591,8 @@
mCameraParams,
mIOModuleConfig->sv2dConfig.sv2dParams,
mIOModuleConfig->sv3dConfig.sv3dParams,
- GetUndistortionScales(),
+ vector<float>(std::begin(kUndistortionScales),
+ std::end(kUndistortionScales)),
mIOModuleConfig->sv2dConfig.carBoundingBox,
mIOModuleConfig->carModelConfig.carModel.texturesMap,
mIOModuleConfig->carModelConfig.carModel.partsMap);
@@ -587,11 +608,11 @@
for (int i = 0; i < kNumFrames; i++) {
mInputPointers[i].width = mCameraParams[i].size.width;
mInputPointers[i].height = mCameraParams[i].size.height;
- mInputPointers[i].format = Format::RGB;
+ mInputPointers[i].format = Format::RGBA;
mInputPointers[i].cpu_data_pointer =
(void*)new uint8_t[mInputPointers[i].width *
mInputPointers[i].height *
- kNumChannels];
+ kInputNumChannels];
}
LOG(INFO) << "Allocated " << kNumFrames << " input pointers";
@@ -604,9 +625,9 @@
mOutputPointer.height = mOutputHeight;
mOutputPointer.width = mOutputWidth;
- mOutputPointer.format = mInputPointers[0].format;
+ mOutputPointer.format = Format::RGB;
mOutputPointer.data_pointer = new char[
- mOutputHeight * mOutputWidth * kNumChannels];
+ mOutputHeight * mOutputWidth * kOutputNumChannels];
if (!mOutputPointer.data_pointer) {
LOG(ERROR) << "Memory allocation failed. Exiting.";
diff --git a/surround_view/service-impl/SurroundView2dSession.h b/surround_view/service-impl/SurroundView2dSession.h
index 5a74c20..8061f23 100644
--- a/surround_view/service-impl/SurroundView2dSession.h
+++ b/surround_view/service-impl/SurroundView2dSession.h
@@ -16,7 +16,6 @@
#pragma once
-#include "CoreLibSetupHelper.h"
#include "IOModule.h"
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
@@ -128,13 +127,13 @@
// Instance and metadata for the opened Evs Camera
sp<IEvsCamera> mCamera;
CameraDesc mCameraDesc;
- vector<SurroundViewCameraParams> mCameraParams;
+ std::vector<SurroundViewCameraParams> mCameraParams;
// Stream subscribed for the session.
sp<ISurroundViewStream> mStream GUARDED_BY(mAccessLock);
StreamStateValues mStreamState GUARDED_BY(mAccessLock);
- thread mProcessThread; // The thread we'll use to process frames
+ std::thread mProcessThread; // The thread we'll use to process frames
// Reference to the inner class, to handle the incoming Evs frames
sp<FramesHandler> mFramesHandler;
@@ -154,13 +153,13 @@
// Synchronization necessary to deconflict mCaptureThread from the main
// service thread
- mutex mAccessLock;
+ std::mutex mAccessLock;
- vector<string> mEvsCameraIds GUARDED_BY(mAccessLock);
+ std::vector<std::string> mEvsCameraIds GUARDED_BY(mAccessLock);
- unique_ptr<SurroundView> mSurroundView GUARDED_BY(mAccessLock);
+ std::unique_ptr<SurroundView> mSurroundView GUARDED_BY(mAccessLock);
- vector<SurroundViewInputBufferPointers>
+ std::vector<SurroundViewInputBufferPointers>
mInputPointers GUARDED_BY(mAccessLock);
SurroundViewResultPointer mOutputPointer GUARDED_BY(mAccessLock);
diff --git a/surround_view/service-impl/SurroundView3dSession.cpp b/surround_view/service-impl/SurroundView3dSession.cpp
index 1a91e0d..3bb2203 100644
--- a/surround_view/service-impl/SurroundView3dSession.cpp
+++ b/surround_view/service-impl/SurroundView3dSession.cpp
@@ -32,6 +32,20 @@
#include "CameraUtils.h"
#include "sv_3d_params.h"
+using ::std::adopt_lock;
+using ::std::array;
+using ::std::lock;
+using ::std::lock_guard;
+using ::std::map;
+using ::std::mutex;
+using ::std::scoped_lock;
+using ::std::set;
+using ::std::string;
+using ::std::thread;
+using ::std::unique_lock;
+using ::std::unique_ptr;
+using ::std::vector;
+
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::hidl_memory;
@@ -55,10 +69,12 @@
int32_t framerate;
} RawStreamConfig;
-static const size_t kStreamCfgSz = sizeof(RawStreamConfig);
+static const size_t kStreamCfgSz = sizeof(RawStreamConfig) / sizeof(int32_t);
static const uint8_t kGrayColor = 128;
static const int kNumFrames = 4;
-static const int kNumChannels = 4;
+static const int kInputNumChannels = 4;
+static const int kOutputNumChannels = 4;
+static const float kUndistortionScales[4] = {1.0f, 1.0f, 1.0f, 1.0f};
SurroundView3dSession::FramesHandler::FramesHandler(
sp<IEvsCamera> pCamera, sp<SurroundView3dSession> pSession)
@@ -85,22 +101,55 @@
<< mSession->mSequenceId;
mCamera->doneWithFrame_1_1(buffers);
return {};
+ } else {
+ // Sets the flag to true immediately so the new coming frames will
+ // be skipped.
+ mSession->mProcessingEvsFrames = true;
}
}
if (buffers.size() != kNumFrames) {
+ scoped_lock<mutex> lock(mSession->mAccessLock);
LOG(ERROR) << "The number of incoming frames is " << buffers.size()
<< ", which is different from the number " << kNumFrames
<< ", specified in config file";
+ mSession->mProcessingEvsFrames = false;
+ mCamera->doneWithFrame_1_1(buffers);
return {};
}
{
scoped_lock<mutex> lock(mSession->mAccessLock);
+
+ // The incoming frames may not follow the same order as listed cameras.
+ // We should re-order them following the camera ids listed in camera
+ // config.
+ vector<int> indices;
+ for (const auto& id
+ : mSession->mIOModuleConfig->cameraConfig.evsCameraIds) {
+ for (int i = 0; i < kNumFrames; i++) {
+ if (buffers[i].deviceId == id) {
+ indices.emplace_back(i);
+ break;
+ }
+ }
+ }
+
+ // If the size of indices is smaller than the kNumFrames, it means that
+ // there is frame(s) that comes from different camera(s) than we
+ // expected.
+ if (indices.size() != kNumFrames) {
+ LOG(ERROR) << "The frames are not from the cameras we expected!";
+ mSession->mProcessingEvsFrames = false;
+ mCamera->doneWithFrame_1_1(buffers);
+ return {};
+ }
+
for (int i = 0; i < kNumFrames; i++) {
- LOG(DEBUG) << "Copying buffer No." << i
- << " to Surround View Service";
- mSession->copyFromBufferToPointers(buffers[i],
+ LOG(DEBUG) << "Copying buffer from camera ["
+ << buffers[indices[i]].deviceId
+ << "] to Surround View Service";
+ mSession->copyFromBufferToPointers(buffers[indices[i]],
mSession->mInputPointers[i]);
}
}
@@ -108,10 +157,6 @@
mCamera->doneWithFrame_1_1(buffers);
// Notify the session that a new set of frames is ready
- {
- scoped_lock<mutex> lock(mSession->mAccessLock);
- mSession->mProcessingEvsFrames = true;
- }
mSession->mFramesSignal.notify_all();
return {};
@@ -120,12 +165,10 @@
Return<void> SurroundView3dSession::FramesHandler::notify(const EvsEventDesc& event) {
switch(event.aType) {
case EvsEventType::STREAM_STOPPED:
+ // The Surround View STREAM_STOPPED event is generated when the
+ // service finished processing the queued frames. So it does not
+ // rely on the Evs STREAM_STOPPED event.
LOG(INFO) << "Received a STREAM_STOPPED event from Evs.";
-
- // TODO(b/158339680): There is currently an issue in EVS reference
- // implementation that causes STREAM_STOPPED event to be delivered
- // properly. When the bug is fixed, we should deal with this event
- // properly in case the EVS stream is stopped unexpectly.
break;
case EvsEventType::PARAMETER_CHANGED:
@@ -190,24 +233,10 @@
LOG(INFO) << "Managed to get read access to GraphicBuffer";
}
- int stride = pDesc->stride;
-
- // readPtr comes from EVS, and it is with 4 channels
- uint8_t* readPtr = static_cast<uint8_t*>(inputDataPtr);
-
- // writePtr is with 3 channels, since that is what SV core lib expects.
- uint8_t* writePtr = static_cast<uint8_t*>(pointers.cpu_data_pointer);
-
- for (int i = 0; i < pDesc->width; i++)
- for (int j = 0; j < pDesc->height; j++) {
- writePtr[(i + j * stride) * 3 + 0] =
- readPtr[(i + j * stride) * 4 + 0];
- writePtr[(i + j * stride) * 3 + 1] =
- readPtr[(i + j * stride) * 4 + 1];
- writePtr[(i + j * stride) * 3 + 2] =
- readPtr[(i + j * stride) * 4 + 2];
- }
- LOG(INFO) << "Brute force copying finished";
+ // Both source and destination are with 4 channels
+ memcpy(pointers.cpu_data_pointer, inputDataPtr,
+ pDesc->height * pDesc->width * kInputNumChannels);
+ LOG(INFO) << "Buffer copying finished";
return true;
}
@@ -271,7 +300,9 @@
stopStream();
// Waiting for the process thread to finish the buffered frames.
- mProcessThread.join();
+ if (mProcessThread.joinable()) {
+ mProcessThread.join();
+ }
mEvs->closeCamera(mCamera);
}
@@ -373,6 +404,11 @@
LOG(DEBUG) << __FUNCTION__;
scoped_lock <mutex> lock(mAccessLock);
+ if (views.size() == 0) {
+ LOG(ERROR) << "Empty view argument, at-least one view is required.";
+ return SvResult::VIEW_NOT_SET;
+ }
+
mViews.resize(views.size());
for (int i=0; i<views.size(); i++) {
mViews[i] = views[i];
@@ -416,7 +452,10 @@
return {};
}
-bool VerifyOverlayData(const OverlaysData& overlaysData) {
+bool VerifyAndGetOverlays(const OverlaysData& overlaysData, std::vector<Overlay>* svCoreOverlays) {
+ // Clear the overlays.
+ svCoreOverlays->clear();
+
// Check size of shared memory matches overlaysMemoryDesc.
const int kVertexSize = 16;
const int kIdSize = 2;
@@ -424,8 +463,8 @@
for (auto& overlayMemDesc : overlaysData.overlaysMemoryDesc) {
memDescSize += kIdSize + kVertexSize * overlayMemDesc.verticesCount;
}
- if (memDescSize != overlaysData.overlaysMemory.size()) {
- LOG(ERROR) << "shared memory and overlaysMemoryDesc size mismatch.";
+ if (overlaysData.overlaysMemory.size() < memDescSize) {
+ LOG(ERROR) << "Allocated shared memory size is less than overlaysMemoryDesc size.";
return false;
}
@@ -450,12 +489,14 @@
if (overlayIdSet.find(overlayMemDesc.id) != overlayIdSet.end()) {
LOG(ERROR) << "Duplicate id within memory descriptor.";
+ svCoreOverlays->clear();
return false;
}
overlayIdSet.insert(overlayMemDesc.id);
if(overlayMemDesc.verticesCount < 3) {
LOG(ERROR) << "Less than 3 vertices.";
+ svCoreOverlays->clear();
return false;
}
@@ -463,34 +504,43 @@
overlayMemDesc.verticesCount % 3 != 0) {
LOG(ERROR) << "Triangles primitive does not have vertices "
<< "multiple of 3.";
+ svCoreOverlays->clear();
return false;
}
const uint16_t overlayId = *((uint16_t*)(pData + idOffset));
if (overlayId != overlayMemDesc.id) {
- LOG(ERROR) << "Overlay id mismatch "
- << overlayId
- << ", "
- << overlayMemDesc.id;
+ LOG(ERROR) << "Overlay id mismatch " << overlayId << ", " << overlayMemDesc.id;
+ svCoreOverlays->clear();
return false;
}
+ // Copy over shared memory data to sv core overlays.
+ Overlay svCoreOverlay;
+ svCoreOverlay.id = overlayMemDesc.id;
+ svCoreOverlay.vertices.resize(overlayMemDesc.verticesCount);
+ uint8_t* verticesDataPtr = pData + idOffset + kIdSize;
+ memcpy(svCoreOverlay.vertices.data(), verticesDataPtr,
+ kVertexSize * overlayMemDesc.verticesCount);
+ svCoreOverlays->push_back(svCoreOverlay);
+
idOffset += kIdSize + (kVertexSize * overlayMemDesc.verticesCount);
}
return true;
}
-// TODO(b/150412555): the overlay related methods are incomplete.
-Return<SvResult> SurroundView3dSession::updateOverlays(
- const OverlaysData& overlaysData) {
+Return<SvResult> SurroundView3dSession::updateOverlays(const OverlaysData& overlaysData) {
+ LOG(DEBUG) << __FUNCTION__;
- if(!VerifyOverlayData(overlaysData)) {
- LOG(ERROR) << "VerifyOverlayData failed.";
+ scoped_lock <mutex> lock(mAccessLock);
+ if(!VerifyAndGetOverlays(overlaysData, &mOverlays)) {
+ LOG(ERROR) << "VerifyAndGetOverlays failed.";
return SvResult::INVALID_ARG;
}
+ mOverlayIsUpdated = true;
return SvResult::OK;
}
@@ -522,8 +572,9 @@
Point3dFloat point3d = {false, 0.0, 0.0, 0.0};
// Verify if camera point is within the camera resolution bounds.
- point3d.isValid = (cameraPoint.x >= 0 && cameraPoint.x < mConfig.width &&
- cameraPoint.y >= 0 && cameraPoint.y < mConfig.height);
+ const Size2dInteger cameraSize = mCameraParams[cameraIndex].size;
+ point3d.isValid = (cameraPoint.x >= 0 && cameraPoint.x < cameraSize.width &&
+ cameraPoint.y >= 0 && cameraPoint.y < cameraSize.height);
if (!point3d.isValid) {
LOG(WARNING) << "Camera point (" << cameraPoint.x << ", " << cameraPoint.y
<< ") is out of camera resolution bounds.";
@@ -582,7 +633,7 @@
mOutputPointer.width = mOutputWidth;
mOutputPointer.format = Format::RGBA;
mOutputPointer.data_pointer =
- new char[mOutputHeight * mOutputWidth * kNumChannels];
+ new char[mOutputHeight * mOutputWidth * kOutputNumChannels];
if (!mOutputPointer.data_pointer) {
LOG(ERROR) << "Memory allocation failed. Exiting.";
@@ -606,16 +657,15 @@
}
}
- // TODO(b/150412555): do not use the setViews for frames generation
- // since there is a discrepancy between the HIDL APIs and core lib APIs.
- array<array<float, 4>, 4> matrix;
-
- // TODO(b/150412555): use hard-coded views for now. Change view every
- // frame.
- int recViewId = sequenceId % 16;
- for (int i=0; i<4; i++)
- for (int j=0; j<4; j++) {
- matrix[i][j] = kRecViews[recViewId][i*4+j];
+ // Set 3d overlays.
+ {
+ scoped_lock<mutex> lock(mAccessLock);
+ if (mOverlayIsUpdated) {
+ if (!mSurroundView->Set3dOverlay(mOverlays)) {
+ LOG(ERROR) << "Set 3d overlays failed.";
+ }
+ mOverlayIsUpdated = false;
+ }
}
// Get the latest VHal property values
@@ -640,14 +690,22 @@
LOG(INFO) << "AnimationParams is empty. Ignored";
}
+ // Get the view.
+ // TODO(161399517): Only single view is currently supported, add support for multiple views.
+ const View3d view3d = mViews[0];
+ const RotationQuat quat = view3d.pose.rotation;
+ const Translation trans = view3d.pose.translation;
+ const std::array<float, 4> viewQuaternion = {quat.x, quat.y, quat.z, quat.w};
+ const std::array<float, 3> viewTranslation = {trans.x, trans.y, trans.z};
+
if (mSurroundView->Get3dSurroundView(
- mInputPointers, matrix, &mOutputPointer)) {
+ mInputPointers, viewQuaternion, viewTranslation, &mOutputPointer)) {
LOG(INFO) << "Get3dSurroundView succeeded";
} else {
LOG(ERROR) << "Get3dSurroundView failed. "
<< "Using memset to initialize to gray.";
memset(mOutputPointer.data_pointer, kGrayColor,
- mOutputHeight * mOutputWidth * kNumChannels);
+ mOutputHeight * mOutputWidth * kOutputNumChannels);
}
void* textureDataPtr = nullptr;
@@ -665,8 +723,8 @@
// data line by line, instead of single memcpy.
uint8_t* writePtr = static_cast<uint8_t*>(textureDataPtr);
uint8_t* readPtr = static_cast<uint8_t*>(mOutputPointer.data_pointer);
- const int readStride = mOutputWidth * kNumChannels;
- const int writeStride = mSvTexture->getStride() * kNumChannels;
+ const int readStride = mOutputWidth * kOutputNumChannels;
+ const int writeStride = mSvTexture->getStride() * kOutputNumChannels;
if (readStride == writeStride) {
memcpy(writePtr, readPtr, readStride * mSvTexture->getHeight());
} else {
@@ -727,7 +785,8 @@
mCameraParams,
mIOModuleConfig->sv2dConfig.sv2dParams,
mIOModuleConfig->sv3dConfig.sv3dParams,
- GetUndistortionScales(),
+ vector<float>(std::begin(kUndistortionScales),
+ std::end(kUndistortionScales)),
mIOModuleConfig->sv2dConfig.carBoundingBox,
mIOModuleConfig->carModelConfig.carModel.texturesMap,
mIOModuleConfig->carModelConfig.carModel.partsMap);
@@ -737,11 +796,11 @@
for (int i = 0; i < kNumFrames; i++) {
mInputPointers[i].width = mCameraParams[i].size.width;
mInputPointers[i].height = mCameraParams[i].size.height;
- mInputPointers[i].format = Format::RGB;
+ mInputPointers[i].format = Format::RGBA;
mInputPointers[i].cpu_data_pointer =
(void*)new uint8_t[mInputPointers[i].width *
mInputPointers[i].height *
- kNumChannels];
+ kInputNumChannels];
}
LOG(INFO) << "Allocated " << kNumFrames << " input pointers";
@@ -756,7 +815,7 @@
mOutputPointer.width = mOutputWidth;
mOutputPointer.format = Format::RGBA;
mOutputPointer.data_pointer = new char[
- mOutputHeight * mOutputWidth * kNumChannels];
+ mOutputHeight * mOutputWidth * kOutputNumChannels];
if (!mOutputPointer.data_pointer) {
LOG(ERROR) << "Memory allocation failed. Exiting.";
diff --git a/surround_view/service-impl/SurroundView3dSession.h b/surround_view/service-impl/SurroundView3dSession.h
index 09f4c90..6c2b8ce 100644
--- a/surround_view/service-impl/SurroundView3dSession.h
+++ b/surround_view/service-impl/SurroundView3dSession.h
@@ -27,7 +27,6 @@
#include <hidl/Status.h>
#include "AnimationModule.h"
-#include "CoreLibSetupHelper.h"
#include "VhalHandler.h"
#include <thread>
@@ -133,13 +132,13 @@
// Instance and metadata for the opened Evs Camera
sp<IEvsCamera> mCamera;
CameraDesc mCameraDesc;
- vector<SurroundViewCameraParams> mCameraParams;
+ std::vector<SurroundViewCameraParams> mCameraParams;
// Stream subscribed for the session.
sp<ISurroundViewStream> mStream GUARDED_BY(mAccessLock);
StreamStateValues mStreamState GUARDED_BY(mAccessLock);
- thread mProcessThread; // The thread we'll use to process frames
+ std::thread mProcessThread; // The thread we'll use to process frames
// Reference to the inner class, to handle the incoming Evs frames
sp<FramesHandler> mFramesHandler;
@@ -158,17 +157,17 @@
FramesRecord mFramesRecord GUARDED_BY(mAccessLock);
// Synchronization necessary to deconflict mCaptureThread from the main service thread
- mutex mAccessLock;
+ std::mutex mAccessLock;
- vector<View3d> mViews GUARDED_BY(mAccessLock);
+ std::vector<View3d> mViews GUARDED_BY(mAccessLock);
Sv3dConfig mConfig GUARDED_BY(mAccessLock);
- vector<string> mEvsCameraIds GUARDED_BY(mAccessLock);
+ std::vector<std::string> mEvsCameraIds GUARDED_BY(mAccessLock);
- unique_ptr<SurroundView> mSurroundView GUARDED_BY(mAccessLock);
+ std::unique_ptr<SurroundView> mSurroundView GUARDED_BY(mAccessLock);
- vector<SurroundViewInputBufferPointers>
+ std::vector<SurroundViewInputBufferPointers>
mInputPointers GUARDED_BY(mAccessLock);
SurroundViewResultPointer mOutputPointer GUARDED_BY(mAccessLock);
int mOutputWidth, mOutputHeight GUARDED_BY(mAccessLock);
@@ -181,6 +180,9 @@
AnimationModule* mAnimationModule;
IOModuleConfig* mIOModuleConfig;
+ std::vector<Overlay> mOverlays GUARDED_BY(mAccessLock);
+ bool mOverlayIsUpdated GUARDED_BY(mAccessLock) = false;
+
std::vector<VehiclePropValue> mPropertyValues;
};
diff --git a/surround_view/service-impl/SurroundViewService.cpp b/surround_view/service-impl/SurroundViewService.cpp
index 910b0ae..e8a2ffd 100644
--- a/surround_view/service-impl/SurroundViewService.cpp
+++ b/surround_view/service-impl/SurroundViewService.cpp
@@ -16,7 +16,6 @@
#include <android-base/logging.h>
-#include "CoreLibSetupHelper.h"
#include "SurroundViewService.h"
using namespace android_auto::surround_view;
@@ -36,14 +35,24 @@
const std::string kCameraIds[] = {"0", "1", "2", "3"};
static const int kVhalUpdateRate = 10;
-SurroundViewService::SurroundViewService() {
+SurroundViewService::SurroundViewService() :
+ mVhalHandler(nullptr), mAnimationModule(nullptr), mIOModule(nullptr) {
mVhalHandler = new VhalHandler();
mIOModule = new IOModule("/vendor/etc/automotive/sv/sv_sample_config.xml");
}
SurroundViewService::~SurroundViewService() {
- delete mVhalHandler;
- delete mAnimationModule;
+ if (mVhalHandler != nullptr) {
+ delete mVhalHandler;
+ }
+
+ if (mIOModule != nullptr) {
+ delete mIOModule;
+ }
+
+ if (mAnimationModule != nullptr) {
+ delete mAnimationModule;
+ }
}
sp<SurroundViewService> SurroundViewService::getInstance() {
diff --git a/surround_view/service-impl/SurroundViewSessionTests.cpp b/surround_view/service-impl/SurroundViewSessionTests.cpp
index b694aaf..a6abd04 100644
--- a/surround_view/service-impl/SurroundViewSessionTests.cpp
+++ b/surround_view/service-impl/SurroundViewSessionTests.cpp
@@ -28,6 +28,7 @@
#include <android-base/logging.h>
#include <gtest/gtest.h>
+#include <time.h>
namespace android {
namespace hardware {
@@ -39,6 +40,7 @@
const char* kSvConfigFilename = "vendor/etc/automotive/sv/sv_sample_config.xml";
+// TODO(b/159733690): Verify the callbacks using help/mock methods
TEST(SurroundViewSessionTests, startAndStopSurroundView2dSession) {
sp<IEvsEnumerator> fakeEvs = new MockEvsEnumerator();
IOModule* ioModule = new IOModule(kSvConfigFilename);
@@ -57,6 +59,8 @@
EXPECT_EQ(sv2dSession->startStream(sv2dCallback), SvResult::OK);
+ sleep(5);
+
sv2dSession->stopStream();
}
@@ -79,13 +83,22 @@
sp<MockSurroundViewCallback> sv3dCallback =
new MockSurroundViewCallback(sv3dSession);
- View3d view = {};
+ View3d view = {
+ .viewId = 0,
+ .pose = {
+ .rotation = {.x=0, .y=0, .z=0, .w=1.0f},
+ .translation = {.x=0, .y=0, .z=0},
+ },
+ .horizontalFov = 90,
+ };
vector<View3d> views;
views.emplace_back(view);
sv3dSession->setViews(views);
EXPECT_EQ(sv3dSession->startStream(sv3dCallback), SvResult::OK);
+ sleep(5);
+
sv3dSession->stopStream();
}
diff --git a/surround_view/service-impl/lib/arm64/libcore_lib_shared.so b/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
index 5ca36a5..f0ad2e6 100755
--- a/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so b/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
index 7f2e039..d84ab5c 100755
--- a/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/lib/x86/libcore_lib_shared.so b/surround_view/service-impl/lib/x86/libcore_lib_shared.so
index 9d0f4ef..ce5bca1 100755
--- a/surround_view/service-impl/lib/x86/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/x86/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/mock-evs/MockEvsCamera.cpp b/surround_view/service-impl/mock-evs/MockEvsCamera.cpp
index f268e5b..dcd7405 100644
--- a/surround_view/service-impl/mock-evs/MockEvsCamera.cpp
+++ b/surround_view/service-impl/mock-evs/MockEvsCamera.cpp
@@ -16,6 +16,8 @@
#include "MockEvsCamera.h"
+#include <stdlib.h>
+
namespace android {
namespace hardware {
namespace automotive {
@@ -23,10 +25,26 @@
namespace V1_0 {
namespace implementation {
-MockEvsCamera::MockEvsCamera() {
- mConfigManager =
- ConfigManager::Create(
- "/vendor/etc/automotive/evs/evs_sample_configuration.xml");
+// TODO(b/159733690): the number should come from xml
+const int kFramesCount = 4;
+const int kFrameGenerationDelayMillis = 30;
+const char kConfigFilePath[] =
+ "/vendor/etc/automotive/evs/evs_sample_configuration.xml";
+
+MockEvsCamera::MockEvsCamera(const string& cameraId, const Stream& streamCfg) {
+ mConfigManager = ConfigManager::Create(kConfigFilePath);
+
+ mStreamCfg.height = streamCfg.height;
+ mStreamCfg.width = streamCfg.width;
+
+ mCameraDesc.v1.cameraId = cameraId;
+ unique_ptr<ConfigManager::CameraGroupInfo>& cameraGroupInfo =
+ mConfigManager->getCameraGroupInfo(mCameraDesc.v1.cameraId);
+ if (cameraGroupInfo != nullptr) {
+ mCameraDesc.metadata.setToExternal(
+ (uint8_t*)cameraGroupInfo->characteristics,
+ get_camera_metadata_size(cameraGroupInfo->characteristics));
+ }
}
Return<void> MockEvsCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) {
@@ -46,8 +64,20 @@
Return<EvsResult> MockEvsCamera::startVideoStream(
const ::android::sp<IEvsCameraStream_1_0>& stream) {
LOG(INFO) << __FUNCTION__;
+ scoped_lock<mutex> lock(mAccessLock);
- (void)stream;
+ mStream = IEvsCameraStream_1_1::castFrom(stream).withDefault(nullptr);
+
+ if (mStreamState != STOPPED) {
+ LOG(ERROR) << "Ignoring startVideoStream call when a stream is "
+ << "already running.";
+ return EvsResult::STREAM_ALREADY_RUNNING;
+ }
+
+ // Start the frame generation thread
+ mStreamState = RUNNING;
+ mCaptureThread = thread([this]() { generateFrames(); });
+
return EvsResult::OK;
}
@@ -60,6 +90,22 @@
Return<void> MockEvsCamera::stopVideoStream() {
LOG(INFO) << __FUNCTION__;
+
+ unique_lock<mutex> lock(mAccessLock);
+ if (mStreamState == RUNNING) {
+ // Tell the GenerateFrames loop we want it to stop
+ mStreamState = STOPPING;
+ // Block outside the mutex until the "stop" flag has been acknowledged
+ // We won't send any more frames, but the client might still get some
+ // already in flight
+ LOG(DEBUG) << __FUNCTION__ << ": Waiting for stream thread to end...";
+ lock.unlock();
+ mCaptureThread.join();
+ lock.lock();
+ mStreamState = STOPPED;
+ mStream = nullptr;
+ LOG(DEBUG) << "Stream marked STOPPED.";
+ }
return {};
}
@@ -80,9 +126,7 @@
}
Return<void> MockEvsCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
- // Not implemented.
-
- (void)_hidl_cb;
+ _hidl_cb(mCameraDesc);
return {};
}
@@ -195,6 +239,69 @@
return {};
}
+void MockEvsCamera::initializeFrames(int framesCount) {
+ LOG(INFO) << "StreamCfg width: " << mStreamCfg.width
+ << " height: " << mStreamCfg.height;
+
+ string label = "EmptyBuffer_";
+ mGraphicBuffers.resize(framesCount);
+ mBufferDescs.resize(framesCount);
+ for (int i = 0; i < framesCount; i++) {
+ mGraphicBuffers[i] = new GraphicBuffer(mStreamCfg.width,
+ mStreamCfg.height,
+ HAL_PIXEL_FORMAT_RGBA_8888,
+ 1,
+ GRALLOC_USAGE_HW_TEXTURE,
+ label + (char)(i + 48));
+ mBufferDescs[i].buffer.nativeHandle =
+ mGraphicBuffers[i]->getNativeBuffer()->handle;
+ AHardwareBuffer_Desc* pDesc =
+ reinterpret_cast<AHardwareBuffer_Desc*>(
+ &mBufferDescs[i].buffer.description);
+ pDesc->width = mStreamCfg.width;
+ pDesc->height = mStreamCfg.height;
+ pDesc->layers = 1;
+ pDesc->usage = GRALLOC_USAGE_HW_TEXTURE;
+ pDesc->stride = mGraphicBuffers[i]->getStride();
+ pDesc->format = HAL_PIXEL_FORMAT_RGBA_8888;
+ }
+}
+
+void MockEvsCamera::generateFrames() {
+ initializeFrames(kFramesCount);
+
+ while (true) {
+ {
+ scoped_lock<mutex> lock(mAccessLock);
+ if (mStreamState != RUNNING) {
+ // Break out of our main thread loop
+ LOG(INFO) << "StreamState does not equal to RUNNING. "
+ << "Exiting the loop";
+ break;
+ }
+ }
+
+ mStream->deliverFrame_1_1(mBufferDescs);
+ std::this_thread::sleep_for(
+ std::chrono::milliseconds(kFrameGenerationDelayMillis));
+ }
+
+ {
+ scoped_lock<mutex> lock(mAccessLock);
+
+ if (mStream != nullptr) {
+ LOG(DEBUG) << "Notify EvsEventType::STREAM_STOPPED";
+
+ EvsEventDesc evsEventDesc;
+ evsEventDesc.aType = EvsEventType::STREAM_STOPPED;
+ mStream->notify(evsEventDesc);
+ } else {
+ LOG(WARNING) << "EVS stream is not valid any more. "
+ << "The notify call is ignored.";
+ }
+ }
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace sv
diff --git a/surround_view/service-impl/mock-evs/MockEvsCamera.h b/surround_view/service-impl/mock-evs/MockEvsCamera.h
index d393702..e06a474 100644
--- a/surround_view/service-impl/mock-evs/MockEvsCamera.h
+++ b/surround_view/service-impl/mock-evs/MockEvsCamera.h
@@ -17,13 +17,21 @@
#pragma once
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
+#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <ConfigManager.h>
+#include <ui/GraphicBuffer.h>
+
+#include <mutex>
+#include <thread>
+
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using ::android::hardware::automotive::evs::V1_1::CameraParam;
+using ::android::hardware::automotive::evs::V1_1::EvsEventDesc;
+using ::android::hardware::automotive::evs::V1_1::EvsEventType;
namespace android {
namespace hardware {
@@ -38,6 +46,7 @@
using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
using IEvsCameraStream_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCameraStream;
+using IEvsCameraStream_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCameraStream;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using IEvsEnumerator_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsEnumerator;
@@ -45,7 +54,7 @@
// implemented.
class MockEvsCamera : public IEvsCamera_1_1 {
public:
- MockEvsCamera();
+ MockEvsCamera(const std::string& cameraId, const Stream& streamCfg);
// Methods from ::android::hardware::automotive::evs::V1_0::IEvsCamera follow.
Return<void> getCameraInfo(getCameraInfo_cb _hidl_cb) override;
@@ -79,7 +88,30 @@
importExternalBuffers_cb _hidl_cb) override;
private:
+ void initializeFrames(int framesCount);
+ void generateFrames();
+
std::unique_ptr<ConfigManager> mConfigManager;
+
+ std::mutex mAccessLock;
+
+ enum StreamStateValues {
+ STOPPED,
+ RUNNING,
+ STOPPING,
+ DEAD,
+ };
+ StreamStateValues mStreamState GUARDED_BY(mAccessLock);
+ Stream mStreamCfg;
+
+ std::vector<android::sp<GraphicBuffer>> mGraphicBuffers;
+ std::vector<BufferDesc_1_1> mBufferDescs;
+ CameraDesc_1_1 mCameraDesc;
+
+ std::string mCameraId;
+ std::thread mCaptureThread; // The thread we'll use to synthesize frames
+
+ android::sp<IEvsCameraStream_1_1> mStream;
};
} // namespace implementation
diff --git a/surround_view/service-impl/mock-evs/MockEvsEnumerator.cpp b/surround_view/service-impl/mock-evs/MockEvsEnumerator.cpp
index 946083c..9e3e5e4 100644
--- a/surround_view/service-impl/mock-evs/MockEvsEnumerator.cpp
+++ b/surround_view/service-impl/mock-evs/MockEvsEnumerator.cpp
@@ -109,11 +109,8 @@
Return<sp<IEvsCamera_1_1>> MockEvsEnumerator::openCamera_1_1(
const hidl_string& cameraId, const Stream& streamCfg) {
- // Not implemented.
-
- (void)cameraId;
- (void)streamCfg;
- return new MockEvsCamera();
+ LOG(INFO) << __FUNCTION__ << ": " << streamCfg.width << ", " << streamCfg.height;
+ return new MockEvsCamera(cameraId, streamCfg);
}
Return<void> MockEvsEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
diff --git a/surround_view/service-impl/mock-evs/MockSurroundViewCallback.cpp b/surround_view/service-impl/mock-evs/MockSurroundViewCallback.cpp
index d059f72..03f9594 100644
--- a/surround_view/service-impl/mock-evs/MockSurroundViewCallback.cpp
+++ b/surround_view/service-impl/mock-evs/MockSurroundViewCallback.cpp
@@ -18,9 +18,13 @@
#include <android-base/logging.h>
+#include <thread>
+
using ::android::sp;
using ::android::hardware::Return;
+using ::std::thread;
+
namespace android {
namespace hardware {
namespace automotive {
@@ -29,9 +33,8 @@
namespace implementation {
MockSurroundViewCallback::MockSurroundViewCallback(
- sp<ISurroundViewSession> pSession) {
- (void)pSession;
-}
+ sp<ISurroundViewSession> pSession) :
+ mSession(pSession) {}
Return<void> MockSurroundViewCallback::notify(SvEvent svEvent) {
LOG(INFO) << __FUNCTION__ << "SvEvent received: " << (int)svEvent;
@@ -42,6 +45,13 @@
const SvFramesDesc& svFramesDesc) {
LOG(INFO) << __FUNCTION__ << svFramesDesc.svBuffers.size()
<< " frames are received";
+
+ // Create a separate thread to return the frames to the session. This
+ // simulates the behavior of oneway HIDL method call.
+ thread mockHidlThread([this, &svFramesDesc]() {
+ mSession->doneWithFrames(svFramesDesc);
+ });
+ mockHidlThread.detach();
return {};
}
diff --git a/surround_view/service-impl/mock-evs/MockSurroundViewCallback.h b/surround_view/service-impl/mock-evs/MockSurroundViewCallback.h
index 7239bf6..eeabc98 100644
--- a/surround_view/service-impl/mock-evs/MockSurroundViewCallback.h
+++ b/surround_view/service-impl/mock-evs/MockSurroundViewCallback.h
@@ -35,6 +35,9 @@
// Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewStream.
android::hardware::Return<void> notify(SvEvent svEvent) override;
android::hardware::Return<void> receiveFrames(const SvFramesDesc& svFramesDesc) override;
+
+private:
+ android::sp<ISurroundViewSession> mSession;
};
} // namespace implementation
diff --git a/tests/BugReportApp/res/values-ne/strings.xml b/tests/BugReportApp/res/values-ne/strings.xml
index 997cea1..7a8464a 100644
--- a/tests/BugReportApp/res/values-ne/strings.xml
+++ b/tests/BugReportApp/res/values-ne/strings.xml
@@ -41,7 +41,7 @@
<string name="toast_bug_report_in_progress" msgid="8319601113129121579">"बग रिपोर्ट पहिलेदेखि नै सङ्कलन भइरहेको छ"</string>
<string name="toast_bug_report_started" msgid="7154589593986557754">"बगबारे रिपोर्ट गर्ने कार्य सुरु भयो"</string>
<string name="toast_status_failed" msgid="6365384202315043395">"बग रिपोर्ट सङ्कलन गर्न सकिएन"</string>
- <string name="toast_status_screencap_failed" msgid="2187083897594745149">"स्क्रिनको तस्बिर खिच्न सकिएन"</string>
+ <string name="toast_status_screencap_failed" msgid="2187083897594745149">"स्क्रिनको फोटो खिच्न सकिएन"</string>
<string name="toast_status_dump_state_failed" msgid="8072469535227541761">"डम्प स्टेटले काम गर्न सकेन"</string>
<string name="notification_bugreport_in_progress" msgid="8486454116357963238">"बग रिपोर्ट सङ्कलन गर्ने कार्य जारी छ"</string>
<string name="notification_bugreport_finished_title" msgid="3970195939909624320">"बग रिपोर्ट सङ्कलन गरियो"</string>
diff --git a/tests/CarDeveloperOptions/res/values-af/strings.xml b/tests/CarDeveloperOptions/res/values-af/strings.xml
index 9857323..80fe046 100644
--- a/tests/CarDeveloperOptions/res/values-af/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-af/strings.xml
@@ -1615,7 +1615,7 @@
<string name="tether_settings_title_bluetooth" msgid="1999590158102569959">"Bluetooth-verbinding"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1159128764162788159">"Verbinding"</string>
<string name="tether_settings_title_all" msgid="6935843543433954181">"Warmkol en verbinding"</string>
- <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"Warmkol is aan, verbinding"</string>
+ <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"Warmkol is aan, verbind"</string>
<string name="tether_settings_summary_hotspot_on_tether_off" msgid="8010689354668285422">"Warmkol is aan"</string>
<string name="tether_settings_summary_hotspot_off_tether_on" msgid="1349909238672649877">"Verbinding"</string>
<string name="tether_settings_disabled_on_data_saver" msgid="3682544845899910726">"Kan nie verbind of Wi-Fi-warmkol gebruik wanneer Databespaarder aan is nie"</string>
diff --git a/tests/CarDeveloperOptions/res/values-am/arrays.xml b/tests/CarDeveloperOptions/res/values-am/arrays.xml
index acbc14e..860c396 100644
--- a/tests/CarDeveloperOptions/res/values-am/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-am/arrays.xml
@@ -323,7 +323,7 @@
<item msgid="6844485713404805301">"ዋናው የድምጽ መቆጣጠሪያ"</item>
<item msgid="1600379420669104929">"የድምጽ መጠን"</item>
<item msgid="6296768210470214866">"የጥሪ ድምጽ መጠን"</item>
- <item msgid="510690696071629241">"የማህደረመረጃ ክፍልፍል"</item>
+ <item msgid="510690696071629241">"የማህደረ መረጃ ድምጽ መጠን"</item>
<item msgid="406861638631430109">"የማንቂያ ድምፅ መጠን"</item>
<item msgid="4715864795872233884">"የማሳወቂያ ድምጽ መጠን"</item>
<item msgid="2311478519251301183">"የብሉቱዝ ድምፅ መጠን"</item>
diff --git a/tests/CarDeveloperOptions/res/values-am/strings.xml b/tests/CarDeveloperOptions/res/values-am/strings.xml
index ba77bc5..f52435a 100644
--- a/tests/CarDeveloperOptions/res/values-am/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-am/strings.xml
@@ -3134,7 +3134,7 @@
<string name="sound_settings_summary_vibrate" msgid="2194491116884798590">"ደዋዩ ወደ ንዘር ተቀናብሯል"</string>
<string name="sound_settings_summary_silent" msgid="899823817462768876">"ደዋዩ ወደ ጸጥታ ተቀናብሯል"</string>
<string name="sound_settings_example_summary" msgid="2091822107298841827">"የጥሪ ድምጽ መጠን 80% ላይ"</string>
- <string name="media_volume_option_title" msgid="3553411883305505682">"የማህደረመረጃ ክፍልፍል"</string>
+ <string name="media_volume_option_title" msgid="3553411883305505682">"የማህደረ መረጃ ድምጽ መጠን"</string>
<string name="remote_media_volume_option_title" msgid="6355710054191873836">"ድምፅን Cast አድርግ"</string>
<string name="call_volume_option_title" msgid="5028003296631037334">"የስልክ ጥሪ ድምጽ መጠን"</string>
<string name="alarm_volume_option_title" msgid="3184076022438477047">"የማንቂያ ድምፅ መጠን"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ar/strings.xml b/tests/CarDeveloperOptions/res/values-ar/strings.xml
index b5310ee..c839a74 100644
--- a/tests/CarDeveloperOptions/res/values-ar/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ar/strings.xml
@@ -107,7 +107,7 @@
<string name="bluetooth_device_name" msgid="3682016026866302981">"اسم الجهاز"</string>
<string name="bluetooth_device_details" msgid="2500840679106321361">"إعدادات الجهاز"</string>
<string name="bluetooth_profile_details" msgid="1785505059738682493">"إعدادات الملف الشخصي"</string>
- <string name="bluetooth_name_not_set" msgid="1886067683138385142">"لم يتم تعيين اسم، استخدام اسم الحساب"</string>
+ <string name="bluetooth_name_not_set" msgid="1886067683138385142">"لم يتم ضبط اسم، استخدام اسم الحساب"</string>
<string name="bluetooth_scan_for_devices" msgid="3215740768422735880">"البحث عن أجهزة"</string>
<string name="bluetooth_rename_device" msgid="7862992396452800566">"إعادة تسمية هذا الجهاز"</string>
<string name="bluetooth_rename_button" msgid="8946904845821073267">"إعادة التسمية"</string>
@@ -216,7 +216,7 @@
<string name="radio_info_dl_kbps" msgid="2903778264453410272">"معدّل نقل بيانات DL (كيلوبت في الثانية):"</string>
<string name="radio_info_ul_kbps" msgid="3802245899811732716">"معدّل نقل بيانات UL (كيلوبت في الثانية):"</string>
<string name="radio_info_signal_location_label" msgid="6788144906873498013">"معلومات الموقع الخلوية (تم الإيقاف):"</string>
- <string name="radio_info_phy_chan_config" msgid="1184401689381480522">"تهيئة قناة LTE Physical:"</string>
+ <string name="radio_info_phy_chan_config" msgid="1184401689381480522">"إعداد قناة LTE Physical:"</string>
<string name="radio_info_cell_info_refresh_rate" msgid="3557422342215875913">"معدل إعادة تحميل المعلومات الخلوية:"</string>
<string name="radio_info_cellinfo_label" msgid="632796561627452215">"جميع معلومات القياس الخلوية:"</string>
<string name="radio_info_gprs_service_label" msgid="7926626443442993242">"خدمة البيانات:"</string>
@@ -235,7 +235,7 @@
<string name="radio_info_band_mode_label" msgid="9181607879920091762">"تحديد النطاق اللاسلكي"</string>
<string name="radio_info_voice_network_type_label" msgid="3686471589514241007">"نوع الشبكة الصوتية:"</string>
<string name="radio_info_data_network_type_label" msgid="5108279335070879015">"نوع شبكة البيانات:"</string>
- <string name="radio_info_set_perferred_label" msgid="1447353131819041587">"تعيين نوع الشبكة المفضل:"</string>
+ <string name="radio_info_set_perferred_label" msgid="1447353131819041587">"ضبط نوع الشبكة المفضل:"</string>
<string name="radio_info_ping_hostname_v4" msgid="4377067049156466290">"فحص اتصال اسم المضيف (www.google.com) عبر IPv4:"</string>
<string name="radio_info_ping_hostname_v6" msgid="3541896405771734445">"فحص اتصال اسم المضيف (www.google.com) عبر IPv6:"</string>
<string name="radio_info_http_client_test" msgid="781411599778629953">"اختبار عميل HTTP:"</string>
@@ -308,7 +308,7 @@
<string name="settings_label" msgid="7263237773415875813">"الإعدادات"</string>
<string name="settings_label_launcher" msgid="500627679902923496">"الإعدادات"</string>
<string name="settings_shortcut" msgid="4503714880251502167">"اختصار الإعدادات"</string>
- <string name="airplane_mode" msgid="4508870277398231073">"وضع الطائرة"</string>
+ <string name="airplane_mode" msgid="4508870277398231073">"وضع الطيران"</string>
<string name="wireless_networks_settings_title" msgid="4298430520189173949">"اللاسلكي والشبكات"</string>
<string name="radio_controls_summary" msgid="4596981962167684814">"إدارة Wi-Fi والبلوتوث ووضع الطائرة وشبكات الجوّال والشبكات الافتراضية الخاصة (VPN)"</string>
<string name="cellular_data_title" msgid="7909624119432695022">"بيانات الجوّال"</string>
@@ -552,9 +552,9 @@
<string name="crypt_keeper_data_corrupt_summary" product="default" msgid="5798580588985326937">"كلمة المرور التي أدخلتها صحيحة، ولكن للأسف بياناتك تالفة. \n\nلاستئناف استخدام هاتفك، يلزمك إجراء إعادة الضبط على الإعدادات الأصلية. عند إعداد الهاتف بعد إعادة الضبط، ستكون لديك فرصة لاستعادة أي بيانات تم نسخها احتياطيًا في حسابك على Google."</string>
<string name="crypt_keeper_switch_input_method" msgid="4744137470890459582">"تبديل أسلوب الإدخال"</string>
<string name="suggested_lock_settings_title" msgid="1518155558803371661">"تأمين هاتفك"</string>
- <string name="suggested_lock_settings_summary" product="tablet" msgid="1861066918594412519">"تعيين قفل شاشة لحماية الجهاز اللوحي"</string>
- <string name="suggested_lock_settings_summary" product="device" msgid="7127114417250029182">"تعيين قفل شاشة لحماية الجهاز"</string>
- <string name="suggested_lock_settings_summary" product="default" msgid="1090621950888321990">"تعيين قفل شاشة لحماية الهاتف"</string>
+ <string name="suggested_lock_settings_summary" product="tablet" msgid="1861066918594412519">"ضبط قفل شاشة لحماية الجهاز اللوحي"</string>
+ <string name="suggested_lock_settings_summary" product="device" msgid="7127114417250029182">"ضبط قفل شاشة لحماية الجهاز"</string>
+ <string name="suggested_lock_settings_summary" product="default" msgid="1090621950888321990">"ضبط قفل شاشة لحماية الهاتف"</string>
<string name="suggested_fingerprint_lock_settings_title" msgid="2860380076519822398">"إضافة بصمة الإصبع لإلغاء القفل"</string>
<string name="suggested_fingerprint_lock_settings_summary" product="tablet" msgid="8114514312665251311"></string>
<string name="suggested_fingerprint_lock_settings_summary" product="device" msgid="8114514312665251311"></string>
@@ -913,7 +913,7 @@
<string name="wifi_stopping" msgid="413711069039939520">"إيقاف Wi-Fi…"</string>
<string name="wifi_error" msgid="5605801874484465557">"خطأ"</string>
<string name="wifi_sap_no_channel_error" msgid="6881796988574851628">"لا يتوفر التردد ٥ غيغاهرتز في هذا البلد"</string>
- <string name="wifi_in_airplane_mode" msgid="4729571191578262246">"في وضع الطائرة"</string>
+ <string name="wifi_in_airplane_mode" msgid="4729571191578262246">"في وضع الطيران"</string>
<string name="wifi_notify_open_networks" msgid="4782239203624619655">"الإشعار بوجود شبكات مفتوحة"</string>
<string name="wifi_notify_open_networks_summary" msgid="1383681260705466715">"الإشعار عند توفر شبكة عامة عالية الجودة"</string>
<string name="wifi_wakeup" msgid="4963732992164721548">"تفعيل اتّصال Wi‑Fi تلقائيًا"</string>
@@ -951,7 +951,7 @@
<string name="wifi_menu_p2p" msgid="4945665601551289791">"اتصال Wi-Fi مباشر"</string>
<string name="wifi_menu_scan" msgid="9082691677803181629">"فحص"</string>
<string name="wifi_menu_advanced" msgid="5984484498045511072">"إعدادات متقدمة"</string>
- <string name="wifi_menu_configure" msgid="52192491120701266">"تهيئة"</string>
+ <string name="wifi_menu_configure" msgid="52192491120701266">"إعداد"</string>
<string name="wifi_menu_connect" msgid="3984327567173931219">"اتصال بالشبكة"</string>
<string name="wifi_menu_remember" msgid="717257200269700641">"تذكر الشبكة"</string>
<string name="wifi_menu_forget" msgid="7561140554450163075">"حذف الشبكة"</string>
@@ -973,7 +973,7 @@
<string name="wifi_ssid_hint" msgid="5010024648106585165">"يُرجى إدخال اسم SSID"</string>
<string name="wifi_security" msgid="9136702039496152831">"الأمان"</string>
<string name="wifi_hidden_network" msgid="6647772204699776833">"شبكة مخفية"</string>
- <string name="wifi_hidden_network_warning" msgid="8182333050353796473">"إذا لم يكن جهاز التوجيه يبث معرّف شبكة وتريد الاتصال به في المستقبل، يمكنك تعيين الشبكة كشبكة مخفية.\n\nربما ينشئ هذا خطرًا أمنيًا حيث سيبث هاتفك إشارته بانتظام للعثور على الشبكة.\n\nلن يؤدي تعيين الشبكة كشبكة مخفية إلى تغيير إعدادات جهاز التوجيه."</string>
+ <string name="wifi_hidden_network_warning" msgid="8182333050353796473">"إذا لم يكن جهاز التوجيه يبث معرّف شبكة وتريد الاتصال به في المستقبل، يمكنك ضبط الشبكة كشبكة مخفية.\n\nربما ينشئ هذا خطرًا أمنيًا حيث سيبث هاتفك إشارته بانتظام للعثور على الشبكة.\n\nلن يؤدي تعيين الشبكة كشبكة مخفية إلى تغيير إعدادات جهاز التوجيه."</string>
<string name="wifi_signal" msgid="696548364467704808">"قوة الإشارة"</string>
<string name="wifi_status" msgid="3439931558930689940">"الحالة"</string>
<string name="tx_wifi_speed" msgid="2571810085003261073">"سرعة نقل الرابط"</string>
@@ -1133,7 +1133,7 @@
<string name="wifi_hotspot_tethering_on_subtext" product="tablet" msgid="71421730039785897">"تتم مشاركة اتصال الإنترنت على هذا الجهاز اللوحي عبر نقطة الاتصال"</string>
<string name="wifi_hotspot_tethering_on_subtext" product="default" msgid="8914285514605049879">"تتم مشاركة اتصال الإنترنت على هذا الهاتف عبر نقطة الاتصال"</string>
<string name="wifi_hotspot_on_local_only_subtext" msgid="7415381343846704553">"يشارك التطبيق المحتوى. لمشاركة اتصال الإنترنت، يجب إيقاف نقطة الاتصال، ثم تفعيلها."</string>
- <string name="wifi_hotspot_no_password_subtext" msgid="5400500962974373706">"لم يتم تعيين كلمة مرور"</string>
+ <string name="wifi_hotspot_no_password_subtext" msgid="5400500962974373706">"لم يتم ضبط كلمة مرور"</string>
<string name="wifi_hotspot_name_title" msgid="6572202165400226127">"اسم نقطة الاتصال"</string>
<string name="wifi_hotspot_name_summary_connecting" msgid="5176787959408511889">"جارٍ تفعيل <xliff:g id="WIFI_HOTSPOT_NAME">%1$s</xliff:g>..."</string>
<string name="wifi_hotspot_name_summary_connected" msgid="8387768642326756749">"يمكن توصيل الأجهزة الأخرى بشبكة <xliff:g id="WIFI_HOTSPOT_NAME">%1$s</xliff:g>"</string>
@@ -1521,7 +1521,7 @@
<string name="storage_dialog_unmountable" msgid="7082856306456936054">"بطاقة <xliff:g id="NAME_0">^1</xliff:g> هذه تالفة. \n\nلاستخدام بطاقة <xliff:g id="NAME_1">^1</xliff:g> هذه، عليك إعدادها أولاً."</string>
<string name="storage_dialog_unsupported" msgid="8274023677580782553">"هذا الجهاز غير متوافق مع <xliff:g id="NAME_0">^1</xliff:g> هذه. \n\nلاستخدام <xliff:g id="NAME_1">^1</xliff:g> هذه مع هذا الجهاز، عليك إعدادها أولاً."</string>
<string name="storage_internal_format_details" msgid="2780806013122012384">"بعد إجراء التنسيق، يمكنك استخدام <xliff:g id="NAME_0">^1</xliff:g> هذه على أجهزة أخرى. \n\nوسيتم محو جميع البيانات الموجودة على <xliff:g id="NAME_1">^1</xliff:g> هذه. يمكنك إجراء النسخ الاحتياطي أولاً. \n\n"<b>"النسخ الاحتياطي للصور والوسائط الأخرى"</b>" \nيمكنك نقل ملفات الوسائط إلى وحدة تخزين بديلة على هذا الجهاز أو نقلها إلى جهاز كمبيوتر باستخدام كابل USB. \n\n"<b>"النسخ الاحتياطي للتطبيقات"</b>" \nستتم إزالة جميع التطبيقات المخزنة على <xliff:g id="NAME_6">^1</xliff:g> هذه وكذلك سيتم محو بياناتها. وللاحتفاظ بهذه التطبيقات، يمكنك نقلها إلى وحدة تخزين بديلة على هذا الجهاز."</string>
- <string name="storage_internal_unmount_details" msgid="4667435317528624039"><b>"عند إخراج <xliff:g id="NAME_0">^1</xliff:g> هذه، فإن التطبيقات المخزنة عليها ستتوقف عن العمل ولن تكون ملفات الوسائط المخزنة عليها متاحة حتى يتم إعادة إدخالها."</b>" \n\nلقد تمت تهيئة <xliff:g id="NAME_1">^1</xliff:g> للعمل على هذا الجهاز فقط. ولن تعمل على أي أجهزة أخرى."</string>
+ <string name="storage_internal_unmount_details" msgid="4667435317528624039"><b>"عند إخراج <xliff:g id="NAME_0">^1</xliff:g> هذه، فإن التطبيقات المخزنة عليها ستتوقف عن العمل ولن تكون ملفات الوسائط المخزنة عليها متاحة حتى يتم إعادة إدخالها."</b>" \n\nلقد تم إعداد <xliff:g id="NAME_1">^1</xliff:g> للعمل على هذا الجهاز فقط. ولن تعمل على أي أجهزة أخرى."</string>
<string name="storage_internal_forget_details" msgid="5655856574682184453">"لاستخدام التطبيقات أو الصور أو البيانات التي يحتوي عليها <xliff:g id="NAME">^1</xliff:g> يمكنك إعادة إدخاله. \n\nبدلاً من ذلك، يمكنك اختيار حذف وحدة التخزين هذه إذا لم يكن الجهاز متاحًا. \n\nوإذا اخترت الحذف، فستفقد جميع البيانات التي يحتوي عليها الجهاز للأبد. \n\nويمكنك إعادة تثبيت التطبيقات لاحقًا، إلا أنه سيتم فقد بياناتها المخزنة على هذا الجهاز."</string>
<string name="storage_internal_forget_confirm_title" msgid="331032276130605241">"هل تريد حذف <xliff:g id="NAME">^1</xliff:g>؟"</string>
<string name="storage_internal_forget_confirm" msgid="3052483375203727176">"سيتم فقد كل التطبيقات والصور والبيانات المخزنة على <xliff:g id="NAME">^1</xliff:g> هذه للأبد."</string>
@@ -1544,7 +1544,7 @@
<string name="storage_wizard_format_confirm_title" msgid="7785358616068633439">"التنسيق كوحدة تخزين داخلية"</string>
<string name="storage_wizard_format_confirm_body" msgid="4107762933332992624">"يتطلب هذا أن يتم تنسيق <xliff:g id="NAME_0">^1</xliff:g> لجعلها آمنة. \n\nبعد التنسيق، لن تعمل <xliff:g id="NAME_1">^1</xliff:g> هذه إلا على هذا الجهاز. \n\n"<b>"يؤدي التنسيق إلى محو جميع البيانات المخزنة حاليًا على <xliff:g id="NAME_2">^1</xliff:g>."</b>" ولتجنب فقد البيانات، يمكنك نسخها احتياطيًا."</string>
<string name="storage_wizard_format_confirm_public_title" msgid="5866830103788091426">"التهيئة كوحدة تخزين محمولة"</string>
- <string name="storage_wizard_format_confirm_public_body" msgid="1451308701654703353">"يتطلب هذا تهيئة <xliff:g id="NAME_0">^1</xliff:g>. \n\n"<b>"وتجدر الإشارة إلى أن التهيئة ستؤدي إلى محو جميع البيانات المخزنة حاليًا على <xliff:g id="NAME_1">^1</xliff:g>."</b>" لتجنب فقد البيانات، يمكنك الاحتفاظ بنسخة احتياطية منها."</string>
+ <string name="storage_wizard_format_confirm_public_body" msgid="1451308701654703353">"يتطلب هذا تهيئة <xliff:g id="NAME_0">^1</xliff:g>. \n\n"<b>"وتجدر الإشارة إلى أن الإعداد سيؤدي إلى محو جميع البيانات المخزنة حاليًا على <xliff:g id="NAME_1">^1</xliff:g>."</b>" لتجنب فقد البيانات، يمكنك الاحتفاظ بنسخة احتياطية منها."</string>
<string name="storage_wizard_format_confirm_next" msgid="236947984802247625">"محو البيانات والتنسيق"</string>
<string name="storage_wizard_format_progress_title" msgid="6905902731208646436">"جارٍ تنسيق <xliff:g id="NAME">^1</xliff:g>…"</string>
<string name="storage_wizard_format_progress_body" msgid="5346709539457190419">"لا تُزِل <xliff:g id="NAME">^1</xliff:g> أثناء تنفيذ عملية التنسيق."</string>
@@ -1604,7 +1604,7 @@
<string name="battery_level_title" msgid="5207775387973771646">"مستوى البطارية"</string>
<string name="apn_settings" msgid="8130776653826271664">"أسماء نقاط الوصول"</string>
<string name="apn_edit" msgid="4350571070853305357">"تعديل نقطة الوصول"</string>
- <string name="apn_not_set" msgid="5344235604466825691">"لم يتم التعيين"</string>
+ <string name="apn_not_set" msgid="5344235604466825691">"لم يتم الضبط"</string>
<string name="apn_name" msgid="8431432886706852226">"الاسم"</string>
<string name="apn_apn" msgid="190519449579357696">"APN"</string>
<string name="apn_http_proxy" msgid="8816906767987944465">"الخادم الوكيل"</string>
@@ -1725,7 +1725,7 @@
<string name="location_title" msgid="8664674161765477168">"موقعي"</string>
<string name="managed_profile_location_switch_title" msgid="8157384427925389680">"موقع الملف الشخصي للعمل"</string>
<string name="location_app_level_permissions" msgid="1298041503927632960">"إذن التطبيقات"</string>
- <string name="location_app_permission_summary_location_off" msgid="541372845344796336">"تم إيقاف خدمة الموقع الجغرافي."</string>
+ <string name="location_app_permission_summary_location_off" msgid="541372845344796336">"الموقع الجغرافي غير مفعّل"</string>
<plurals name="location_app_permission_summary_location_on" formatted="false" msgid="7904821382328758218">
<item quantity="zero">لدى <xliff:g id="BACKGROUND_LOCATION_APP_COUNT_2">%1$d</xliff:g> من أصل <xliff:g id="TOTAL_LOCATION_APP_COUNT_3">%2$d</xliff:g> تطبيق إذن وصول غير محدود.</item>
<item quantity="two">لدى <xliff:g id="BACKGROUND_LOCATION_APP_COUNT_2">%1$d</xliff:g> من أصل <xliff:g id="TOTAL_LOCATION_APP_COUNT_3">%2$d</xliff:g> تطبيق إذن وصول غير محدود.</item>
@@ -1801,8 +1801,8 @@
<string name="lockpassword_draw_your_pattern_again_header" msgid="9017394036814402348">"ارسم النقش مرة أخرى"</string>
<string name="lockpassword_choose_lock_generic_header" msgid="4418423132980560119">"اختيار طريقة فتح القفل"</string>
<string name="lockpassword_password_set_toast" msgid="601928982984489868">"تم ضبط كلمة المرور"</string>
- <string name="lockpassword_pin_set_toast" msgid="172594825722240059">"تم تعيين رمز PIN"</string>
- <string name="lockpassword_pattern_set_toast" msgid="6923260369475481406">"تم تعيين النقش"</string>
+ <string name="lockpassword_pin_set_toast" msgid="172594825722240059">"تم ضبط رمز PIN"</string>
+ <string name="lockpassword_pattern_set_toast" msgid="6923260369475481406">"تم ضبط النقش"</string>
<string name="lockpassword_choose_your_password_header_for_face" msgid="8823110536502072216">"لاستخدام المصادقة بالوجه، اضبط كلمة المرور"</string>
<string name="lockpassword_choose_your_pattern_header_for_face" msgid="5563793748503883666">"لاستخدام المصادقة بالوجه، اضبط النمط"</string>
<string name="lockpassword_choose_your_pin_header_for_face" msgid="7238352632535405068">"لاستخدام المصادقة بالوجه، اضبط رقم التعريف الشخصي"</string>
@@ -1913,7 +1913,7 @@
<string name="app_factory_reset" msgid="8718986000278776272">"إزالة التحديثات"</string>
<string name="auto_launch_enable_text" msgid="3372898942144027341">"لقد اخترت تشغيل هذا التطبيق بشكل تلقائي لبعض الإجراءات."</string>
<string name="always_allow_bind_appwidgets_text" msgid="2286211654774611037">"لقد اخترت السماح لهذا التطبيق بإنشاء الأدوات والوصول إلى بياناتها."</string>
- <string name="auto_launch_disable_text" msgid="8560921288036801416">"لم يتم تعيين إعدادات تلقائية."</string>
+ <string name="auto_launch_disable_text" msgid="8560921288036801416">"لم يتم ضبط إعدادات تلقائية."</string>
<string name="clear_activities" msgid="2068014972549235347">"محو الإعدادات التلقائية"</string>
<string name="screen_compatibility_text" msgid="1768064020294301496">"ربما لم يتم تصميم هذا التطبيق ليلائم شاشتك، يمكنك التحكم في كيفية ضبطه ليلائم شاشتك هنا."</string>
<string name="ask_compatibility" msgid="6687958195768084807">"السؤال عند الإطلاق"</string>
@@ -2144,7 +2144,7 @@
<string name="accessibility_screen_magnification_navbar_short_summary" msgid="5418767043532322397">"انقر على أحد الأزرار للتكبير"</string>
<string name="accessibility_screen_magnification_summary" msgid="3363006902079431772"><b>"للتكبير أو التصغير"</b>"، انقر على الشاشة 3 مرات بسرعة.\n"<ul><li>"اسحب بإصبعين أو أكثر للتمرير"</li>\n<li>"اضغط بإصبعين أو أكثر على الشاشة لضبط التكبير/التصغير"</li></ul>\n\n<b>"للتكبير أو التصغير مؤقتًا"</b>"، انقر على الشاشة 3 مرات بسرعة واستمر بالضغط بإصبعك بعد النقرة الثالثة.\n"<ul><li>"اسحب للتنقل على الشاشة"</li>\n<li>"ارفع إصبعك للتصغير"</li></ul>\n\n"لا يمكنك استخدام التكبير عند استخدام لوحة المفاتيح وشريط التنقل."</string>
<string name="accessibility_screen_magnification_navbar_summary" msgid="4726360285256503132">"عند تفعيل ميزة التكبير، استخدم زر إمكانية الوصول في أسفل الشاشة للتكبير بسرعة.\n\n"<b>"للتكبير أو التصغير"</b>"، انقر على زر إمكانية الوصول، ثم انقر في أي مكان على الشاشة.\n"<ul><li>"اسحب بإصبعين أو أكثر للتمرير"</li>\n<li>"اضغط بإصبعين أو أكثر على الشاشة لضبط التكبير/التصغير"</li></ul>\n\n<b>"للتكبير أو التصغير مؤقتًا"</b>"، انقر على زر إمكانية الوصول، ثم المس أي موضع على الشاشة مع الاستمرار.\n"<ul><li>"اسحب للتنقل على الشاشة"</li>\n<li>"ارفع إصبعك للتصغير"</li></ul>\n\n"لا يمكنك استخدام التكبير عند استخدام لوحة المفاتيح وشريط التنقل."</string>
- <string name="accessibility_screen_magnification_navbar_configuration_warning" msgid="6477234309484795550">"تم تعيين زر إمكانية الوصول لخدمة <xliff:g id="SERVICE">%1$s</xliff:g>. لاستخدام التكبير، المس زر إمكانية الوصول مع الاستمرار ثم اختر التكبير."</string>
+ <string name="accessibility_screen_magnification_navbar_configuration_warning" msgid="6477234309484795550">"تم ضبط زر إمكانية الوصول لخدمة <xliff:g id="SERVICE">%1$s</xliff:g>. لاستخدام التكبير، المس زر إمكانية الوصول مع الاستمرار ثم اختر التكبير."</string>
<string name="accessibility_global_gesture_preference_title" msgid="3842279082831426816">"مفتاح الاختصار لمستوى الصوت"</string>
<string name="accessibility_shortcut_service_title" msgid="3516052294376744060">"خدمة الاختصار"</string>
<string name="accessibility_shortcut_service_on_lock_screen_title" msgid="1279441617927949980">"السماح من شاشة القفل"</string>
@@ -2335,7 +2335,7 @@
<string name="print_restart" msgid="4090462480288441779">"إعادة تشغيل"</string>
<string name="print_cancel" msgid="4567831028966698753">"إلغاء"</string>
<string name="print_job_summary" msgid="438156926959424058">"<xliff:g id="PRINTER">%1$s</xliff:g>\n<xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="print_configuring_state_title_template" msgid="5052801061241050737">"جارٍ تهيئة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="print_configuring_state_title_template" msgid="5052801061241050737">"جارٍ إعداد <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="print_printing_state_title_template" msgid="8796814912920963803">"جارٍ طباعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="print_cancelling_state_title_template" msgid="4627355699517405600">"جارٍ إلغاء <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="print_failed_state_title_template" msgid="6575080578316671101">"خطأ في الطابعة في تنفيذ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -2546,7 +2546,7 @@
<string name="battery_desc_standby" product="tablet" msgid="2941777996429933419">"البطارية المستخدمة عندما يكون الجهاز اللوحي خاملاً"</string>
<string name="battery_desc_standby" product="default" msgid="8889482616564520287">"يتم استخدام البطارية عندما يكون الهاتف في وضع الخمول"</string>
<string name="battery_desc_radio" msgid="5119078473833865414">"البطارية مستخدمة بواسطة الراديو الخلوي"</string>
- <string name="battery_sugg_radio" msgid="3616364509738133415">"تبديل إلى وضع الطائرة للحفاظ على الطاقة في المناطق التي لا توجد بها تغطية للشبكة"</string>
+ <string name="battery_sugg_radio" msgid="3616364509738133415">"تبديل إلى وضع الطيران للحفاظ على الطاقة في المناطق التي لا توجد بها تغطية للشبكة"</string>
<string name="battery_desc_flashlight" msgid="4574819522143720917">"طاقة البطارية المستخدمة بواسطة ضوء الفلاش"</string>
<string name="battery_desc_camera" msgid="517966830222999462">"طاقة البطارية التي استهلكتها الكاميرا"</string>
<string name="battery_desc_display" msgid="6701005808894183097">"طاقة البطارية المستخدمة بواسطة العرض والإضاءة الخلفية"</string>
@@ -3078,7 +3078,7 @@
<string name="nfc_payment_how_it_works" msgid="7607901964687787177">"آلية العمل"</string>
<string name="nfc_payment_no_apps" msgid="8844440783395420860">"استخدِم هاتفك للدفع في المتاجر"</string>
<string name="nfc_payment_default" msgid="7869273092463612271">"التطبيق التلقائي للدفع"</string>
- <string name="nfc_payment_default_not_set" msgid="955804193510335338">"لم يتم التعيين"</string>
+ <string name="nfc_payment_default_not_set" msgid="955804193510335338">"لم يتم الضبط"</string>
<string name="nfc_payment_app_and_desc" msgid="102312684211458190">"<xliff:g id="APP">%1$s</xliff:g> - <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="nfc_payment_use_default" msgid="3098724195746409476">"استخدام التلقائي"</string>
<string name="nfc_payment_favor_default" msgid="7555356982142464260">"دومًا"</string>
@@ -3149,7 +3149,7 @@
<string name="sim_settings_title" msgid="8818243954752261922">"بطاقات SIM"</string>
<string name="sim_settings_summary" msgid="6516330865408217800">"<xliff:g id="SIM_NAME">%1$s</xliff:g> - <xliff:g id="SIM_NUMBER">%2$s</xliff:g>"</string>
<string name="sim_cards_changed_message" msgid="1012486903583092731">"تم تغيير بطاقات SIM"</string>
- <string name="sim_cards_changed_message_summary" msgid="5753692480107865077">"انقر لتعيين الأنشطة."</string>
+ <string name="sim_cards_changed_message_summary" msgid="5753692480107865077">"انقر لضبط الأنشطة."</string>
<string name="sim_cellular_data_unavailable" msgid="1832472508352891641">"بيانات الجوّال غير متاحة"</string>
<string name="sim_cellular_data_unavailable_summary" msgid="3093797406601964131">"انقر لاختيار شريحة SIM للبيانات."</string>
<string name="sim_calls_always_use" msgid="5322696995795851734">"استخدام هذا للمكالمات دائمًا"</string>
@@ -3295,8 +3295,8 @@
<string name="default_sound" msgid="6675629744816442953">"الصوت التلقائي"</string>
<string name="sound_settings_summary" msgid="8467549670633195109">"مستوى صوت الرنين على <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
<string name="sound_dashboard_summary" msgid="5187301919242823508">"مستوى الصوت والاهتزاز ووضع\"عدم الإزعاج\""</string>
- <string name="sound_settings_summary_vibrate" msgid="2194491116884798590">"تم تعيين الرنين على اهتزاز"</string>
- <string name="sound_settings_summary_silent" msgid="899823817462768876">"تم تعيين الرنين على صامت"</string>
+ <string name="sound_settings_summary_vibrate" msgid="2194491116884798590">"تم ضبط الرنين على اهتزاز"</string>
+ <string name="sound_settings_summary_silent" msgid="899823817462768876">"تم ضبط الرنين على صامت"</string>
<string name="sound_settings_example_summary" msgid="2091822107298841827">"مستوى صوت الرنين على ۸۰٪"</string>
<string name="media_volume_option_title" msgid="3553411883305505682">"مستوى صوت الوسائط"</string>
<string name="remote_media_volume_option_title" msgid="6355710054191873836">"مستوى صوت الإرسال"</string>
@@ -3867,7 +3867,7 @@
<string name="filter_notif_blocked_channels" msgid="6110799550327612670">"الفئات: متوفقة"</string>
<string name="filter_notif_dnd_channels" msgid="3251570137256371092">"الفئات: تتجاوز خيار \"عدم الإزعاج\""</string>
<string name="advanced_apps" msgid="6643869089344883537">"إعدادات متقدّمة"</string>
- <string name="configure_apps" msgid="4066683118857400943">"تهيئة التطبيقات"</string>
+ <string name="configure_apps" msgid="4066683118857400943">"إعداد التطبيقات"</string>
<string name="unknown_app" msgid="2312052973570376877">"تطبيق غير معروف"</string>
<string name="app_permissions" msgid="3215958256821756086">"مدير الأذونات"</string>
<string name="app_permissions_summary" msgid="8785798165776061594">"التطبيقات التي تستخدم <xliff:g id="APPS">%1$s</xliff:g>"</string>
@@ -3973,7 +3973,7 @@
<string name="usb_use_MIDI" msgid="4710632870781041401">"MIDI"</string>
<string name="usb_use_MIDI_desc" msgid="1770966187150010947">"يمكنك استخدام هذا الجهاز باعتباره MIDI"</string>
<string name="usb_use" msgid="8940500223316278632">"استخدام USB في"</string>
- <string name="usb_default_label" msgid="7471316635263936101">"تهيئة USB التلقائية"</string>
+ <string name="usb_default_label" msgid="7471316635263936101">"إعداد USB التلقائي"</string>
<string name="usb_default_info" msgid="953775292571786528">"عند الاتصال بجهاز آخر وإلغاء قفل هاتفك، سيتم تطبيق هذه الإعدادات. لذلك يجب الاتصال بالأجهزة الموثوق بها فقط."</string>
<string name="usb_pref" msgid="6194821550693495068">"USB"</string>
<string name="usb_preference" msgid="7092987095048592826">"إعدادات USB"</string>
@@ -4132,7 +4132,7 @@
<string name="condition_expand_show" msgid="4118818022763913777">"إظهار"</string>
<string name="condition_expand_hide" msgid="1112721783024332643">"إخفاء"</string>
<string name="condition_hotspot_title" msgid="4143299802283098506">"نقطة الاتصال مفعّلة"</string>
- <string name="condition_airplane_title" msgid="8484582712516148433">"وضع الطائرة قيد التفعيل"</string>
+ <string name="condition_airplane_title" msgid="8484582712516148433">"وضع الطيران قيد التفعيل"</string>
<string name="condition_airplane_summary" msgid="3021193218494740742">"الشبكات غير متوفرة"</string>
<string name="condition_zen_title" msgid="2128184708916052585">"تمّ تفعيل \"الرجاء عدم الإزعاج\""</string>
<string name="condition_zen_summary_phone_muted" msgid="4396050395522974654">"تم كتم صوت الهاتف."</string>
@@ -4217,7 +4217,7 @@
<string name="set_data_limit" msgid="5043770023229990674">"ضبط الحد الأقصى للبيانات"</string>
<string name="data_limit" msgid="5793521160051596228">"الحد الأقصى للبيانات"</string>
<string name="data_usage_template" msgid="6848274347956096882">"<xliff:g id="ID_1">%1$s</xliff:g> مستخدمة خلال <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="configure" msgid="8232696842838580549">"تهيئة"</string>
+ <string name="configure" msgid="8232696842838580549">"إعداد"</string>
<string name="data_usage_other_apps" msgid="7002491980141402084">"التطبيقات الأخرى المضمّنة في الاستخدام"</string>
<plurals name="data_saver_unrestricted_summary" formatted="false" msgid="6046013861315713697">
<item quantity="zero">هناك <xliff:g id="COUNT">%1$d</xliff:g> تطبيق مسموح له باستخدام البيانات بدون قيود عند تفعيل ميزة \"توفير البيانات\"</item>
@@ -4436,7 +4436,7 @@
<string name="domain_url_section_title" msgid="206403507921518321">"التطبيقات المثبَّتة"</string>
<string name="automatic_storage_manager_activation_warning" msgid="2630083316417707308">"تتم إدارة مساحة التخزين لجهازك الآن عن طريق مدير مساحة التخزين"</string>
<string name="account_for_section_header" msgid="5975241715840642563">"حسابات <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
- <string name="configure_section_header" msgid="6988981883075615136">"تهيئة"</string>
+ <string name="configure_section_header" msgid="6988981883075615136">"إعداد"</string>
<string name="auto_sync_account_title" msgid="2394463123733529506">"مزامنة البيانات تلقائيًا"</string>
<string name="auto_sync_personal_account_title" msgid="6844465157916100655">"مزامنة البيانات الشخصية تلقائيًا"</string>
<string name="auto_sync_work_account_title" msgid="2403222633447522376">"مزامنة بيانات العمل تلقائيًا"</string>
@@ -4482,11 +4482,11 @@
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> تطبيق</item>
</plurals>
<string name="enterprise_privacy_input_method" msgid="5885916325874284011">"لوحة المفاتيح التلقائية"</string>
- <string name="enterprise_privacy_input_method_name" msgid="439610095825218563">"تعيين على <xliff:g id="APP_LABEL">%s</xliff:g>"</string>
+ <string name="enterprise_privacy_input_method_name" msgid="439610095825218563">"ضبط على <xliff:g id="APP_LABEL">%s</xliff:g>"</string>
<string name="enterprise_privacy_always_on_vpn_device" msgid="2022700916516458213">"تم تفعيل إعداد \"شبكة افتراضية خاصة (VPN) دائمة التفعيل\""</string>
<string name="enterprise_privacy_always_on_vpn_personal" msgid="5644065780843002044">"تم تفعيل إعداد \"شبكة افتراضية خاصة (VPN) دائمة التفعيل\" في الملف الشخصي"</string>
<string name="enterprise_privacy_always_on_vpn_work" msgid="6443089897985373564">"تم تفعيل \"شبكة افتراضية خاصة (VPN) دائمة التفعيل\" في الملف الشخصي للعمل"</string>
- <string name="enterprise_privacy_global_http_proxy" msgid="3862135895716080830">"تم تعيين الخادم الوكيل HTTP العام"</string>
+ <string name="enterprise_privacy_global_http_proxy" msgid="3862135895716080830">"تم ضبط الخادم الوكيل HTTP العام"</string>
<string name="enterprise_privacy_ca_certs_device" msgid="7715658848470643878">"بيانات الاعتماد الموثوقة"</string>
<string name="enterprise_privacy_ca_certs_personal" msgid="1356447417193483802">"بيانات اعتماد موثوقة في ملفك الشخصي"</string>
<string name="enterprise_privacy_ca_certs_work" msgid="836419648894546893">"بيانات اعتماد موثوقة في ملفك الشخصي للعمل"</string>
@@ -4594,7 +4594,7 @@
<string name="show_first_crash_dialog" msgid="3682063068903692710">"عرض مربع حوار الأعطال دائمًا"</string>
<string name="show_first_crash_dialog_summary" msgid="8197987550025401754">"عرض مربع الحوار في كل مرة يتعطل فيها تطبيق"</string>
<string name="angle_enabled_app" msgid="4359266182151708733">"اختيار التطبيق الذي يستخدم ANGLE"</string>
- <string name="angle_enabled_app_not_set" msgid="7428910515748621910">"لم يتم تعيين تطبيق لاستخدام ANGLE"</string>
+ <string name="angle_enabled_app_not_set" msgid="7428910515748621910">"لم يتم ضبط تطبيق لاستخدام ANGLE"</string>
<string name="angle_enabled_app_set" msgid="7313088703610569320">"التطبيق الذي يستخدم ANGLE: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="game_driver_dashboard_title" msgid="219443350404091201">"إعدادات Game Driver المفضّلة"</string>
<string name="game_driver_dashboard_summary" msgid="1500674075618790528">"تعديل إعدادات Game Driver"</string>
@@ -4781,7 +4781,7 @@
<string name="settings_panel_title" msgid="8181989386118232534">"لوحة الإعدادات"</string>
<string name="internet_connectivity_panel_title" msgid="341712994620215750">"اتصال الإنترنت"</string>
<string name="volume_connectivity_panel_title" msgid="4998755371496690971">"مستوى الصوت"</string>
- <string name="mobile_data_ap_mode_disabled" msgid="2452716524753472885">"غير متاح أثناء وضع الطائرة"</string>
+ <string name="mobile_data_ap_mode_disabled" msgid="2452716524753472885">"غير متاح أثناء وضع الطيران"</string>
<string name="force_desktop_mode" msgid="6973100177551040740">"فرض وضع سطح المكتب"</string>
<string name="force_desktop_mode_summary" msgid="8865007610266954719">"فرض وضع سطح المكتب التجريبي على شاشات العرض الثانوية"</string>
<string name="hwui_force_dark_title" msgid="3744825212652331461">"إلغاء ميزة فرض تعتيم الشاشة"</string>
diff --git a/tests/CarDeveloperOptions/res/values-as/strings.xml b/tests/CarDeveloperOptions/res/values-as/strings.xml
index 0a739bb..90bf1a6 100644
--- a/tests/CarDeveloperOptions/res/values-as/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-as/strings.xml
@@ -3726,7 +3726,7 @@
<string name="sharing_remote_bugreport_dialog_message" msgid="3814787466701526359">"আপোনাৰ আইটি প্ৰশাসকৰ সৈতে এই বাগ প্ৰতিবেদনটো শ্বেয়াৰ কৰা হৈছে। অধিক তথ্যৰ বাবে তেওঁলোকৰ সৈতে যোগাযোগ কৰক।"</string>
<string name="share_remote_bugreport_action" msgid="8600797271670537888">"শ্বেয়াৰ কৰক"</string>
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"প্ৰত্যাখ্যান কৰক"</string>
- <string name="usb_use_charging_only" msgid="2344625733377110164">"কোনো ডেটা স্থানান্তৰণ কৰিব নোৱাৰি"</string>
+ <string name="usb_use_charging_only" msgid="2344625733377110164">"ডেটা স্থানান্তৰ কৰিব নোৱাৰি"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"ডিভাইচটো কেৱল চাৰ্জ কৰক"</string>
<string name="usb_use_power_only" msgid="6595783381323810697">"চ্চাৰ্জাৰ ডিভাইচত সংযোগ কৰা হ’ল"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"ফাইল স্থানান্তৰণৰ বাবে"</string>
diff --git a/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml b/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
index ad1d89f..f3b11bc 100644
--- a/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
@@ -1644,7 +1644,7 @@
<string name="usb_tethering_subtext" product="tablet" msgid="154536000235361034">"Deljenje internet veze tableta preko USB-a"</string>
<string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"Bluetooth privezivanje"</string>
<string name="bluetooth_tethering_subtext" product="tablet" msgid="6868756914621131635">"Delite internet vezu tableta preko Bluetooth-a"</string>
- <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Delite internet vezu telefona preko Bluetooth-a"</string>
+ <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Deljenje internet veze telefona preko Bluetooth-a"</string>
<string name="bluetooth_tethering_off_subtext_config" msgid="3981528184780083266">"Internet veza uređaja <xliff:g id="DEVICE_NAME">%1$d</xliff:g> se deli preko Bluetooth-a"</string>
<string name="bluetooth_tethering_overflow_error" msgid="6946561351369376943">"Privezivanje na više od <xliff:g id="MAXCONNECTION">%1$d</xliff:g> uređaja nije moguće."</string>
<string name="bluetooth_untether_blank" msgid="5428300773782256084">"Internet veza sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> će biti prekinuta."</string>
diff --git a/tests/CarDeveloperOptions/res/values-be/strings.xml b/tests/CarDeveloperOptions/res/values-be/strings.xml
index 33ea083..9bbff0d 100644
--- a/tests/CarDeveloperOptions/res/values-be/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-be/strings.xml
@@ -1411,7 +1411,7 @@
<string name="memory_media_usage" msgid="2744652206722240527">"Медыя"</string>
<string name="memory_downloads_usage" msgid="7039979723012065168">"Спампаваць"</string>
<string name="memory_dcim_usage" msgid="599009211606524732">"Выявы, відэа"</string>
- <string name="memory_music_usage" msgid="809605300042546279">"Аўдыё (музыка, рынгтоны, падкасты і г. д.)"</string>
+ <string name="memory_music_usage" msgid="809605300042546279">"Аўдыя (музыка, рынгтоны, падкасты і г. д.)"</string>
<string name="memory_media_misc_usage" msgid="6258827529046910705">"Іншыя файлы"</string>
<string name="memory_media_cache_usage" msgid="1307620682751377717">"Кэшаваныя дадзеныя"</string>
<string name="sd_eject" product="nosdcard" msgid="3016608823130472449">"Адключыць сумеснае сховішча"</string>
@@ -3231,7 +3231,7 @@
<string name="other_sound_settings" msgid="5250376066099818676">"Іншыя гукі"</string>
<string name="dial_pad_tones_title" msgid="8877212139988655769">"Гукі панэлі набору"</string>
<string name="screen_locking_sounds_title" msgid="4407110895465866809">"Гукі блакіроўкі экрана"</string>
- <string name="charging_sounds_title" msgid="5070437987230894287">"Сігнал зарадкі і вібрацыя"</string>
+ <string name="charging_sounds_title" msgid="5070437987230894287">"Гукі і вібрацыя пры зарадцы"</string>
<string name="docking_sounds_title" msgid="2573137471605541366">"Гукі док-станцыі"</string>
<string name="touch_sounds_title" msgid="165237488496165652">"Гукі пры дотыку"</string>
<string name="vibrate_on_touch_title" msgid="6360155469279157684">"Вібрацыя пры націсканні"</string>
diff --git a/tests/CarDeveloperOptions/res/values-bg/strings.xml b/tests/CarDeveloperOptions/res/values-bg/strings.xml
index 6d0ce88..8b44d0a 100644
--- a/tests/CarDeveloperOptions/res/values-bg/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bg/strings.xml
@@ -3285,7 +3285,7 @@
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Звуците за служебния и личния потребителски профил са едни и същи"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"Служебна мелодия на телефона"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"Стандартен звук за служебните известия"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Стандартен звук за служебните будилници"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Стандартен звук за служебните аларми"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Като за личния потребителски профил"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"Да се заменят ли звуците?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"Замяна"</string>
diff --git a/tests/CarDeveloperOptions/res/values-bs/arrays.xml b/tests/CarDeveloperOptions/res/values-bs/arrays.xml
index 220dbb9..524fd82 100644
--- a/tests/CarDeveloperOptions/res/values-bs/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-bs/arrays.xml
@@ -202,7 +202,7 @@
<item msgid="3778273775365258534">"IS95A"</item>
</string-array>
<string-array name="mvno_type_entries">
- <item msgid="6984770764726663331">"Nema"</item>
+ <item msgid="6984770764726663331">"Ništa"</item>
<item msgid="1469208769491004112">"SPN"</item>
<item msgid="7556656048009090524">"IMSI"</item>
<item msgid="8636516530542473799">"GID"</item>
diff --git a/tests/CarDeveloperOptions/res/values-bs/strings.xml b/tests/CarDeveloperOptions/res/values-bs/strings.xml
index 602a26b..fc50378 100644
--- a/tests/CarDeveloperOptions/res/values-bs/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bs/strings.xml
@@ -278,8 +278,8 @@
<string name="dlg_remove_locales_error_title" msgid="9090578326002163975">"Ne mogu se ukloniti svi jezici"</string>
<string name="dlg_remove_locales_error_message" msgid="6799897638891903618">"Zadržite najmanje jedan preferirani jezik"</string>
<string name="locale_not_translated" msgid="7943669576006420058">"Možda nije dostupno u nekim aplikacijama"</string>
- <string name="action_drag_label_move_up" msgid="2074064283966078352">"Pomjeri prema gore"</string>
- <string name="action_drag_label_move_down" msgid="1367989732445492291">"Pomjeri prema dolje"</string>
+ <string name="action_drag_label_move_up" msgid="2074064283966078352">"Pomjeri nagore"</string>
+ <string name="action_drag_label_move_down" msgid="1367989732445492291">"Pomjeri nadolje"</string>
<string name="action_drag_label_move_top" msgid="2033098833739345957">"Pomjeri na vrh"</string>
<string name="action_drag_label_move_bottom" msgid="5583190721915611567">"Pomjeri na dno"</string>
<string name="action_drag_label_remove" msgid="3362982836323040394">"Ukloni jezik"</string>
@@ -735,7 +735,7 @@
</plurals>
<string name="manage_trust_agents" msgid="8129970926213142261">"Pouzdani agenti"</string>
<string name="disabled_because_no_backup_security" msgid="8127039979909203528">"Da biste ovo koristili, prvo postavite zaključavanje ekrana"</string>
- <string name="manage_trust_agents_summary" msgid="2023116850759962248">"Nema"</string>
+ <string name="manage_trust_agents_summary" msgid="2023116850759962248">"Ništa"</string>
<plurals name="manage_trust_agents_summary_on" formatted="false" msgid="5550538038916606097">
<item quantity="one"><xliff:g id="COUNT">%d</xliff:g> aktivni pouzdani agent</item>
<item quantity="few"><xliff:g id="COUNT">%d</xliff:g> aktivna pouzdana agenta</item>
@@ -3165,9 +3165,9 @@
<string name="keywords_default_payment_app" msgid="845369409578423996">"plaćanje, zadano"</string>
<string name="keywords_ambient_display" msgid="8835182491798487184">"dolazno obavještenje"</string>
<string name="keywords_hotspot_tethering" msgid="1723591462602613867">"povezivanje putem usb uređaja, povezivanje putem bluetooth uređaja, wifi pristupna tačka"</string>
- <string name="keywords_touch_vibration" msgid="2081175517528255224">"haptika, vibriranje, ekran, osjetljivost"</string>
- <string name="keywords_ring_vibration" msgid="4210509151866460210">"haptika, vibriranje, telefon, poziv, osjetljivost, zvono"</string>
- <string name="keywords_notification_vibration" msgid="1077515502086745166">"haptika, vibriranje, osjetljivost"</string>
+ <string name="keywords_touch_vibration" msgid="2081175517528255224">"haptička tehnologija, vibriranje, ekran, osjetljivost"</string>
+ <string name="keywords_ring_vibration" msgid="4210509151866460210">"haptička tehnologija, vibriranje, telefon, poziv, osjetljivost, zvono"</string>
+ <string name="keywords_notification_vibration" msgid="1077515502086745166">"haptička tehnologija, vibriranje, osjetljivost"</string>
<string name="keywords_battery_saver_sticky" msgid="8733804259716284872">"ušteda baterije, ljepljivo, istrajnost, ušteda energije, baterija"</string>
<string name="default_sound" msgid="6675629744816442953">"Podrazumijevani zvuk"</string>
<string name="sound_settings_summary" msgid="8467549670633195109">"Jačina zvuka zvona je na <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
@@ -3325,7 +3325,7 @@
<string name="zen_onboarding_current_setting_summary" msgid="3569246708507270821">"(Trenutna postavka)"</string>
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"Promijeniti postavke obavještenja načina rada Ne ometaj?"</string>
<string name="sound_work_settings" msgid="4140215240360927923">"Zvukovi radnog profila"</string>
- <string name="work_use_personal_sounds_title" msgid="531727195073003599">"Koristite zvukove ličnog profila"</string>
+ <string name="work_use_personal_sounds_title" msgid="531727195073003599">"Koristi zvukove ličnog profila"</string>
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Zvukovi su isti za radni i lični profil"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"Melodija zvona radnog telefona"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"Zadani zvuk radnih obavještenja"</string>
@@ -4248,7 +4248,7 @@
<string name="enterprise_privacy_network_logs" msgid="5427398751599441159">"Najskoriji zapis mrežnog saobraćaja"</string>
<string name="enterprise_privacy_bug_reports" msgid="283443567328836380">"Najnoviji izvještaj o greškama"</string>
<string name="enterprise_privacy_security_logs" msgid="8936969480449604726">"Najnoviji zapisnik o aktivnostima"</string>
- <string name="enterprise_privacy_none" msgid="5990646476868794882">"Nema"</string>
+ <string name="enterprise_privacy_none" msgid="5990646476868794882">"Ništa"</string>
<string name="enterprise_privacy_enterprise_installed_packages" msgid="6575025134782391212">"Aplikacije su instalirane"</string>
<string name="enterprise_privacy_apps_count_estimation_info" msgid="5020730108878608500">"Broj aplikacija je samo procjena. Možda nisu obuhvaćene aplikacije koje su instalirane izvan Play trgovine."</string>
<plurals name="enterprise_privacy_number_packages_lower_bound" formatted="false" msgid="5161417161943060602">
diff --git a/tests/CarDeveloperOptions/res/values-ca/arrays.xml b/tests/CarDeveloperOptions/res/values-ca/arrays.xml
index dc71c8e..2ff467c 100644
--- a/tests/CarDeveloperOptions/res/values-ca/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-ca/arrays.xml
@@ -257,7 +257,7 @@
<item msgid="5420704980305018295">"volum de la veu"</item>
<item msgid="5797363115508970204">"volum del to"</item>
<item msgid="8233154098550715999">"volum de multimèdia"</item>
- <item msgid="5196715605078153950">"volum de l\'alarma"</item>
+ <item msgid="5196715605078153950">"volum d\'alarma"</item>
<item msgid="394030698764284577">"volum de notificació"</item>
<item msgid="8952898972491680178">"volum del Bluetooth"</item>
<item msgid="8506227454543690851">"mantén actiu"</item>
@@ -324,7 +324,7 @@
<item msgid="1600379420669104929">"Volum de la veu"</item>
<item msgid="6296768210470214866">"Volum del to"</item>
<item msgid="510690696071629241">"Volum de multimèdia"</item>
- <item msgid="406861638631430109">"Volum de l\'alarma"</item>
+ <item msgid="406861638631430109">"Volum d\'alarma"</item>
<item msgid="4715864795872233884">"Volum de notificació"</item>
<item msgid="2311478519251301183">"Volum del Bluetooth"</item>
<item msgid="5133991377896747027">"Mantén actiu"</item>
diff --git a/tests/CarDeveloperOptions/res/values-ca/strings.xml b/tests/CarDeveloperOptions/res/values-ca/strings.xml
index 4694958..7a19e51 100644
--- a/tests/CarDeveloperOptions/res/values-ca/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ca/strings.xml
@@ -1615,7 +1615,7 @@
<string name="tether_settings_title_bluetooth" msgid="1999590158102569959">"Compartició de xarxa per Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1159128764162788159">"Compartició de xarxa"</string>
<string name="tether_settings_title_all" msgid="6935843543433954181">"Punt d\'accés Wi-Fi i compartició de xarxa"</string>
- <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"Punt d\'accés Wi-Fi i compartició de xarxa activats"</string>
+ <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"Punt d\'accés Wi-Fi activat, compartició de xarxa"</string>
<string name="tether_settings_summary_hotspot_on_tether_off" msgid="8010689354668285422">"Punt d\'accés Wi-Fi activat"</string>
<string name="tether_settings_summary_hotspot_off_tether_on" msgid="1349909238672649877">"Compartició de xarxa"</string>
<string name="tether_settings_disabled_on_data_saver" msgid="3682544845899910726">"No es pot compartir la xarxa ni utilitzar punts d\'accés Wi-Fi mentre la funció Economitzador de dades està activada"</string>
@@ -1648,7 +1648,7 @@
<string name="mobile_connect_to_internet" msgid="6031886097365170913">"Connecta a Internet"</string>
<string name="location_title" msgid="8664674161765477168">"La meva ubicació"</string>
<string name="managed_profile_location_switch_title" msgid="8157384427925389680">"Ubicació per al perfil de treball"</string>
- <string name="location_app_level_permissions" msgid="1298041503927632960">"Permís d\'aplicacions"</string>
+ <string name="location_app_level_permissions" msgid="1298041503927632960">"Permisos de les aplicacions"</string>
<string name="location_app_permission_summary_location_off" msgid="541372845344796336">"La ubicació està desactivada"</string>
<plurals name="location_app_permission_summary_location_on" formatted="false" msgid="7904821382328758218">
<item quantity="other">Aplicacions que tenen accés il·limitat: <xliff:g id="BACKGROUND_LOCATION_APP_COUNT_2">%1$d</xliff:g> de <xliff:g id="TOTAL_LOCATION_APP_COUNT_3">%2$d</xliff:g></item>
@@ -3137,7 +3137,7 @@
<string name="media_volume_option_title" msgid="3553411883305505682">"Volum de multimèdia"</string>
<string name="remote_media_volume_option_title" msgid="6355710054191873836">"Volum emès"</string>
<string name="call_volume_option_title" msgid="5028003296631037334">"Volum de trucada"</string>
- <string name="alarm_volume_option_title" msgid="3184076022438477047">"Volum de l\'alarma"</string>
+ <string name="alarm_volume_option_title" msgid="3184076022438477047">"Volum d\'alarma"</string>
<string name="ring_volume_option_title" msgid="2038924918468372264">"Volum del to"</string>
<string name="notification_volume_option_title" msgid="1358512611511348260">"Volum de notificació"</string>
<string name="ringtone_title" msgid="1409086028485922583">"So de trucada del telèfon"</string>
diff --git a/tests/CarDeveloperOptions/res/values-cs/strings.xml b/tests/CarDeveloperOptions/res/values-cs/strings.xml
index 4457f48..ea461a7 100644
--- a/tests/CarDeveloperOptions/res/values-cs/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-cs/strings.xml
@@ -1162,7 +1162,7 @@
<string name="ring_volume_title" msgid="5874791723449821646">"Hlasitost vyzvánění"</string>
<string name="vibrate_in_silent_title" msgid="2314667015729841220">"Vibrovat v tichém režimu"</string>
<string name="notification_sound_title" msgid="6812164482799723931">"Výchozí zvuk oznámení"</string>
- <string name="incoming_call_volume_title" msgid="4736570528754310450">"Vyzváněcí tón"</string>
+ <string name="incoming_call_volume_title" msgid="4736570528754310450">"Vyzvánění"</string>
<string name="notification_volume_title" msgid="6022562909288085275">"Oznámení"</string>
<string name="checkbox_notification_same_as_incoming_call" msgid="7312942422655861175">"Použije hlasitost příchozích hovorů také pro oznámení"</string>
<string name="home_work_profile_not_supported" msgid="6137073723297076818">"Nepodporuje pracovní profily"</string>
@@ -1677,7 +1677,7 @@
<string name="sms_change_default_no_previous_dialog_text" msgid="4680224695080527907">"Chcete pro zprávy SMS používat aplikaci <xliff:g id="NEW_APP">%s</xliff:g>?"</string>
<string name="network_scorer_picker_title" msgid="1691073966560952916">"Poskytovatel hodnocení sítí"</string>
<string name="network_scorer_picker_none_preference" msgid="6448280557733231737">"Žádné"</string>
- <string name="network_scorer_change_active_dialog_title" msgid="4274159562371475090">"Změnit nastavení Google Wi-Fi Assistant?"</string>
+ <string name="network_scorer_change_active_dialog_title" msgid="4274159562371475090">"Změnit asistenta pro Wi-Fi?"</string>
<string name="network_scorer_change_active_dialog_text" msgid="4264089809189760730">"Chcete spravovat síťová připojení pomocí aplikace <xliff:g id="NEW_APP">%1$s</xliff:g> namísto aplikace <xliff:g id="CURRENT_APP">%2$s</xliff:g>?"</string>
<string name="network_scorer_change_active_no_previous_dialog_text" msgid="6394483538843474495">"Chcete spravovat síťová připojení pomocí aplikace <xliff:g id="NEW_APP">%s</xliff:g>?"</string>
<string name="mobile_unknown_sim_operator" msgid="872589370085135817">"Operátor SIM karty není znám"</string>
@@ -3222,7 +3222,7 @@
<string name="alarm_volume_option_title" msgid="3184076022438477047">"Hlasitost budíku"</string>
<string name="ring_volume_option_title" msgid="2038924918468372264">"Hlasitost vyzvánění"</string>
<string name="notification_volume_option_title" msgid="1358512611511348260">"Hlasitost oznámení"</string>
- <string name="ringtone_title" msgid="1409086028485922583">"Vyzváněcí tón telefonu"</string>
+ <string name="ringtone_title" msgid="1409086028485922583">"Vyzvánění telefonu"</string>
<string name="notification_ringtone_title" msgid="2932960620843976285">"Výchozí zvuk oznámení"</string>
<string name="notification_unknown_sound_title" msgid="8043718667804838398">"Zvuk z aplikace"</string>
<string name="notification_sound_default" msgid="2664544380802426260">"Výchozí zvuk oznámení"</string>
@@ -3371,7 +3371,7 @@
<string name="sound_work_settings" msgid="4140215240360927923">"Zvuky pracovního profilu"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"Použít zvuky osobního profilu"</string>
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Zvuky pracovního a osobního profilu jsou stejné"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"Vyzváněcí tón prac. telefonu"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"Vyzvánění prac. telefonu"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"Výchozí zvuk pracovního oznámení"</string>
<string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Výchozí zvuk pracovního budíku"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Stejné jako v osobním profilu"</string>
@@ -3380,7 +3380,7 @@
<string name="work_sync_dialog_message" msgid="944233463059129156">"Pro pracovní profil budou použity zvuky z osobního profilu"</string>
<string name="ringtones_install_custom_sound_title" msgid="210551218424553671">"Přidat vlastní zvuk?"</string>
<string name="ringtones_install_custom_sound_content" msgid="6683649115132255452">"Soubor bude zkopírován do složky <xliff:g id="FOLDER_NAME">%s</xliff:g>"</string>
- <string name="ringtones_category_preference_title" msgid="4491932700769815470">"Vyzváněcí tóny"</string>
+ <string name="ringtones_category_preference_title" msgid="4491932700769815470">"Vyzvánění"</string>
<string name="other_sound_category_preference_title" msgid="2045757472469840859">"Další zvuky a vibrace"</string>
<string name="configure_notification_settings" msgid="291914315140851270">"Oznámení"</string>
<string name="recent_notifications" msgid="8125865995065032049">"Nedávno odeslané"</string>
diff --git a/tests/CarDeveloperOptions/res/values-de/strings.xml b/tests/CarDeveloperOptions/res/values-de/strings.xml
index 704cc29..be3c5fe 100644
--- a/tests/CarDeveloperOptions/res/values-de/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-de/strings.xml
@@ -2278,9 +2278,9 @@
<string name="battery_tip_smart_battery_title" product="tablet" msgid="203494973250969040">"Akkulaufzeit des Tablets verbessern"</string>
<string name="battery_tip_smart_battery_title" product="device" msgid="7419448992583346364">"Akkulaufzeit des Geräts verbessern"</string>
<string name="battery_tip_smart_battery_summary" msgid="5344821856478265778">"Funktion \"Akku-Manager\" aktivieren"</string>
- <string name="battery_tip_early_heads_up_title" msgid="707163785378746813">"Energiesparmodus aktivieren"</string>
+ <string name="battery_tip_early_heads_up_title" msgid="707163785378746813">"Stromsparmodus aktivieren"</string>
<string name="battery_tip_early_heads_up_summary" msgid="4231489566422395156">"Der Akku könnte früher als üblich leer sein"</string>
- <string name="battery_tip_early_heads_up_done_title" msgid="112550885882648429">"Energiesparmodus ist aktiviert"</string>
+ <string name="battery_tip_early_heads_up_done_title" msgid="112550885882648429">"Stromsparmodus ist aktiviert"</string>
<string name="battery_tip_early_heads_up_done_summary" msgid="8692257022962771181">"Einige Funktionen sind eventuell eingeschränkt"</string>
<string name="battery_tip_high_usage_title" product="default" msgid="4103005178310487352">"Smartphone mehr als üblich genutzt"</string>
<string name="battery_tip_high_usage_title" product="tablet" msgid="1019583260005768965">"Tablet mehr als üblich genutzt"</string>
@@ -2318,9 +2318,9 @@
<string name="battery_tip_unrestrict_app_dialog_message" msgid="8120081438825031335">"Diese App kann dann im Hintergrund laufen und beansprucht dabei den Akku. Er könnte deshalb früher als erwartet leer sein."</string>
<string name="battery_tip_unrestrict_app_dialog_ok" msgid="9154938931448151479">"Entfernen"</string>
<string name="battery_tip_unrestrict_app_dialog_cancel" msgid="7331148618292397166">"Abbrechen"</string>
- <string name="battery_tip_dialog_summary_message" product="default" msgid="7244950433272770280">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Energiesparmodus aktivieren."</string>
- <string name="battery_tip_dialog_summary_message" product="tablet" msgid="1721081030632329647">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Energiesparmodus aktivieren."</string>
- <string name="battery_tip_dialog_summary_message" product="device" msgid="146872407040848465">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Energiesparmodus aktivieren."</string>
+ <string name="battery_tip_dialog_summary_message" product="default" msgid="7244950433272770280">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Stromsparmodus aktivieren."</string>
+ <string name="battery_tip_dialog_summary_message" product="tablet" msgid="1721081030632329647">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Stromsparmodus aktivieren."</string>
+ <string name="battery_tip_dialog_summary_message" product="device" msgid="146872407040848465">"Der Akkuverbrauch durch Apps ist zurzeit normal. Falls der Akku zu stark beansprucht wird, werden dir mögliche Maßnahmen vorgeschlagen.\n\nBei niedrigem Akkustand kannst du jederzeit den Stromsparmodus aktivieren."</string>
<string name="smart_battery_manager_title" msgid="5744035036663849515">"Akku-Manager"</string>
<string name="smart_battery_title" msgid="4919670408532804351">"Apps automatisch verwalten"</string>
<string name="smart_battery_summary" msgid="640027046471198174">"Akkunutzung für selten verwendete Apps einschränken"</string>
@@ -2415,7 +2415,7 @@
<string name="battery_sugg_bluetooth_headset" msgid="2421931037149315202">"Mit einem anderen Bluetooth-Gerät verbinden"</string>
<string name="battery_desc_apps" msgid="6826726880149226823">"Akkuverbrauch durch App"</string>
<string name="battery_sugg_apps_info" msgid="9175761965559743977">"App anhalten oder deinstallieren"</string>
- <string name="battery_sugg_apps_gps" msgid="489694612870772770">"Energiesparmodus auswählen"</string>
+ <string name="battery_sugg_apps_gps" msgid="489694612870772770">"Stromsparmodus auswählen"</string>
<string name="battery_sugg_apps_settings" msgid="20465932930350295">"Die App bietet unter Umständen Einstellungen für einen geringeren Akkuverbrauch."</string>
<string name="battery_desc_users" msgid="3736510265433457165">"Akkuverbrauch durch Nutzer"</string>
<string name="battery_desc_unaccounted" msgid="1713437127406964501">"Sonstiger Akkuverbrauch"</string>
@@ -2447,22 +2447,22 @@
<string name="process_kernel_label" msgid="4175060316414593760">"Android OS"</string>
<string name="process_mediaserver_label" msgid="8591722404282619153">"Mediaserver"</string>
<string name="process_dex2oat_label" msgid="8249082119748556085">"App-Optimierung"</string>
- <string name="battery_saver" msgid="3989710213758938398">"Energiesparmodus"</string>
+ <string name="battery_saver" msgid="3989710213758938398">"Stromsparmodus"</string>
<string name="battery_saver_auto_title" msgid="4158659069641849952">"Automatisch aktivieren"</string>
<string name="battery_saver_auto_no_schedule" msgid="739814529432092706">"Keine Aktivierung nach Zeitplan"</string>
<string name="battery_saver_auto_routine" msgid="886514412067906980">"Anhand meiner üblichen Abläufe"</string>
<string name="battery_saver_auto_percentage" msgid="5791982309331921556">"Anhand des Ladestands"</string>
- <string name="battery_saver_auto_routine_summary" msgid="9182044424547482889">"Der Energiesparmodus wird automatisch aktiviert, wenn der Akku wahrscheinlich nicht bis zum nächsten Aufladen hält (ermittelt anhand deines üblichen Aufladezeitpunkts)."</string>
+ <string name="battery_saver_auto_routine_summary" msgid="9182044424547482889">"Der Stromsparmodus wird automatisch aktiviert, wenn der Akku wahrscheinlich nicht bis zum nächsten Aufladen hält (ermittelt anhand deines üblichen Aufladezeitpunkts)."</string>
<string name="battery_saver_auto_percentage_summary" msgid="2036128588460338677">"Wird bei <xliff:g id="PERCENT">%1$s</xliff:g> aktiviert"</string>
<string name="battery_saver_schedule_settings_title" msgid="574233428557678128">"Zeitplan festlegen"</string>
<string name="battery_saver_sticky_title_new" msgid="5328707297110866082">"Bei vollem Akku ausschalten"</string>
- <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Der Energiesparmodus wird deaktiviert, sobald dein Smartphone wieder zu <xliff:g id="PERCENT">%1$s</xliff:g> geladen ist"</string>
- <string name="battery_saver_sticky_description_new" product="tablet" msgid="3284967694001857194">"Der Energiesparmodus wird deaktiviert, wenn dein Tabletakku bei <xliff:g id="PERCENT">%1$s</xliff:g> steht"</string>
- <string name="battery_saver_sticky_description_new" product="device" msgid="5056520668081504111">"Der Energiesparmodus wird deaktiviert, wenn dein Geräteakku bei <xliff:g id="PERCENT">%1$s</xliff:g> steht"</string>
+ <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Der Stromsparmodus wird deaktiviert, sobald dein Smartphone wieder zu <xliff:g id="PERCENT">%1$s</xliff:g> geladen ist"</string>
+ <string name="battery_saver_sticky_description_new" product="tablet" msgid="3284967694001857194">"Der Stromsparmodus wird deaktiviert, wenn dein Tabletakku bei <xliff:g id="PERCENT">%1$s</xliff:g> steht"</string>
+ <string name="battery_saver_sticky_description_new" product="device" msgid="5056520668081504111">"Der Stromsparmodus wird deaktiviert, wenn dein Geräteakku bei <xliff:g id="PERCENT">%1$s</xliff:g> steht"</string>
<!-- no translation found for battery_saver_seekbar_title (7607123201469333645) -->
<skip />
<string name="battery_saver_seekbar_title_placeholder" msgid="2321082163892561703">"Aktivieren"</string>
- <string name="battery_saver_master_switch_title" msgid="8241862826825517212">"Energiesparmodus aktivieren"</string>
+ <string name="battery_saver_master_switch_title" msgid="8241862826825517212">"Stromsparmodus aktivieren"</string>
<string name="battery_saver_turn_on_automatically_title" msgid="7316920304024245838">"Automatisch aktivieren"</string>
<string name="battery_saver_turn_on_automatically_never" msgid="2623381258359775227">"Nie"</string>
<string name="battery_saver_turn_on_automatically_pct" msgid="434270432432390307">"bei <xliff:g id="PERCENT">%1$s</xliff:g> Akku"</string>
@@ -3128,7 +3128,7 @@
<string name="keywords_touch_vibration" msgid="2081175517528255224">"haptik, vibrieren, display, empfindlichkeit"</string>
<string name="keywords_ring_vibration" msgid="4210509151866460210">"Haptik, vibrieren, Smartphone, Anruf, Empfindlichkeit, klingeln"</string>
<string name="keywords_notification_vibration" msgid="1077515502086745166">"Haptik, vibrieren, Empfindlichkeit"</string>
- <string name="keywords_battery_saver_sticky" msgid="8733804259716284872">"Energiesparmodus, fixiert, nichtflüchtig, Stromsparfunktion, Akku"</string>
+ <string name="keywords_battery_saver_sticky" msgid="8733804259716284872">"Stromsparmodus, fixiert, nichtflüchtig, Stromsparfunktion, Akku"</string>
<string name="default_sound" msgid="6675629744816442953">"Standardton"</string>
<string name="sound_settings_summary" msgid="8467549670633195109">"Klingeltonlautstärke: <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
<string name="sound_dashboard_summary" msgid="5187301919242823508">"Lautstärke, Vibration, Bitte nicht stören"</string>
@@ -3894,7 +3894,7 @@
<string name="condition_zen_title" msgid="2128184708916052585">"\"Bitte nicht stören\" aktiviert"</string>
<string name="condition_zen_summary_phone_muted" msgid="4396050395522974654">"Smartphone stummgeschaltet"</string>
<string name="condition_zen_summary_with_exceptions" msgid="3435216391993785818">"Mit Ausnahmen"</string>
- <string name="condition_battery_title" msgid="6704870010912986274">"Energiesparmodus aktiviert"</string>
+ <string name="condition_battery_title" msgid="6704870010912986274">"Stromsparmodus aktiviert"</string>
<string name="condition_battery_summary" msgid="1236078243905690620">"Funktionen eingeschränkt"</string>
<string name="condition_cellular_title" msgid="6605277435894307935">"Mobile Daten sind deaktiviert"</string>
<string name="condition_cellular_summary" msgid="3607459310548343777">"Internet nur über WLAN verfügbar"</string>
diff --git a/tests/CarDeveloperOptions/res/values-es/strings.xml b/tests/CarDeveloperOptions/res/values-es/strings.xml
index 8ffe730..dd617fb 100644
--- a/tests/CarDeveloperOptions/res/values-es/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-es/strings.xml
@@ -322,7 +322,7 @@
<string name="date_and_time_settings_title" msgid="7827088656940910631">"Fecha y hora"</string>
<string name="date_and_time_settings_title_setup_wizard" msgid="1573030770187844365">"Establecer fecha y hora"</string>
<string name="date_and_time_settings_summary" msgid="4617979434474713417">"Establecer fecha, hora, zona horaria y formatos"</string>
- <string name="date_time_auto" msgid="2679132152303750218">"Usar hora de la red"</string>
+ <string name="date_time_auto" msgid="2679132152303750218">"Usar la hora proporcionada por la red"</string>
<string name="zone_auto_title" msgid="5500880975376882488">"Usar la zona horaria proporcionada por la red"</string>
<string name="date_time_24hour_auto" msgid="7499659679134962547">"Usar la configuración regional predeterminada"</string>
<string name="date_time_24hour_title" msgid="6209923858891621283">"Formato de 24 horas"</string>
@@ -916,7 +916,7 @@
<string name="passpoint_content" msgid="340527524510304327">"Credenciales de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="wifi_eap_method" msgid="3752116941487485859">"Método EAP"</string>
<string name="please_select_phase2" msgid="5848080896810435677">"Autenticación de fase 2"</string>
- <string name="wifi_eap_ca_cert" msgid="1496395241849383785">"Certificado de CA"</string>
+ <string name="wifi_eap_ca_cert" msgid="1496395241849383785">"Certificado AC"</string>
<string name="wifi_eap_domain" msgid="3298302320003640130">"Dominio"</string>
<string name="wifi_eap_user_cert" msgid="6786839531765719173">"Certificado de usuario"</string>
<string name="wifi_eap_identity" msgid="5280457017705738773">"Identidad"</string>
@@ -1057,7 +1057,7 @@
<string name="wifi_p2p_cancel_connect_message" msgid="3752679335020392154">"¿Quieres cancelar la invitación para conectar con <xliff:g id="PEER_NAME">%1$s</xliff:g>?"</string>
<string name="wifi_p2p_delete_group_message" msgid="3206660449067701089">"¿Olvidar este grupo?"</string>
<string name="wifi_hotspot_checkbox_text" msgid="12062341344410520">"Punto de acceso Wi-Fi"</string>
- <string name="wifi_hotspot_off_subtext" msgid="6177054857136221058">"No se está compartiendo Internet ni el contenido con otros dispositivos"</string>
+ <string name="wifi_hotspot_off_subtext" msgid="6177054857136221058">"No se está compartiendo Internet ni contenido con otros dispositivos"</string>
<string name="wifi_hotspot_tethering_on_subtext" product="tablet" msgid="71421730039785897">"Se está compartiendo la conexión a Internet de este tablet mediante un punto de acceso"</string>
<string name="wifi_hotspot_tethering_on_subtext" product="default" msgid="8914285514605049879">"Se está compartiendo la conexión a Internet de este teléfono mediante un punto de acceso"</string>
<string name="wifi_hotspot_on_local_only_subtext" msgid="7415381343846704553">"La aplicación está compartiendo contenido. Para compartir la conexión a Internet, desactiva el punto de acceso y vuelve a activarlo"</string>
@@ -1298,7 +1298,7 @@
<string name="sim_multi_sims_summary" msgid="8237021982527032257">"Selecciona la SIM que prefieras para usar datos móviles."</string>
<string name="sim_change_data_title" msgid="2512227368681250054">"¿Usar <xliff:g id="CARRIER">%1$s</xliff:g> para los datos móviles?"</string>
<string name="sim_change_data_message" msgid="51004703157782900">"Estás utilizando <xliff:g id="CARRIER2_0">%2$s</xliff:g> para los datos móviles. Si cambias a <xliff:g id="CARRIER1">%1$s</xliff:g>, no se utilizará más a <xliff:g id="CARRIER2_1">%2$s</xliff:g> para los datos móviles."</string>
- <string name="sim_change_data_ok" msgid="7491552537317573235">"Utilizar <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+ <string name="sim_change_data_ok" msgid="7491552537317573235">"Usar <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
<string name="sim_preferred_title" msgid="3389680276182899407">"¿Actualizar tarjeta SIM preferida?"</string>
<string name="sim_preferred_message" msgid="3751011329746359050">"<xliff:g id="NEW_SIM">%1$s</xliff:g> es la única SIM del dispositivo. ¿Quieres usarla para los datos móviles, las llamadas y los mensajes SMS?"</string>
<string name="wrong_pin_code_pukked" msgid="3214670264775760428">"Código PIN de la tarjeta SIM incorrecto. Debes ponerte en contacto con tu operador para desbloquear el dispositivo."</string>
@@ -2747,7 +2747,7 @@
<string name="vpn_ipsec_identifier" msgid="1230238784830362888">"Identificador de IPSec"</string>
<string name="vpn_ipsec_secret" msgid="1531503910441962752">"Clave precompartida de IPSec"</string>
<string name="vpn_ipsec_user_cert" msgid="2762078384595366852">"Certificado de usuario de IPSec"</string>
- <string name="vpn_ipsec_ca_cert" msgid="5537567128766402789">"Certificado de CA de IPSec"</string>
+ <string name="vpn_ipsec_ca_cert" msgid="5537567128766402789">"Certificado AC de IPSec"</string>
<string name="vpn_ipsec_server_cert" msgid="3066696943831527934">"Certificado del servidor IPSec"</string>
<string name="vpn_show_options" msgid="7672984921872882859">"Mostrar opciones avanzadas"</string>
<string name="vpn_search_domains" msgid="8469394307693909080">"Dominios de búsqueda de DNS"</string>
@@ -2809,13 +2809,13 @@
<string name="trusted_credentials_enable_label" msgid="8991649977058280799">"Habilitar"</string>
<string name="trusted_credentials_remove_label" msgid="530728557358501000">"Quitar"</string>
<string name="trusted_credentials_trust_label" msgid="1580022708780121664">"Confiar"</string>
- <string name="trusted_credentials_enable_confirmation" msgid="936560980286792656">"¿Quieres habilitar el certificado de CA del sistema?"</string>
- <string name="trusted_credentials_disable_confirmation" msgid="643386483024801539">"¿Quieres inhabilitar el certificado de CA del sistema?"</string>
- <string name="trusted_credentials_remove_confirmation" msgid="3731678919848637342">"¿Eliminar el certificado de CA de usuario de forma permanente?"</string>
+ <string name="trusted_credentials_enable_confirmation" msgid="936560980286792656">"¿Quieres habilitar el certificado AC del sistema?"</string>
+ <string name="trusted_credentials_disable_confirmation" msgid="643386483024801539">"¿Quieres inhabilitar el certificado AC del sistema?"</string>
+ <string name="trusted_credentials_remove_confirmation" msgid="3731678919848637342">"¿Eliminar el certificado AC de usuario de forma permanente?"</string>
<string name="credential_contains" msgid="483346955378412119">"Esta entrada incluye:"</string>
<string name="one_userkey" msgid="5349738921509013845">"una clave de usuario"</string>
<string name="one_usercrt" msgid="856282310586987313">"un certificado de usuario"</string>
- <string name="one_cacrt" msgid="4757720453112732485">"un certificado de CA"</string>
+ <string name="one_cacrt" msgid="4757720453112732485">"un certificado AC"</string>
<string name="n_cacrts" msgid="7539893176217891549">"%d certificados de CA"</string>
<string name="user_credential_title" msgid="6237611303219831419">"Detalles de credenciales"</string>
<string name="user_credential_removed" msgid="6243576567538844852">"Quitar credencial: <xliff:g id="CREDENTIAL_NAME">%s</xliff:g>"</string>
@@ -3746,7 +3746,7 @@
<string name="usb_control_device" msgid="9154790265254725254">"Este dispositivo"</string>
<string name="usb_switching" msgid="1230386065163529904">"Cambiando..."</string>
<string name="usb_switching_failed" msgid="6857722544186145439">"No se ha podido hacer el cambio"</string>
- <string name="usb_summary_charging_only" msgid="4118449308708872339">"Cargando el dispositivo"</string>
+ <string name="usb_summary_charging_only" msgid="4118449308708872339">"Cargando este dispositivo"</string>
<string name="usb_summary_power_only" msgid="3552240122641051107">"Cargando dispositivo conectado"</string>
<string name="usb_summary_file_transfers" msgid="7805342797099821502">"Transferencia de archivos"</string>
<string name="usb_summary_tether" msgid="778845069037366883">"Compartir conexión por USB"</string>
diff --git a/tests/CarDeveloperOptions/res/values-eu/strings.xml b/tests/CarDeveloperOptions/res/values-eu/strings.xml
index cbac0c2..ccb1cb3 100644
--- a/tests/CarDeveloperOptions/res/values-eu/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-eu/strings.xml
@@ -978,7 +978,7 @@
<string name="wifi_no_domain_warning" msgid="735859919311067606">"Domeinua zehaztu behar da."</string>
<string name="wifi_wps_available_first_item" msgid="3221671453930485243">"WPSa erabilgarri"</string>
<string name="wifi_wps_available_second_item" msgid="5703265526619705185">" (WPSa erabilgarri)"</string>
- <string name="wifi_carrier_connect" msgid="7202618367339982884">"Operadorearen Wi‑Fi sarea"</string>
+ <string name="wifi_carrier_connect" msgid="7202618367339982884">"Operadorearen wifi-sarea"</string>
<string name="wifi_carrier_content" msgid="3467402515071949783">"Konektatu <xliff:g id="NAME">%1$s</xliff:g> bidez"</string>
<string name="wifi_scan_always_turnon_message" msgid="7811846312032594248">"Kokapenaren zehaztasuna hobetzeko eta beste helburu batzuetarako, <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak sare-bilaketa aktibatu nahi du, Wi-Fia desaktibatuta egonda ere.\n\nBilaketa egin nahi duten beste aplikazio guztiei ere baimendu nahi diezu?"</string>
<string name="wifi_scan_always_turnoff_message" msgid="556993843641750002">"Desaktibatzeko, joan menuko \"Ezarpen aurreratuak\" aukerara."</string>
@@ -3312,7 +3312,7 @@
<string name="bubbles_app_toggle_title" msgid="6401217027603326439">"Burbuilak"</string>
<string name="bubbles_app_toggle_summary" msgid="7707611139796553855">"Baimendu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioari jakinarazpen batzuk burbuila gisa erakustea"</string>
<string name="bubbles_feature_disabled_dialog_title" msgid="3375452386012079293">"Aktibatu burbuilak"</string>
- <string name="bubbles_feature_disabled_dialog_text" msgid="326945485806386477">"Aplikazio honetan burbuilak aktibatu ahal izateko, gailuan aktibatu behar dituzu lehendabizi. Ekintza horrek eragina izango du burbuilak lehendik ere aktibatuta dituzten aplikazioetan."</string>
+ <string name="bubbles_feature_disabled_dialog_text" msgid="326945485806386477">"Aplikazio honetan burbuilak aktibatu ahal izateko, gailuan aktibatu behar dituzu lehendabizi. Ekintza horrek eragina izango du burbuilak lehendik ere aktibatuta dauzkaten aplikazioetan."</string>
<string name="bubbles_feature_disabled_button_approve" msgid="6661464849674493351">"Gailua pizteko"</string>
<string name="bubbles_feature_disabled_button_cancel" msgid="4807286844588486198">"Utzi"</string>
<string name="swipe_direction_title" msgid="7535031630668873009">"Hatza pasatuta gauzatzen diren ekintzak"</string>
@@ -4164,7 +4164,7 @@
<string name="account_sync_title" msgid="1570164819114297154">"Kontuaren sinkronizazioa"</string>
<string name="account_sync_summary_some_on" msgid="1934556869158274053">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> elementuk aktibatuta daukate sinkronizazioa"</string>
<string name="account_sync_summary_all_on" msgid="3634161204232431700">"Elementu guztiek aktibatuta daukate sinkronizazioa"</string>
- <string name="account_sync_summary_all_off" msgid="1971584632343645602">"Elementu guztiek desaktibatuta dute sinkronizazioa"</string>
+ <string name="account_sync_summary_all_off" msgid="1971584632343645602">"Elementu guztiek desaktibatuta daukate sinkronizazioa"</string>
<string name="enterprise_privacy_settings" msgid="2777101678653072889">"Gailu kudeatuaren informazioa"</string>
<string name="enterprise_privacy_settings_summary_generic" msgid="5557859169062703683">"Erakundeak kudeatzen dituen aldaketak eta ezarpenak"</string>
<string name="enterprise_privacy_settings_summary_with_name" msgid="4884479123751308407">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak kudeatzen dituen aldaketak eta ezarpenak"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fa/strings.xml b/tests/CarDeveloperOptions/res/values-fa/strings.xml
index 785e1c2..d53894d 100644
--- a/tests/CarDeveloperOptions/res/values-fa/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fa/strings.xml
@@ -935,14 +935,14 @@
<string name="wifi_privacy_settings" msgid="4462092795794247809">"حریم خصوصی"</string>
<string name="wifi_privacy_settings_ephemeral_summary" msgid="2411375348287064283">"MAC تصادفی"</string>
<string name="wifi_dpp_add_device_to_network" msgid="8871041525483253430">"افزودن دستگاه"</string>
- <string name="wifi_dpp_center_qr_code" msgid="3826108361797476758">"برای افزودن دستگاه به «<xliff:g id="SSID">%1$s</xliff:g>»، کد QR را در مرکز پنجره زیر قرار دهید"</string>
- <string name="wifi_dpp_scan_qr_code" msgid="6021600592661235546">"اسکن کد QR"</string>
- <string name="wifi_dpp_scan_qr_code_join_network" msgid="3085162928804379545">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، کد QR را در مرکز پنجره زیر قرار دهید"</string>
- <string name="wifi_dpp_scan_qr_code_join_unknown_network" msgid="5682308317067290738">"با اسکن کردن کد QR، به Wi‑Fi بپیوندید"</string>
+ <string name="wifi_dpp_center_qr_code" msgid="3826108361797476758">"برای افزودن دستگاه به «<xliff:g id="SSID">%1$s</xliff:g>»، رمزینه پاسخسریع را در مرکز پنجره زیر قرار دهید"</string>
+ <string name="wifi_dpp_scan_qr_code" msgid="6021600592661235546">"اسکن رمزینه پاسخسریع"</string>
+ <string name="wifi_dpp_scan_qr_code_join_network" msgid="3085162928804379545">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، رمزینه پاسخسریع را در مرکز پنجره زیر قرار دهید"</string>
+ <string name="wifi_dpp_scan_qr_code_join_unknown_network" msgid="5682308317067290738">"با اسکن کردن رمزینه پاسخسریع، به Wi‑Fi بپیوندید"</string>
<string name="wifi_dpp_share_wifi" msgid="1724161216219646284">"استفاده مشترک از Wi‑Fi"</string>
- <string name="wifi_dpp_scan_qr_code_with_another_device" msgid="4357387474444884759">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، این کد QR را اسکن کنید و گذرواژه مربوطه را همرسانی کنید"</string>
- <string name="wifi_dpp_scan_open_network_qr_code_with_another_device" msgid="572011882416511818">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، این کد QR را اسکن کنید"</string>
- <string name="wifi_dpp_could_not_detect_valid_qr_code" msgid="27667719861826438">"کد QR خوانده نشد. کد را در مرکز قرار دهید و دوباره امتحان کنید"</string>
+ <string name="wifi_dpp_scan_qr_code_with_another_device" msgid="4357387474444884759">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، این رمزینه پاسخسریع را اسکن کنید و گذرواژه مربوطه را همرسانی کنید"</string>
+ <string name="wifi_dpp_scan_open_network_qr_code_with_another_device" msgid="572011882416511818">"برای اتصال به «<xliff:g id="SSID">%1$s</xliff:g>»، این رمزینه پاسخسریع را اسکن کنید"</string>
+ <string name="wifi_dpp_could_not_detect_valid_qr_code" msgid="27667719861826438">"رمزینه پاسخسریع خوانده نشد. کد را در مرکز قرار دهید و دوباره امتحان کنید"</string>
<string name="wifi_dpp_failure_authentication_or_configuration" msgid="9142051662156233679">"دوباره امتحان کنید. اگر مشکل همچنان ادامه دارد، با سازنده دستگاه تماس بگیرید"</string>
<string name="wifi_dpp_failure_not_compatible" msgid="4320027179973678283">"مشکلی رخ داده است"</string>
<string name="wifi_dpp_failure_timeout" msgid="5060065168142109420">"مطمئن شوید دستگاه متصل، شارژ و روشن شده است"</string>
@@ -964,7 +964,7 @@
<string name="wifi_dpp_wifi_password" msgid="8007558344032612455">"گذرواژه Wi-Fi: <xliff:g id="PASSWORD">%1$s</xliff:g>"</string>
<string name="wifi_dpp_hotspot_password" msgid="6172326289042241924">"گذرواژه نقطه اتصال: <xliff:g id="PASSWORD">%1$s</xliff:g>"</string>
<string name="wifi_dpp_add_device" msgid="1347056725253936358">"افزودن دستگاه"</string>
- <string name="wifi_dpp_connect_network_using_qr_code" msgid="115993715600532357">"بااستفاده از کد QR، به این شبکه متصل شوید"</string>
+ <string name="wifi_dpp_connect_network_using_qr_code" msgid="115993715600532357">"بااستفاده از رمزینه پاسخسریع، به این شبکه متصل شوید"</string>
<string name="retry" msgid="8500839563577344702">"امتحان مجدد"</string>
<string name="wifi_shared" msgid="5054256778276524960">"اشتراکگذاری با دیگر استفادهکنندگان از دستگاه"</string>
<string name="wifi_unchanged" msgid="6804964646942333992">"(بدون تغییر)"</string>
@@ -1836,7 +1836,7 @@
<string name="enable_compatibility" msgid="1754177974320410195">"مقیاسبندی برنامه"</string>
<string name="unknown" msgid="2780743426415501227">"ناشناس"</string>
<string name="sort_order_alpha" msgid="6689698854460261212">"مرتب سازی براساس نام"</string>
- <string name="sort_order_size" msgid="3167376197248713027">"مرتبسازی براساس اندازه"</string>
+ <string name="sort_order_size" msgid="3167376197248713027">"بهترتیب اندازه"</string>
<string name="sort_order_recent_notification" msgid="5592496977404445941">"جدیدترین"</string>
<string name="sort_order_frequent_notification" msgid="5640245013098010347">"پرتکرارترین"</string>
<string name="show_running_services" msgid="1895994322704667543">"نمایش سرویسهای در حال اجرا"</string>
@@ -1980,7 +1980,7 @@
<string name="game_controller_settings_category" msgid="9066526500617769463">"دسته کنترل بازی"</string>
<string name="vibrate_input_devices" msgid="3584406079534121467">"تغییر مسیر لرزش"</string>
<string name="vibrate_input_devices_summary" msgid="7503148018220540038">"وقتی متصل شد، لرزش به دسته کنترل بازی ارسال شود"</string>
- <string name="keyboard_layout_dialog_title" msgid="4762706917037085797">"انتخاب طرحبندی صفحهکلید"</string>
+ <string name="keyboard_layout_dialog_title" msgid="4762706917037085797">"انتخاب جانمایی صفحهکلید"</string>
<string name="keyboard_layout_dialog_setup_button" msgid="771293535107618283">"تنظیم طرحبندیهای صفحهکلید"</string>
<string name="keyboard_layout_dialog_switch_hint" msgid="138516114253502182">"برای تغییر، Control-کلید فاصله را فشار هید"</string>
<string name="keyboard_layout_default_label" msgid="8368579311667189793">"پیشفرض"</string>
@@ -2020,7 +2020,7 @@
<string name="input_method_settings_button" msgid="6151412131733672062">"تنظیمات"</string>
<string name="input_methods_settings_label_format" msgid="5927400388781960176">"<xliff:g id="IME_NAME">%1$s</xliff:g> تنظیمات"</string>
<string name="input_methods_and_subtype_enabler_title" msgid="75557930915149416">"انتخاب روشهای ورودی فعال"</string>
- <string name="onscreen_keyboard_settings_summary" msgid="148763210673670769">"تنظیمات صفحهکلید روی صفحه"</string>
+ <string name="onscreen_keyboard_settings_summary" msgid="148763210673670769">"تنظیمات صفحهکلید مجازی"</string>
<string name="builtin_keyboard_settings_title" msgid="3683883402326039724">"صفحهکلید فیزیکی"</string>
<string name="builtin_keyboard_settings_summary" msgid="6498739864479285932">"تنظیمات صفحهکلید فیزیکی"</string>
<string name="gadget_picker_title" msgid="9146981887780645322">"انتخاب اسبابک"</string>
@@ -2030,7 +2030,7 @@
<string name="allow_bind_app_widget_activity_always_allow_bind" msgid="1185486443615658430">"همیشه به <xliff:g id="WIDGET_HOST_NAME">%1$s</xliff:g> برای ایجاد ابزارکها و دسترسی به اطلاعات آنها اجازه داده شود"</string>
<string name="usage_stats_label" msgid="3128999956478977035">"آمار کاربرد"</string>
<string name="testing_usage_stats" msgid="704965692323956976">"آمار کاربرد"</string>
- <string name="display_order_text" msgid="2973620313510295873">"ترتیب براساس:"</string>
+ <string name="display_order_text" msgid="2973620313510295873">"بهترتیب:"</string>
<string name="app_name_label" msgid="2258469951312794816">"برنامه"</string>
<string name="last_time_used_label" msgid="1119322667349666930">"آخرین زمان استفاده"</string>
<string name="usage_time_label" msgid="5615725415876461039">"زمان استفاده"</string>
@@ -3772,8 +3772,8 @@
<string name="memory_details" msgid="5165105904103664110">"جزئیات"</string>
<string name="memory_use_summary" msgid="7676311343819965850">"<xliff:g id="SIZE">%1$s</xliff:g> متوسط حافظه استفاده شده در ۳ ساعت گذشته"</string>
<string name="no_memory_use_summary" msgid="3966550113388917978">"در ۳ ساعت گذشته از حافظه استفاده نشده است"</string>
- <string name="sort_avg_use" msgid="78428601253054298">"مرتبسازی براساس مصرف متوسط"</string>
- <string name="sort_max_use" msgid="322772647893307413">"مرتبسازی براساس حداکثر مصرف"</string>
+ <string name="sort_avg_use" msgid="78428601253054298">"بهترتیب مصرف متوسط"</string>
+ <string name="sort_max_use" msgid="322772647893307413">"بهترتیب حداکثر مصرف"</string>
<string name="memory_performance" msgid="3506743771947250453">"عملکرد"</string>
<string name="total_memory" msgid="7352192982476976453">"کل حافظه"</string>
<string name="average_used" msgid="3022736210190754669">"مصرف متوسط (%)"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fi/strings.xml b/tests/CarDeveloperOptions/res/values-fi/strings.xml
index 6f55fcb..3a755b9 100644
--- a/tests/CarDeveloperOptions/res/values-fi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fi/strings.xml
@@ -1053,7 +1053,7 @@
<string name="wifi_p2p_disconnect_title" msgid="915880461655863812">"Katkaistaanko yhteys?"</string>
<string name="wifi_p2p_disconnect_message" msgid="3745286932812740784">"Jos katkaiset yhteyden, yhteys laitteeseen <xliff:g id="PEER_NAME">%1$s</xliff:g> katkaistaan."</string>
<string name="wifi_p2p_disconnect_multiple_message" msgid="6051173422663731688">"Jos kosketat Katkaise yhteys, yhteys laitteeseen <xliff:g id="PEER_NAME">%1$s</xliff:g> ja <xliff:g id="PEER_COUNT">%2$s</xliff:g> muuhun laitteeseen katkaistaan."</string>
- <string name="wifi_p2p_cancel_connect_title" msgid="2465200999145769427">"Peruutetaanko kutsu?"</string>
+ <string name="wifi_p2p_cancel_connect_title" msgid="2465200999145769427">"Perutaanko kutsu?"</string>
<string name="wifi_p2p_cancel_connect_message" msgid="3752679335020392154">"Haluatko peruuttaa laitteelle <xliff:g id="PEER_NAME">%1$s</xliff:g> lähetetyn yhteydenmuodostuskutsun?"</string>
<string name="wifi_p2p_delete_group_message" msgid="3206660449067701089">"Unohdetaanko tämä ryhmä?"</string>
<string name="wifi_hotspot_checkbox_text" msgid="12062341344410520">"Wi‑Fi-hotspot"</string>
@@ -3789,7 +3789,7 @@
<string name="zen_access_warning_dialog_title" msgid="7704910289810337055">"Myönnetäänkö Älä häiritse -tilan käyttöoikeus sovellukselle <xliff:g id="APP">%1$s</xliff:g>?"</string>
<string name="zen_access_warning_dialog_summary" msgid="2717755746850874577">"Sovellus voi ottaa Älä häiritse -tilan käyttöön tai poistaa sen käytöstä sekä muokata siihen liittyviä asetuksia."</string>
<string name="zen_access_disabled_package_warning" msgid="7086237569177576966">"Tämän täytyy olla käytössä, sillä ilmoitusten käyttöoikeus on myönnetty."</string>
- <string name="zen_access_revoke_warning_dialog_title" msgid="6850994585577513299">"Peruutetaanko sovellukselta <xliff:g id="APP">%1$s</xliff:g> Älä häiritse -tilan käyttöoikeus?"</string>
+ <string name="zen_access_revoke_warning_dialog_title" msgid="6850994585577513299">"Perutaanko sovellukselta <xliff:g id="APP">%1$s</xliff:g> Älä häiritse -tilan käyttöoikeus?"</string>
<string name="zen_access_revoke_warning_dialog_summary" msgid="3487422193181311403">"Kaikki tämän sovelluksen luomat Älä häiritse -säännöt poistetaan."</string>
<string name="ignore_optimizations_on" msgid="4373971641328943551">"Älä optimoi"</string>
<string name="ignore_optimizations_off" msgid="4372289432580282870">"Optimoi"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fr/strings.xml b/tests/CarDeveloperOptions/res/values-fr/strings.xml
index 2d4038f..1708273 100644
--- a/tests/CarDeveloperOptions/res/values-fr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fr/strings.xml
@@ -3731,7 +3731,7 @@
<string name="usb_use_power_only" msgid="6595783381323810697">"Recharger l\'appareil connecté"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Transfert de fichiers"</string>
<string name="usb_use_file_transfers_desc" msgid="6953866660041189580">"Transférer des fichiers vers un autre appareil"</string>
- <string name="usb_use_photo_transfers" msgid="5974236250197451257">"PTP"</string>
+ <string name="usb_use_photo_transfers" msgid="5974236250197451257">"Transfert de photos (PTP)"</string>
<string name="usb_use_photo_transfers_desc" msgid="2325112887316125320">"Transférer des photos ou des fichiers si MTP n\'est pas compatible (PTP)"</string>
<string name="usb_use_tethering" msgid="4250626730173163846">"Partage de connexion via USB"</string>
<string name="usb_use_MIDI" msgid="4710632870781041401">"Mode MIDI"</string>
@@ -3741,7 +3741,7 @@
<string name="usb_default_info" msgid="953775292571786528">"Ces paramètres sont appliqués lorsqu\'un autre appareil est connecté et que votre téléphone est déverrouillé. Connectez-vous uniquement à des appareils vérifiés."</string>
<string name="usb_pref" msgid="6194821550693495068">"USB"</string>
<string name="usb_preference" msgid="7092987095048592826">"Préférences USB"</string>
- <string name="usb_control_title" msgid="2379698856760894768">"USB contrôlé par"</string>
+ <string name="usb_control_title" msgid="2379698856760894768">"Connexion USB contrôlée par"</string>
<string name="usb_control_host" msgid="193292043691034178">"Appareil connecté"</string>
<string name="usb_control_device" msgid="9154790265254725254">"Cet appareil"</string>
<string name="usb_switching" msgid="1230386065163529904">"Changement…"</string>
diff --git a/tests/CarDeveloperOptions/res/values-gu/arrays.xml b/tests/CarDeveloperOptions/res/values-gu/arrays.xml
index 9671c68..8ad9984 100644
--- a/tests/CarDeveloperOptions/res/values-gu/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-gu/arrays.xml
@@ -257,7 +257,7 @@
<item msgid="5420704980305018295">"વૉઇસ વૉલ્યૂમ"</item>
<item msgid="5797363115508970204">"રિંગ વૉલ્યૂમ"</item>
<item msgid="8233154098550715999">"મીડિયા વૉલ્યૂમ"</item>
- <item msgid="5196715605078153950">"એલાર્મ વૉલ્યૂમ"</item>
+ <item msgid="5196715605078153950">"અલાર્મ વૉલ્યૂમ"</item>
<item msgid="394030698764284577">"નોટિફિકેશન વૉલ્યૂમ"</item>
<item msgid="8952898972491680178">"બ્લૂટૂથ વૉલ્યૂમ"</item>
<item msgid="8506227454543690851">"સક્રિય રાખો"</item>
@@ -324,7 +324,7 @@
<item msgid="1600379420669104929">"વૉઇસ વૉલ્યૂમ"</item>
<item msgid="6296768210470214866">"રિંગ વૉલ્યૂમ"</item>
<item msgid="510690696071629241">"મીડિયા વૉલ્યૂમ"</item>
- <item msgid="406861638631430109">"એલાર્મ વૉલ્યૂમ"</item>
+ <item msgid="406861638631430109">"અલાર્મ વૉલ્યૂમ"</item>
<item msgid="4715864795872233884">"નોટિફિકેશન વૉલ્યૂમ"</item>
<item msgid="2311478519251301183">"બ્લૂટૂથ વૉલ્યૂમ"</item>
<item msgid="5133991377896747027">"સક્રિય રાખો"</item>
diff --git a/tests/CarDeveloperOptions/res/values-gu/strings.xml b/tests/CarDeveloperOptions/res/values-gu/strings.xml
index ec8cdb1..7110571 100644
--- a/tests/CarDeveloperOptions/res/values-gu/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-gu/strings.xml
@@ -1791,7 +1791,7 @@
<string name="applications_settings_header" msgid="3766501606045211098">"ઍપ્લિકેશન સેટિંગ્સ"</string>
<string name="install_applications" msgid="7745902974984889179">"અજાણ્યા સ્ત્રોતો"</string>
<string name="install_applications_title" msgid="8164828577588659496">"બધા ઍપ્લિકેશન સ્રોતોને મંજૂરી આપો"</string>
- <string name="recent_app_category_title" msgid="7688788038277126727">"તાજેતરમાં ખોલેલી ઍપ્લિકેશનો"</string>
+ <string name="recent_app_category_title" msgid="7688788038277126727">"તાજેતરમાં ખોલેલી ઍપ"</string>
<string name="see_all_apps_title" msgid="6435061912110347474">"બધી <xliff:g id="COUNT">%1$d</xliff:g> ઍપ્લિકેશન જુઓ"</string>
<string name="install_all_warning" product="tablet" msgid="4580699862358542727">"તમારું ટૅબ્લેટ અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનોના હુમલા પ્રતિ વધુ સંવેદનશીલ છે. આ સ્રોત પરથી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે તેમનો ઉપયોગ કરવાના પરિણામે તમારા ટૅબ્લેટને થતી કોઈ પણ ક્ષતિ કે ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
<string name="install_all_warning" product="default" msgid="7445839116997296358">"તમારો ફોન અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનોના હુમલા પ્રતિ વધુ સંવેદનશીલ છે. આ સ્રોત પરથી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે તેમનો ઉપયોગ કરવાના પરિણામે તમારા ફોનને થતી કોઈ પણ ક્ષતિ કે ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
@@ -3040,12 +3040,12 @@
<string name="connected_devices_dashboard_no_nfc_summary" msgid="2610085597733526722">"બ્લૂટૂથ, ડ્રાઇવિંગ મોડ"</string>
<string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"બ્લૂટૂથ, NFC"</string>
<string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary" msgid="7881286613528299400">"બ્લૂટૂથ"</string>
- <string name="app_and_notification_dashboard_title" msgid="8448096608058843730">"ઍપ્લિકેશનો અને નોટિફિકેશન"</string>
+ <string name="app_and_notification_dashboard_title" msgid="8448096608058843730">"ઍપ અને નોટિફિકેશન"</string>
<string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"Assistant, તાજેતરની ઍપ, ડિફૉલ્ટ ઍપ"</string>
<string name="notification_settings_work_profile" msgid="7190550347842400029">"કાર્યાલયની પ્રોફાઇલમાં ઍપ માટે નોટિફિકેશન ઍક્સેસ ઉપલબ્ધ નથી."</string>
<string name="account_dashboard_title" msgid="4734300939532555885">"એકાઉન્ટ"</string>
<string name="account_dashboard_default_summary" msgid="6822549669771936206">"કોઈ એકાઉન્ટ ઉમેરવામાં આવ્યાં નથી"</string>
- <string name="app_default_dashboard_title" msgid="6575301028225232193">"ડિફૉલ્ટ ઍપ્લિકેશનો"</string>
+ <string name="app_default_dashboard_title" msgid="6575301028225232193">"ડિફૉલ્ટ ઍપ"</string>
<string name="system_dashboard_summary" msgid="6582464466735779394">"ભાષાઓ, જેશ્ચર સમય, બૅકઅપ"</string>
<string name="search_results_title" msgid="4160717656435503940">"સેટિંગ્સ"</string>
<string name="keywords_wifi" msgid="8477688080895466846">"વાઇફાઇ, વાઇ-ફાઇ, નેટવર્ક કનેક્શન, ઇન્ટરનેટ, વાયરલેસ, ડેટા, વાઇ-ફાઇ"</string>
@@ -3137,7 +3137,7 @@
<string name="media_volume_option_title" msgid="3553411883305505682">"મીડિયા વૉલ્યૂમ"</string>
<string name="remote_media_volume_option_title" msgid="6355710054191873836">"કાસ્ટનું વૉલ્યૂમ"</string>
<string name="call_volume_option_title" msgid="5028003296631037334">"કૉલ વૉલ્યૂમ"</string>
- <string name="alarm_volume_option_title" msgid="3184076022438477047">"એલાર્મ વૉલ્યૂમ"</string>
+ <string name="alarm_volume_option_title" msgid="3184076022438477047">"અલાર્મ વૉલ્યૂમ"</string>
<string name="ring_volume_option_title" msgid="2038924918468372264">"રિંગ વૉલ્યૂમ"</string>
<string name="notification_volume_option_title" msgid="1358512611511348260">"નોટિફિકેશન વૉલ્યૂમ"</string>
<string name="ringtone_title" msgid="1409086028485922583">"ફોન રિંગટોન"</string>
@@ -3151,7 +3151,7 @@
<string name="screen_locking_sounds_title" msgid="4407110895465866809">"સ્ક્રીન લૉકિંગ ધ્વનિઓ"</string>
<string name="charging_sounds_title" msgid="5070437987230894287">"ચાર્જિંગ સાઉન્ડ અને વાઇબ્રેશન"</string>
<string name="docking_sounds_title" msgid="2573137471605541366">"ડૉકિંગ સાઉન્ડ્સ"</string>
- <string name="touch_sounds_title" msgid="165237488496165652">"ટચ સાઉન્ડ્સ"</string>
+ <string name="touch_sounds_title" msgid="165237488496165652">"ટચ સાઉન્ડ"</string>
<string name="vibrate_on_touch_title" msgid="6360155469279157684">"સ્પર્શ વાઇબ્રેશન"</string>
<string name="vibrate_on_touch_summary" msgid="5504424764028676043">"ટૅપ, કીબોર્ડ અને વધુ માટે સ્પર્શ દ્વારા આપેલ અભિપ્રાય"</string>
<string name="dock_audio_media_title" msgid="1859521680502040781">"ડૉક સ્પીકર ચલાવે છે"</string>
@@ -3280,12 +3280,12 @@
<string name="zen_onboarding_new_setting_summary" msgid="8264430315983860075">"તમે કોઈ નોટિફિકેશન જોઈ અથવા સાંભળી શકશો નહીં. સ્ટાર આપેલા સંપર્કો અને રિપીટ કૉલરના કૉલને પરવાનગી આપવામાં આવે છે."</string>
<string name="zen_onboarding_current_setting_summary" msgid="3569246708507270821">"(વર્તમાન સેટિંગ)"</string>
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"ખલેલ પાડશો નહીં નોટિફિકેશનની સેટિંગમાં ફેરફાર કરીએ?"</string>
- <string name="sound_work_settings" msgid="4140215240360927923">"કાર્યાલયની પ્રોફાઇલની ધ્વનિઓ"</string>
- <string name="work_use_personal_sounds_title" msgid="531727195073003599">"વ્યક્તિગત પ્રોફાઇલ ધ્વનિઓ વાપરો"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"કાર્ય અને વ્યક્તિગત પ્રોફાઇલો માટે ધ્વનિ સમાન રહે છે"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"કાર્ય ફોન રિંગટોન"</string>
- <string name="work_notification_ringtone_title" msgid="8059159087214025757">"કાર્યાલયના નોટિફિકેશન માટે ડિફૉલ્ટ ધ્વનિ"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ડિફૉલ્ટ કાર્ય એલાર્મ માટે સાઉન્ડ"</string>
+ <string name="sound_work_settings" msgid="4140215240360927923">"ઑફિસની પ્રોફાઇલના સાઉન્ડ"</string>
+ <string name="work_use_personal_sounds_title" msgid="531727195073003599">"વ્યક્તિગત પ્રોફાઇલ સાઉન્ડ વાપરો"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"ઑફિસ અને વ્યક્તિગત પ્રોફાઇલો માટે સાઉન્ડ સમાન રહે છે"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"ઑફિસ ફોન રિંગટોન"</string>
+ <string name="work_notification_ringtone_title" msgid="8059159087214025757">"ઑફિસના નોટિફિકેશન માટે ડિફૉલ્ટ સાઉન્ડ"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ઑફિસના અલાર્મ માટે ડિફૉલ્ટ સાઉન્ડ"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"વ્યક્તિગત પ્રોફાઇલની જેમ જ"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"ધ્વનિ બદલીએ?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"બદલો"</string>
@@ -3728,7 +3728,7 @@
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"નકારો"</string>
<string name="usb_use_charging_only" msgid="2344625733377110164">"કોઈ ડેટા ટ્રાન્સફર નથી"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"બસ આ ઉપકરણને ચાર્જ કરો"</string>
- <string name="usb_use_power_only" msgid="6595783381323810697">"કનેક્ટ થયેલ ઉપકરણને ચાર્જ કરો"</string>
+ <string name="usb_use_power_only" msgid="6595783381323810697">"કનેક્ટ થયેલ ડિવાઇસને ચાર્જ કરો"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"ફાઇલ ટ્રાન્સફર"</string>
<string name="usb_use_file_transfers_desc" msgid="6953866660041189580">"ફાઇલોને બીજા ઉપકરણ પર ટ્રાન્સફર કરો"</string>
<string name="usb_use_photo_transfers" msgid="5974236250197451257">"PTP"</string>
@@ -4188,7 +4188,7 @@
<string name="enterprise_privacy_location_access" msgid="110406267468274216">"સ્થાન માટેની પરવાનગીઓ"</string>
<string name="enterprise_privacy_microphone_access" msgid="4586428105675460207">"માઇક્રોફોન માટેની પરવાનગીઓ"</string>
<string name="enterprise_privacy_camera_access" msgid="2366392786153103482">"કૅમેરા માટેની પરવાનગીઓ"</string>
- <string name="enterprise_privacy_enterprise_set_default_apps" msgid="6142937923758931242">"ડિફૉલ્ટ ઍપ્લિકેશનો"</string>
+ <string name="enterprise_privacy_enterprise_set_default_apps" msgid="6142937923758931242">"ડિફૉલ્ટ ઍપ"</string>
<plurals name="enterprise_privacy_number_packages" formatted="false" msgid="1480745164313890415">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ઍપ્લિકેશન</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ઍપ્લિકેશન</item>
diff --git a/tests/CarDeveloperOptions/res/values-hi/strings.xml b/tests/CarDeveloperOptions/res/values-hi/strings.xml
index 43bfdbc..e4750bd 100644
--- a/tests/CarDeveloperOptions/res/values-hi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hi/strings.xml
@@ -3136,7 +3136,7 @@
<string name="sound_settings_example_summary" msgid="2091822107298841827">"रिंग की आवाज़ 80% है"</string>
<string name="media_volume_option_title" msgid="3553411883305505682">"मीडिया की आवाज़"</string>
<string name="remote_media_volume_option_title" msgid="6355710054191873836">"आवाज़ कास्ट करें"</string>
- <string name="call_volume_option_title" msgid="5028003296631037334">"कॉल की आवाज़"</string>
+ <string name="call_volume_option_title" msgid="5028003296631037334">"कॉल वॉल्यूम"</string>
<string name="alarm_volume_option_title" msgid="3184076022438477047">"अलार्म की आवाज़"</string>
<string name="ring_volume_option_title" msgid="2038924918468372264">"रिंग की आवाज़"</string>
<string name="notification_volume_option_title" msgid="1358512611511348260">"सूचना की आवाज़"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hr/strings.xml b/tests/CarDeveloperOptions/res/values-hr/strings.xml
index be961be..c6d1e9d 100644
--- a/tests/CarDeveloperOptions/res/values-hr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hr/strings.xml
@@ -3327,9 +3327,9 @@
<string name="sound_work_settings" msgid="4140215240360927923">"Zvukovi radnog profila"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"Upotreba zvuka osobnog profila"</string>
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Zvukovi su isti za radni i osobni profil"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"Melodija zvona radnog telefona"</string>
- <string name="work_notification_ringtone_title" msgid="8059159087214025757">"Zadani zvuk radne obavijesti"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Zadani zvuk radnog alarma"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"Melodija zvona poslovnog telefona"</string>
+ <string name="work_notification_ringtone_title" msgid="8059159087214025757">"Zadani zvuk poslovne obavijesti"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Zadani zvuk poslovnog alarma"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Isto kao osobni profil"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"Zamijeniti zvukove?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"Zamijeni"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hu/strings.xml b/tests/CarDeveloperOptions/res/values-hu/strings.xml
index eec3eb8..434f37d 100644
--- a/tests/CarDeveloperOptions/res/values-hu/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hu/strings.xml
@@ -916,7 +916,7 @@
<string name="passpoint_content" msgid="340527524510304327">"A(z) <xliff:g id="NAME">%1$s</xliff:g> hitelesítési adatai"</string>
<string name="wifi_eap_method" msgid="3752116941487485859">"EAP módszer"</string>
<string name="please_select_phase2" msgid="5848080896810435677">"Hitelesítés 2. fázisa"</string>
- <string name="wifi_eap_ca_cert" msgid="1496395241849383785">"CA tanúsítvány"</string>
+ <string name="wifi_eap_ca_cert" msgid="1496395241849383785">"CA-tanúsítvány"</string>
<string name="wifi_eap_domain" msgid="3298302320003640130">"Domain"</string>
<string name="wifi_eap_user_cert" msgid="6786839531765719173">"Felhasználói tanúsítvány"</string>
<string name="wifi_eap_identity" msgid="5280457017705738773">"Azonosság"</string>
@@ -2747,7 +2747,7 @@
<string name="vpn_ipsec_identifier" msgid="1230238784830362888">"IPSec-azonosító"</string>
<string name="vpn_ipsec_secret" msgid="1531503910441962752">"Megosztott IPSec-kulcs"</string>
<string name="vpn_ipsec_user_cert" msgid="2762078384595366852">"IPSec felhasználói tanúsítvány"</string>
- <string name="vpn_ipsec_ca_cert" msgid="5537567128766402789">"IPSec CA tanúsítvány"</string>
+ <string name="vpn_ipsec_ca_cert" msgid="5537567128766402789">"IPSec CA-tanúsítvány"</string>
<string name="vpn_ipsec_server_cert" msgid="3066696943831527934">"IPSec-szervertanúsítvány"</string>
<string name="vpn_show_options" msgid="7672984921872882859">"Speciális beállítások megjelenítése"</string>
<string name="vpn_search_domains" msgid="8469394307693909080">"DNS-keresési domainek"</string>
@@ -2815,8 +2815,8 @@
<string name="credential_contains" msgid="483346955378412119">"A bejegyzés a következőket tartalmazza:"</string>
<string name="one_userkey" msgid="5349738921509013845">"egy felhasználói kulcs"</string>
<string name="one_usercrt" msgid="856282310586987313">"egy felhasználói tanúsítvány"</string>
- <string name="one_cacrt" msgid="4757720453112732485">"egy CA tanúsítvány"</string>
- <string name="n_cacrts" msgid="7539893176217891549">"%d CA tanúsítvány"</string>
+ <string name="one_cacrt" msgid="4757720453112732485">"egy CA-tanúsítvány"</string>
+ <string name="n_cacrts" msgid="7539893176217891549">"%d CA-tanúsítvány"</string>
<string name="user_credential_title" msgid="6237611303219831419">"Hitelesítési adatok"</string>
<string name="user_credential_removed" msgid="6243576567538844852">"A következő hitelesítési adatot törölte a rendszer: <xliff:g id="CREDENTIAL_NAME">%s</xliff:g>"</string>
<string name="user_credential_none_installed" msgid="4129252817676332368">"Nincsenek telepített felhasználói hitelesítési adatok"</string>
@@ -4203,8 +4203,8 @@
<string name="enterprise_privacy_ca_certs_personal" msgid="1356447417193483802">"Megbízható hitelesítési adatok a személyes profilban"</string>
<string name="enterprise_privacy_ca_certs_work" msgid="836419648894546893">"Megbízható hitelesítési adatok a munkaprofilban"</string>
<plurals name="enterprise_privacy_number_ca_certs" formatted="false" msgid="7953528945502561752">
- <item quantity="other">Legalább <xliff:g id="COUNT_1">%d</xliff:g> CA tanúsítvány</item>
- <item quantity="one">Legalább <xliff:g id="COUNT_0">%d</xliff:g> CA tanúsítvány</item>
+ <item quantity="other">Legalább <xliff:g id="COUNT_1">%d</xliff:g> CA-tanúsítvány</item>
+ <item quantity="one">Legalább <xliff:g id="COUNT_0">%d</xliff:g> CA-tanúsítvány</item>
</plurals>
<string name="enterprise_privacy_lock_device" msgid="1533125067038409945">"A rendszergazda zárolhatja az eszközt, és új jelszót állíthat be"</string>
<string name="enterprise_privacy_wipe_device" msgid="7555287990273929922">"A rendszergazda törölheti az összes adatot az eszközről"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hy/strings.xml b/tests/CarDeveloperOptions/res/values-hy/strings.xml
index 7c3b63f..7aae021 100644
--- a/tests/CarDeveloperOptions/res/values-hy/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hy/strings.xml
@@ -474,12 +474,12 @@
<string name="security_settings_fingerprint_enroll_enrolling_skip" msgid="1473280156532146933">"Ավելի ուշ"</string>
<string name="setup_fingerprint_enroll_enrolling_skip_title" msgid="2816424026528101690">"Բաց թողնե՞լ մատնահետքի կարգավորումը:"</string>
<string name="setup_fingerprint_enroll_enrolling_skip_message" msgid="8139299964344809780">"Դուք ընտրել եք մատնահետքի օգտագործումը որպես հեռախոսն ապակողպելու եղանակներից մեկը: Եթե բաց թողնեք հիմա, ապա ձեզ անհրաժեշտ կլինի կատարել կարգավորումն ավելի ուշ: Կարգավորումը տևում է ընդամենը մոտ մեկ րոպե:"</string>
- <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="tablet" msgid="1384438077720821127">"Պաշտպանեք ձեր պլանշետը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք պլանշետը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
- <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="device" msgid="7207112623501771824">"Պաշտպանեք ձեր սարքը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք սարքը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
- <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="default" msgid="7623975730623531606">"Պաշտպանեք ձեր հեռախոսը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք հեռախոսը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
- <string name="face_lock_screen_setup_skip_dialog_text" product="tablet" msgid="2998863111689476550">"Պաշտպանեք ձեր պլանշետը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք պլանշետը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
- <string name="face_lock_screen_setup_skip_dialog_text" product="device" msgid="6780557259734235952">"Պաշտպանեք ձեր սարքը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք սարքը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
- <string name="face_lock_screen_setup_skip_dialog_text" product="default" msgid="8541640018478926775">"Պաշտպանեք ձեր հեռախոսը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե կորցնեք հեռախոսը կամ այն գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="tablet" msgid="1384438077720821127">"Պաշտպանեք ձեր պլանշետը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="device" msgid="7207112623501771824">"Պաշտպանեք ձեր սարքը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="fingerprint_lock_screen_setup_skip_dialog_text" product="default" msgid="7623975730623531606">"Պաշտպանեք ձեր հեռախոսը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև մատնահետքը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="tablet" msgid="2998863111689476550">"Պաշտպանեք ձեր պլանշետը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="device" msgid="6780557259734235952">"Պաշտպանեք ձեր սարքը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="default" msgid="8541640018478926775">"Պաշտպանեք ձեր հեռախոսը էկրանի կողպման միջոցով, որպեսզի ձեր տվյալները հասանելի չդառնան կողմնակի անձանց, եթե այն կորցնեք կամ գողանան: Էկրանի կողպումն անհրաժեշտ է նաև դեմքի ճանաչումը կարգավորելու համար։ Հպեք «Չեղարկել» կոճակին, ապա ավելացրեք PIN կոդ կամ ընտրեք էկրանի կողպման այլ տարբերակ։"</string>
<string name="lock_screen_pin_skip_title" msgid="8217519439213393785">"Բաց թողնե՞լ PIN-ի կարգավորումը"</string>
<string name="lock_screen_password_skip_title" msgid="3725788215672959827">"Չավելացնե՞լ գաղտնաբառ"</string>
<string name="lock_screen_pattern_skip_title" msgid="4237030500353932005">"Բաց թողնե՞լ նախշի կարգավորումը"</string>
@@ -980,7 +980,7 @@
<string name="wifi_wps_available_second_item" msgid="5703265526619705185">" (WPS-ը հասանելի է)"</string>
<string name="wifi_carrier_connect" msgid="7202618367339982884">"Օպերատորի Wi‑Fi ցանց"</string>
<string name="wifi_carrier_content" msgid="3467402515071949783">"Միանալ <xliff:g id="NAME">%1$s</xliff:g>-ի միջոցով"</string>
- <string name="wifi_scan_always_turnon_message" msgid="7811846312032594248">"Տեղադրության ճշգրտությունը կատարելագործելու կամ այլ նպատակների համար` <xliff:g id="APP_NAME">%1$s</xliff:g>-ը ցանկանում է միացնել ցանցի սկանավորումը, նույնիսկ եթե Wi-Fi-ը անջատված է:\n\nԹույլատրե՞լ բոլոր սկանավորում ցանկացող ծրագրերին:"</string>
+ <string name="wifi_scan_always_turnon_message" msgid="7811846312032594248">"Տեղադրության ճշգրտությունը կատարելագործելու կամ այլ նպատակների համար՝ <xliff:g id="APP_NAME">%1$s</xliff:g>-ը ցանկանում է միացնել ցանցի սկանավորումը, նույնիսկ եթե Wi-Fi-ը անջատված է:\n\nԹույլատրե՞լ բոլոր սկանավորում ցանկացող ծրագրերին:"</string>
<string name="wifi_scan_always_turnoff_message" msgid="556993843641750002">"Սա անջատելու համար գերբեռնված ցանկում անցեք Ընդլայնված:"</string>
<string name="wifi_scan_always_confirm_allow" msgid="8857664849515496237">"Թույլատրել"</string>
<string name="wifi_scan_always_confirm_deny" msgid="6190909841125369403">"Մերժել"</string>
@@ -1287,9 +1287,9 @@
<string name="sim_change_pin" msgid="1674620855223900785">"SIM PIN"</string>
<string name="sim_bad_pin" msgid="2409776007569751629">"Սխալ PIN"</string>
<string name="sim_pins_dont_match" msgid="1076283313667637902">"PIN-երը չեն համընկնում"</string>
- <string name="sim_change_failed" msgid="8874765697694275459">"Չհաջողվեց փոխել PIN-ը:\nՀնարավոր է` PIN-ը սխալ է:"</string>
+ <string name="sim_change_failed" msgid="8874765697694275459">"Չհաջողվեց փոխել PIN-ը:\nՀնարավոր է՝ PIN-ը սխալ է:"</string>
<string name="sim_change_succeeded" msgid="8802418023120614533">"SIM քարտի PIN կոդը հաջողությամբ փոխվել է"</string>
- <string name="sim_lock_failed" msgid="7949781515066772755">"Հնարավոր չէ բացել SIM քարտի կողպված կարգավիճակը:\nՀնարավոր է` սխալ PIN է մուտքագրվել:"</string>
+ <string name="sim_lock_failed" msgid="7949781515066772755">"Հնարավոր չէ բացել SIM քարտի կողպված կարգավիճակը:\nՀնարավոր է՝ սխալ PIN է մուտքագրվել:"</string>
<string name="sim_pin_disable_failed" msgid="6780973900290546751">"Չհաջողվեց անջատել PIN կոդը"</string>
<string name="sim_pin_enable_failed" msgid="804897359922298792">"Չհաջողվեց միացնել PIN կոդը"</string>
<string name="sim_enter_ok" msgid="5103626479976731229">"Հաստատել"</string>
@@ -1593,7 +1593,7 @@
<string name="master_clear_desc_also_erases_esim" msgid="4497260499055258773"><li>"eSIM քարտեր"</li></string>
<string name="master_clear_desc_no_cancel_mobile_plan" msgid="6072668588881679461">\n\n"Բջջային ծառայությունների ձեր փաթեթը չի չեղարկվի:"</string>
<string name="master_clear_desc_erase_external_storage" product="nosdcard" msgid="2723272952715259307">\n\n"Երաժշտությունը, նկարները և այլ տվյալները ջնջելու համար "<b>"USB կրիչը "</b>"պետք է ջնջվի:"</string>
- <string name="master_clear_desc_erase_external_storage" product="default" msgid="9003555775524798797">\n\n"Երաժշտությունը, նկարները և այլ տվյալները "<b>"SD քարտից"</b>" մաքրելու համար` այն պետք է ջնջել:"</string>
+ <string name="master_clear_desc_erase_external_storage" product="default" msgid="9003555775524798797">\n\n"Երաժշտությունը, նկարները և այլ տվյալները "<b>"SD քարտից"</b>" մաքրելու համար՝ այն պետք է ջնջել:"</string>
<string name="erase_external_storage" product="nosdcard" msgid="8989746770347525207">"Ջնջել USB կրիչը"</string>
<string name="erase_external_storage" product="default" msgid="194249742376770215">"Ջնջել SD քարտը"</string>
<string name="erase_external_storage_description" product="nosdcard" msgid="8020275102431496261">"Ջնջել ներքին USB կրիչի բոլոր տվյալները, ինչպիսիք են երաժշտությունը կամ լուսանկարները"</string>
@@ -1621,11 +1621,11 @@
<string name="tether_settings_disabled_on_data_saver" msgid="3682544845899910726">"Երբ թրաֆիկի տնտեսումն ակտիվ է, հնարավոր չէ կապել կամ օգտագործել շարժական հասանելիության կետերը"</string>
<string name="usb_title" msgid="7480927657535578688">"USB"</string>
<string name="usb_tethering_button_text" msgid="6242228383142012332">"USB մոդեմ"</string>
- <string name="usb_tethering_subtext" product="default" msgid="1573513260339548671">"Տարածել հեռախոսի ինտերնետային կապը USB-ով"</string>
+ <string name="usb_tethering_subtext" product="default" msgid="1573513260339548671">"Տարածել հեռախոսի ինտերնետ կապը USB-ով"</string>
<string name="usb_tethering_subtext" product="tablet" msgid="154536000235361034">"Տարածել պլանշետի ինտերնետային կապը USB-ով"</string>
<string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"Bluetooth մոդեմ"</string>
<string name="bluetooth_tethering_subtext" product="tablet" msgid="6868756914621131635">"Տարածել պլանշետի ինտերնետային կապը Bluetooth-ով"</string>
- <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Տարածել հեռախոսի ինտերնետային կապը Bluetooth-ով"</string>
+ <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Տարածել հեռախոսի ինտերնետ կապը Bluetooth-ով"</string>
<string name="bluetooth_tethering_off_subtext_config" msgid="3981528184780083266">"<xliff:g id="DEVICE_NAME">%1$d</xliff:g> սարքի ինտերնետային կապը տարածվում է Bluetooth-ով"</string>
<string name="bluetooth_tethering_overflow_error" msgid="6946561351369376943">"Հնարավոր չէ միանալ ավելի քան <xliff:g id="MAXCONNECTION">%1$d</xliff:g> սարքերի հետ:"</string>
<string name="bluetooth_untether_blank" msgid="5428300773782256084">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ը կանջատվի:"</string>
@@ -1670,8 +1670,8 @@
<string name="location_neighborhood_level" msgid="8459352741296587916">"Թույլատրել ծրագրերին օգտագործել Google-ի տեղակայման ծառայությունները` ձեր տեղադրությունը ավելի արագ որոշելու համար: Անանուն տեղակայման տվյալները կհավաքագրվեն և կուղարկվեն Google-ին:"</string>
<string name="location_neighborhood_level_wifi" msgid="6120133551482003840">"Տեղադրությունը որոշված է Wi‑Fi-ի օգնությամբ"</string>
<string name="location_gps" msgid="688049341158297763">"GPS արբանյակներ"</string>
- <string name="location_street_level" product="tablet" msgid="4459804798444296650">"Թույլատրել հավելվածին օգտագործել GPS-ը` ձեր տեղադրությունը պլանշետում ամրագրելու համար"</string>
- <string name="location_street_level" product="default" msgid="7407688345675450051">"Թույլատրել հավելվածին օգտագործել GPS-ը` ձեր տեղադրությունը հեռախոսում ամրագրելու համար"</string>
+ <string name="location_street_level" product="tablet" msgid="4459804798444296650">"Թույլատրել հավելվածին օգտագործել GPS-ը՝ ձեր տեղադրությունը պլանշետում ամրագրելու համար"</string>
+ <string name="location_street_level" product="default" msgid="7407688345675450051">"Թույլատրել հավելվածին օգտագործել GPS-ը՝ ձեր տեղադրությունը հեռախոսում ամրագրելու համար"</string>
<string name="assisted_gps" msgid="5411780261117055175">"Օգատգործեք աջակցող GPS-ը"</string>
<string name="assisted_gps_enabled" msgid="2561022181775725369">"Օգտագործեք սերվերը` GPS-ին միանալու համար (ապագնշեք` ցանցի օգտագործումը նվազեցնելու համար)"</string>
<string name="assisted_gps_disabled" msgid="6448758788217415937">"Օգտագործել սերվերը GPS աջակցման համար (ապընտրել` GPS-ի արդյունավետությունը բարելավելու համար)"</string>
@@ -1831,12 +1831,12 @@
<string name="always_allow_bind_appwidgets_text" msgid="2286211654774611037">"Դուք ընտրել եք թույտարել այս ծրագրին ստեղծել վիջեթներ և մուտք գործել իրենց տվյալներ:"</string>
<string name="auto_launch_disable_text" msgid="8560921288036801416">"Լռելյայները կարգավորված չեն:"</string>
<string name="clear_activities" msgid="2068014972549235347">"Մաքրել լռելյայնները"</string>
- <string name="screen_compatibility_text" msgid="1768064020294301496">"Հնարավոր է` այս ծրագիրը մշակված չէ ձեր էկրանի համար: Դուք կարող եք վերահսկել դրա` ձեր էկրանին հարմարեցումը:"</string>
+ <string name="screen_compatibility_text" msgid="1768064020294301496">"Հնարավոր է՝ այս ծրագիրը մշակված չէ ձեր էկրանի համար: Դուք կարող եք վերահսկել դրա` ձեր էկրանին հարմարեցումը:"</string>
<string name="ask_compatibility" msgid="6687958195768084807">"Հարցնել մեկնարկելիս"</string>
<string name="enable_compatibility" msgid="1754177974320410195">"Աստիճանակարգել հավելվածները"</string>
<string name="unknown" msgid="2780743426415501227">"Անհայտ"</string>
<string name="sort_order_alpha" msgid="6689698854460261212">"Դասակարգել ըստ անունների"</string>
- <string name="sort_order_size" msgid="3167376197248713027">"Տեսակավորել ըստ չափի"</string>
+ <string name="sort_order_size" msgid="3167376197248713027">"Դասավորել ըստ չափի"</string>
<string name="sort_order_recent_notification" msgid="5592496977404445941">"Վերջինները"</string>
<string name="sort_order_frequent_notification" msgid="5640245013098010347">"Առավել հաճախ"</string>
<string name="show_running_services" msgid="1895994322704667543">"Ցույց տալ ընթացիկ ծառայությունները"</string>
@@ -2673,7 +2673,7 @@
<string name="account_settings_menu_auto_sync_personal" msgid="3235831897309033754">"Ինքնահամաժամացնել անձնական տվյալները"</string>
<string name="account_settings_menu_auto_sync_work" msgid="5721442464286552815">"Ինքնահամաժամացնել աշխատանքային տվյալները"</string>
<string name="data_usage_change_cycle" msgid="447761920472170031">"Ցիկլի փոփոխում…"</string>
- <string name="data_usage_pick_cycle_day" msgid="6319750879145917066">"Ամսվա մի օր` տվյալների օգտագործման աշխատաշրջանը սահմանելու համար`"</string>
+ <string name="data_usage_pick_cycle_day" msgid="6319750879145917066">"Ամսվա մի օր` տվյալների օգտագործման աշխատաշրջանը սահմանելու համար՝"</string>
<string name="data_usage_empty" msgid="7981405723435034032">"Այս ընթացքում հավելվածները տվյալներ չեն օգտագործել:"</string>
<string name="data_usage_label_foreground" msgid="2471091128648754601">"Ակտիվ ռեժիմ"</string>
<string name="data_usage_label_background" msgid="1618794447370396845">"Ֆոնային ռեժիմ"</string>
@@ -2751,8 +2751,8 @@
<string name="vpn_ipsec_server_cert" msgid="3066696943831527934">"IPSec սերվերի վկայական"</string>
<string name="vpn_show_options" msgid="7672984921872882859">"Ցույց տալ լրացուցիչ ընտրանքները"</string>
<string name="vpn_search_domains" msgid="8469394307693909080">"DNS որոնման տիրույթներ"</string>
- <string name="vpn_dns_servers" msgid="3017453300909321239">"DNS սերվերներ (օրինակ` 8.8.8.8)"</string>
- <string name="vpn_routes" msgid="3393989650778663742">"Փոխանցման երթուղիներ (օրինակ` 10.0.0.0/8)"</string>
+ <string name="vpn_dns_servers" msgid="3017453300909321239">"DNS սերվերներ (օրինակ՝ 8.8.8.8)"</string>
+ <string name="vpn_routes" msgid="3393989650778663742">"Փոխանցման երթուղիներ (օրինակ՝ 10.0.0.0/8)"</string>
<string name="vpn_username" msgid="5357878823189445042">"Օգտանուն"</string>
<string name="vpn_password" msgid="5325943601523662246">"Գաղտնաբառ"</string>
<string name="vpn_save_login" msgid="6215503139606646915">"Պահել հաշվի տեղեկությունները"</string>
@@ -3772,8 +3772,8 @@
<string name="memory_details" msgid="5165105904103664110">"Մանրամասներ"</string>
<string name="memory_use_summary" msgid="7676311343819965850">"Վերջին 3 ժամվա մեջ օգտագործվել է միջինը <xliff:g id="SIZE">%1$s</xliff:g> հիշողություն"</string>
<string name="no_memory_use_summary" msgid="3966550113388917978">"Վերջին 3 ժամվա մեջ հիշողություն չի օգտագործվել"</string>
- <string name="sort_avg_use" msgid="78428601253054298">"Տեսակավորել ըստ միջին օգտագործման"</string>
- <string name="sort_max_use" msgid="322772647893307413">"Տեսակավորել ըստ առավելագույն օգտագործման"</string>
+ <string name="sort_avg_use" msgid="78428601253054298">"Դասավորել ըստ միջին օգտագործման"</string>
+ <string name="sort_max_use" msgid="322772647893307413">"Դասավորել ըստ առավելագույն օգտագործման"</string>
<string name="memory_performance" msgid="3506743771947250453">"Արդյունավետություն"</string>
<string name="total_memory" msgid="7352192982476976453">"Ընդհանուր հիշողությունը"</string>
<string name="average_used" msgid="3022736210190754669">"Միջին օգագործում (%)"</string>
diff --git a/tests/CarDeveloperOptions/res/values-in/strings.xml b/tests/CarDeveloperOptions/res/values-in/strings.xml
index bd342ef..241f948 100644
--- a/tests/CarDeveloperOptions/res/values-in/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-in/strings.xml
@@ -490,7 +490,7 @@
<string name="security_settings_fingerprint_enroll_error_dialog_title" msgid="1415709674142168770">"Pendaftaran tidak selesai"</string>
<string name="security_settings_fingerprint_enroll_error_timeout_dialog_message" msgid="498951203761192366">"Waktu pendaftaran sidik jari habis. Coba lagi."</string>
<string name="security_settings_fingerprint_enroll_error_generic_dialog_message" msgid="7896295829530444810">"Pendaftaran sidik jari tidak berhasil. Coba lagi atau gunakan jari lain."</string>
- <string name="fingerprint_enroll_button_add" msgid="6335782936874996629">"Tambahkan yang lain"</string>
+ <string name="fingerprint_enroll_button_add" msgid="6335782936874996629">"Tambahkan lainnya"</string>
<string name="fingerprint_enroll_button_next" msgid="6419214079104413695">"Berikutnya"</string>
<string name="security_settings_fingerprint_enroll_disclaimer" msgid="5831834311961551423">"Selain membuka kunci ponsel, Anda juga dapat menggunakan sidik jari untuk mengotorisasi pembelian dan akses aplikasi. "<annotation id="url">"Pelajari lebih lanjut"</annotation></string>
<string name="security_settings_fingerprint_enroll_disclaimer_lockscreen_disabled" msgid="7954742554236652690">" Opsi layar kunci dinonaktifkan. Untuk mempelajari lebih lanjut, hubungi admin organisasi Anda. "<annotation id="admin_details">"Detail selengkapnya"</annotation>\n\n"Anda tetap dapat menggunakan sidik jari untuk mengotorisasi pembelian dan akses aplikasi. "<annotation id="url">"Pelajari lebih lanjut"</annotation></string>
@@ -3726,7 +3726,7 @@
<string name="sharing_remote_bugreport_dialog_message" msgid="3814787466701526359">"Laporan bug ini sedang dibagikan kepada admin IT. Hubungi mereka untuk detail selengkapnya."</string>
<string name="share_remote_bugreport_action" msgid="8600797271670537888">"Bagikan"</string>
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"Tolak"</string>
- <string name="usb_use_charging_only" msgid="2344625733377110164">"Tidak ada transfer data"</string>
+ <string name="usb_use_charging_only" msgid="2344625733377110164">"Jangan transfer data"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"Mengisi daya perangkat ini saja"</string>
<string name="usb_use_power_only" msgid="6595783381323810697">"Isi daya baterai perangkat yang terhubung"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Transfer File"</string>
diff --git a/tests/CarDeveloperOptions/res/values-is/strings.xml b/tests/CarDeveloperOptions/res/values-is/strings.xml
index 0707eb3..9aa0c80 100644
--- a/tests/CarDeveloperOptions/res/values-is/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-is/strings.xml
@@ -2092,7 +2092,7 @@
<string name="accessibility_autoclick_description" msgid="5492414927846407499">"Ef þú notar mús geturðu stillt bendilinn þannig að hann framkvæmi aðgerð sjálfkrafa þegar hann er óhreyfður í tiltekinn tíma."</string>
<string name="accessibility_autoclick_delay_preference_title" msgid="8303022510942147049">"Bíða áður en smellt er"</string>
<string name="accessibility_vibration_settings_title" msgid="1902649657883159406">"Titringur"</string>
- <string name="accessibility_notification_vibration_title" msgid="1005799039440510298">"Titringur fyrir tilkynningar"</string>
+ <string name="accessibility_notification_vibration_title" msgid="1005799039440510298">"Titringur tilkynninga"</string>
<string name="accessibility_ring_vibration_title" msgid="7943341443551359985">"Titringur hringingar"</string>
<string name="accessibility_touch_vibration_title" msgid="285890135612038092">"Snertititringur"</string>
<string name="accessibility_service_master_switch_title" msgid="2734791644475782924">"Nota þjónustu"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ja/strings.xml b/tests/CarDeveloperOptions/res/values-ja/strings.xml
index 218aa51..01cbc44 100644
--- a/tests/CarDeveloperOptions/res/values-ja/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ja/strings.xml
@@ -3308,9 +3308,9 @@
<string name="notification_badging_title" msgid="6311699476970264712">"通知ドットの許可"</string>
<string name="notification_bubbles_title" msgid="9196562435741861317">"ふきだし"</string>
<string name="notification_bubbles_summary" msgid="4624512775901949578">"フローティング ショートカットにより、アプリのコンテンツにどこからでもすぐにアクセスできます"</string>
- <string name="bubbles_feature_education" msgid="8979109826818881018">"一部の通知や他のコンテンツを画面にふきだしとして表示できます。ふきだしはタップすると開き、画面の下へドラッグすると消えます。"</string>
+ <string name="bubbles_feature_education" msgid="8979109826818881018">"一部の通知や他のコンテンツを画面にバブルとして表示できます。バブルはタップすると開き、画面の下へドラッグすると消えます。"</string>
<string name="bubbles_app_toggle_title" msgid="6401217027603326439">"ふきだし"</string>
- <string name="bubbles_app_toggle_summary" msgid="7707611139796553855">"一部の通知をふきだしとして表示することを <xliff:g id="APP_NAME">%1$s</xliff:g> に許可します"</string>
+ <string name="bubbles_app_toggle_summary" msgid="7707611139796553855">"一部の通知をバブルとして表示することを <xliff:g id="APP_NAME">%1$s</xliff:g> に許可します"</string>
<string name="bubbles_feature_disabled_dialog_title" msgid="3375452386012079293">"ふきだしの有効化"</string>
<string name="bubbles_feature_disabled_dialog_text" msgid="326945485806386477">"このアプリのふきだしを有効にするには、デバイスでふきだしを有効にしておく必要があります。この設定は、ふきだしを以前に有効にした他のアプリにも反映されます。"</string>
<string name="bubbles_feature_disabled_button_approve" msgid="6661464849674493351">"デバイスで有効にする"</string>
diff --git a/tests/CarDeveloperOptions/res/values-kk/strings.xml b/tests/CarDeveloperOptions/res/values-kk/strings.xml
index 60d43a3..d735349 100644
--- a/tests/CarDeveloperOptions/res/values-kk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-kk/strings.xml
@@ -162,7 +162,7 @@
<string name="bluetooth_map_acceptance_dialog_text" msgid="736507842082640410">"%1$s хабарларыңызға кіруді қалайды. %2$s кірсін бе?"</string>
<string name="bluetooth_sap_request" msgid="6318039677671263261">"SIM картасына кіру сұрауы"</string>
<string name="bluetooth_sap_acceptance_dialog_text" msgid="1909352413109340355">"<xliff:g id="DEVICE_NAME_0">%1$s</xliff:g> сіздің SIM картаңызға кіруге рұқсат сұрайды. Ондай рұқсатты берсеңіз, байланыс барысында дерек тасымалы өшіріледі. <xliff:g id="DEVICE_NAME_1">%2$s?</xliff:g> құрылғысына рұқсат беру"</string>
- <string name="bluetooth_device_name_summary" msgid="8661066392056595005">"Басқа құрылғыларға \"<xliff:g id="DEVICE_NAME">^1</xliff:g>\" атымен көрінеді"</string>
+ <string name="bluetooth_device_name_summary" msgid="8661066392056595005">"Басқа құрылғыларға \"<xliff:g id="DEVICE_NAME">^1</xliff:g>\" атымен көрінеді."</string>
<string name="bluetooth_off_footer" msgid="7658444560543730571">"Басқа құрылғыларға қосылу үшін Bluetooth функциясын қосыңыз."</string>
<string name="bluetooth_paired_device_title" msgid="8361860197780425286">"Құрылғыларыңыз"</string>
<string name="bluetooth_pairing_page_title" msgid="9053463656712597709">"Жаңа құрылғымен жұптастыру"</string>
@@ -2279,7 +2279,7 @@
<string name="battery_tip_smart_battery_summary" msgid="5344821856478265778">"Battery Manager функциясын қосыңыз"</string>
<string name="battery_tip_early_heads_up_title" msgid="707163785378746813">"Battery Saver функциясын қосу"</string>
<string name="battery_tip_early_heads_up_summary" msgid="4231489566422395156">"Батареяның заряды тез азаюы мүмкін"</string>
- <string name="battery_tip_early_heads_up_done_title" msgid="112550885882648429">"Battery Saver қосулы"</string>
+ <string name="battery_tip_early_heads_up_done_title" msgid="112550885882648429">"Батареяны үнемдеу режимі қосулы"</string>
<string name="battery_tip_early_heads_up_done_summary" msgid="8692257022962771181">"Кейбір функциялар шектелуі мүмкін"</string>
<string name="battery_tip_high_usage_title" product="default" msgid="4103005178310487352">"Телефон әдеттегіден көп қолданылды"</string>
<string name="battery_tip_high_usage_title" product="tablet" msgid="1019583260005768965">"Планшет әдеттегіден көп қолданылды"</string>
@@ -2446,7 +2446,7 @@
<string name="process_kernel_label" msgid="4175060316414593760">"Android операциялық жүйесі"</string>
<string name="process_mediaserver_label" msgid="8591722404282619153">"Meдиасервері"</string>
<string name="process_dex2oat_label" msgid="8249082119748556085">"Қолданбаны оңтайландыру"</string>
- <string name="battery_saver" msgid="3989710213758938398">"Battery Saver"</string>
+ <string name="battery_saver" msgid="3989710213758938398">"Батареяны үнемдеу режимі"</string>
<string name="battery_saver_auto_title" msgid="4158659069641849952">"Автоматты түрде қосу"</string>
<string name="battery_saver_auto_no_schedule" msgid="739814529432092706">"Кесте жоқ"</string>
<string name="battery_saver_auto_routine" msgid="886514412067906980">"Әрекеттеріңіз негізінде"</string>
@@ -2455,7 +2455,7 @@
<string name="battery_saver_auto_percentage_summary" msgid="2036128588460338677">"Заряд деңгейі <xliff:g id="PERCENT">%1$s</xliff:g> болғанда, қосылады"</string>
<string name="battery_saver_schedule_settings_title" msgid="574233428557678128">"Кестені белгілеу"</string>
<string name="battery_saver_sticky_title_new" msgid="5328707297110866082">"Толық зарядталғанда өшіру"</string>
- <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Телефон заряды <xliff:g id="PERCENT">%1$s</xliff:g> болғанда, Battery Saver өшіріледі."</string>
+ <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Телефон заряды <xliff:g id="PERCENT">%1$s</xliff:g> болғанда, Батареяны үнемдеу режимі өшеді."</string>
<string name="battery_saver_sticky_description_new" product="tablet" msgid="3284967694001857194">"Планшет заряды <xliff:g id="PERCENT">%1$s</xliff:g> болғанда, Battery Saver өшіріледі."</string>
<string name="battery_saver_sticky_description_new" product="device" msgid="5056520668081504111">"Құрылғы заряды <xliff:g id="PERCENT">%1$s</xliff:g> болғанда, Battery Saver өшіріледі."</string>
<!-- no translation found for battery_saver_seekbar_title (7607123201469333645) -->
@@ -3282,10 +3282,10 @@
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"\"Мазаламау\" режиміндегі хабарландыру параметрлері өзгертілсін бе?"</string>
<string name="sound_work_settings" msgid="4140215240360927923">"Жұмыс профилінің дыбыстары"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"Жеке профиль дыбыстарын пайдалану"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Жұмыс пен жеке профильдер үшін дыбысы қолданылады"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Жұмыс профилі мен жеке профиль дыбыстары бірдей"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"Жұмыс телефонының рингтоны"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"Әдепкі жұмыс хабарландыруының дыбысы"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Әдепкі жұмыс дабылының дыбысы"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Әдепкі жұмыс оятқышының дыбысы"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Жеке профильдікімен бірдей"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"Дыбыстарды ауыстыру керек пе?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"Ауыстыру"</string>
@@ -3746,7 +3746,7 @@
<string name="usb_control_device" msgid="9154790265254725254">"Осы құрылғы"</string>
<string name="usb_switching" msgid="1230386065163529904">"Ауыстырылуда..."</string>
<string name="usb_switching_failed" msgid="6857722544186145439">"Ауыстырылмады"</string>
- <string name="usb_summary_charging_only" msgid="4118449308708872339">"Осы құрылғыны зарядтауда"</string>
+ <string name="usb_summary_charging_only" msgid="4118449308708872339">"Осы құрылғыны зарядтауда."</string>
<string name="usb_summary_power_only" msgid="3552240122641051107">"Жалғанған құрылғыны зарядтау"</string>
<string name="usb_summary_file_transfers" msgid="7805342797099821502">"Файл жіберу"</string>
<string name="usb_summary_tether" msgid="778845069037366883">"USB тетеринг"</string>
diff --git a/tests/CarDeveloperOptions/res/values-km/strings.xml b/tests/CarDeveloperOptions/res/values-km/strings.xml
index 4ac7a2c..4d1a4a0 100644
--- a/tests/CarDeveloperOptions/res/values-km/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-km/strings.xml
@@ -3736,7 +3736,7 @@
<string name="usb_use_tethering" msgid="4250626730173163846">"ការភ្ជាប់តាម USB"</string>
<string name="usb_use_MIDI" msgid="4710632870781041401">"MIDI"</string>
<string name="usb_use_MIDI_desc" msgid="1770966187150010947">"ប្រើឧបករណ៍នេះជាមីឌី"</string>
- <string name="usb_use" msgid="8940500223316278632">"ប្រើ USB ដើម្បី"</string>
+ <string name="usb_use" msgid="8940500223316278632">"ប្រើ USB សម្រាប់"</string>
<string name="usb_default_label" msgid="7471316635263936101">"ការកំណត់រចនាសម្ព័ន្ធ USB លំនាំដើម"</string>
<string name="usb_default_info" msgid="953775292571786528">"ការកំណត់ទាំងនេះនឹងអនុវត្ត នៅពេលដែលទូរសព្ទរបស់អ្នកដោះសោ ហើយឧបករណ៍ផ្សេងទៀតត្រូវបានភ្ជាប់។ សូមភ្ជាប់ជាមួយឧបករណ៍ដែលទុកចិត្តតែប៉ុណ្ណោះ។"</string>
<string name="usb_pref" msgid="6194821550693495068">"USB"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ko/strings.xml b/tests/CarDeveloperOptions/res/values-ko/strings.xml
index 8d36e87..d842be6 100644
--- a/tests/CarDeveloperOptions/res/values-ko/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ko/strings.xml
@@ -3282,7 +3282,7 @@
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"방해 금지 모드의 알림 설정을 변경하시겠습니까?"</string>
<string name="sound_work_settings" msgid="4140215240360927923">"직장 프로필 사운드"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"개인 프로필 사운드 사용"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"직장 프로필과 개인 프로필의 소리가 같습니다."</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"직장 프로필과 개인 프로필의 사운드가 같습니다."</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"직장 휴대전화 벨소리"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"기본 직장 알림 소리"</string>
<string name="work_alarm_ringtone_title" msgid="5328487181385375130">"기본 직장 알람 소리"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ky/strings.xml b/tests/CarDeveloperOptions/res/values-ky/strings.xml
index b26f23a..e778766 100644
--- a/tests/CarDeveloperOptions/res/values-ky/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ky/strings.xml
@@ -3726,7 +3726,7 @@
<string name="sharing_remote_bugreport_dialog_message" msgid="3814787466701526359">"Мүчүлүштүк тууралуу бул баяндама IT администраторуңуз менен бөлүшүлүүдө. Көбүрөөк маалымат үчүн администраторуңузга кайрылыңыз."</string>
<string name="share_remote_bugreport_action" msgid="8600797271670537888">"Бөлүшүү"</string>
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"Четке кагуу"</string>
- <string name="usb_use_charging_only" msgid="2344625733377110164">"Дайындар өткөрүлбөйт"</string>
+ <string name="usb_use_charging_only" msgid="2344625733377110164">"Дайын-даректер өткөрүлбөйт"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"Жөн гана бул түзмөктү кубаттоо"</string>
<string name="usb_use_power_only" msgid="6595783381323810697">"Туташкан түзмөктү кубаттоо"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Файл өткөрүү"</string>
diff --git a/tests/CarDeveloperOptions/res/values-mk/strings.xml b/tests/CarDeveloperOptions/res/values-mk/strings.xml
index 22e2fa5..c1e59f0 100644
--- a/tests/CarDeveloperOptions/res/values-mk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-mk/strings.xml
@@ -3296,7 +3296,7 @@
<string name="other_sound_category_preference_title" msgid="2045757472469840859">"Други звуци и вибрации"</string>
<string name="configure_notification_settings" msgid="291914315140851270">"Известувања"</string>
<string name="recent_notifications" msgid="8125865995065032049">"Неодамна испратени"</string>
- <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Приказ на сите од последните 7 дена"</string>
+ <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Преглед на сите од минатите 7 дена"</string>
<string name="advanced_section_header" msgid="984680389373090015">"Напредни"</string>
<string name="profile_section_header" msgid="5471479005472037417">"Известувања за работен профил"</string>
<string name="asst_capability_prioritizer_title" msgid="3488284760645922160">"Автоматско доделување предност на известувањата"</string>
@@ -3726,7 +3726,7 @@
<string name="sharing_remote_bugreport_dialog_message" msgid="3814787466701526359">"Извештајот за грешки е споделен со вашиот администратор за информатичка технологија. За повеќе детали, контактирајте со него."</string>
<string name="share_remote_bugreport_action" msgid="8600797271670537888">"Сподели"</string>
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"Одбиј"</string>
- <string name="usb_use_charging_only" msgid="2344625733377110164">"Нема пренос на податоци"</string>
+ <string name="usb_use_charging_only" msgid="2344625733377110164">"Без пренос на податоци"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"Само ја полни батеријата"</string>
<string name="usb_use_power_only" msgid="6595783381323810697">"Полнење на поврзаниот уред"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Пренос на датотеки"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ml/strings.xml b/tests/CarDeveloperOptions/res/values-ml/strings.xml
index 803c8b3..cada1a6 100644
--- a/tests/CarDeveloperOptions/res/values-ml/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ml/strings.xml
@@ -3282,7 +3282,7 @@
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"ശല്ല്യപ്പെടുത്തരുത് അറിയിപ്പ് ക്രമീകരണം മാറ്റണോ?"</string>
<string name="sound_work_settings" msgid="4140215240360927923">"ഔദ്യോഗിക പ്രൊഫൈൽ ശബ്ദങ്ങൾ"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"സ്വകാര്യ പ്രൊഫൈൽ ശബ്ദങ്ങൾ ഉപയോഗിക്കുക"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"ഔദ്യോഗിക പ്രൊഫൈലുകൾക്കും വ്യക്തിഗത പ്രൊഫൈലുകൾക്കുമുള്ള ശബ്ദങ്ങൾ ഒന്നുതന്നെ ആയിരിക്കും"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"ഔദ്യോഗിക പ്രൊഫൈലുകൾക്കും സ്വകാര്യ പ്രൊഫൈലുകൾക്കുമുള്ള ശബ്ദങ്ങൾ ഒന്നുതന്നെ ആയിരിക്കും"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"ഔദ്യോഗിക ഫോൺ റിംഗ്ടോൺ"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"ഡിഫോൾട്ട് ഔദ്യോഗിക അറിയിപ്പ് ശബ്ദം"</string>
<string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ഡിഫോൾട്ട് ഔദ്യോഗിക അലാറം ശബ്ദം"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ne/strings.xml b/tests/CarDeveloperOptions/res/values-ne/strings.xml
index b86e082..78f5da8 100644
--- a/tests/CarDeveloperOptions/res/values-ne/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ne/strings.xml
@@ -113,7 +113,7 @@
<string name="bluetooth_disconnect_all_profiles" product="device" msgid="4707569949253450208">"तपाईंको यन्त्र <xliff:g id="DEVICE_NAME">%1$s</xliff:g> बाट विच्छेद हुनेछ।"</string>
<string name="bluetooth_disconnect_dialog_ok" msgid="4183522987246110145">"विच्छेद गर्नुहोस्"</string>
<string name="bluetooth_empty_list_user_restricted" msgid="3616298363281495777">"तपाईं सँग ब्लुटुथ सेटिङहरू परिवर्तन गर्न अनुमति छैन।"</string>
- <string name="bluetooth_pairing_pref_title" msgid="2904954138013884029">"नयाँ यन्त्रलाई जोडा बनाउनुहोस्"</string>
+ <string name="bluetooth_pairing_pref_title" msgid="2904954138013884029">"नयाँ यन्त्रको जोडा बनाउनुहोस्"</string>
<string name="bluetooth_is_visible_message" msgid="6341088682252805612">"ब्लुटुथ सेटिङहरू खुला हुँदा <xliff:g id="DEVICE_NAME">%1$s</xliff:g> लाई नजिकैका उपकरणहरू देख्न सक्नेछन्।"</string>
<string name="bluetooth_footer_mac_message" product="default" msgid="335341476746836260">"फोनको ब्लुटुथ ठेगाना: <xliff:g id="BLUETOOTH_MAC_ADDRESS">%1$s</xliff:g>"</string>
<string name="bluetooth_footer_mac_message" product="tablet" msgid="6033609611245782463">"ट्याब्लेटको ब्लुटुथ ठेगाना: <xliff:g id="BLUETOOTH_MAC_ADDRESS">%1$s</xliff:g>"</string>
@@ -165,7 +165,7 @@
<string name="bluetooth_device_name_summary" msgid="8661066392056595005">"अन्य यन्त्रहरूमा <xliff:g id="DEVICE_NAME">^1</xliff:g> को रूपमा देखिन्छ"</string>
<string name="bluetooth_off_footer" msgid="7658444560543730571">"अन्य यन्त्रहरूमा जडान गर्न ब्लुटुथ सक्रिय गर्नुहोस्।"</string>
<string name="bluetooth_paired_device_title" msgid="8361860197780425286">"तपाईंका यन्त्रहरू"</string>
- <string name="bluetooth_pairing_page_title" msgid="9053463656712597709">"नयाँ यन्त्रलाई जोडा बनाउनुहोस्"</string>
+ <string name="bluetooth_pairing_page_title" msgid="9053463656712597709">"नयाँ यन्त्रको जोडा बनाउनुहोस्"</string>
<string name="bluetooth_pref_summary" product="tablet" msgid="3601662966604648212">"आफ्नो ट्याब्लेटलाई वरपरका ब्लुटुथ यन्त्रहरूसँग सञ्चार गर्न दिनुहोस्"</string>
<string name="bluetooth_pref_summary" product="device" msgid="2286727776570956969">"आफ्नो यन्त्रलाई वरपरका ब्लुटुथ यन्त्रहरूसँग सञ्चार गर्न दिनुहोस्"</string>
<string name="bluetooth_pref_summary" product="default" msgid="863659221858781186">"आफ्नो फोनलाई वरपरका ब्लुटुथ यन्त्रहरूसँग सञ्चार गर्न दिनुहोस्"</string>
@@ -515,7 +515,7 @@
<string name="crypt_keeper_low_charge_text" msgid="1422879728632636311">"तपाईँको ब्याट्री चार्ज गरी पुनःप्रयास गर्नुहोस्।"</string>
<string name="crypt_keeper_unplugged_text" msgid="6597684068340036200">"तपाईंको चार्जरमा प्लग इन गरेर फेरि प्रयास गर्नुहोस्।"</string>
<string name="crypt_keeper_dialog_need_password_title" msgid="8532211509636340535">"कुनै लक स्क्रिन PIN वा पासवर्ड छैन"</string>
- <string name="crypt_keeper_dialog_need_password_message" msgid="1341590897367808702">"तपाईंले इन्क्रिप्सन सुरु गर्नु अघि लक स्क्रिन PIN वा पासवर्ड सेट गर्न आवश्यक छ।"</string>
+ <string name="crypt_keeper_dialog_need_password_message" msgid="1341590897367808702">"तपाईंले इन्क्रिप्सन सुरु गर्नुअघि लक स्क्रिन PIN वा पासवर्ड सेट गर्न आवश्यक छ।"</string>
<string name="crypt_keeper_confirm_title" msgid="8884417036062084547">"इन्क्रिप्ट गर्ने हो?"</string>
<string name="crypt_keeper_final_desc" product="tablet" msgid="2713708841024805586">"इन्क्रिप्सन कार्य उल्ट्याउन मिल्दैन र यदि तपाईँले अवरोध पुर्याउनु भयो भने तपाईँले डेटा गुमाउनु हुने छ। इन्क्रिप्सनले एक घन्टा वा बढी समय लिन सक्छ, यस समयमा ट्याब्लेट धेरै पटक पुनःस्टार्ट हुन सक्छ।"</string>
<string name="crypt_keeper_final_desc" product="default" msgid="2483549885938505746">"इन्क्रिप्सन अपरेसन उल्टाउन मिल्दैन र यदि तपाईँले यसलाई अवरूद्ध गर्नु भयो भने तपाईँले डेटा गुमाउनु हुने छ। इनक्रिप्सनलाई करिब एक घन्टा वा बढी लाग्छ जुन समय फोन धेरै चोटि पुनःस्टार्ट हुन सक्छ।"</string>
@@ -1157,7 +1157,7 @@
<string name="dock_audio_summary_unknown" msgid="1615958511030469507">"संलग्न डकको लागि सेटिङहरू"</string>
<string name="dock_not_found_title" msgid="2035088760477532435">"डक भेटिएन"</string>
<string name="dock_not_found_text" product="tablet" msgid="5996654431405111902">"डक अडियो सेट गर्न अघि तपाईँले ट्याब्लेट डक गर्नु पर्ने हुन्छ।"</string>
- <string name="dock_not_found_text" product="default" msgid="8275091896320216368">"तपाईंले डक अडियो सेटिङ गर्नु अघि फोन डक गर्नु आवश्यक पर्दछ।"</string>
+ <string name="dock_not_found_text" product="default" msgid="8275091896320216368">"तपाईंले डक अडियो सेटिङ गर्नुअघि फोन डक गर्नु आवश्यक पर्दछ।"</string>
<string name="dock_sounds_enable_title" msgid="3385931465312084061">"डक राख्ने आवाज"</string>
<string name="dock_sounds_enable_summary_on" product="tablet" msgid="4322104626905111669">"डकबाट ट्याब्लेट हटाउँदा वा राख्दा आवाज बजाउनुहोस्"</string>
<string name="dock_sounds_enable_summary_on" product="default" msgid="2751810717801098293">"फोन डकमा राख्दा वा झिक्दा आवाज बजाउनुहोस्"</string>
@@ -1372,7 +1372,7 @@
<string name="memory_apps_usage" msgid="1886814780760368266">"एप & एप डेटा"</string>
<string name="memory_media_usage" msgid="2744652206722240527">"मिडिया"</string>
<string name="memory_downloads_usage" msgid="7039979723012065168">"डाउनलोडहरू"</string>
- <string name="memory_dcim_usage" msgid="599009211606524732">"तस्बिरहरू, भिडियोहरू"</string>
+ <string name="memory_dcim_usage" msgid="599009211606524732">"फोटोहरू, भिडियोहरू"</string>
<string name="memory_music_usage" msgid="809605300042546279">"अडियो (सङ्गीत, रिङ्गटोन, पडकास्ट, आदि)"</string>
<string name="memory_media_misc_usage" msgid="6258827529046910705">"अन्य फाइलहरू"</string>
<string name="memory_media_cache_usage" msgid="1307620682751377717">"क्यास गरेको डेटा"</string>
@@ -1388,7 +1388,7 @@
<string name="sd_mount_summary" product="default" msgid="6849124618494311233"></string>
<string name="sd_format" product="nosdcard" msgid="918370986254863144">"USB भण्डारण मेटाउनुहोस्"</string>
<string name="sd_format" product="default" msgid="1346245995138883960">"SD कार्ड मेटाउनुहोस्"</string>
- <string name="sd_format_summary" product="nosdcard" msgid="1179857727779521920">"आन्तरिक USB भण्डारणमा सम्पूर्ण डेटाहरू मेटाउँछ, जस्तै सङ्गीत र तस्बिरहरू"</string>
+ <string name="sd_format_summary" product="nosdcard" msgid="1179857727779521920">"आन्तरिक USB भण्डारणमा सम्पूर्ण डेटाहरू मेटाउँछ, जस्तै सङ्गीत र फोटोहरू"</string>
<string name="sd_format_summary" product="default" msgid="4284028411908176234">"SD कार्डमा सबै डेटा जस्तै सङ्गीत र फोटोहरू मेटाउँछ"</string>
<string name="memory_clear_cache_title" msgid="4306793268129306684">"क्यास डेटा हटाउनु हुन्छ?"</string>
<string name="memory_clear_cache_message" msgid="6723120398411410031">"यसले सबै अनुप्रयोगहरूको लागि केस गरिएको डेटा हटाउँछ।"</string>
@@ -1444,11 +1444,11 @@
<string name="storage_dialog_unmounted" msgid="515810851912430933">"यो <xliff:g id="NAME_0">^1</xliff:g> सुरक्षित रूपमा निकालियो, तर अझै पनि उपलब्ध छ। \n\n यो <xliff:g id="NAME_1">^1</xliff:g> प्रयोग गर्न, तपाईँले पहिला यो माउन्ट गर्नुपर्छ।"</string>
<string name="storage_dialog_unmountable" msgid="7082856306456936054">"यो <xliff:g id="NAME_0">^1</xliff:g> बिग्रिएको छ। \n\n यो <xliff:g id="NAME_1">^1</xliff:g> प्रयोग गर्न, तपाईँले पहिले यसलाई सेटअप गर्नुहोस्।"</string>
<string name="storage_dialog_unsupported" msgid="8274023677580782553">"यो यन्त्रले यो <xliff:g id="NAME_0">^1</xliff:g> लाई समर्थन गर्दैन। \n\n यस यन्त्रसँग यो <xliff:g id="NAME_1">^1</xliff:g> प्रयोग गर्न, तपाईँले पहिला यो सेटअप गर्नुपर्छ।"</string>
- <string name="storage_internal_format_details" msgid="2780806013122012384">"ढाँचामा मिलाएपछि, तपाईँले यसलाई <xliff:g id="NAME_0">^1</xliff:g> अन्य यन्त्रहरूमा प्रयोग गर्न सक्नुहुन्छ। \n\nयसका <xliff:g id="NAME_1">^1</xliff:g> सबै डेटा मेटिनेछन्। पहिले ब्याकअप राख्ने बारे विचार गर्नुहोस्। \n\n"<b>"तस्बिर तथा अन्य मिडिया ब्याकअप गर्नुहोस्"</b>" \n यस यन्त्रमा वैकल्पिक भण्डारण गर्न आफ्नो मिडिया फाइलहरू सार्नुहोस्, वा USB केबल प्रयोग गरी कम्प्युटरको स्थानान्तरण गर्नुहोस्। \n\n"<b>"एपहरू ब्याकअप गर्नुहोस्"</b>" \n यसमा <xliff:g id="NAME_6">^1</xliff:g> भण्डारित सबै एपहरू हटाइने छन् र तिनका डेटा मेटिनेछन्। यी एपहरू राख्न, यस यन्त्रमा वैकल्पिक भण्डारण गर्न तिनीहरूलाई सार्नुहोस्।"</string>
+ <string name="storage_internal_format_details" msgid="2780806013122012384">"ढाँचामा मिलाएपछि, तपाईँले यसलाई <xliff:g id="NAME_0">^1</xliff:g> अन्य यन्त्रहरूमा प्रयोग गर्न सक्नुहुन्छ। \n\nयसका <xliff:g id="NAME_1">^1</xliff:g> सबै डेटा मेटिनेछन्। पहिले ब्याकअप राख्ने बारे विचार गर्नुहोस्। \n\n"<b>"फोटो तथा अन्य मिडिया ब्याकअप गर्नुहोस्"</b>" \n यस यन्त्रमा वैकल्पिक भण्डारण गर्न आफ्नो मिडिया फाइलहरू सार्नुहोस्, वा USB केबल प्रयोग गरी कम्प्युटरको स्थानान्तरण गर्नुहोस्। \n\n"<b>"एपहरू ब्याकअप गर्नुहोस्"</b>" \n यसमा <xliff:g id="NAME_6">^1</xliff:g> भण्डारित सबै एपहरू हटाइने छन् र तिनका डेटा मेटिनेछन्। यी एपहरू राख्न, यस यन्त्रमा वैकल्पिक भण्डारण गर्न तिनीहरूलाई सार्नुहोस्।"</string>
<string name="storage_internal_unmount_details" msgid="4667435317528624039"><b>"जब तपाईं <xliff:g id="NAME_0">^1</xliff:g> लाई निकाल्नुहुन्छ, यसमा भएका एपहरू चल्न छोड्नेछन्, र पुनः नघुसाएसम्म त्यसमा भएका मिडिया फाइलहरू उपलब्ध हुने छैनन्।"</b>\n\n"यो <xliff:g id="NAME_1">^1</xliff:g> यस यन्त्रमा मात्र काम गर्ने हिसाबले फरम्याट गरिएको छ। यो अन्य कुनैमा काम गर्ने छैन।"</string>
<string name="storage_internal_forget_details" msgid="5655856574682184453">"<xliff:g id="NAME">^1</xliff:g> मा भएका एपहरू, तस्बिरहरु, र डेटाको प्रयोग गर्न, यसलाई पुन: घुसाउनुहोस्।\n\nवैकल्पिक रूपमा, यन्त्र उपलब्ध नभएको खण्डमा यस भण्डारणलाई भुल्नको लागि रोज्न सक्नुहुनेछ।\n\nयदि तपाईँले भुल्ने विकल्प रोज्नु हुन्छ भने, यन्त्रमा भएका सम्पूर्ण डेटा सदाको लागि नष्ट हुनेछ।\n\nतपाईँले पछि पनि एपहरू पुन: स्थापना गर्न सक्नुहुन्छ तर यस यन्त्रमा भण्डारण भएका डेटा नष्ट हुनेछ।"</string>
<string name="storage_internal_forget_confirm_title" msgid="331032276130605241">"<xliff:g id="NAME">^1</xliff:g> भुल्नुभयो?"</string>
- <string name="storage_internal_forget_confirm" msgid="3052483375203727176">"यो <xliff:g id="NAME">^1</xliff:g> मा भण्डारण गरिएका सबै एपहरू, तस्बिरहरू, र डेटा सधैंका लागि नष्ट हुनेछन्।"</string>
+ <string name="storage_internal_forget_confirm" msgid="3052483375203727176">"यो <xliff:g id="NAME">^1</xliff:g> मा भण्डारण गरिएका सबै एपहरू, फोटोहरू, र डेटा सधैंका लागि नष्ट हुनेछन्।"</string>
<string name="storage_detail_apps" msgid="8154648512504196820">"एपहरू"</string>
<string name="storage_detail_images" msgid="6996202225684468964">"छविहरू"</string>
<string name="storage_detail_videos" msgid="6030983354721080849">"भिडियोहरू"</string>
@@ -1459,12 +1459,12 @@
<string name="storage_detail_explore" msgid="8206900269596580264">"<xliff:g id="NAME">^1</xliff:g> अन्वेषण गर्नुहोस्"</string>
<string name="storage_detail_dialog_other" msgid="5073511663616043370">"अन्यमा एपहरूले सुरक्षित गेरका साझा फाइल, इन्टरनेट वा ब्लुटुथबाट डाउनलोड गरिएका फाइल, Android का फाइलहरू र यस्तै थप कुराहरू पर्छन्। \n\nयो <xliff:g id="NAME">^1</xliff:g> का देख्न सकिने सामग्रीहरू हेर्न अन्वेषण गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्।"</string>
<string name="storage_detail_dialog_system" msgid="1472572861360014226">"प्रणालीमा Android संस्करण <xliff:g id="VERSION">%s</xliff:g> चलाउनका लागि प्रयोग भएका फाइलहरू समावेश छन्"</string>
- <string name="storage_detail_dialog_user" msgid="1663117417635010371">"<xliff:g id="USER_0">^1</xliff:g> ले तस्बिर, सङ्गीत, एप वा अन्य डेटा सुरक्षित गर्नुभएको हुनसक्छ, जसले <xliff:g id="SIZE">^2</xliff:g> भण्डारण ओगटिरहेको छ। \n\nविवरणहरू हेर्न <xliff:g id="USER_1">^1</xliff:g> मा स्विच गर्नुहोस्।"</string>
+ <string name="storage_detail_dialog_user" msgid="1663117417635010371">"<xliff:g id="USER_0">^1</xliff:g> ले फोटो, सङ्गीत, एप वा अन्य डेटा सुरक्षित गर्नुभएको हुनसक्छ, जसले <xliff:g id="SIZE">^2</xliff:g> भण्डारण ओगटिरहेको छ। \n\nविवरणहरू हेर्न <xliff:g id="USER_1">^1</xliff:g> मा स्विच गर्नुहोस्।"</string>
<string name="storage_wizard_init_title" msgid="3407283236421089014">"तपाईँको <xliff:g id="NAME">^1</xliff:g> सेट गर्नुहोस्"</string>
<string name="storage_wizard_init_external_title" msgid="6853250619674645478">"पोर्टेबल भण्डारणको रूपमा प्रयोग गर्नुहोस्"</string>
- <string name="storage_wizard_init_external_summary" msgid="6993815290050489327">"यन्त्रहरू बीच तस्बिर र अन्य मिडिया सार्नका लागि।"</string>
+ <string name="storage_wizard_init_external_summary" msgid="6993815290050489327">"यन्त्रहरू बीच फोटो र अन्य मिडिया सार्नका लागि।"</string>
<string name="storage_wizard_init_internal_title" msgid="8750856962785644870">"आन्तरिक भण्डारणको रूपमा प्रयोग गर्नुहोस्"</string>
- <string name="storage_wizard_init_internal_summary" msgid="4510546464921608029">"यस यन्त्रमा मात्र कुनै पनि चिज, एप र तस्बिरहरू भण्डारण गर्नाका लागि। यसलाई ढाँचा मिलाउन आवश्यक हुन्छ जसले अर्का यन्त्रहरूसँग काम गर्नबाट रोक्छ।"</string>
+ <string name="storage_wizard_init_internal_summary" msgid="4510546464921608029">"यस यन्त्रमा मात्र कुनै पनि चिज, एप र फोटोहरू भण्डारण गर्नाका लागि। यसलाई ढाँचा मिलाउन आवश्यक हुन्छ जसले अर्का यन्त्रहरूसँग काम गर्नबाट रोक्छ।"</string>
<string name="storage_wizard_format_confirm_title" msgid="7785358616068633439">"आन्तरिक भण्डारणको रुपमा ढाँचा गर्नुहोस्"</string>
<string name="storage_wizard_format_confirm_body" msgid="4107762933332992624">"यो सुरक्षित बनाउन यसलाई <xliff:g id="NAME_0">^1</xliff:g> ढाँचा बनाउन आवश्यकता छ। \n\nढाँचामा मिलाएपछि, यो यन्त्रमा यसले <xliff:g id="NAME_1">^1</xliff:g> मात्र काम गर्ने छ। \n\n"<b>" ढाँचा मिलाउँदा <xliff:g id="NAME_2">^1</xliff:g> मा हालैका भण्डारित सबै डेटा मेटिन्छ।"</b>" डेटा गुमाउनुपर्ने बाट जोगिन, यसको ब्याकअप राख्ने बारे विचार गर्नुहोस्।"</string>
<string name="storage_wizard_format_confirm_public_title" msgid="5866830103788091426">"पोर्टेबल भण्डारणका रूपमा फरम्याट गर्नुहोस्"</string>
@@ -1482,8 +1482,8 @@
<string name="storage_wizard_migrate_progress_title" msgid="7542196688665109833">"डेटा सार्दै..."</string>
<string name="storage_wizard_migrate_details" msgid="4269509141637554985">"सार्दाको समयमा: \n• <xliff:g id="NAME">^1</xliff:g> नहटाउनुहोस्। \n• केही एपहरूले सही काम गर्ने छैन। \n• यन्त्र चार्जमा राख्नुहोस्।"</string>
<string name="storage_wizard_ready_title" msgid="4905921139763520341">"तपाईंको <xliff:g id="NAME">^1</xliff:g> प्रयोगका लागि तयार छ"</string>
- <string name="storage_wizard_ready_external_body" msgid="8785407468656286236">"तपाईँको <xliff:g id="NAME">^1</xliff:g> तस्बिर र अन्य मिडिया प्रयोग गर्न सबै सेट छ।"</string>
- <string name="storage_wizard_ready_internal_body" msgid="2258287496678469217">"तपाईँको नयाँ <xliff:g id="NAME">^1</xliff:g> ले काम गर्दैछ। \n\n यो यन्त्रमा तस्बिरहरू, फाइलहरू, र एप डेटा सार्न, सेटिङ &gt मा जानुहोस्; भण्डारण गर्नुहोस्।"</string>
+ <string name="storage_wizard_ready_external_body" msgid="8785407468656286236">"तपाईँको <xliff:g id="NAME">^1</xliff:g> फोटो र अन्य मिडिया प्रयोग गर्न सबै सेट छ।"</string>
+ <string name="storage_wizard_ready_internal_body" msgid="2258287496678469217">"तपाईँको नयाँ <xliff:g id="NAME">^1</xliff:g> ले काम गर्दैछ। \n\n यो यन्त्रमा फोटोहरू, फाइलहरू, र एप डेटा सार्न, सेटिङ &gt मा जानुहोस्; भण्डारण गर्नुहोस्।"</string>
<string name="storage_wizard_move_confirm_title" msgid="7362472162039287488">"सार्नुहोस् <xliff:g id="APP">^1</xliff:g>"</string>
<string name="storage_wizard_move_confirm_body" msgid="502315190416551319">"<xliff:g id="NAME_0">^2</xliff:g> मा <xliff:g id="APP">^1</xliff:g> र यसको डेटा सार्न केही बेर मात्र लिनेछ। तपाईं सार्ने क्रम पूरा नहुन्जेल एप प्रयोग गर्न सक्नुहुने छैन। \n\n सार्ने क्रममा <xliff:g id="NAME_1">^2</xliff:g> नहटाउनुहोस्।"</string>
<string name="storage_wizard_move_unlock" msgid="7978193904519827600">"डेटा सार्न तपाईंले प्रयोगकर्ताको <xliff:g id="APP">^1</xliff:g> अनलक गर्नु पर्ने हुन्छ।"</string>
@@ -1610,9 +1610,9 @@
<string name="master_clear_progress_text" msgid="5418958116008976218">"कृपया प्रतीक्षा गर्नुहोला..."</string>
<string name="call_settings_title" msgid="5033906789261282752">"कल सेटिङहरू"</string>
<string name="call_settings_summary" msgid="2119161087671450035">"भ्वाइस मेल, कल फर्वार्ड, कल प्रतीक्षा, र कलर ID सेटअप गर्नुहोस्"</string>
- <string name="tether_settings_title_usb" msgid="4265582654602420357">"USB टेथर गर्दै"</string>
+ <string name="tether_settings_title_usb" msgid="4265582654602420357">"USB टेदर गर्दै"</string>
<string name="tether_settings_title_wifi" msgid="2060965130234484613">"पोर्टेबल हटस्पट"</string>
- <string name="tether_settings_title_bluetooth" msgid="1999590158102569959">"ब्लुटुथ टेथर गर्दै"</string>
+ <string name="tether_settings_title_bluetooth" msgid="1999590158102569959">"ब्लुटुथ टेदर गर्दै"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1159128764162788159">"टेदर गर्दै"</string>
<string name="tether_settings_title_all" msgid="6935843543433954181">"हटस्पट र टेदरिङ"</string>
<string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"हटस्पट सक्रिय छ, टेदरिङ"</string>
@@ -1623,7 +1623,7 @@
<string name="usb_tethering_button_text" msgid="6242228383142012332">"USB टेदर गर्दै"</string>
<string name="usb_tethering_subtext" product="default" msgid="1573513260339548671">"USB मार्फत फोनको इन्टरनेट सेयर गर्नुहोस्"</string>
<string name="usb_tethering_subtext" product="tablet" msgid="154536000235361034">"USB मार्फत ट्याब्लेटको इन्टरनेट जडान साझा गर्नुहोस्"</string>
- <string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"ब्लुटुथ टेथर गर्दै"</string>
+ <string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"ब्लुटुथ टेदर गर्दै"</string>
<string name="bluetooth_tethering_subtext" product="tablet" msgid="6868756914621131635">"ब्लुटुथमार्फत ट्याब्लेटको इन्टरनेट जडान सझा गर्नुहोस्"</string>
<string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"ब्लुटुथमार्फत फोनको इन्टरनेट सेयर गर्नुहोस्"</string>
<string name="bluetooth_tethering_off_subtext_config" msgid="3981528184780083266">"ब्लुटुथमार्फत यो <xliff:g id="DEVICE_NAME">%1$d</xliff:g> को इन्टरनेट जडान साझा गर्दै"</string>
@@ -2563,7 +2563,7 @@
<string name="backup_erase_dialog_title" msgid="8178424339104463014"></string>
<string name="backup_erase_dialog_message" msgid="8767843355330070902">"तपाईँको Wi-Fi पासवर्डहरू, बुकमार्क, अन्य सेटिङहरू, र एप डेटाको जगेडा राख्न बन्द गर्ने र Google सर्भरबाट सम्पूर्ण प्रतिलिपिहरू मेटाउने हो?"</string>
<string name="fullbackup_erase_dialog_message" msgid="2588536036471144070">"के यन्त्र डेटा (जस्तै Wi-Fi पासवर्डहरू र इतिहास कल) र एप डेटा (जस्तै एपहरू द्वारा भण्डारण सेटिङहरू र फाइलहरू) को ब्याकअपलाई रोक्ने, र थप रिमोट सर्भरहरूमा सबै प्रतिलिपिहरू मेटाउन चाहनु हुन्छ?"</string>
- <string name="fullbackup_data_summary" msgid="406274198094268556">"यन्त्र डेटा (जस्तै Wi-Fi पासवर्डहरू र कल इतिहास) र एप डेटा (जस्तै एपहरूद्वारा भण्डारित सेटिङहरू र फाइलहरू) टाढाबाट स्वचालित रुपमा ब्याकअप गर्नुहोस्। \n\nजब तपाईं स्वचालित ब्याकअप यन्त्र सक्षम गर्नुहुन्छ, यन्त्र र एप डेटा आवधिक रूपमा टाढाबाट सुरक्षित गरिएको छ। सम्पर्क, सन्देशहरू, र तस्बिरहरू जस्तै सम्भावित संवेदनशील डेटा सहित, एप डेटा कुनै पनि डेटा हुनसक्छ जुन एपले (विकासकर्ता सेटिङहरूमा आधारित) सुरक्षित गरेको छ।"</string>
+ <string name="fullbackup_data_summary" msgid="406274198094268556">"यन्त्र डेटा (जस्तै Wi-Fi पासवर्डहरू र कल इतिहास) र एप डेटा (जस्तै एपहरूद्वारा भण्डारित सेटिङहरू र फाइलहरू) टाढाबाट स्वचालित रुपमा ब्याकअप गर्नुहोस्। \n\nजब तपाईं स्वचालित ब्याकअप यन्त्र सक्षम गर्नुहुन्छ, यन्त्र र एप डेटा आवधिक रूपमा टाढाबाट सुरक्षित गरिएको छ। सम्पर्क, सन्देशहरू, र फोटोहरू जस्तै सम्भावित संवेदनशील डेटा सहित, एप डेटा कुनै पनि डेटा हुनसक्छ जुन एपले (विकासकर्ता सेटिङहरूमा आधारित) सुरक्षित गरेको छ।"</string>
<string name="device_admin_settings_title" msgid="2074319456047334589">"यन्त्रका प्रशासक सम्बन्धी सेटिङहरू"</string>
<string name="active_device_admin_msg" msgid="6929247869516924549">"यन्त्रको प्रशासन सम्बन्धी एप"</string>
<string name="remove_device_admin" msgid="4413438593788336400">"यो यन्त्रको प्रशासकीय एपलाई निष्क्रिय पार्नुहोस्"</string>
@@ -2938,7 +2938,7 @@
<string name="help_label" msgid="1296484776243905646">"मद्दत र प्रतिक्रिया"</string>
<string name="support_summary" msgid="3278943815956130740">"मद्दतसम्बन्धी लेखहरू, फोन, कुराकानी र सुरूवात गर्नेसम्बन्धी सहायता"</string>
<string name="user_account_title" msgid="2108666882630552859">"सामग्रीको लागि खाता"</string>
- <string name="user_picture_title" msgid="6664602422948159123">"तस्बिर ID"</string>
+ <string name="user_picture_title" msgid="6664602422948159123">"फोटो ID"</string>
<string name="extreme_threats_title" msgid="1405820547540456436">"चरम धम्की"</string>
<string name="extreme_threats_summary" msgid="4967919167246852181">"जीवन र सम्पत्तिको चरम खतराहरूको लागि चेतावनीहरू प्राप्त"</string>
<string name="severe_threats_title" msgid="1987698359027211862">"गम्भीर खतराहरू"</string>
@@ -2981,9 +2981,9 @@
<string name="wizard_back" msgid="223654213898117594">"पछाडि जानुहोस्"</string>
<string name="wizard_next" msgid="5239664512608113542">"अर्को"</string>
<string name="wizard_finish" msgid="3742102879981212094">"समाप्त गर्नुहोस्"</string>
- <string name="user_image_take_photo" msgid="2000247510236178111">"तस्बिर खिच्नुहोस्"</string>
- <string name="user_image_choose_photo" msgid="4920315415203051898">"कुनै तस्बिर छनौट गर्नुहोस्"</string>
- <string name="user_image_photo_selector" msgid="8429694590849882411">"तस्बिर छान्नुहोस्"</string>
+ <string name="user_image_take_photo" msgid="2000247510236178111">"फोटो खिच्नुहोस्"</string>
+ <string name="user_image_choose_photo" msgid="4920315415203051898">"कुनै फोटो छनौट गर्नुहोस्"</string>
+ <string name="user_image_photo_selector" msgid="8429694590849882411">"फोटो छान्नुहोस्"</string>
<string name="regulatory_info_text" msgid="9112993912873512834"></string>
<string name="sim_setup_wizard_title" msgid="77627575294867180">"सिम कार्ड"</string>
<string name="sim_settings_title" msgid="8818243954752261922">"SIM कार्डहरू"</string>
@@ -3386,7 +3386,7 @@
<string name="display_vr_pref_off" msgid="4681320968818852691">"स्क्रिन झिलमिलाउने प्रभाव कम गर्नुहोस्"</string>
<string name="picture_in_picture_title" msgid="4960733106166035448">"Picture-in-picture"</string>
<string name="picture_in_picture_empty_text" msgid="8664071475324685241">"स्थापना गरिएका कुनै पनि एपहरूले Picture-in-picture मोडलाई समर्थन गर्दैनन्"</string>
- <string name="picture_in_picture_keywords" msgid="7326958702002259262">"तस्बिरमा तस्बिर मोडमा तस्बिर"</string>
+ <string name="picture_in_picture_keywords" msgid="7326958702002259262">"फोटोमा फोटो मोडमा फोटो"</string>
<string name="picture_in_picture_app_detail_title" msgid="3916189052657425936">"Picture-in-picture"</string>
<string name="picture_in_picture_app_detail_switch" msgid="747422998967185418">"Picture-in-picture लाई अनुमति दिनुहोस्"</string>
<string name="picture_in_picture_app_detail_summary" msgid="918632751775525347">"यो एप खुला रहेको अवस्थामा वा तपाईंले यसलाई छाड्नुभएपछि (उदाहरणका लागि, भिडियो हेर्ने कार्य जारी राख्न) यस एपलाई picture-in-picture विन्डो सिर्जना गर्न अनुमति दिनुहोस्। यो विन्डो तपाईंले प्रयोग गरिरहनुभएका अन्य एपहरूको शीर्ष भागमा देखिन्छ।"</string>
@@ -4100,8 +4100,8 @@
<item quantity="one">१ सेकेन्ड</item>
</plurals>
<string name="automatic_storage_manager_settings" msgid="2403621409625820182">"भण्डारणको व्यवस्थापन गर्नुहोस्"</string>
- <string name="automatic_storage_manager_text" msgid="4270379105066667493">"भण्डारण प्रबन्धकले भण्डारणको ठाउँ खाली गर्न मद्दतका लागि तपाईँको यन्त्रबाट ब्याक अप गरिएका तस्बिर र भिडियोहरू हटाउँदछ।"</string>
- <string name="automatic_storage_manager_days_title" msgid="1783767804707813799">"तस्बिर र भिडियोहरूलाई मेट्नुहोस्"</string>
+ <string name="automatic_storage_manager_text" msgid="4270379105066667493">"भण्डारण प्रबन्धकले भण्डारणको ठाउँ खाली गर्न मद्दतका लागि तपाईँको यन्त्रबाट ब्याक अप गरिएका फोटो र भिडियोहरू हटाउँदछ।"</string>
+ <string name="automatic_storage_manager_days_title" msgid="1783767804707813799">"फोटो र भिडियोहरूलाई मेट्नुहोस्"</string>
<string name="automatic_storage_manager_preference_title" msgid="4668642150512639466">"भण्डारण प्रबन्धक"</string>
<string name="automatic_storage_manager_master_switch_title" msgid="1456978117739582562">"भण्डारण प्रबन्धक प्रयोग गर्नुहोस्"</string>
<string name="deletion_helper_automatic_title" msgid="4370975149425263205">"स्वतः"</string>
@@ -4235,7 +4235,7 @@
</plurals>
<string name="app_names_concatenation_template_2" msgid="8267577900046506189">"<xliff:g id="FIRST_APP_NAME">%1$s</xliff:g>, <xliff:g id="SECOND_APP_NAME">%2$s</xliff:g>"</string>
<string name="app_names_concatenation_template_3" msgid="5129064036161862327">"<xliff:g id="FIRST_APP_NAME">%1$s</xliff:g>, <xliff:g id="SECOND_APP_NAME">%2$s</xliff:g>, <xliff:g id="THIRD_APP_NAME">%3$s</xliff:g>"</string>
- <string name="storage_photos_videos" msgid="1890829312367477559">"तस्बिर र भिडियोहरू"</string>
+ <string name="storage_photos_videos" msgid="1890829312367477559">"फोटो र भिडियोहरू"</string>
<string name="storage_music_audio" msgid="3661289086715297149">"सङ्गीत तथा अडियो"</string>
<string name="storage_games" msgid="7740038143749092373">"खेलहरू"</string>
<string name="storage_other_apps" msgid="3202407095387420842">"अन्य एपहरू"</string>
diff --git a/tests/CarDeveloperOptions/res/values-nl/strings.xml b/tests/CarDeveloperOptions/res/values-nl/strings.xml
index 6034129..8d95cc0 100644
--- a/tests/CarDeveloperOptions/res/values-nl/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-nl/strings.xml
@@ -198,7 +198,7 @@
<string name="proxy_port_label" msgid="8285157632538848509">"Proxy-poort"</string>
<string name="proxy_exclusionlist_label" msgid="8179084955547941904">"Proxy omzeilen voor"</string>
<string name="proxy_defaultView_text" msgid="5785775257042403261">"Standaardwaarden herstellen"</string>
- <string name="proxy_action_text" msgid="814511434843981413">"Gereed"</string>
+ <string name="proxy_action_text" msgid="814511434843981413">"Klaar"</string>
<string name="proxy_hostname_label" msgid="6798891831427287847">"Hostnaam van proxy"</string>
<string name="proxy_error" msgid="5036164133669802299">"Let op"</string>
<string name="proxy_error_dismiss" msgid="883805570485635650">"OK"</string>
@@ -293,7 +293,7 @@
<string name="okay" msgid="5838476766924989056">"OK"</string>
<string name="forget" msgid="7735525146062672874">"Vergeten"</string>
<string name="save" msgid="3418211178410498517">"Opslaan"</string>
- <string name="done" msgid="5143229467535372339">"Gereed"</string>
+ <string name="done" msgid="5143229467535372339">"Klaar"</string>
<string name="apply" msgid="951230399613164126">"Toepassen"</string>
<string name="share" msgid="3567029787293158575">"Delen"</string>
<string name="add" msgid="903114118076816060">"Toevoegen"</string>
@@ -415,7 +415,7 @@
<string name="security_settings_face_enroll_error_timeout_dialog_message" msgid="4917894418448325405">"Tijdlimiet voor gezichtsregistratie is bereikt. Probeer het opnieuw."</string>
<string name="security_settings_face_enroll_error_generic_dialog_message" msgid="5160473187142616862">"Gezichtsregistratie is mislukt"</string>
<string name="security_settings_face_enroll_finish_title" msgid="6800717857394410769">"Alles is ingesteld."</string>
- <string name="security_settings_face_enroll_done" msgid="5409739233373490971">"Gereed"</string>
+ <string name="security_settings_face_enroll_done" msgid="5409739233373490971">"Klaar"</string>
<string name="security_settings_face_settings_use_face_category" msgid="1586532139528115416">"Gezicht gebr. voor"</string>
<string name="security_settings_face_settings_use_face_unlock_phone" msgid="318274519126401671">"Apparaatontgrendeling"</string>
<string name="security_settings_face_settings_use_face_for_apps" msgid="5479369083370664351">"App-login en -betalingen"</string>
@@ -484,7 +484,7 @@
<string name="lock_screen_password_skip_title" msgid="3725788215672959827">"Instell. wachtwoord overslaan?"</string>
<string name="lock_screen_pattern_skip_title" msgid="4237030500353932005">"Instellen patroon overslaan?"</string>
<string name="security_settings_fingerprint_enroll_setup_screen_lock" msgid="9036983528330627756">"Schermvergrendeling instellen"</string>
- <string name="security_settings_fingerprint_enroll_done" msgid="4111289529758845926">"Gereed"</string>
+ <string name="security_settings_fingerprint_enroll_done" msgid="4111289529758845926">"Klaar"</string>
<string name="security_settings_fingerprint_enroll_touch_dialog_title" msgid="7410398793283818609">"Dat is niet de sensor"</string>
<string name="security_settings_fingerprint_enroll_touch_dialog_message" msgid="7192100314788868883">"Raak de sensor achter op je telefoon aan. Gebruik je wijsvinger."</string>
<string name="security_settings_fingerprint_enroll_error_dialog_title" msgid="1415709674142168770">"Registratie is niet voltooid"</string>
@@ -808,7 +808,7 @@
<string name="wifi_display_details" msgid="6379855523460749126">"Weergave-instellingen"</string>
<string name="wifi_display_options_title" msgid="4587264519668872213">"Opties voor draadloze weergave"</string>
<string name="wifi_display_options_forget" msgid="7882982544626742073">"Vergeten"</string>
- <string name="wifi_display_options_done" msgid="5922060890309265817">"Gereed"</string>
+ <string name="wifi_display_options_done" msgid="5922060890309265817">"Klaar"</string>
<string name="wifi_display_options_name" msgid="8477627781133827607">"Naam"</string>
<string name="wifi_band_24ghz" msgid="2973143764653628618">"2,4 GHz"</string>
<string name="wifi_band_5ghz" msgid="6469832209748522207">"5 GHz"</string>
@@ -1625,7 +1625,7 @@
<string name="usb_tethering_subtext" product="tablet" msgid="154536000235361034">"Internetverbinding van tablet delen via USB"</string>
<string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"Bluetooth-tethering"</string>
<string name="bluetooth_tethering_subtext" product="tablet" msgid="6868756914621131635">"Internetverbinding van deze tablet delen via bluetooth"</string>
- <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Internetverbinding van deze telefoon delen via bluetooth"</string>
+ <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Internetverbinding van telefoon delen via bluetooth"</string>
<string name="bluetooth_tethering_off_subtext_config" msgid="3981528184780083266">"Internetverbinding van deze <xliff:g id="DEVICE_NAME">%1$d</xliff:g> delen via bluetooth"</string>
<string name="bluetooth_tethering_overflow_error" msgid="6946561351369376943">"Kan niet meer dan <xliff:g id="MAXCONNECTION">%1$d</xliff:g> apparaten tetheren."</string>
<string name="bluetooth_untether_blank" msgid="5428300773782256084">"Tethering van <xliff:g id="DEVICE_NAME">%1$s</xliff:g> wordt opgeheven."</string>
@@ -2455,7 +2455,7 @@
<string name="battery_saver_auto_percentage_summary" msgid="2036128588460338677">"Wordt ingeschakeld bij <xliff:g id="PERCENT">%1$s</xliff:g>"</string>
<string name="battery_saver_schedule_settings_title" msgid="574233428557678128">"Een planning instellen"</string>
<string name="battery_saver_sticky_title_new" msgid="5328707297110866082">"Uitschakelen wanneer volledig opgeladen"</string>
- <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Batterijbesparing wordt uitgeschakeld wanneer je telefoon <xliff:g id="PERCENT">%1$s</xliff:g> batterijlading heeft"</string>
+ <string name="battery_saver_sticky_description_new" product="default" msgid="3406582427270935879">"Batterijbesparing wordt uitgeschakeld als je telefoon <xliff:g id="PERCENT">%1$s</xliff:g> batterijlading heeft"</string>
<string name="battery_saver_sticky_description_new" product="tablet" msgid="3284967694001857194">"Batterijbesparing wordt uitgeschakeld wanneer je tablet <xliff:g id="PERCENT">%1$s</xliff:g> batterijlading heeft"</string>
<string name="battery_saver_sticky_description_new" product="device" msgid="5056520668081504111">"Batterijbesparing wordt uitgeschakeld wanneer je apparaat <xliff:g id="PERCENT">%1$s</xliff:g> batterijlading heeft"</string>
<!-- no translation found for battery_saver_seekbar_title (7607123201469333645) -->
@@ -2829,7 +2829,7 @@
<string name="backup_pw_cancel_button_text" msgid="6170984655621611957">"Annuleren"</string>
<string name="additional_system_update_settings_list_item_title" msgid="8674710454802166341">"Aanvullende systeemupdates"</string>
<string name="ssl_ca_cert_warning" msgid="7794291734272626026">"Netwerk kan worden gemonitord"</string>
- <string name="done_button" msgid="7652373284597307008">"Gereed"</string>
+ <string name="done_button" msgid="7652373284597307008">"Klaar"</string>
<plurals name="ssl_ca_cert_dialog_title" formatted="false" msgid="7323708984446517980">
<item quantity="other">Certificaten vertrouwen of verwijderen</item>
<item quantity="one">Certificaat vertrouwen of verwijderen</item>
@@ -3295,7 +3295,7 @@
<string name="ringtones_category_preference_title" msgid="4491932700769815470">"Ringtones"</string>
<string name="other_sound_category_preference_title" msgid="2045757472469840859">"Andere geluiden en trillingen"</string>
<string name="configure_notification_settings" msgid="291914315140851270">"Meldingen"</string>
- <string name="recent_notifications" msgid="8125865995065032049">"Recent verzonden"</string>
+ <string name="recent_notifications" msgid="8125865995065032049">"Recent verstuurd"</string>
<string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Alles weergeven van de afgelopen zeven dagen"</string>
<string name="advanced_section_header" msgid="984680389373090015">"Geavanceerd"</string>
<string name="profile_section_header" msgid="5471479005472037417">"Werkmeldingen"</string>
@@ -3428,7 +3428,7 @@
<string name="app_notification_row_banned" msgid="2079325338122151677">"Geblokkeerd"</string>
<string name="app_notification_row_priority" msgid="432299064888787236">"Prioriteit"</string>
<string name="app_notification_row_sensitive" msgid="4919671519227722958">"Gevoelig"</string>
- <string name="app_notifications_dialog_done" msgid="5395611029779655968">"Gereed"</string>
+ <string name="app_notifications_dialog_done" msgid="5395611029779655968">"Klaar"</string>
<string name="app_notification_importance_title" msgid="1902794400671001142">"Belang"</string>
<string name="notification_show_lights_title" msgid="5381920725933228542">"Knipperlicht"</string>
<string name="notification_vibrate_title" msgid="8221718258793835282">"Trillen"</string>
@@ -4251,15 +4251,15 @@
<string name="app_info_storage_title" msgid="6643391804949509308">"Gebruikte ruimte"</string>
<string name="webview_uninstalled_for_user" msgid="3407952144444040557">"(verwijderd voor gebruiker <xliff:g id="USER">%s</xliff:g>)"</string>
<string name="webview_disabled_for_user" msgid="8057805373224993504">"(uitgezet voor gebruiker <xliff:g id="USER">%s</xliff:g>)"</string>
- <string name="autofill_app" msgid="3990765434980280073">"Service voor automatisch aanvullen"</string>
+ <string name="autofill_app" msgid="3990765434980280073">"Service voor automatisch invullen"</string>
<string name="autofill_keywords" msgid="7717726766232862218">"auto, automatisch, invullen, aanvullen"</string>
<string name="autofill_confirmation_message" msgid="1385894598730361304">"<b>Zorg dat je deze app vertrouwt</b> <br/> <br/> <xliff:g id=app_name example=Google Autofill>%1$s</xliff:g> maakt gebruik van de content op je scherm om te bepalen wat automatisch kan worden aangevuld."</string>
- <string name="debug_autofill_category" msgid="6262526615416295645">"Automatisch aanvullen"</string>
+ <string name="debug_autofill_category" msgid="6262526615416295645">"Automatisch invullen"</string>
<string name="autofill_logging_level_title" msgid="2577340324541102626">"Logniveau"</string>
<string name="autofill_max_partitions" msgid="125269645910590057">"Max. aantal verzoeken per sessie"</string>
<string name="autofill_max_visible_datasets" msgid="2791081640248423492">"Max. zichtbare gegevenssets"</string>
<string name="autofill_reset_developer_options" msgid="7208417230269613101">"Resetten naar standaardwaarden"</string>
- <string name="autofill_reset_developer_options_complete" msgid="5686061993002179524">"Ontwikkelaarsopties voor automatisch aanvullen zijn gereset"</string>
+ <string name="autofill_reset_developer_options_complete" msgid="5686061993002179524">"Ontwikkelaarsopties voor automatisch invullen zijn gereset"</string>
<string name="device_theme" msgid="8992291311481135893">"Apparaatthema"</string>
<string name="default_theme" msgid="5986996377385956138">"Standaard"</string>
<string name="show_operator_name_title" msgid="5056163028128447308">"Netwerknaam"</string>
diff --git a/tests/CarDeveloperOptions/res/values-or/strings.xml b/tests/CarDeveloperOptions/res/values-or/strings.xml
index ab1e3a1..2f05467 100644
--- a/tests/CarDeveloperOptions/res/values-or/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-or/strings.xml
@@ -1125,7 +1125,7 @@
<string name="musicfx_title" msgid="6456079041566773649">"ମ୍ୟୁଜିକ୍ ଇଫେକ୍ଟସ୍"</string>
<string name="ring_volume_title" msgid="5874791723449821646">"ରିଙ୍ଗ ଭଲ୍ୟୁମ୍"</string>
<string name="vibrate_in_silent_title" msgid="2314667015729841220">"ନୀରବ ଥିବା ବେଳେ କମ୍ପନ କରନ୍ତୁ"</string>
- <string name="notification_sound_title" msgid="6812164482799723931">"ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ବିଜ୍ଞପ୍ତିର ଶବ୍ଦ"</string>
+ <string name="notification_sound_title" msgid="6812164482799723931">"ଡିଫଲ୍ଟ ବିଜ୍ଞପ୍ତି ସାଉଣ୍ଡ"</string>
<string name="incoming_call_volume_title" msgid="4736570528754310450">"ରିଙ୍ଗଟୋନ୍"</string>
<string name="notification_volume_title" msgid="6022562909288085275">"ବିଜ୍ଞପ୍ତି"</string>
<string name="checkbox_notification_same_as_incoming_call" msgid="7312942422655861175">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଇଁ ଇନ୍କମିଙ୍ଗ କଲ୍ ଭଲ୍ୟୁମ୍କୁ ବ୍ୟବହାର କର"</string>
@@ -1615,7 +1615,7 @@
<string name="tether_settings_title_bluetooth" msgid="1999590158102569959">"ବ୍ଲୁଟୁଥ ଟିଥରିଂ"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1159128764162788159">"ଟିଥରିଂ"</string>
<string name="tether_settings_title_all" msgid="6935843543433954181">"ହଟସ୍ପଟ୍ ଓ ଟିଥରିଂ"</string>
- <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"Hotspot ଅନ୍ ଅଛି, ଟିଥର୍ କରୁଛି"</string>
+ <string name="tether_settings_summary_hotspot_on_tether_on" msgid="1289593649526514499">"ହଟସ୍ପଟ୍ ଚାଲୁ ଅଛି, ଟିଥର୍ କରୁଛି"</string>
<string name="tether_settings_summary_hotspot_on_tether_off" msgid="8010689354668285422">"ହଟସ୍ପଟ୍ ଅନ୍"</string>
<string name="tether_settings_summary_hotspot_off_tether_on" msgid="1349909238672649877">"ଟିଥରିଂ"</string>
<string name="tether_settings_disabled_on_data_saver" msgid="3682544845899910726">"ଡାଟା ସେଭର୍ ଅନ୍ ଥିବାବେଳେ ଟିଥର୍ କିମ୍ୱା ପୋର୍ଟେବଲ୍ ହଟ୍ସ୍ପଟ୍ ବ୍ୟବହାର କରିପାରିବ ନାହିଁ"</string>
@@ -3141,7 +3141,7 @@
<string name="ring_volume_option_title" msgid="2038924918468372264">"ରିଙ୍ଗ ଭଲ୍ୟୁମ୍"</string>
<string name="notification_volume_option_title" msgid="1358512611511348260">"ସୂଚନା ଭଲ୍ୟୁମ"</string>
<string name="ringtone_title" msgid="1409086028485922583">"ଫୋନ୍ ରିଙ୍ଗଟୋନ୍"</string>
- <string name="notification_ringtone_title" msgid="2932960620843976285">"ଡିଫଲ୍ଟ୍ ବିଜ୍ଞପ୍ତି ଶବ୍ଦ"</string>
+ <string name="notification_ringtone_title" msgid="2932960620843976285">"ଡିଫଲ୍ଟ ବିଜ୍ଞପ୍ତି ସାଉଣ୍ଡ"</string>
<string name="notification_unknown_sound_title" msgid="8043718667804838398">"ଆପ୍ ଦ୍ୱାରା ପ୍ରଦତ୍ତ ଶବ୍ଦ"</string>
<string name="notification_sound_default" msgid="2664544380802426260">"ଡିଫଲ୍ଟ ବିଜ୍ଞପ୍ତି ସାଉଣ୍ଡ"</string>
<string name="alarm_ringtone_title" msgid="6411326147408635902">"ଡିଫଲ୍ଟ ଆଲାର୍ମ ସାଉଣ୍ଡ"</string>
@@ -3280,12 +3280,12 @@
<string name="zen_onboarding_new_setting_summary" msgid="8264430315983860075">"ଆପଣ ବିଜ୍ଞପ୍ତିକୁ ଦେଖି କିମ୍ବା ଶୁଣିପାରିବେ ନାହିଁ। ତାରାଙ୍କିତ ଯୋଗାଯୋଗରୁ ଆସିଥିବା କଲ୍ ଏବଂ ପୁଣି କଲ୍ କରୁଥିବା କଲର୍ଙ୍କୁ ଅନୁମତି ଦିଆଯାଇଛି।"</string>
<string name="zen_onboarding_current_setting_summary" msgid="3569246708507270821">"(ସାମ୍ପ୍ରତିକ ସେଟିଙ୍ଗ)"</string>
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"’ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ’ ବିଜ୍ଞପ୍ତି ସେଟିଙ୍ଗ ବଦଳାଇବେ?"</string>
- <string name="sound_work_settings" msgid="4140215240360927923">"କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ଶବ୍ଦ"</string>
- <string name="work_use_personal_sounds_title" msgid="531727195073003599">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ ଧ୍ୱନୀ ବ୍ୟବହାର କରନ୍ତୁ"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"କାର୍ଯ୍ୟ ଓ ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ ପାଇଁ ଶବ୍ଦଗୁଡ଼ିକ ସମାନ ଅଟେ"</string>
+ <string name="sound_work_settings" msgid="4140215240360927923">"କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ସାଉଣ୍ଡ"</string>
+ <string name="work_use_personal_sounds_title" msgid="531727195073003599">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ ସାଉଣ୍ଡ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"କାର୍ଯ୍ୟ ଓ ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ ପାଇଁ ସାଉଣ୍ଡଗୁଡ଼ିକ ସମାନ ଅଟେ"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"ଅଫିସ୍ ଫୋନ୍ର ରିଙ୍ଗଟୋନ୍"</string>
- <string name="work_notification_ringtone_title" msgid="8059159087214025757">"ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ କାର୍ଯ୍ୟ ବିଜ୍ଞପ୍ତି ଶବ୍ଦ"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ଡିଫଲ୍ଟ କାର୍ଯ୍ୟ ଆଲାର୍ମ ଶବ୍ଦ"</string>
+ <string name="work_notification_ringtone_title" msgid="8059159087214025757">"ଡିଫଲ୍ଟ କାର୍ଯ୍ୟ ବିଜ୍ଞପ୍ତି ସାଉଣ୍ଡ"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ଡିଫଲ୍ଟ କାର୍ଯ୍ୟ ଆଲାର୍ମ ସାଉଣ୍ଡ"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍ ପରି ସମାନ"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"ଶବ୍ଦ ବଦଳାଇବେ?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"ବଦଳାଇବ"</string>
@@ -3728,7 +3728,7 @@
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
<string name="usb_use_charging_only" msgid="2344625733377110164">"ଡାଟା ସ୍ଥାନାନ୍ତର ହେବ ନାହିଁ"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"ଏହି ଡିଭାଇସ୍କୁ ଚାର୍ଜ କରିଦିଅନ୍ତୁ"</string>
- <string name="usb_use_power_only" msgid="6595783381323810697">"କନେକ୍ଟ ହୋଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ କରନ୍ତୁ"</string>
+ <string name="usb_use_power_only" msgid="6595783381323810697">"ସଂଯୁକ୍ତ ହୋଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ କରନ୍ତୁ"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍"</string>
<string name="usb_use_file_transfers_desc" msgid="6953866660041189580">"ଅନ୍ୟଏକ ଡିଭାଇସ୍କୁ ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍ କରନ୍ତୁ"</string>
<string name="usb_use_photo_transfers" msgid="5974236250197451257">"PTP"</string>
diff --git a/tests/CarDeveloperOptions/res/values-pl/strings.xml b/tests/CarDeveloperOptions/res/values-pl/strings.xml
index 231b22b..375a3b7 100644
--- a/tests/CarDeveloperOptions/res/values-pl/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-pl/strings.xml
@@ -3370,8 +3370,8 @@
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"Zmienić ustawienia trybu Nie przeszkadzać?"</string>
<string name="sound_work_settings" msgid="4140215240360927923">"Dźwięki w profilu do pracy"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"Użyj dźwięków z profilu osobistego"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Dźwięki są takie same w profilu osobistym i do pracy"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"Dzwonek w profilu do pracy"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Dźwięki są takie same w profilu osobistym i służbowym"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"Dzwonek w profilu służbowym"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"Domyślny dźwięk powiadomienia w profilu służbowym"</string>
<string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Domyślny dźwięk alarmu w profilu służbowym"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Taki sam jak w profilu osobistym"</string>
diff --git a/tests/CarDeveloperOptions/res/values-pt/strings.xml b/tests/CarDeveloperOptions/res/values-pt/strings.xml
index f22e075..7450371 100644
--- a/tests/CarDeveloperOptions/res/values-pt/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-pt/strings.xml
@@ -3753,7 +3753,7 @@
<string name="usb_summary_photo_transfers" msgid="4743028167400644354">"PTP (fotos)"</string>
<string name="usb_summary_MIDI" msgid="5540604166270861247">"MIDI"</string>
<string name="usb_summary_file_transfers_power" msgid="1684501026426766867">"Transferência de arquivo e fornecimento de energia"</string>
- <string name="usb_summary_tether_power" msgid="5684170912136320002">"Tethering USB e fornecimento de energia"</string>
+ <string name="usb_summary_tether_power" msgid="5684170912136320002">"Tethering por USB e fornecimento de energia"</string>
<string name="usb_summary_photo_transfers_power" msgid="4424106272137720464">"PTP e fornecimento de energia"</string>
<string name="usb_summary_MIDI_power" msgid="7685597621357005180">"MIDI e fornecimento de energia"</string>
<string name="background_check_pref" msgid="664081406854758392">"Verificação em segundo plano"</string>
@@ -4052,7 +4052,7 @@
<string name="display_cutout_emulation_keywords" msgid="6795671536772871439">"corte de tela, entalhe"</string>
<string name="overlay_option_device_default" msgid="165508753381657697">"Padrão do dispositivo"</string>
<string name="overlay_toast_failed_to_apply" msgid="5692251825129250040">"Falha ao aplicar sobreposição"</string>
- <string name="special_access" msgid="1453926335914696206">"Acesso especial a apps"</string>
+ <string name="special_access" msgid="1453926335914696206">"Acesso especial para apps"</string>
<plurals name="special_access_summary" formatted="false" msgid="5182092345063909346">
<item quantity="one"><xliff:g id="COUNT">%d</xliff:g> app pode usar dados ilimitados</item>
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> apps podem usar dados ilimitados</item>
diff --git a/tests/CarDeveloperOptions/res/values-ru/strings.xml b/tests/CarDeveloperOptions/res/values-ru/strings.xml
index 50e4d34..67c7e24 100644
--- a/tests/CarDeveloperOptions/res/values-ru/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ru/strings.xml
@@ -4601,7 +4601,7 @@
<string name="mobile_network_mode_error" msgid="6818434186286086554">"Недопустимый режим сети (<xliff:g id="NETWORKMODEID">%1$d</xliff:g>). Не используется."</string>
<string name="mobile_network_apn_title" msgid="5628635067747404382">"Точки доступа"</string>
<string name="manual_mode_disallowed_summary" msgid="799800630000340665">"Недоступны при подключении к <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
- <string name="emergency_info_contextual_card_summary" msgid="5541444321969803486">"Медицинская информация, контакты для чрезвычайных ситуаций"</string>
+ <string name="emergency_info_contextual_card_summary" msgid="5541444321969803486">"Медицинская информация, контакты для экстренных случаев"</string>
<string name="see_more" msgid="7463940160389802632">"Ещё"</string>
<string name="see_less" msgid="3718892257002813387">"Скрыть"</string>
<string name="network_connection_request_dialog_title" msgid="3150489262902506588">"Устройство для работы с приложением \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
diff --git a/tests/CarDeveloperOptions/res/values-sl/strings.xml b/tests/CarDeveloperOptions/res/values-sl/strings.xml
index 59d5c2e..b364c6c 100644
--- a/tests/CarDeveloperOptions/res/values-sl/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sl/strings.xml
@@ -1093,7 +1093,7 @@
<string name="wifi_p2p_cancel_connect_message" msgid="3752679335020392154">"Ali želite preklicati povabilo za povezavo z napravo <xliff:g id="PEER_NAME">%1$s</xliff:g>?"</string>
<string name="wifi_p2p_delete_group_message" msgid="3206660449067701089">"Želite pozabiti to skupino?"</string>
<string name="wifi_hotspot_checkbox_text" msgid="12062341344410520">"Dostopna točka Wi-Fi"</string>
- <string name="wifi_hotspot_off_subtext" msgid="6177054857136221058">"Internetna povezava ali vsebina ni v skupni rabi z drugimi napravami"</string>
+ <string name="wifi_hotspot_off_subtext" msgid="6177054857136221058">"Internetna povezava ali vsebina ni deljena z drugimi napravami"</string>
<string name="wifi_hotspot_tethering_on_subtext" product="tablet" msgid="71421730039785897">"Skupna raba internetne povezave tega tabličnega računalnika prek dostopne točke"</string>
<string name="wifi_hotspot_tethering_on_subtext" product="default" msgid="8914285514605049879">"Skupna raba internetne povezave tega telefona prek dostopne točke"</string>
<string name="wifi_hotspot_on_local_only_subtext" msgid="7415381343846704553">"Aplikacija daje vsebino v skupno rabo. Če želite omogočiti skupno rabo internetne povezave, dostopno točko izklopite in znova vklopite."</string>
diff --git a/tests/CarDeveloperOptions/res/values-sq/strings.xml b/tests/CarDeveloperOptions/res/values-sq/strings.xml
index ac2c3bc..b4f1be0 100644
--- a/tests/CarDeveloperOptions/res/values-sq/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sq/strings.xml
@@ -3149,7 +3149,7 @@
<string name="other_sound_settings" msgid="5250376066099818676">"Tinguj të tjerë"</string>
<string name="dial_pad_tones_title" msgid="8877212139988655769">"Tonet e bllokut të tasteve"</string>
<string name="screen_locking_sounds_title" msgid="4407110895465866809">"Tingujt e kyçjes së ekranit"</string>
- <string name="charging_sounds_title" msgid="5070437987230894287">"Tingujt dhe dridhja e ngarkimit"</string>
+ <string name="charging_sounds_title" msgid="5070437987230894287">"Tingujt dhe dridhja e karikimit"</string>
<string name="docking_sounds_title" msgid="2573137471605541366">"Tingujt e stacionimit"</string>
<string name="touch_sounds_title" msgid="165237488496165652">"Tingujt e prekjes"</string>
<string name="vibrate_on_touch_title" msgid="6360155469279157684">"Dridhje për prekjen"</string>
@@ -3728,7 +3728,7 @@
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"Refuzo"</string>
<string name="usb_use_charging_only" msgid="2344625733377110164">"Nuk ka transferim të të dhënave"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"Vetëm karikoje këtë pajisje"</string>
- <string name="usb_use_power_only" msgid="6595783381323810697">"Ngarko pajisjen e lidhur"</string>
+ <string name="usb_use_power_only" msgid="6595783381323810697">"Kariko pajisjen e lidhur"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Transferimi i skedarëve"</string>
<string name="usb_use_file_transfers_desc" msgid="6953866660041189580">"Transfero skedarët te një pajisje tjetër"</string>
<string name="usb_use_photo_transfers" msgid="5974236250197451257">"PTP"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sr/strings.xml b/tests/CarDeveloperOptions/res/values-sr/strings.xml
index 03c8229..d7e63c5 100644
--- a/tests/CarDeveloperOptions/res/values-sr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sr/strings.xml
@@ -1644,7 +1644,7 @@
<string name="usb_tethering_subtext" product="tablet" msgid="154536000235361034">"Дељење интернет везе таблета преко USB-а"</string>
<string name="bluetooth_tether_checkbox_text" msgid="7257293066139372774">"Bluetooth привезивање"</string>
<string name="bluetooth_tethering_subtext" product="tablet" msgid="6868756914621131635">"Делите интернет везу таблета преко Bluetooth-а"</string>
- <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Делите интернет везу телефона преко Bluetooth-а"</string>
+ <string name="bluetooth_tethering_subtext" product="default" msgid="9167912297565425178">"Дељење интернет везе телефона преко Bluetooth-а"</string>
<string name="bluetooth_tethering_off_subtext_config" msgid="3981528184780083266">"Интернет веза уређаја <xliff:g id="DEVICE_NAME">%1$d</xliff:g> се дели преко Bluetooth-а"</string>
<string name="bluetooth_tethering_overflow_error" msgid="6946561351369376943">"Привезивање на више од <xliff:g id="MAXCONNECTION">%1$d</xliff:g> уређаја није могуће."</string>
<string name="bluetooth_untether_blank" msgid="5428300773782256084">"Интернет веза са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ће бити прекинута."</string>
diff --git a/tests/CarDeveloperOptions/res/values-sv/strings.xml b/tests/CarDeveloperOptions/res/values-sv/strings.xml
index e17d281..d9b7a98 100644
--- a/tests/CarDeveloperOptions/res/values-sv/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sv/strings.xml
@@ -1681,7 +1681,7 @@
<string name="location_access_summary" msgid="6919495149026354355">"Ge appar som har bett om tillstånd möjlighet att använda din platsinformation"</string>
<string name="location_sources_heading" msgid="8526658357120282741">"Platskällor"</string>
<string name="about_settings" product="tablet" msgid="4869626690708456341">"Om surfplattan"</string>
- <string name="about_settings" product="default" msgid="6019547763377294261">"Om mobilen"</string>
+ <string name="about_settings" product="default" msgid="6019547763377294261">"Om telefonen"</string>
<string name="about_settings" product="device" msgid="1770438316234693655">"Om enheten"</string>
<string name="about_settings" product="emulator" msgid="4497482494770487014">"Om emulerad enhet"</string>
<string name="about_settings_summary" msgid="4506081667462281647">"Visa juridisk information, status, programversion"</string>
@@ -4083,7 +4083,7 @@
<string name="sensors_off_quick_settings_title" msgid="3655699045300438902">"Sensorer är inaktiverade"</string>
<string name="managed_profile_settings_title" msgid="4340409321523532402">"Inställningar för jobbprofilen"</string>
<string name="managed_profile_contact_search_title" msgid="7337225196804457095">"Kontaktsökning"</string>
- <string name="managed_profile_contact_search_summary" msgid="7278267480246726951">"Tillåt att organisationen söker bland kontakter för att identifiera ringande och kontakter"</string>
+ <string name="managed_profile_contact_search_summary" msgid="7278267480246726951">"Tillåt att organisationen söker bland kontakter för att identifiera uppringare och kontakter"</string>
<string name="cross_profile_calendar_title" msgid="2351605904015067145">"Kalender för flera profiler"</string>
<string name="cross_profile_calendar_summary" msgid="3196258680438896098">"Visa jobbhändelser i den personliga kalendern"</string>
<string name="cross_profile_calendar_restricted_summary" msgid="6892589892357409107">"Organisationen tillåter inte åtkomst till jobbkalendern via personliga appar"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sw/strings.xml b/tests/CarDeveloperOptions/res/values-sw/strings.xml
index 6a8d648..91226e6 100644
--- a/tests/CarDeveloperOptions/res/values-sw/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sw/strings.xml
@@ -3284,8 +3284,8 @@
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"Tumia sauti za wasifu wako binafsi"</string>
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"Sauti za wasifu wa binafsi na wa kazini ni sawa"</string>
<string name="work_ringtone_title" msgid="5499360583947410224">"Mlio wa simu ya kazini"</string>
- <string name="work_notification_ringtone_title" msgid="8059159087214025757">"Sauti chaguomsingi ya arifa ya kazini"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Sauti chaguomsingi ya kengele ya kazini"</string>
+ <string name="work_notification_ringtone_title" msgid="8059159087214025757">"Sauti chaguomsingi ya arifa za kazini"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"Sauti chaguomsingi ya kengele za kazini"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"Sawa na wasifu binafsi"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"Ungependa kubadilisha sauti?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"Badilisha"</string>
diff --git a/tests/CarDeveloperOptions/res/values-te/strings.xml b/tests/CarDeveloperOptions/res/values-te/strings.xml
index 2379b9e..cdcd5f5 100644
--- a/tests/CarDeveloperOptions/res/values-te/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-te/strings.xml
@@ -2935,7 +2935,7 @@
<string name="restriction_menu_reset" msgid="3642252461410370554">"పరిమితులను తీసివేయి"</string>
<string name="restriction_menu_change_pin" msgid="592512748243421101">"పిన్ను మార్చు"</string>
<string name="app_notifications_switch_label" msgid="670683308275498821">"నోటిఫికేషన్లను చూపు"</string>
- <string name="help_label" msgid="1296484776243905646">"సహాయం & అభిప్రాయం"</string>
+ <string name="help_label" msgid="1296484776243905646">"సహాయం & ఫీడ్బ్యాక్"</string>
<string name="support_summary" msgid="3278943815956130740">"సహాయక కథనాలు, ఫోన్ & చాట్, ప్రారంభించండి"</string>
<string name="user_account_title" msgid="2108666882630552859">"కంటెంట్ కోసం ఖాతా"</string>
<string name="user_picture_title" msgid="6664602422948159123">"ఫోటో ID"</string>
@@ -3045,7 +3045,7 @@
<string name="notification_settings_work_profile" msgid="7190550347842400029">"కార్యాలయ ప్రొఫైల్లో ఉన్న యాప్లకు సంబంధించి నోటిఫికేషన్ యాక్సెస్ అందుబాటులో లేదు."</string>
<string name="account_dashboard_title" msgid="4734300939532555885">"ఖాతాలు"</string>
<string name="account_dashboard_default_summary" msgid="6822549669771936206">"ఖాతాలు జోడించబడలేదు"</string>
- <string name="app_default_dashboard_title" msgid="6575301028225232193">"డిఫాల్ట్ యాప్లు"</string>
+ <string name="app_default_dashboard_title" msgid="6575301028225232193">"ఆటోమేటిక్ యాప్లు"</string>
<string name="system_dashboard_summary" msgid="6582464466735779394">"భాషలు, సంజ్ఞలు, సమయం, బ్యాకప్"</string>
<string name="search_results_title" msgid="4160717656435503940">"సెట్టింగ్లు"</string>
<string name="keywords_wifi" msgid="8477688080895466846">"wifi, wi-fi, నెట్వర్క్ కనెక్షన్, ఇంటర్నెట్, వైర్లెస్, డేటా, wi fi"</string>
@@ -3280,12 +3280,12 @@
<string name="zen_onboarding_new_setting_summary" msgid="8264430315983860075">"మీరు నోటిఫికేషన్లను చూడలేరు లేదా వినలేరు. నక్షత్రం గుర్తు ఉన్న పరిచయాల మరియు రిపీట్ కాలర్ల నుండి కాల్లు అనుమతించబడతాయి."</string>
<string name="zen_onboarding_current_setting_summary" msgid="3569246708507270821">"(ప్రస్తుత సెట్టింగ్)"</string>
<string name="zen_onboarding_dnd_visual_disturbances_header" msgid="7584229011611927613">"అంతరాయం కలిగించవద్దు నోటిఫికేషన్ సెట్టింగ్లను మార్చాలా?"</string>
- <string name="sound_work_settings" msgid="4140215240360927923">"కార్యాలయ ప్రొఫైల్ శబ్దాలు"</string>
+ <string name="sound_work_settings" msgid="4140215240360927923">"ఆఫీస్ ప్రొఫైల్ శబ్దాలు"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"వ్యక్తిగత ప్రొఫైల్ శబ్దాలు ఉంచు"</string>
- <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"కార్యాలయ మరియు వ్యక్తిగత ప్రొఫైల్లకు ఒకే ధ్వనులు ఉపయోగించబడతాయి"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"కార్యాలయ ఫోన్ రింగ్టోన్"</string>
- <string name="work_notification_ringtone_title" msgid="8059159087214025757">"డిఫాల్ట్ కార్యాలయ నోటిఫికేషన్ ధ్వని"</string>
- <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"డిఫాల్ట్ కార్యాలయ అలారం ధ్వని"</string>
+ <string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"ఆఫీస్తో పాటు వ్యక్తిగత ప్రొఫైల్లకు ఒకే రకమైన ధ్వనులు ఉపయోగించబడతాయి"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"ఆఫీస్ ఫోన్ రింగ్టోన్"</string>
+ <string name="work_notification_ringtone_title" msgid="8059159087214025757">"ఆటోమేటిక్ ఆఫీస్ నోటిఫికేషన్ ధ్వని"</string>
+ <string name="work_alarm_ringtone_title" msgid="5328487181385375130">"ఆటోమేటిక్ ఆఫీస్ అలారం ధ్వని"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"వ్యక్తిగత ప్రొఫైల్లో వలె ఉంచబడతాయి"</string>
<string name="work_sync_dialog_title" msgid="4799120971202956837">"ధ్వనులను భర్తీ చేయాలా?"</string>
<string name="work_sync_dialog_yes" msgid="2110726233746476066">"భర్తీ చేయి"</string>
@@ -4190,7 +4190,7 @@
<string name="enterprise_privacy_location_access" msgid="110406267468274216">"స్థాన అనుమతులు"</string>
<string name="enterprise_privacy_microphone_access" msgid="4586428105675460207">"మైక్రోఫోన్ అనుమతులు"</string>
<string name="enterprise_privacy_camera_access" msgid="2366392786153103482">"కెమెరా అనుమతులు"</string>
- <string name="enterprise_privacy_enterprise_set_default_apps" msgid="6142937923758931242">"డిఫాల్ట్ యాప్లు"</string>
+ <string name="enterprise_privacy_enterprise_set_default_apps" msgid="6142937923758931242">"ఆటోమేటిక్ యాప్లు"</string>
<plurals name="enterprise_privacy_number_packages" formatted="false" msgid="1480745164313890415">
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> యాప్లు</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> యాప్</item>
diff --git a/tests/CarDeveloperOptions/res/values-uk/strings.xml b/tests/CarDeveloperOptions/res/values-uk/strings.xml
index 19a4068..ed75037 100644
--- a/tests/CarDeveloperOptions/res/values-uk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-uk/strings.xml
@@ -2084,7 +2084,7 @@
<string name="vision_settings_suggestion_title" msgid="7268661419110951128">"Змінити розмір шрифту"</string>
<string name="screen_reader_category_title" msgid="6300714148519645544">"Програми зчитування з екрана"</string>
<string name="audio_and_captions_category_title" msgid="6140472938769619212">"Аудіо й текст на екрані"</string>
- <string name="display_category_title" msgid="545168481672250195">"Дисплей"</string>
+ <string name="display_category_title" msgid="545168481672250195">"Екран"</string>
<string name="interaction_control_category_title" msgid="8775039211811947683">"Елементи керування взаємодією"</string>
<string name="user_installed_services_category_title" msgid="4288689493753221319">"Завантажені служби"</string>
<string name="experimental_category_title" msgid="3797000069740110717">"Експериментальні налаштування"</string>
@@ -3860,8 +3860,8 @@
<string name="usb_pref" msgid="6194821550693495068">"USB"</string>
<string name="usb_preference" msgid="7092987095048592826">"Параметри USB"</string>
<string name="usb_control_title" msgid="2379698856760894768">"USB керує"</string>
- <string name="usb_control_host" msgid="193292043691034178">"Підключений пристрій"</string>
- <string name="usb_control_device" msgid="9154790265254725254">"Цей пристрій"</string>
+ <string name="usb_control_host" msgid="193292043691034178">"Підключеним пристроєм"</string>
+ <string name="usb_control_device" msgid="9154790265254725254">"Цим пристроєм"</string>
<string name="usb_switching" msgid="1230386065163529904">"Змінюється…"</string>
<string name="usb_switching_failed" msgid="6857722544186145439">"Не вдалося змінити"</string>
<string name="usb_summary_charging_only" msgid="4118449308708872339">"Заряджання пристрою"</string>
diff --git a/tests/CarDeveloperOptions/res/values-uz/strings.xml b/tests/CarDeveloperOptions/res/values-uz/strings.xml
index c2bb5e9..8dae0ee 100644
--- a/tests/CarDeveloperOptions/res/values-uz/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-uz/strings.xml
@@ -3661,7 +3661,7 @@
<string name="advanced_apps" msgid="6643869089344883537">"Kengaytirilgan sozlamalar"</string>
<string name="configure_apps" msgid="4066683118857400943">"Ilovalarni sozlash"</string>
<string name="unknown_app" msgid="2312052973570376877">"Noma’lum ilova"</string>
- <string name="app_permissions" msgid="3215958256821756086">"Ruxsatlar menejeri"</string>
+ <string name="app_permissions" msgid="3215958256821756086">"Ruxsatlar boshqaruvi"</string>
<string name="app_permissions_summary" msgid="8785798165776061594">"Ruxsatga ega ilovalar (<xliff:g id="APPS">%1$s</xliff:g>)"</string>
<string name="tap_to_wake" msgid="1902991239401652323">"Teginib yoqish"</string>
<string name="tap_to_wake_summary" msgid="8485222120721006793">"Qurilmani yoqish uchun ekranning istalgan joyiga ikki marta bosing"</string>
@@ -3746,7 +3746,7 @@
<string name="decline_remote_bugreport_action" msgid="706319275774199033">"Rad etish"</string>
<string name="usb_use_charging_only" msgid="2344625733377110164">"Axborot uzatilmasin"</string>
<string name="usb_use_charging_only_desc" msgid="3283518562582478950">"Faqat shu qurilmani quvvatlash"</string>
- <string name="usb_use_power_only" msgid="6595783381323810697">"Ulangan qurilmani quvvatlang"</string>
+ <string name="usb_use_power_only" msgid="6595783381323810697">"Ulangan qurilmani quvvatlash"</string>
<string name="usb_use_file_transfers" msgid="6153021302176151884">"Fayl uzatish"</string>
<string name="usb_use_file_transfers_desc" msgid="6953866660041189580">"Boshqa qurilmaga fayl o‘tkazish"</string>
<string name="usb_use_photo_transfers" msgid="5974236250197451257">"PTP"</string>
diff --git a/tests/CarDeveloperOptions/res/values-vi/strings.xml b/tests/CarDeveloperOptions/res/values-vi/strings.xml
index 66d3ead..731dc7c 100644
--- a/tests/CarDeveloperOptions/res/values-vi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-vi/strings.xml
@@ -162,7 +162,7 @@
<string name="bluetooth_map_acceptance_dialog_text" msgid="736507842082640410">"%1$s muốn truy cập tin nhắn của bạn. Bạn có muốn cấp quyền truy cập cho %2$s không?"</string>
<string name="bluetooth_sap_request" msgid="6318039677671263261">"Yêu cầu truy cập SIM"</string>
<string name="bluetooth_sap_acceptance_dialog_text" msgid="1909352413109340355">"<xliff:g id="DEVICE_NAME_0">%1$s</xliff:g> muốn truy cập vào thẻ SIM của bạn. Cấp quyền truy cập vào thẻ SIM sẽ vô hiệu hóa khả năng kết nối dữ liệu trên thiết bị của bạn trong suốt thời gian kết nối. Cấp quyền truy cập vào <xliff:g id="DEVICE_NAME_1">%2$s?</xliff:g>"</string>
- <string name="bluetooth_device_name_summary" msgid="8661066392056595005">"Hiển thị là \"<xliff:g id="DEVICE_NAME">^1</xliff:g>\" với các thiết bị khác"</string>
+ <string name="bluetooth_device_name_summary" msgid="8661066392056595005">"Tên xuất hiện trên các thiết bị khác: <xliff:g id="DEVICE_NAME">^1</xliff:g>"</string>
<string name="bluetooth_off_footer" msgid="7658444560543730571">"Bật Bluetooth để kết nối với các thiết bị khác."</string>
<string name="bluetooth_paired_device_title" msgid="8361860197780425286">"Thiết bị của bạn"</string>
<string name="bluetooth_pairing_page_title" msgid="9053463656712597709">"Ghép nối thiết bị mới"</string>
@@ -3426,7 +3426,7 @@
<string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Cho phép những thông báo này tiếp tục làm gián đoạn khi chế độ Không làm phiền đang bật"</string>
<string name="app_notification_visibility_override_title" msgid="2349335170165637672">"Trên màn hình khóa"</string>
<string name="app_notification_row_banned" msgid="2079325338122151677">"Bị chặn"</string>
- <string name="app_notification_row_priority" msgid="432299064888787236">"Mức độ ưu tiên"</string>
+ <string name="app_notification_row_priority" msgid="432299064888787236">"Ưu tiên"</string>
<string name="app_notification_row_sensitive" msgid="4919671519227722958">"Nhạy cảm"</string>
<string name="app_notifications_dialog_done" msgid="5395611029779655968">"Xong"</string>
<string name="app_notification_importance_title" msgid="1902794400671001142">"Mức độ quan trọng"</string>
diff --git a/tests/CarDeveloperOptions/res/values-zh-rTW/strings.xml b/tests/CarDeveloperOptions/res/values-zh-rTW/strings.xml
index 1ea9dfb..1ca3fdb 100644
--- a/tests/CarDeveloperOptions/res/values-zh-rTW/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-zh-rTW/strings.xml
@@ -3283,7 +3283,7 @@
<string name="sound_work_settings" msgid="4140215240360927923">"工作資料夾音效"</string>
<string name="work_use_personal_sounds_title" msgid="531727195073003599">"使用個人設定檔音效"</string>
<string name="work_use_personal_sounds_summary" msgid="2886871383995187441">"工作資料夾和個人設定檔使用相同的音效"</string>
- <string name="work_ringtone_title" msgid="5499360583947410224">"Work 手機鈴聲"</string>
+ <string name="work_ringtone_title" msgid="5499360583947410224">"工作手機鈴聲"</string>
<string name="work_notification_ringtone_title" msgid="8059159087214025757">"預設 Work 通知音效"</string>
<string name="work_alarm_ringtone_title" msgid="5328487181385375130">"預設 Work 鬧鐘音效"</string>
<string name="work_sound_same_as_personal" msgid="7728560881697159758">"與個人設定檔相同"</string>
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AppsNotRespondingPreferenceController.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AppsNotRespondingPreferenceController.java
index f504d1b..86d89f4 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AppsNotRespondingPreferenceController.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/development/AppsNotRespondingPreferenceController.java
@@ -16,6 +16,7 @@
package com.android.car.developeroptions.development;
import android.content.Context;
+import android.os.UserHandle;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
@@ -47,24 +48,31 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean isEnabled = (Boolean) newValue;
- Settings.Secure.putInt(mContext.getContentResolver(),
+ // Set for system user since Android framework will read it as that user.
+ // Note that this will enable/disable this option for all users.
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ANR_SHOW_BACKGROUND,
- isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
+ isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF,
+ UserHandle.SYSTEM.getIdentifier());
return true;
}
@Override
public void updateState(Preference preference) {
- final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ANR_SHOW_BACKGROUND, SETTING_VALUE_OFF);
+ final int mode = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ANR_SHOW_BACKGROUND,
+ SETTING_VALUE_OFF, UserHandle.SYSTEM.getIdentifier());
((SwitchPreference) mPreference).setChecked(mode != SETTING_VALUE_OFF);
}
@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ANR_SHOW_BACKGROUND, SETTING_VALUE_OFF);
+ // Set for system user since Android framework will read it as that user.
+ // Note that this will enable/disable this option for all users.
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ANR_SHOW_BACKGROUND,
+ SETTING_VALUE_OFF, UserHandle.SYSTEM.getIdentifier());
((SwitchPreference) mPreference).setChecked(false);
}
}
diff --git a/tests/CarSecurityPermissionTest/Android.bp b/tests/CarSecurityPermissionTest/Android.bp
index 066ecc8..7be1d0b 100644
--- a/tests/CarSecurityPermissionTest/Android.bp
+++ b/tests/CarSecurityPermissionTest/Android.bp
@@ -21,6 +21,7 @@
libs: [
"android.car",
+ "android.hardware.automotive.vehicle-V2.0-java",
"android.test.runner",
"android.test.base",
"android.test.mock",
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
index ec480c4..1c40b88 100644
--- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
+++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
@@ -94,6 +94,7 @@
<!-- use for CarServiceTest -->
<uses-permission android:name="android.permission.MONITOR_INPUT"/>
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER"/>
+ <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!-- use for vendor properties -->
@@ -104,6 +105,9 @@
<uses-permission android:name="android.car.permission.CONTROL_CAR_FEATURES"/>
+ <!-- use for rotary fragment to enable/disable packages related to rotary -->
+ <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+
<application android:label="@string/app_title"
android:icon="@drawable/ic_launcher">
<uses-library android:name="android.test.runner"/>
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/kitchen_activity.xml b/tests/EmbeddedKitchenSinkApp/res/layout/kitchen_activity.xml
index e6de221..56f3dc8 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/kitchen_activity.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/kitchen_activity.xml
@@ -20,6 +20,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
+ first focusable view in the window automatically. Adding a FocusParkingView to the window
+ can fix this issue, because it can take focus, and it is transparent and its default focus
+ highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
+ -->
+ <com.android.car.ui.FocusParkingView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
<Button
android:id="@+id/menu_button"
android:layout_width="wrap_content"
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/rotary_fragment.xml b/tests/EmbeddedKitchenSinkApp/res/layout/rotary_fragment.xml
new file mode 100644
index 0000000..e1f739a
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/rotary_fragment.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fadeScrollbars="false">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/unavailable_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="CarRotaryService does not exist in this build"
+ android:textSize="30sp"
+ android:textColor="@*android:color/red"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:text="Overall Controls"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/enable_all_rotary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Enable All"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/disable_all_rotary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Disable All"
+ android:textSize="30sp"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_margin="10dp">
+
+ <TextView
+ android:layout_width="500dp"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:text="CarRotaryService state"/>
+
+ <Switch
+ android:id="@+id/rotary_service_toggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:layout_gravity="center"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_margin="10dp">
+
+ <TextView
+ android:layout_width="500dp"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:text="RotaryIME state"/>
+
+ <Switch
+ android:id="@+id/rotary_ime_toggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:layout_gravity="center"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_margin="10dp">
+
+ <TextView
+ android:layout_width="500dp"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:text="RotaryPlayground state"/>
+
+ <Switch
+ android:id="@+id/rotary_playground_toggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ android:layout_gravity="center"/>
+
+ </LinearLayout>
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/window_insets_fragment.xml b/tests/EmbeddedKitchenSinkApp/res/layout/window_insets_fragment.xml
new file mode 100644
index 0000000..5533668
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/window_insets_fragment.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fadeScrollbars="false">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Control Status Bar Insets"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/show_status_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show Status Bar Insets"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/hide_status_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Hide Status Bar Insets"
+ android:textSize="30sp"/>
+
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Control Navigation Bar Insets"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/show_nav_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show Navigation Bar Insets"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/hide_nav_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Hide Navigation Bar Insets"
+ android:textSize="30sp"/>
+
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Control System Bar Insets (both Status and Navigation)"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/show_system_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show System Bar Insets"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/hide_system_bar_insets"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Hide System Bar Insets"
+ android:textSize="30sp"/>
+
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Set System Bar Behavior"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/show_bars_by_touch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show By Touch"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/show_bars_by_swipe"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show By Swipe"
+ android:textSize="30sp"/>
+
+ <Button
+ android:id="@+id/show_transient_bars_by_swipe"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="Show Transient By Swipe"
+ android:textSize="30sp"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index 20dd9fc..0732562 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -56,12 +56,14 @@
import com.google.android.car.kitchensink.displayinfo.DisplayInfoFragment;
import com.google.android.car.kitchensink.experimental.ExperimentalFeatureTestFragment;
import com.google.android.car.kitchensink.hvac.HvacTestFragment;
+import com.google.android.car.kitchensink.insets.WindowInsetsFragment;
import com.google.android.car.kitchensink.notification.NotificationFragment;
import com.google.android.car.kitchensink.orientation.OrientationTestFragment;
import com.google.android.car.kitchensink.packageinfo.PackageInfoFragment;
import com.google.android.car.kitchensink.power.PowerTestFragment;
import com.google.android.car.kitchensink.projection.ProjectionFragment;
import com.google.android.car.kitchensink.property.PropertyTestFragment;
+import com.google.android.car.kitchensink.rotary.RotaryFragment;
import com.google.android.car.kitchensink.sensor.SensorsTestFragment;
import com.google.android.car.kitchensink.storagelifetime.StorageLifetimeFragment;
import com.google.android.car.kitchensink.storagevolumes.StorageVolumesFragment;
@@ -189,6 +191,7 @@
new FragmentMenuEntry("profile_user", ProfileUserFragment.class),
new FragmentMenuEntry("projection", ProjectionFragment.class),
new FragmentMenuEntry("property test", PropertyTestFragment.class),
+ new FragmentMenuEntry("rotary", RotaryFragment.class),
new FragmentMenuEntry("sensors", SensorsTestFragment.class),
new FragmentMenuEntry("storage lifetime", StorageLifetimeFragment.class),
new FragmentMenuEntry("storage volumes", StorageVolumesFragment.class),
@@ -198,7 +201,8 @@
new FragmentMenuEntry("vehicle ctrl", VehicleCtrlFragment.class),
new FragmentMenuEntry("vehicle hal", VehicleHalFragment.class),
new FragmentMenuEntry("volume test", VolumeTestFragment.class),
- new FragmentMenuEntry("web links", WebLinksTestFragment.class));
+ new FragmentMenuEntry("web links", WebLinksTestFragment.class),
+ new FragmentMenuEntry("window insets", WindowInsetsFragment.class));
private Car mCarApi;
private CarHvacManager mHvacManager;
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/insets/WindowInsetsFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/insets/WindowInsetsFragment.java
new file mode 100644
index 0000000..f4d52cf
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/insets/WindowInsetsFragment.java
@@ -0,0 +1,87 @@
+/*
+ * 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.google.android.car.kitchensink.insets;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.kitchensink.R;
+
+/** Test fragment for controlling window insets. */
+public final class WindowInsetsFragment extends Fragment {
+
+ private WindowInsetsController mWindowInsetsController;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.window_insets_fragment, container,
+ /* attachToRoot= */ false);
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mWindowInsetsController = view.getWindowInsetsController();
+ initStatusBarInsetsButtons(view);
+ initNavigationBarInsetsButtons(view);
+ initSystemBarInsetsButtons(view);
+ initSystemBarBehaviorButtons(view);
+ }
+
+ private void initStatusBarInsetsButtons(View view) {
+ view.findViewById(R.id.show_status_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.show(WindowInsets.Type.statusBars()));
+ view.findViewById(R.id.hide_status_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.hide(WindowInsets.Type.statusBars()));
+ }
+
+ private void initNavigationBarInsetsButtons(View view) {
+ view.findViewById(R.id.show_nav_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.show(WindowInsets.Type.navigationBars()));
+ view.findViewById(R.id.hide_nav_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.hide(WindowInsets.Type.navigationBars()));
+ }
+
+ private void initSystemBarInsetsButtons(View view) {
+ view.findViewById(R.id.show_system_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.show(WindowInsets.Type.systemBars()));
+ view.findViewById(R.id.hide_system_bar_insets).setOnClickListener(
+ v -> mWindowInsetsController.hide(WindowInsets.Type.systemBars()));
+ }
+
+ private void initSystemBarBehaviorButtons(View view) {
+ view.findViewById(R.id.show_bars_by_touch).setOnClickListener(
+ v -> mWindowInsetsController.setSystemBarsBehavior(
+ WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH));
+ view.findViewById(R.id.show_bars_by_swipe).setOnClickListener(
+ v -> mWindowInsetsController.setSystemBarsBehavior(
+ WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE));
+ view.findViewById(R.id.show_transient_bars_by_swipe).setOnClickListener(
+ v -> mWindowInsetsController.setSystemBarsBehavior(
+ WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE));
+ }
+}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/rotary/RotaryFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/rotary/RotaryFragment.java
new file mode 100644
index 0000000..bf13017
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/rotary/RotaryFragment.java
@@ -0,0 +1,306 @@
+/*
+ * 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.google.android.car.kitchensink.rotary;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.kitchensink.R;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/** Test fragment to enable/disable various components related to RotaryController. */
+public final class RotaryFragment extends Fragment {
+
+ private static final String TAG = RotaryFragment.class.getSimpleName();
+ private static final String ROTARY_CONTROLLER_PACKAGE = "com.android.car.rotary";
+ private static final ComponentName ROTARY_SERVICE_NAME = ComponentName.unflattenFromString(
+ ROTARY_CONTROLLER_PACKAGE + "/com.android.car.rotary.RotaryService");
+ private static final String ROTARY_PLAYGROUND_PACKAGE = "com.android.car.rotaryplayground";
+ private static final String ROTARY_IME_PACKAGE = "com.android.car.rotaryime";
+
+ private static final String ACCESSIBILITY_DELIMITER = ":";
+
+ private static final int ON = 1;
+ private static final int OFF = 0;
+
+ private final IntentFilter mFilter = new IntentFilter();
+
+ private TextView mUnavailableMessage;
+ private Button mEnableAllButton;
+ private Button mDisableAllButton;
+ private Switch mRotaryServiceToggle;
+ private Switch mRotaryImeToggle;
+ private Switch mRotaryPlaygroundToggle;
+
+ private final BroadcastReceiver mPackagesUpdatedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case Intent.ACTION_PACKAGE_ADDED:
+ case Intent.ACTION_PACKAGE_CHANGED:
+ case Intent.ACTION_PACKAGE_REMOVED:
+ refreshUi();
+ break;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ mFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ mFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.rotary_fragment, container, /* attachToRoot= */ false);
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mUnavailableMessage = view.findViewById(R.id.unavailable_message);
+
+ mEnableAllButton = view.findViewById(R.id.enable_all_rotary);
+ mDisableAllButton = view.findViewById(R.id.disable_all_rotary);
+
+ mRotaryServiceToggle = view.findViewById(R.id.rotary_service_toggle);
+ mRotaryImeToggle = view.findViewById(R.id.rotary_ime_toggle);
+ mRotaryPlaygroundToggle = view.findViewById(R.id.rotary_playground_toggle);
+
+ mRotaryServiceToggle.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> enableRotaryService(getContext(), isChecked));
+ mRotaryImeToggle.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> enableApplication(getContext(), ROTARY_IME_PACKAGE,
+ isChecked));
+ mRotaryPlaygroundToggle.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> enableApplication(getContext(),
+ ROTARY_PLAYGROUND_PACKAGE, isChecked));
+
+ mEnableAllButton.setOnClickListener(v -> {
+ if (mRotaryServiceToggle.isEnabled()) {
+ mRotaryServiceToggle.setChecked(true);
+ }
+ if (mRotaryImeToggle.isEnabled()) {
+ mRotaryImeToggle.setChecked(true);
+ }
+ if (mRotaryPlaygroundToggle.isEnabled()) {
+ mRotaryPlaygroundToggle.setChecked(true);
+ }
+ });
+
+ mDisableAllButton.setOnClickListener(v -> {
+ if (mRotaryServiceToggle.isEnabled()) {
+ mRotaryServiceToggle.setChecked(false);
+ }
+ if (mRotaryImeToggle.isEnabled()) {
+ mRotaryImeToggle.setChecked(false);
+ }
+ if (mRotaryPlaygroundToggle.isEnabled()) {
+ mRotaryPlaygroundToggle.setChecked(false);
+ }
+ });
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ getContext().registerReceiver(mPackagesUpdatedReceiver, mFilter);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ refreshUi();
+ }
+
+ private void refreshUi() {
+ ApplicationInfo info = findApplication(getContext(), ROTARY_CONTROLLER_PACKAGE);
+ boolean rotaryApplicationExists = info != null;
+ info = findApplication(getContext(), ROTARY_IME_PACKAGE);
+ boolean rotaryImeExists = info != null;
+ info = findApplication(getContext(), ROTARY_PLAYGROUND_PACKAGE);
+ boolean rotaryPlaygroundExists = info != null;
+
+ mUnavailableMessage.setVisibility(!rotaryApplicationExists ? View.VISIBLE : View.GONE);
+
+ mEnableAllButton.setEnabled(rotaryApplicationExists);
+ mDisableAllButton.setEnabled(rotaryApplicationExists);
+ mRotaryServiceToggle.setEnabled(rotaryApplicationExists);
+ mRotaryImeToggle.setEnabled(rotaryApplicationExists && rotaryImeExists);
+ mRotaryPlaygroundToggle.setEnabled(rotaryApplicationExists && rotaryPlaygroundExists);
+
+ mRotaryServiceToggle.setChecked(isRotaryServiceEnabled(getContext()));
+ mRotaryImeToggle.setChecked(
+ rotaryImeExists && isApplicationEnabled(getContext(), ROTARY_IME_PACKAGE));
+ mRotaryPlaygroundToggle.setChecked(
+ rotaryPlaygroundExists && isApplicationEnabled(getContext(),
+ ROTARY_PLAYGROUND_PACKAGE));
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+
+ getContext().unregisterReceiver(mPackagesUpdatedReceiver);
+ }
+
+ @Nullable
+ private static ApplicationInfo findApplication(Context context, String packageName) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ Log.d(TAG, "Searching for: " + packageName);
+ return pm.getApplicationInfoAsUser(packageName, /* flags= */ 0,
+ ActivityManager.getCurrentUser());
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Could not find: " + packageName);
+ return null;
+ }
+ }
+
+ private static boolean isApplicationEnabled(Context context, String packageName) {
+ ApplicationInfo info = findApplication(context, packageName);
+ if (info == null) {
+ return false;
+ }
+
+ return info.enabled;
+ }
+
+ private static void enableApplication(Context context, String packageName, boolean enable) {
+ // Check that the application exists.
+ ApplicationInfo info = findApplication(context, packageName);
+ if (info == null) {
+ Log.e(TAG, "Cannot enable application. " + packageName + " package does not exist");
+ return;
+ }
+
+ PackageManager pm = context.getPackageManager();
+ int currentState = pm.getApplicationEnabledSetting(packageName);
+ int desiredState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+
+ boolean isEnabled = currentState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ if (isEnabled != enable
+ || currentState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+ Log.d(TAG, "Application state updated for " + packageName + ": " + enable);
+ pm.setApplicationEnabledSetting(packageName, desiredState, /* flags= */ 0);
+ }
+ }
+
+ private static boolean isRotaryServiceEnabled(Context context) {
+ ApplicationInfo info = findApplication(context, ROTARY_CONTROLLER_PACKAGE);
+ if (info == null) {
+ return false;
+ }
+
+ int isAccessibilityEnabled = Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, OFF);
+ if (isAccessibilityEnabled != ON) {
+ return false;
+ }
+
+ String services = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ if (services == null) {
+ return false;
+ }
+
+ return services.contains(ROTARY_CONTROLLER_PACKAGE);
+ }
+
+ private static void enableRotaryService(Context context, boolean enable) {
+ // Check that the RotaryController exists.
+ ApplicationInfo info = findApplication(context, ROTARY_CONTROLLER_PACKAGE);
+ if (info == null) {
+ Log.e(TAG, "Cannot enable rotary service. " + ROTARY_CONTROLLER_PACKAGE
+ + " package does not exist");
+ return;
+ }
+
+ // Set the list of accessibility services.
+ String services = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ if (services == null) {
+ services = "";
+ }
+ Log.d(TAG, "Current list of accessibility services: " + services);
+
+ String[] servicesArray = services.split(ACCESSIBILITY_DELIMITER);
+ Set<ComponentName> servicesSet = new HashSet<>();
+ for (String service : servicesArray) {
+ ComponentName name = ComponentName.unflattenFromString(service);
+ if (name != null) {
+ servicesSet.add(name);
+ }
+ }
+
+ if (enable) {
+ servicesSet.add(ROTARY_SERVICE_NAME);
+ } else {
+ servicesSet.remove(ROTARY_SERVICE_NAME);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (ComponentName service : servicesSet) {
+ if (builder.length() > 0) {
+ builder.append(ACCESSIBILITY_DELIMITER);
+ }
+ builder.append(service.flattenToString());
+ }
+
+ Log.d(TAG, "New list of accessibility services: " + builder);
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ builder.toString());
+
+ // Set the overall enabled state.
+ int desiredState = enable ? ON : OFF;
+ Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED,
+ desiredState);
+ }
+}
diff --git a/tests/carservice_unit_test/src/android/car/userlib/InitialUserSetterTest.java b/tests/carservice_unit_test/src/android/car/userlib/InitialUserSetterTest.java
index 785cbc4..9fbe5b3 100644
--- a/tests/carservice_unit_test/src/android/car/userlib/InitialUserSetterTest.java
+++ b/tests/carservice_unit_test/src/android/car/userlib/InitialUserSetterTest.java
@@ -338,6 +338,28 @@
}
@Test
+ public void testCanReplaceGuestUser_NotGuest() {
+ UserInfo user = expectUserExists(USER_ID);
+
+ assertThat(mSetter.canReplaceGuestUser(user)).isFalse();
+ }
+
+ @Test
+ public void testCanReplaceGuestUser_Guest() {
+ UserInfo user = expectGuestExists(USER_ID, /* isEphemeral */true);
+
+ assertThat(mSetter.canReplaceGuestUser(user)).isTrue();
+ }
+
+ @Test
+ public void testCanReplaceGuestUser_GuestLocked() {
+ UserInfo user = expectGuestExists(USER_ID, /* isEphemeral */true);
+ expectUserIsSecure(USER_ID);
+
+ assertThat(mSetter.canReplaceGuestUser(user)).isFalse();
+ }
+
+ @Test
public void testCreateUser_ok_noflags() throws Exception {
UserInfo newUser = expectCreateFullUser(USER_ID, "TheDude", NO_FLAGS);
expectSwitchUser(USER_ID);
@@ -486,6 +508,51 @@
}
@Test
+ public void testReplaceUser_ok() throws Exception {
+ mockGetCurrentUser(CURRENT_USER_ID);
+ expectGuestExists(CURRENT_USER_ID, /* ephemeral */ true); // ephemeral doesn't matter
+ UserInfo newGuest = expectGuestExists(NEW_USER_ID, /* ephemeral */ true);
+ expectGuestReplaced(CURRENT_USER_ID, newGuest);
+ expectSwitchUser(NEW_USER_ID);
+
+ mSetter.set(new Builder(InitialUserSetter.TYPE_REPLACE_GUEST)
+ .build());
+
+ verifyUserSwitched(NEW_USER_ID);
+ verifyFallbackDefaultBehaviorNeverCalled();
+ verifySystemUserUnlocked();
+ verifyUserDeleted(CURRENT_USER_ID);
+ assertInitialUserSet(newGuest);
+ }
+
+ @Test
+ public void testReplaceUser_fail_cantCreate() throws Exception {
+ mockGetCurrentUser(CURRENT_USER_ID);
+ expectGuestExists(CURRENT_USER_ID, /* ephemeral */ true); // ephemeral doesn't matter
+ expectGuestReplaced(CURRENT_USER_ID, null);
+
+ mSetter.set(new Builder(InitialUserSetter.TYPE_REPLACE_GUEST)
+ .build());
+
+ verifyFallbackDefaultBehaviorCalledFromReaplceUser();
+ }
+
+ @Test
+ public void testReplaceUser_ok_sameUser() throws Exception {
+ mockGetCurrentUser(CURRENT_USER_ID);
+ UserInfo userInfo = expectGuestExists(CURRENT_USER_ID, /* ephemeral */ true);
+ expectGuestReplaced(CURRENT_USER_ID, userInfo);
+
+ mSetter.set(new Builder(InitialUserSetter.TYPE_REPLACE_GUEST)
+ .build());
+
+ verifyUserNeverSwitched();
+ verifyFallbackDefaultBehaviorNeverCalled();
+ verifySystemUserUnlocked();
+ assertInitialUserSet(userInfo);
+ }
+
+ @Test
public void testDefaultBehavior_firstBoot_ok() throws Exception {
// no need to mock hasInitialUser(), it will return false by default
UserInfo newUser = expectCreateFullUser(USER_ID, OWNER_NAME, UserInfo.FLAG_ADMIN);
@@ -858,6 +925,11 @@
assertInitialUserSet(null);
}
+ private void verifyFallbackDefaultBehaviorCalledFromReaplceUser() {
+ verify(mSetter).fallbackDefaultBehavior(isInitialInfo(false), eq(true), anyString());
+ assertInitialUserSet(null);
+ }
+
private void verifyFallbackDefaultBehaviorNeverCalled() {
verifyFallbackDefaultBehaviorNeverCalled(/* supportsOverrideUserIdProperty= */ false);
}
diff --git a/tests/carservice_unit_test/src/android/car/userlib/UserHelperTest.java b/tests/carservice_unit_test/src/android/car/userlib/UserHelperTest.java
index c372a28..6a94c71 100644
--- a/tests/carservice_unit_test/src/android/car/userlib/UserHelperTest.java
+++ b/tests/carservice_unit_test/src/android/car/userlib/UserHelperTest.java
@@ -16,21 +16,48 @@
package android.car.userlib;
+import static android.car.test.util.UserTestingHelper.newUser;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
import android.car.test.mocks.AbstractExtendedMockitoTestCase;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
import android.os.UserHandle;
import android.os.UserManager;
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
public final class UserHelperTest extends AbstractExtendedMockitoTestCase {
+ @Mock private Context mContext;
+ @Mock private UserManager mUserManager;
+
+ // Not worth to mock because it would need to mock a Drawable used by UserIcons.
+ private final Resources mResources = InstrumentationRegistry.getTargetContext().getResources();
+
@Override
protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
session.spyStatic(UserManager.class);
}
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mContext.getResources()).thenReturn(mResources);
+ }
+
@Test
public void testSafeName() {
assertThat(UserHelper.safeName(null)).isNull();
@@ -63,4 +90,57 @@
mockIsHeadlessSystemUserMode(false);
assertThat(UserHelper.isHeadlessSystemUser(10)).isFalse();
}
+
+ @Test
+ public void testDefaultNonAdminRestrictions() {
+ int userId = 20;
+ UserInfo newNonAdmin = newUser(userId);
+
+ UserHelper.setDefaultNonAdminRestrictions(mContext, newNonAdmin, /* enable= */ true);
+
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_FACTORY_RESET, /* enable= */ true, UserHandle.of(userId));
+ }
+
+ @Test
+ public void testDefaultNonAdminRestrictions_nullContext_throwsException() {
+ int userId = 20;
+ UserInfo newNonAdmin = newUser(userId);
+
+ assertThrows(IllegalArgumentException.class,
+ () -> UserHelper.setDefaultNonAdminRestrictions(/* context= */ null,
+ newNonAdmin, /* enable= */ true));
+ }
+
+ @Test
+ public void testDefaultNonAdminRestrictions_nullUser_throwsException() {
+ assertThrows(IllegalArgumentException.class,
+ () -> UserHelper.setDefaultNonAdminRestrictions(mContext, /* user= */
+ null, /* enable= */ true));
+ }
+
+ @Test
+ public void testAssignDefaultIcon() {
+ int userId = 20;
+ UserInfo newNonAdmin = newUser(userId);
+
+ Bitmap bitmap = UserHelper.assignDefaultIcon(mContext, newNonAdmin);
+
+ verify(mUserManager).setUserIcon(userId, bitmap);
+ }
+
+ @Test
+ public void testAssignDefaultIcon_nullContext_throwsException() {
+ int userId = 20;
+ UserInfo newNonAdmin = newUser(userId);
+
+ assertThrows(IllegalArgumentException.class,
+ () -> UserHelper.assignDefaultIcon(/* context= */ null, newNonAdmin));
+ }
+
+ @Test
+ public void testAssignDefaultIcon_nullUser_throwsException() {
+ assertThrows(IllegalArgumentException.class,
+ () -> UserHelper.assignDefaultIcon(mContext, /* user= */ null));
+ }
}
diff --git a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
index 3cbfffc..df2d9bf 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
@@ -16,9 +16,6 @@
package com.android.car;
-import static android.car.test.mocks.CarArgumentMatchers.isUserInfo;
-import static android.car.test.util.UserTestingHelper.newGuestUser;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -352,33 +349,21 @@
@Test
public void testUserSwitchingOnResume_disabledByOEM_nonGuest() throws Exception {
UserInfo currentUser = setCurrentUser(CURRENT_USER_ID, /* isGuest= */ false);
- expectNewGuestCreated(CURRENT_USER_ID, currentUser);
+ expectCurrentGuestCanBeReplaced(false);
suspendAndResumeForUserSwitchingTestsWhileDisabledByOem();
- verifyUserNotSwitched();
+ verifyNoSetCall();
}
@Test
public void testUserSwitchingOnResume_disabledByOEM_guest() throws Exception {
setCurrentUser(CURRENT_GUEST_ID, /* isGuest= */ true);
- UserInfo newGuest = newGuestUser(NEW_GUEST_ID, /* ephemeral= */ true);
- expectNewGuestCreated(CURRENT_GUEST_ID, newGuest);
+ expectCurrentGuestCanBeReplaced(true);
suspendAndResumeForUserSwitchingTestsWhileDisabledByOem();
- verifyUserSwitched(NEW_GUEST_ID);
- }
-
- @Test
- public void testUserSwitchingOnResume_disabledByOEM_guestReplacementFails() throws Exception {
- setCurrentUser(CURRENT_GUEST_ID, /* isGuest= */ true);
- expectNewGuestCreated(CURRENT_GUEST_ID, /* newGuest= */ null);
-
- suspendAndResumeForUserSwitchingTestsWhileDisabledByOem();
-
- verifyUserNotSwitched();
- verifyDefaultInitialUserBehaviorCalled();
+ verifyUserReplaced();
}
@Test
@@ -622,9 +607,8 @@
}));
}
- private void expectNewGuestCreated(int existingGuestId, UserInfo newGuest) {
- when(mInitialUserSetter.replaceGuestIfNeeded(isUserInfo(existingGuestId)))
- .thenReturn(newGuest);
+ private void expectCurrentGuestCanBeReplaced(boolean result) {
+ when(mInitialUserSetter.canReplaceGuestUser(notNull())).thenReturn(result);
}
private void verifyDefaultInitialUserBehaviorCalled() {
@@ -649,6 +633,16 @@
}));
}
+ private void verifyUserReplaced() {
+ verify(mInitialUserSetter).set(argThat((info) -> {
+ return info.type == InitialUserSetter.TYPE_REPLACE_GUEST;
+ }));
+ }
+
+ private void verifyNoSetCall() {
+ verify(mInitialUserSetter, never()).set(notNull());
+ }
+
private static final class MockDisplayInterface implements DisplayInterface {
private boolean mDisplayOn = true;
private final Semaphore mDisplayStateWait = new Semaphore(0);
diff --git a/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java b/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
index 6d1cc76..c3f57ad 100644
--- a/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
@@ -23,6 +23,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -33,6 +34,7 @@
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.car.hardware.power.CarPowerManager;
import android.car.test.mocks.AbstractExtendedMockitoTestCase;
@@ -78,6 +80,8 @@
@Mock
private IActivityManager mActivityManager;
@Mock
+ private IActivityTaskManager mActivityTaskManager;
+ @Mock
private UserManager mUserManager;
@Mock
private DisplayManager mDisplayManager;
@@ -102,8 +106,8 @@
when(mContext.getPackageManager()).thenReturn(mPackageManager);
doReturn(mCarUserService).when(() -> CarLocalServices.getService(CarUserService.class));
doReturn(mCarPowerManager).when(() -> CarLocalServices.createCarPowerManager(mContext));
- mFixedActivityService = new FixedActivityService(mContext, mActivityManager, mUserManager,
- mDisplayManager);
+ mFixedActivityService = new FixedActivityService(mContext, mActivityManager,
+ mActivityTaskManager, mUserManager, mDisplayManager);
}
@After
@@ -142,7 +146,7 @@
mockAmGetCurrentUser(userId);
expectActivityStackInfo(
createEmptyStackInfo(),
- createStackInfo(intent, userIds, mValidDisplayId, taskIds)
+ createStackInfoList(intent, userIds, mValidDisplayId, taskIds)
);
// No running activities
@@ -172,7 +176,7 @@
mockAmGetCurrentUser(userId);
expectActivityStackInfo(
createEmptyStackInfo(),
- createStackInfo(intent, userIds, mValidDisplayId, taskIds)
+ createStackInfoList(intent, userIds, mValidDisplayId, taskIds)
);
// No running activities
@@ -202,7 +206,7 @@
mockAmGetCurrentUser(userId);
expectActivityStackInfo(
createEmptyStackInfo(),
- createStackInfo(intent, userIds, mValidDisplayId, taskIds)
+ createStackInfoList(intent, userIds, mValidDisplayId, taskIds)
);
// No running activities
@@ -219,7 +223,7 @@
int appId = 987;
BroadcastReceiver receiver = receiverCaptor.getValue();
Intent packageIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
- packageIntent.setData(new Uri.Builder().path(packageName).build());
+ packageIntent.setData(new Uri.Builder().path("Any package").build());
packageIntent.putExtra(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
receiver.onReceive(mContext, packageIntent);
verify(mContext).startActivityAsUser(eq(intent), any(Bundle.class),
@@ -323,6 +327,88 @@
verify(mActivityManager, never()).unregisterTaskStackListener(any(TaskStackListener.class));
}
+ @Test
+ public void testHandleTaskFocusChanged_returnForcusBack() throws Exception {
+ int userId = 10;
+ int testTaskId = 1234;
+ int[] userIds = new int[]{userId};
+ int[] taskIds = new int[]{testTaskId};
+ ActivityOptions options = new ActivityOptions(new Bundle());
+ Intent intent = expectComponentAvailable("test_package", "com.test.dude", userId);
+ mockAmGetCurrentUser(userId);
+ expectActivityStackInfo(createStackInfoList(intent, userIds, mValidDisplayId, taskIds));
+
+ // Make FixedActivityService to update the taskIds.
+ boolean ret = mFixedActivityService.startFixedActivityModeForDisplayAndUser(intent,
+ options, mValidDisplayId, userId);
+ assertThat(ret).isTrue();
+
+ Intent homeIntent = expectComponentAvailable("home", "homeActivity", userId);
+ int homeTaskId = 4567;
+ when(mActivityTaskManager.getAllStackInfosOnDisplay(Display.DEFAULT_DISPLAY)).thenReturn(
+ createStackInfoList(
+ homeIntent, userIds, Display.DEFAULT_DISPLAY, new int[]{homeTaskId}));
+
+ mFixedActivityService.handleTaskFocusChanged(testTaskId, true);
+
+ verify(mActivityTaskManager).setFocusedTask(homeTaskId);
+ }
+
+ // If there are two tasks in one display id, then there is a bug to invalidate
+ // RunningActivityInfo.taskId examining 2nd task and it prevents from checking FixedActivity
+ // in handleTaskFocusChanged(). This test makes sure if the bug doesn't exist.
+ @Test
+ public void testHandleTaskFocusChanged_returnForcusBackInTwoStackInfos() throws Exception {
+ int userId = 10;
+ int testTaskId = 1234;
+ int[] userIds = new int[]{userId};
+ int[] taskIds = new int[]{testTaskId};
+ int[] taskIds2 = new int[]{testTaskId + 1111};
+ ActivityOptions options = new ActivityOptions(new Bundle());
+ Intent intent = expectComponentAvailable("test_package", "com.test.dude", userId);
+ Intent intent2 = expectComponentAvailable("test_package2", "com.test.others", userId);
+ mockAmGetCurrentUser(userId);
+ expectActivityStackInfo(Arrays.asList(
+ createStackInfo(intent, userIds, mValidDisplayId, taskIds),
+ createStackInfo(intent2, userIds, mValidDisplayId, taskIds2)));
+
+ // Make FixedActivityService to update the taskIds.
+ boolean ret = mFixedActivityService.startFixedActivityModeForDisplayAndUser(intent,
+ options, mValidDisplayId, userId);
+ assertThat(ret).isTrue();
+
+ Intent homeIntent = expectComponentAvailable("home", "homeActivity", userId);
+ int homeTaskId = 4567;
+ when(mActivityTaskManager.getAllStackInfosOnDisplay(Display.DEFAULT_DISPLAY)).thenReturn(
+ createStackInfoList(
+ homeIntent, userIds, Display.DEFAULT_DISPLAY, new int[]{homeTaskId}));
+
+ mFixedActivityService.handleTaskFocusChanged(testTaskId, true);
+
+ verify(mActivityTaskManager).setFocusedTask(homeTaskId);
+ }
+
+ @Test
+ public void testHandleTaskFocusChanged_noForcusBack() throws Exception {
+ int userId = 10;
+ int testTaskId = 1234;
+ int[] userIds = new int[]{userId};
+ int[] taskIds = new int[]{testTaskId};
+ ActivityOptions options = new ActivityOptions(new Bundle());
+ Intent intent = expectComponentAvailable("test_package", "com.test.dude", userId);
+ mockAmGetCurrentUser(userId);
+ expectActivityStackInfo(createStackInfoList(intent, userIds, mValidDisplayId, taskIds));
+
+ // Make FixedActivityService to update the taskIds.
+ boolean ret = mFixedActivityService.startFixedActivityModeForDisplayAndUser(intent,
+ options, mValidDisplayId, userId);
+ assertThat(ret).isTrue();
+
+ mFixedActivityService.handleTaskFocusChanged(testTaskId + 1, true);
+
+ verify(mActivityTaskManager, never()).setFocusedTask(anyInt());
+ }
+
private void expectNoProfileUser(@UserIdInt int userId) {
when(mUserManager.getEnabledProfileIds(userId)).thenReturn(new int[0]);
}
@@ -371,7 +457,7 @@
return new ArrayList<StackInfo>();
}
- private List<StackInfo> createStackInfo(Intent intent, @UserIdInt int[] userIds, int displayId,
+ private StackInfo createStackInfo(Intent intent, @UserIdInt int[] userIds, int displayId,
int[] taskIds) {
StackInfo stackInfo = new StackInfo();
stackInfo.taskUserIds = userIds;
@@ -379,6 +465,11 @@
stackInfo.visible = true;
stackInfo.displayId = displayId;
stackInfo.taskIds = taskIds;
- return Arrays.asList(stackInfo);
+ return stackInfo;
+ }
+
+ private List<StackInfo> createStackInfoList(Intent intent, @UserIdInt int[] userIds,
+ int displayId, int[] taskIds) {
+ return Arrays.asList(createStackInfo(intent, userIds, displayId, taskIds));
}
}
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
index b339c9a..76b7344 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
@@ -710,14 +710,22 @@
}
@Test
- public void testRemoveUser_lastAdminUser() throws Exception {
- mockCurrentUser(mRegularUser);
- mockExistingUsers(mExistingUsers);
+ public void testRemoveUser_LastAdminUser_success() throws Exception {
+ List<UserInfo> existingUsers =
+ new ArrayList<UserInfo>(Arrays.asList(mAdminUser, mGuestUser, mRegularUser));
+ UserInfo currentUser = mRegularUser;
+ mockExistingUsersAndCurrentUser(existingUsers, currentUser);
+ UserInfo removeUser = mAdminUser;
+ doAnswer((invocation) -> {
+ existingUsers.remove(removeUser);
+ return true;
+ }).when(mMockedUserManager).removeUser(eq(removeUser.id));
UserRemovalResult result = mCarUserService.removeUser(mAdminUser.id);
assertThat(result.getStatus())
- .isEqualTo(UserRemovalResult.STATUS_TARGET_USER_IS_LAST_ADMIN_USER);
+ .isEqualTo(UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED);
+ assertHalRemove(currentUser, removeUser, existingUsers);
}
@Test
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogManagerUnitTest.java b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogManagerUnitTest.java
index ce51364..e6b6ca4 100644
--- a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogManagerUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogManagerUnitTest.java
@@ -25,9 +25,9 @@
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
-import android.automotive.watchdog.ICarWatchdogClient;
import android.car.Car;
import android.car.watchdog.CarWatchdogManager;
+import android.car.watchdog.ICarWatchdogServiceCallback;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
@@ -70,11 +70,11 @@
@Test
public void testRegisterClient() throws Exception {
TestClient client = new TestClient();
- ICarWatchdogClient clientImpl = registerClient(client);
+ ICarWatchdogServiceCallback clientImpl = registerClient(client);
mCarWatchdogManager.unregisterClient(client);
verify(mService).unregisterClient(clientImpl);
- clientImpl.checkIfAlive(123456, TIMEOUT_CRITICAL);
+ clientImpl.onCheckHealthStatus(123456, TIMEOUT_CRITICAL);
verify(mService, never()).tellClientAlive(clientImpl, 123456);
}
@@ -111,10 +111,11 @@
testClientResponse(new ReturnAndPongClient());
}
- private ICarWatchdogClient registerClient(CarWatchdogManager.CarWatchdogClientCallback client) {
+ private ICarWatchdogServiceCallback registerClient(
+ CarWatchdogManager.CarWatchdogClientCallback client) {
mCarWatchdogManager.registerClient(mExecutor, client, TIMEOUT_CRITICAL);
- ArgumentCaptor<ICarWatchdogClient> clientImplCaptor =
- ArgumentCaptor.forClass(ICarWatchdogClient.class);
+ ArgumentCaptor<ICarWatchdogServiceCallback> clientImplCaptor =
+ ArgumentCaptor.forClass(ICarWatchdogServiceCallback.class);
verify(mService).registerClient(clientImplCaptor.capture(), eq(TIMEOUT_CRITICAL));
return clientImplCaptor.getValue();
@@ -122,8 +123,8 @@
private void testClientResponse(CarWatchdogManager.CarWatchdogClientCallback client)
throws Exception {
- ICarWatchdogClient clientImpl = registerClient(client);
- clientImpl.checkIfAlive(123456, TIMEOUT_CRITICAL);
+ ICarWatchdogServiceCallback clientImpl = registerClient(client);
+ clientImpl.onCheckHealthStatus(123456, TIMEOUT_CRITICAL);
verify(mService, timeout(MAX_WAIT_TIME_MS)).tellClientAlive(clientImpl, 123456);
}
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
index 99b6011..b1b04bb 100644
--- a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
@@ -33,6 +33,7 @@
import android.automotive.watchdog.ICarWatchdog;
import android.automotive.watchdog.ICarWatchdogClient;
import android.car.test.mocks.AbstractExtendedMockitoTestCase;
+import android.car.watchdog.ICarWatchdogServiceCallback;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.IBinder;
@@ -159,27 +160,17 @@
assertThat(notRespondingClients.getValue().length).isEqualTo(badClientCount);
}
- private class TestClient extends ICarWatchdogClient.Stub {
+ private class TestClient extends ICarWatchdogServiceCallback.Stub {
protected int mLastSessionId = INVALID_SESSION_ID;
@Override
- public void checkIfAlive(int sessionId, int timeout) {
+ public void onCheckHealthStatus(int sessionId, int timeout) {
mLastSessionId = sessionId;
mCarWatchdogService.tellClientAlive(this, sessionId);
}
@Override
- public void prepareProcessTermination() {}
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
+ public void onPrepareProcessTermination() {}
public int getLastSessionId() {
return mLastSessionId;
@@ -188,7 +179,7 @@
private final class BadTestClient extends TestClient {
@Override
- public void checkIfAlive(int sessionId, int timeout) {
+ public void onCheckHealthStatus(int sessionId, int timeout) {
mLastSessionId = sessionId;
// This client doesn't respond to CarWatchdogService.
}
diff --git a/tools/emulator/README.md b/tools/emulator/README.md
new file mode 100644
index 0000000..45708f8
--- /dev/null
+++ b/tools/emulator/README.md
@@ -0,0 +1,84 @@
+# VHAL Host Emulator
+This is a collection of python modules as tools for VHAL development.
+
+[TOC]
+
+## vhal_emulator.py
+This allow you to create script to interate with the Vehicle HAL in an AAOS
+device from a host.
+
+* It sends and receives messages to/from the Vehicle HAL via port forwarding
+over ADB to communicate with the AAOS device.
+* On the device side, VHAL module VehicleService creates VehicleEmulator to
+setup SocketComm to serve the requests.
+ * hardware/interfaces/automotive/vehicle/2.0/default/VehicleService.cpp
+ * hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
+ * hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
+* vhal_emulator_test.py tests the Vehicle HAL via adb socket.
+ * Note: This may outdated becuase there is no dedicated resrouce. Contribution is welcome.
+
+## vhal_const_generate.py
+This generates vhal_consts_2_0.py to update definitions for property ID, value
+type, zone, etc. from the types.hal. Run this script whenever types.hal is
+changed.
+
+* Must re-generate when the types.hal file changes.
+
+```
+packages/services/Car/tools/emulator/vhal_const_generate.py
+```
+
+* hardware/interfaces/automotive/vehicle/2.0/types.hal
+
+## VehicleHalProto_pb2.py
+This defines message interface to VHAL Emulator from VehicleHalProto.proto.
+
+* Must re-generate whenever the proto file changes.
+* Generated from hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
+
+```
+protoDir=$ANDROID_BUILD_TOP/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto
+outDir=$ANDROID_BUILD_TOP/packages/services/Car/tools/emulator
+# or protoc if perferred
+aprotoc -I=$protoDir --python_out=$outDir $protoDir/VehicleHalProto.proto
+
+```
+
+* It requires Protocol Buffers. You may build one from Android, e.g.
+
+```
+. build/envsetup.sh
+lunch sdk_gcar_x86-userdebug
+m aprotoc -j16
+```
+
+
+## OBD2 Diagnostic Injector
+These scripts are useful for testing the Diagnostics API
+
+### diagnostic_builder.py
+
+* Helper class used by diagnostic_injector.py
+* Stores diagnostic sensor values and bitmasks
+* VehiclePropValue-compatible
+
+### diagnostic_injector.py
+
+* Deserializes JSON into diagnostic events
+* Sends over HAL Emulator Interface
+* Diagnostic JSON Format example: diagjson.example
+
+```
+./diagnostic_injector.py ./diagjson.example
+```
+
+## Python GUI Example
+gui.py is an example to create an GUI to set the property.
+
+* packages/services/Car/tools/emulator/gui.py
+* GUI runs on host machine (PyQt4-based widgets)
+* Drives VHAL on target
+ * Works only with default VHAL
+ * Interactions generate SET messages
+* Supports bench testing of apps
+* Easy to add support for more properties
diff --git a/tools/emulator/vhal_consts_2_0.py b/tools/emulator/vhal_consts_2_0.py
index d4e3b61..12857b9 100644
--- a/tools/emulator/vhal_consts_2_0.py
+++ b/tools/emulator/vhal_consts_2_0.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 The Android Open Source Project
+# 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.
@@ -15,283 +15,6 @@
# DO NOT EDIT MANUALLY
# This file was autogenerated by vhal_const_generate.py
-# VehicleUnit
-VEHICLEUNIT_SHOULD_NOT_USE = 0x0
-VEHICLEUNIT_METER_PER_SEC = 0x1
-VEHICLEUNIT_RPM = 0x2
-VEHICLEUNIT_HERTZ = 0x3
-VEHICLEUNIT_PERCENTILE = 0x10
-VEHICLEUNIT_MILLIMETER = 0x20
-VEHICLEUNIT_METER = 0x21
-VEHICLEUNIT_KILOMETER = 0x23
-VEHICLEUNIT_MILE = 0x24
-VEHICLEUNIT_CELSIUS = 0x30
-VEHICLEUNIT_FAHRENHEIT = 0x31
-VEHICLEUNIT_KELVIN = 0x32
-VEHICLEUNIT_MILLILITER = 0x40
-VEHICLEUNIT_LITER = 0x41
-VEHICLEUNIT_GALLON = 0x42
-VEHICLEUNIT_US_GALLON = 0x42
-VEHICLEUNIT_IMPERIAL_GALLON = 0x43
-VEHICLEUNIT_NANO_SECS = 0x50
-VEHICLEUNIT_SECS = 0x53
-VEHICLEUNIT_YEAR = 0x59
-VEHICLEUNIT_WATT_HOUR = 0x60
-VEHICLEUNIT_MILLIAMPERE = 0x61
-VEHICLEUNIT_MILLIVOLT = 0x62
-VEHICLEUNIT_MILLIWATTS = 0x63
-VEHICLEUNIT_AMPERE_HOURS = 0x64
-VEHICLEUNIT_KILOWATT_HOUR = 0x65
-VEHICLEUNIT_KILOPASCAL = 0x70
-VEHICLEUNIT_PSI = 0x71
-VEHICLEUNIT_BAR = 0x72
-VEHICLEUNIT_DEGREES = 0x80
-VEHICLEUNIT_MILES_PER_HOUR = 0x90
-VEHICLEUNIT_KILOMETERS_PER_HOUR = 0x91
-
-# VehicleLightSwitch
-VEHICLELIGHTSWITCH_OFF = 0x0
-VEHICLELIGHTSWITCH_ON = 0x1
-VEHICLELIGHTSWITCH_DAYTIME_RUNNING = 0x2
-VEHICLELIGHTSWITCH_AUTOMATIC = 0x100
-
-# VmsMessageWithLayerIntegerValuesIndex
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_TYPE = 0x1
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_SUBTYPE = 0x2
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_VERSION = 0x3
-
-# VehiclePropertyGroup
-VEHICLEPROPERTYGROUP_SYSTEM = 0x10000000
-VEHICLEPROPERTYGROUP_VENDOR = 0x20000000
-VEHICLEPROPERTYGROUP_MASK = 0xf0000000
-
-# VehicleApPowerStateShutdownParam
-VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_IMMEDIATELY = 0x1
-VEHICLEAPPOWERSTATESHUTDOWNPARAM_CAN_SLEEP = 0x2
-VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_ONLY = 0x3
-
-# Obd2CommonIgnitionMonitors
-OBD2COMMONIGNITIONMONITORS_COMPONENTS_AVAILABLE = 0x1
-OBD2COMMONIGNITIONMONITORS_COMPONENTS_INCOMPLETE = 0x2
-OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_AVAILABLE = 0x4
-OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_INCOMPLETE = 0x8
-OBD2COMMONIGNITIONMONITORS_MISFIRE_AVAILABLE = 0x10
-OBD2COMMONIGNITIONMONITORS_MISFIRE_INCOMPLETE = 0x20
-
-# PortLocationType
-PORTLOCATIONTYPE_UNKNOWN = 0x0
-PORTLOCATIONTYPE_FRONT_LEFT = 0x1
-PORTLOCATIONTYPE_FRONT_RIGHT = 0x2
-PORTLOCATIONTYPE_REAR_RIGHT = 0x3
-PORTLOCATIONTYPE_REAR_LEFT = 0x4
-PORTLOCATIONTYPE_FRONT = 0x5
-PORTLOCATIONTYPE_REAR = 0x6
-
-# Obd2SparkIgnitionMonitors
-OBD2SPARKIGNITIONMONITORS_EGR_AVAILABLE = 0x40
-OBD2SPARKIGNITIONMONITORS_EGR_INCOMPLETE = 0x80
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_AVAILABLE = 0x100
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x200
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_AVAILABLE = 0x400
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_INCOMPLETE = 0x800
-OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_AVAILABLE = 0x1000
-OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_INCOMPLETE = 0x2000
-OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_AVAILABLE = 0x4000
-OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x8000
-OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_AVAILABLE = 0x10000
-OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_INCOMPLETE = 0x20000
-OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_AVAILABLE = 0x40000
-OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_INCOMPLETE = 0x80000
-OBD2SPARKIGNITIONMONITORS_CATALYST_AVAILABLE = 0x100000
-OBD2SPARKIGNITIONMONITORS_CATALYST_INCOMPLETE = 0x200000
-
-# VmsSubscriptionsStateIntegerValuesIndex
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_LAYERS = 0x2
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x3
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SUBSCRIPTIONS_START = 0x4
-
-# VehicleApPowerStateReq
-VEHICLEAPPOWERSTATEREQ_ON = 0x0
-VEHICLEAPPOWERSTATEREQ_SHUTDOWN_PREPARE = 0x1
-VEHICLEAPPOWERSTATEREQ_CANCEL_SHUTDOWN = 0x2
-VEHICLEAPPOWERSTATEREQ_FINISHED = 0x3
-
-# VehicleApPowerStateReqIndex
-VEHICLEAPPOWERSTATEREQINDEX_STATE = 0x0
-VEHICLEAPPOWERSTATEREQINDEX_ADDITIONAL = 0x1
-
-# Obd2IgnitionMonitorKind
-OBD2IGNITIONMONITORKIND_SPARK = 0x0
-OBD2IGNITIONMONITORKIND_COMPRESSION = 0x1
-
-# VehiclePropertyAccess
-VEHICLEPROPERTYACCESS_NONE = 0x0
-VEHICLEPROPERTYACCESS_READ = 0x1
-VEHICLEPROPERTYACCESS_WRITE = 0x2
-VEHICLEPROPERTYACCESS_READ_WRITE = 0x3
-
-# VehicleOilLevel
-VEHICLEOILLEVEL_CRITICALLY_LOW = 0x0
-VEHICLEOILLEVEL_LOW = 0x1
-VEHICLEOILLEVEL_NORMAL = 0x2
-VEHICLEOILLEVEL_HIGH = 0x3
-VEHICLEOILLEVEL_ERROR = 0x4
-
-# VmsBaseMessageIntegerValuesIndex
-VMSBASEMESSAGEINTEGERVALUESINDEX_MESSAGE_TYPE = 0x0
-
-# StatusCode
-STATUSCODE_OK = 0x0
-STATUSCODE_TRY_AGAIN = 0x1
-STATUSCODE_INVALID_ARG = 0x2
-STATUSCODE_NOT_AVAILABLE = 0x3
-STATUSCODE_ACCESS_DENIED = 0x4
-STATUSCODE_INTERNAL_ERROR = 0x5
-
-# VehicleLightState
-VEHICLELIGHTSTATE_OFF = 0x0
-VEHICLELIGHTSTATE_ON = 0x1
-VEHICLELIGHTSTATE_DAYTIME_RUNNING = 0x2
-
-# VmsStartSessionMessageIntegerValuesIndex
-VMSSTARTSESSIONMESSAGEINTEGERVALUESINDEX_SERVICE_ID = 0x1
-VMSSTARTSESSIONMESSAGEINTEGERVALUESINDEX_CLIENT_ID = 0x2
-
-# VmsPublisherInformationIntegerValuesIndex
-VMSPUBLISHERINFORMATIONINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
-
-# VehiclePropertyChangeMode
-VEHICLEPROPERTYCHANGEMODE_STATIC = 0x0
-VEHICLEPROPERTYCHANGEMODE_ON_CHANGE = 0x1
-VEHICLEPROPERTYCHANGEMODE_CONTINUOUS = 0x2
-
-# VmsMessageType
-VMSMESSAGETYPE_SUBSCRIBE = 0x1
-VMSMESSAGETYPE_SUBSCRIBE_TO_PUBLISHER = 0x2
-VMSMESSAGETYPE_UNSUBSCRIBE = 0x3
-VMSMESSAGETYPE_UNSUBSCRIBE_TO_PUBLISHER = 0x4
-VMSMESSAGETYPE_OFFERING = 0x5
-VMSMESSAGETYPE_AVAILABILITY_REQUEST = 0x6
-VMSMESSAGETYPE_SUBSCRIPTIONS_REQUEST = 0x7
-VMSMESSAGETYPE_AVAILABILITY_RESPONSE = 0x8
-VMSMESSAGETYPE_AVAILABILITY_CHANGE = 0x9
-VMSMESSAGETYPE_SUBSCRIPTIONS_RESPONSE = 0xa
-VMSMESSAGETYPE_SUBSCRIPTIONS_CHANGE = 0xb
-VMSMESSAGETYPE_DATA = 0xc
-VMSMESSAGETYPE_PUBLISHER_ID_REQUEST = 0xd
-VMSMESSAGETYPE_PUBLISHER_ID_RESPONSE = 0xe
-VMSMESSAGETYPE_PUBLISHER_INFORMATION_REQUEST = 0xf
-VMSMESSAGETYPE_PUBLISHER_INFORMATION_RESPONSE = 0x10
-VMSMESSAGETYPE_START_SESSION = 0x11
-VMSMESSAGETYPE_LAST_VMS_MESSAGE_TYPE = 0x11
-
-# DiagnosticIntegerSensorIndex
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_SYSTEM_STATUS = 0x0
-DIAGNOSTICINTEGERSENSORINDEX_MALFUNCTION_INDICATOR_LIGHT_ON = 0x1
-DIAGNOSTICINTEGERSENSORINDEX_IGNITION_MONITORS_SUPPORTED = 0x2
-DIAGNOSTICINTEGERSENSORINDEX_IGNITION_SPECIFIC_MONITORS = 0x3
-DIAGNOSTICINTEGERSENSORINDEX_INTAKE_AIR_TEMPERATURE = 0x4
-DIAGNOSTICINTEGERSENSORINDEX_COMMANDED_SECONDARY_AIR_STATUS = 0x5
-DIAGNOSTICINTEGERSENSORINDEX_NUM_OXYGEN_SENSORS_PRESENT = 0x6
-DIAGNOSTICINTEGERSENSORINDEX_RUNTIME_SINCE_ENGINE_START = 0x7
-DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 0x8
-DIAGNOSTICINTEGERSENSORINDEX_WARMUPS_SINCE_CODES_CLEARED = 0x9
-DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 0xa
-DIAGNOSTICINTEGERSENSORINDEX_ABSOLUTE_BAROMETRIC_PRESSURE = 0xb
-DIAGNOSTICINTEGERSENSORINDEX_CONTROL_MODULE_VOLTAGE = 0xc
-DIAGNOSTICINTEGERSENSORINDEX_AMBIENT_AIR_TEMPERATURE = 0xd
-DIAGNOSTICINTEGERSENSORINDEX_TIME_WITH_MALFUNCTION_LIGHT_ON = 0xe
-DIAGNOSTICINTEGERSENSORINDEX_TIME_SINCE_TROUBLE_CODES_CLEARED = 0xf
-DIAGNOSTICINTEGERSENSORINDEX_MAX_FUEL_AIR_EQUIVALENCE_RATIO = 0x10
-DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_VOLTAGE = 0x11
-DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_CURRENT = 0x12
-DIAGNOSTICINTEGERSENSORINDEX_MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 0x13
-DIAGNOSTICINTEGERSENSORINDEX_MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 0x14
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_TYPE = 0x15
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_RAIL_ABSOLUTE_PRESSURE = 0x16
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_OIL_TEMPERATURE = 0x17
-DIAGNOSTICINTEGERSENSORINDEX_DRIVER_DEMAND_PERCENT_TORQUE = 0x18
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_ACTUAL_PERCENT_TORQUE = 0x19
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_REFERENCE_PERCENT_TORQUE = 0x1a
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_IDLE = 0x1b
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT1 = 0x1c
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT2 = 0x1d
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT3 = 0x1e
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT4 = 0x1f
-DIAGNOSTICINTEGERSENSORINDEX_LAST_SYSTEM_INDEX = 0x1f
-
-# VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
-VMSMESSAGEWITHLAYERANDPUBLISHERIDINTEGERVALUESINDEX_PUBLISHER_ID = 0x4
-
-# VmsOfferingMessageIntegerValuesIndex
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_NUMBER_OF_OFFERS = 0x2
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_OFFERING_START = 0x3
-
-# VehicleApPowerStateConfigFlag
-VEHICLEAPPOWERSTATECONFIGFLAG_ENABLE_DEEP_SLEEP_FLAG = 0x1
-VEHICLEAPPOWERSTATECONFIGFLAG_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2
-
-# FuelType
-FUELTYPE_FUEL_TYPE_UNKNOWN = 0x0
-FUELTYPE_FUEL_TYPE_UNLEADED = 0x1
-FUELTYPE_FUEL_TYPE_LEADED = 0x2
-FUELTYPE_FUEL_TYPE_DIESEL_1 = 0x3
-FUELTYPE_FUEL_TYPE_DIESEL_2 = 0x4
-FUELTYPE_FUEL_TYPE_BIODIESEL = 0x5
-FUELTYPE_FUEL_TYPE_E85 = 0x6
-FUELTYPE_FUEL_TYPE_LPG = 0x7
-FUELTYPE_FUEL_TYPE_CNG = 0x8
-FUELTYPE_FUEL_TYPE_LNG = 0x9
-FUELTYPE_FUEL_TYPE_ELECTRIC = 0xa
-FUELTYPE_FUEL_TYPE_HYDROGEN = 0xb
-FUELTYPE_FUEL_TYPE_OTHER = 0xc
-
-# VehicleSeatOccupancyState
-VEHICLESEATOCCUPANCYSTATE_UNKNOWN = 0x0
-VEHICLESEATOCCUPANCYSTATE_VACANT = 0x1
-VEHICLESEATOCCUPANCYSTATE_OCCUPIED = 0x2
-
-# VehicleIgnitionState
-VEHICLEIGNITIONSTATE_UNDEFINED = 0x0
-VEHICLEIGNITIONSTATE_LOCK = 0x1
-VEHICLEIGNITIONSTATE_OFF = 0x2
-VEHICLEIGNITIONSTATE_ACC = 0x3
-VEHICLEIGNITIONSTATE_ON = 0x4
-VEHICLEIGNITIONSTATE_START = 0x5
-
-# VehicleAreaSeat
-VEHICLEAREASEAT_ROW_1_LEFT = 0x1
-VEHICLEAREASEAT_ROW_1_CENTER = 0x2
-VEHICLEAREASEAT_ROW_1_RIGHT = 0x4
-VEHICLEAREASEAT_ROW_2_LEFT = 0x10
-VEHICLEAREASEAT_ROW_2_CENTER = 0x20
-VEHICLEAREASEAT_ROW_2_RIGHT = 0x40
-VEHICLEAREASEAT_ROW_3_LEFT = 0x100
-VEHICLEAREASEAT_ROW_3_CENTER = 0x200
-VEHICLEAREASEAT_ROW_3_RIGHT = 0x400
-
-# VehicleTurnSignal
-VEHICLETURNSIGNAL_NONE = 0x0
-VEHICLETURNSIGNAL_RIGHT = 0x1
-VEHICLETURNSIGNAL_LEFT = 0x2
-
-# EvConnectorType
-EVCONNECTORTYPE_UNKNOWN = 0x0
-EVCONNECTORTYPE_IEC_TYPE_1_AC = 0x1
-EVCONNECTORTYPE_IEC_TYPE_2_AC = 0x2
-EVCONNECTORTYPE_IEC_TYPE_3_AC = 0x3
-EVCONNECTORTYPE_IEC_TYPE_4_DC = 0x4
-EVCONNECTORTYPE_IEC_TYPE_1_CCS_DC = 0x5
-EVCONNECTORTYPE_IEC_TYPE_2_CCS_DC = 0x6
-EVCONNECTORTYPE_TESLA_ROADSTER = 0x7
-EVCONNECTORTYPE_TESLA_HPWC = 0x8
-EVCONNECTORTYPE_TESLA_SUPERCHARGER = 0x9
-EVCONNECTORTYPE_GBT_AC = 0xa
-EVCONNECTORTYPE_GBT_DC = 0xb
-EVCONNECTORTYPE_OTHER = 0x65
-
# VehiclePropertyType
VEHICLEPROPERTYTYPE_STRING = 0x100000
VEHICLEPROPERTYTYPE_BOOLEAN = 0x200000
@@ -305,102 +28,19 @@
VEHICLEPROPERTYTYPE_MIXED = 0xe00000
VEHICLEPROPERTYTYPE_MASK = 0xff0000
-# VehicleAreaMirror
-VEHICLEAREAMIRROR_DRIVER_LEFT = 0x1
-VEHICLEAREAMIRROR_DRIVER_RIGHT = 0x2
-VEHICLEAREAMIRROR_DRIVER_CENTER = 0x4
+# VehicleArea
+VEHICLEAREA_GLOBAL = 0x1000000
+VEHICLEAREA_WINDOW = 0x3000000
+VEHICLEAREA_MIRROR = 0x4000000
+VEHICLEAREA_SEAT = 0x5000000
+VEHICLEAREA_DOOR = 0x6000000
+VEHICLEAREA_WHEEL = 0x7000000
+VEHICLEAREA_MASK = 0xf000000
-# Obd2FuelSystemStatus
-OBD2FUELSYSTEMSTATUS_OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 0x1
-OBD2FUELSYSTEMSTATUS_CLOSED_LOOP = 0x2
-OBD2FUELSYSTEMSTATUS_OPEN_ENGINE_LOAD_OR_DECELERATION = 0x4
-OBD2FUELSYSTEMSTATUS_OPEN_SYSTEM_FAILURE = 0x8
-OBD2FUELSYSTEMSTATUS_CLOSED_LOOP_BUT_FEEDBACK_FAULT = 0x10
-
-# Obd2SecondaryAirStatus
-OBD2SECONDARYAIRSTATUS_UPSTREAM = 0x1
-OBD2SECONDARYAIRSTATUS_DOWNSTREAM_OF_CATALYCIC_CONVERTER = 0x2
-OBD2SECONDARYAIRSTATUS_FROM_OUTSIDE_OR_OFF = 0x4
-OBD2SECONDARYAIRSTATUS_PUMP_ON_FOR_DIAGNOSTICS = 0x8
-
-# VehicleAreaWheel
-VEHICLEAREAWHEEL_UNKNOWN = 0x0
-VEHICLEAREAWHEEL_LEFT_FRONT = 0x1
-VEHICLEAREAWHEEL_RIGHT_FRONT = 0x2
-VEHICLEAREAWHEEL_LEFT_REAR = 0x4
-VEHICLEAREAWHEEL_RIGHT_REAR = 0x8
-
-# VehicleGear
-VEHICLEGEAR_GEAR_NEUTRAL = 0x1
-VEHICLEGEAR_GEAR_REVERSE = 0x2
-VEHICLEGEAR_GEAR_PARK = 0x4
-VEHICLEGEAR_GEAR_DRIVE = 0x8
-VEHICLEGEAR_GEAR_1 = 0x10
-VEHICLEGEAR_GEAR_2 = 0x20
-VEHICLEGEAR_GEAR_3 = 0x40
-VEHICLEGEAR_GEAR_4 = 0x80
-VEHICLEGEAR_GEAR_5 = 0x100
-VEHICLEGEAR_GEAR_6 = 0x200
-VEHICLEGEAR_GEAR_7 = 0x400
-VEHICLEGEAR_GEAR_8 = 0x800
-VEHICLEGEAR_GEAR_9 = 0x1000
-
-# VmsAvailabilityStateIntegerValuesIndex
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x2
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_LAYERS_START = 0x3
-
-# VehicleHwKeyInputAction
-VEHICLEHWKEYINPUTACTION_ACTION_DOWN = 0x0
-VEHICLEHWKEYINPUTACTION_ACTION_UP = 0x1
-
-# VehicleApPowerStateReport
-VEHICLEAPPOWERSTATEREPORT_WAIT_FOR_VHAL = 0x1
-VEHICLEAPPOWERSTATEREPORT_DEEP_SLEEP_ENTRY = 0x2
-VEHICLEAPPOWERSTATEREPORT_DEEP_SLEEP_EXIT = 0x3
-VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_POSTPONE = 0x4
-VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_START = 0x5
-VEHICLEAPPOWERSTATEREPORT_ON = 0x6
-VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_PREPARE = 0x7
-VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_CANCELLED = 0x8
-
-# VehicleDisplay
-VEHICLEDISPLAY_MAIN = 0x0
-VEHICLEDISPLAY_INSTRUMENT_CLUSTER = 0x1
-
-# Obd2CompressionIgnitionMonitors
-OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_AVAILABLE = 0x40
-OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_INCOMPLETE = 0x80
-OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_AVAILABLE = 0x100
-OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_INCOMPLETE = 0x200
-OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_AVAILABLE = 0x400
-OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_INCOMPLETE = 0x800
-OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_AVAILABLE = 0x1000
-OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_INCOMPLETE = 0x2000
-OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_AVAILABLE = 0x4000
-OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_INCOMPLETE = 0x8000
-OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_AVAILABLE = 0x10000
-OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_INCOMPLETE = 0x20000
-
-# VehicleHvacFanDirection
-VEHICLEHVACFANDIRECTION_FACE = 0x1
-VEHICLEHVACFANDIRECTION_FLOOR = 0x2
-VEHICLEHVACFANDIRECTION_DEFROST = 0x4
-
-# VehicleAreaDoor
-VEHICLEAREADOOR_ROW_1_LEFT = 0x1
-VEHICLEAREADOOR_ROW_1_RIGHT = 0x4
-VEHICLEAREADOOR_ROW_2_LEFT = 0x10
-VEHICLEAREADOOR_ROW_2_RIGHT = 0x40
-VEHICLEAREADOOR_ROW_3_LEFT = 0x100
-VEHICLEAREADOOR_ROW_3_RIGHT = 0x400
-VEHICLEAREADOOR_HOOD = 0x10000000
-VEHICLEAREADOOR_REAR = 0x20000000
-
-# SubscribeFlags
-SUBSCRIBEFLAGS_UNDEFINED = 0x0
-SUBSCRIBEFLAGS_EVENTS_FROM_CAR = 0x1
-SUBSCRIBEFLAGS_EVENTS_FROM_ANDROID = 0x2
+# VehiclePropertyGroup
+VEHICLEPROPERTYGROUP_SYSTEM = 0x10000000
+VEHICLEPROPERTYGROUP_VENDOR = 0x20000000
+VEHICLEPROPERTYGROUP_MASK = 0xf0000000
# VehicleProperty
VEHICLEPROPERTY_INVALID = 0x0
@@ -415,10 +55,13 @@
VEHICLEPROPERTY_INFO_FUEL_DOOR_LOCATION = 0x11400108
VEHICLEPROPERTY_INFO_EV_PORT_LOCATION = 0x11400109
VEHICLEPROPERTY_INFO_DRIVER_SEAT = 0x1540010a
+VEHICLEPROPERTY_INFO_EXTERIOR_DIMENSIONS = 0x1141010b
+VEHICLEPROPERTY_INFO_MULTI_EV_PORT_LOCATIONS = 0x1141010c
VEHICLEPROPERTY_PERF_ODOMETER = 0x11600204
VEHICLEPROPERTY_PERF_VEHICLE_SPEED = 0x11600207
VEHICLEPROPERTY_PERF_VEHICLE_SPEED_DISPLAY = 0x11600208
VEHICLEPROPERTY_PERF_STEERING_ANGLE = 0x11600209
+VEHICLEPROPERTY_PERF_REAR_STEERING_ANGLE = 0x11600210
VEHICLEPROPERTY_ENGINE_COOLANT_TEMP = 0x11600301
VEHICLEPROPERTY_ENGINE_OIL_LEVEL = 0x11400303
VEHICLEPROPERTY_ENGINE_OIL_TEMP = 0x11600304
@@ -462,6 +105,7 @@
VEHICLEPROPERTY_HVAC_FAN_DIRECTION_AVAILABLE = 0x15410511
VEHICLEPROPERTY_HVAC_AUTO_RECIRC_ON = 0x15200512
VEHICLEPROPERTY_HVAC_SEAT_VENTILATION = 0x15400513
+VEHICLEPROPERTY_HVAC_ELECTRIC_DEFROSTER_ON = 0x13200514
VEHICLEPROPERTY_DISTANCE_DISPLAY_UNITS = 0x11400600
VEHICLEPROPERTY_FUEL_VOLUME_DISPLAY_UNITS = 0x11400601
VEHICLEPROPERTY_TIRE_PRESSURE_DISPLAY_UNITS = 0x11400602
@@ -474,6 +118,7 @@
VEHICLEPROPERTY_AP_POWER_BOOTUP_REASON = 0x11400a02
VEHICLEPROPERTY_DISPLAY_BRIGHTNESS = 0x11400a03
VEHICLEPROPERTY_HW_KEY_INPUT = 0x11410a10
+VEHICLEPROPERTY_HW_ROTARY_INPUT = 0x11410a20
VEHICLEPROPERTY_DOOR_POS = 0x16400b00
VEHICLEPROPERTY_DOOR_MOVE = 0x16400b01
VEHICLEPROPERTY_DOOR_LOCK = 0x16200b02
@@ -531,6 +176,355 @@
VEHICLEPROPERTY_CABIN_LIGHTS_SWITCH = 0x11400f02
VEHICLEPROPERTY_READING_LIGHTS_STATE = 0x15400f03
VEHICLEPROPERTY_READING_LIGHTS_SWITCH = 0x15400f04
+VEHICLEPROPERTY_SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x11200f05
+VEHICLEPROPERTY_DISABLED_OPTIONAL_FEATURES = 0x11100f06
+VEHICLEPROPERTY_INITIAL_USER_INFO = 0x11e00f07
+VEHICLEPROPERTY_SWITCH_USER = 0x11e00f08
+VEHICLEPROPERTY_CREATE_USER = 0x11e00f09
+VEHICLEPROPERTY_REMOVE_USER = 0x11e00f0a
+VEHICLEPROPERTY_USER_IDENTIFICATION_ASSOCIATION = 0x11e00f0b
+
+# VehicleVendorPermission
+VEHICLEVENDORPERMISSION_PERMISSION_DEFAULT = 0x0
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 0x1
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x2
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x3
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x4
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x5
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x6
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 0x7
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x8
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x9
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_INFO = 0xa
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 0xb
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0xc
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0xd
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0xe
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0xf
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x10
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_1 = 0x10000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_1 = 0x11000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_2 = 0x20000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_2 = 0x21000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_3 = 0x30000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_3 = 0x31000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_4 = 0x40000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_4 = 0x41000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_5 = 0x50000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_5 = 0x51000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_6 = 0x60000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_6 = 0x61000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_7 = 0x70000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_7 = 0x71000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_8 = 0x80000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_8 = 0x81000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_9 = 0x90000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_9 = 0x91000
+VEHICLEVENDORPERMISSION_PERMISSION_SET_VENDOR_CATEGORY_10 = 0xa0000
+VEHICLEVENDORPERMISSION_PERMISSION_GET_VENDOR_CATEGORY_10 = 0xa1000
+VEHICLEVENDORPERMISSION_PERMISSION_NOT_ACCESSIBLE = 0xf0000000
+
+# VehicleSeatOccupancyState
+VEHICLESEATOCCUPANCYSTATE_UNKNOWN = 0x0
+VEHICLESEATOCCUPANCYSTATE_VACANT = 0x1
+VEHICLESEATOCCUPANCYSTATE_OCCUPIED = 0x2
+
+# VehicleLightState
+VEHICLELIGHTSTATE_OFF = 0x0
+VEHICLELIGHTSTATE_ON = 0x1
+VEHICLELIGHTSTATE_DAYTIME_RUNNING = 0x2
+
+# VehicleLightSwitch
+VEHICLELIGHTSWITCH_OFF = 0x0
+VEHICLELIGHTSWITCH_ON = 0x1
+VEHICLELIGHTSWITCH_DAYTIME_RUNNING = 0x2
+VEHICLELIGHTSWITCH_AUTOMATIC = 0x100
+
+# EvConnectorType
+EVCONNECTORTYPE_UNKNOWN = 0x0
+EVCONNECTORTYPE_IEC_TYPE_1_AC = 0x1
+EVCONNECTORTYPE_IEC_TYPE_2_AC = 0x2
+EVCONNECTORTYPE_IEC_TYPE_3_AC = 0x3
+EVCONNECTORTYPE_IEC_TYPE_4_DC = 0x4
+EVCONNECTORTYPE_IEC_TYPE_1_CCS_DC = 0x5
+EVCONNECTORTYPE_IEC_TYPE_2_CCS_DC = 0x6
+EVCONNECTORTYPE_TESLA_ROADSTER = 0x7
+EVCONNECTORTYPE_TESLA_HPWC = 0x8
+EVCONNECTORTYPE_TESLA_SUPERCHARGER = 0x9
+EVCONNECTORTYPE_GBT_AC = 0xa
+EVCONNECTORTYPE_GBT_DC = 0xb
+EVCONNECTORTYPE_OTHER = 0x65
+
+# PortLocationType
+PORTLOCATIONTYPE_UNKNOWN = 0x0
+PORTLOCATIONTYPE_FRONT_LEFT = 0x1
+PORTLOCATIONTYPE_FRONT_RIGHT = 0x2
+PORTLOCATIONTYPE_REAR_RIGHT = 0x3
+PORTLOCATIONTYPE_REAR_LEFT = 0x4
+PORTLOCATIONTYPE_FRONT = 0x5
+PORTLOCATIONTYPE_REAR = 0x6
+
+# FuelType
+FUELTYPE_FUEL_TYPE_UNKNOWN = 0x0
+FUELTYPE_FUEL_TYPE_UNLEADED = 0x1
+FUELTYPE_FUEL_TYPE_LEADED = 0x2
+FUELTYPE_FUEL_TYPE_DIESEL_1 = 0x3
+FUELTYPE_FUEL_TYPE_DIESEL_2 = 0x4
+FUELTYPE_FUEL_TYPE_BIODIESEL = 0x5
+FUELTYPE_FUEL_TYPE_E85 = 0x6
+FUELTYPE_FUEL_TYPE_LPG = 0x7
+FUELTYPE_FUEL_TYPE_CNG = 0x8
+FUELTYPE_FUEL_TYPE_LNG = 0x9
+FUELTYPE_FUEL_TYPE_ELECTRIC = 0xa
+FUELTYPE_FUEL_TYPE_HYDROGEN = 0xb
+FUELTYPE_FUEL_TYPE_OTHER = 0xc
+
+# VehicleHvacFanDirection
+VEHICLEHVACFANDIRECTION_UNKNOWN = 0x0
+VEHICLEHVACFANDIRECTION_FACE = 0x1
+VEHICLEHVACFANDIRECTION_FLOOR = 0x2
+VEHICLEHVACFANDIRECTION_FACE_AND_FLOOR = 0x3
+VEHICLEHVACFANDIRECTION_DEFROST = 0x4
+VEHICLEHVACFANDIRECTION_DEFROST_AND_FLOOR = 0x6
+
+# VehicleOilLevel
+VEHICLEOILLEVEL_CRITICALLY_LOW = 0x0
+VEHICLEOILLEVEL_LOW = 0x1
+VEHICLEOILLEVEL_NORMAL = 0x2
+VEHICLEOILLEVEL_HIGH = 0x3
+VEHICLEOILLEVEL_ERROR = 0x4
+
+# VehicleApPowerStateConfigFlag
+VEHICLEAPPOWERSTATECONFIGFLAG_ENABLE_DEEP_SLEEP_FLAG = 0x1
+VEHICLEAPPOWERSTATECONFIGFLAG_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2
+
+# VehicleApPowerStateReq
+VEHICLEAPPOWERSTATEREQ_ON = 0x0
+VEHICLEAPPOWERSTATEREQ_SHUTDOWN_PREPARE = 0x1
+VEHICLEAPPOWERSTATEREQ_CANCEL_SHUTDOWN = 0x2
+VEHICLEAPPOWERSTATEREQ_FINISHED = 0x3
+
+# VehicleApPowerStateReqIndex
+VEHICLEAPPOWERSTATEREQINDEX_STATE = 0x0
+VEHICLEAPPOWERSTATEREQINDEX_ADDITIONAL = 0x1
+
+# VehicleApPowerStateShutdownParam
+VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_IMMEDIATELY = 0x1
+VEHICLEAPPOWERSTATESHUTDOWNPARAM_CAN_SLEEP = 0x2
+VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_ONLY = 0x3
+VEHICLEAPPOWERSTATESHUTDOWNPARAM_SLEEP_IMMEDIATELY = 0x4
+
+# VehicleApPowerStateReport
+VEHICLEAPPOWERSTATEREPORT_WAIT_FOR_VHAL = 0x1
+VEHICLEAPPOWERSTATEREPORT_DEEP_SLEEP_ENTRY = 0x2
+VEHICLEAPPOWERSTATEREPORT_DEEP_SLEEP_EXIT = 0x3
+VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_POSTPONE = 0x4
+VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_START = 0x5
+VEHICLEAPPOWERSTATEREPORT_ON = 0x6
+VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_PREPARE = 0x7
+VEHICLEAPPOWERSTATEREPORT_SHUTDOWN_CANCELLED = 0x8
+
+# VehicleHwKeyInputAction
+VEHICLEHWKEYINPUTACTION_ACTION_DOWN = 0x0
+VEHICLEHWKEYINPUTACTION_ACTION_UP = 0x1
+
+# VehicleDisplay
+VEHICLEDISPLAY_MAIN = 0x0
+VEHICLEDISPLAY_INSTRUMENT_CLUSTER = 0x1
+
+# VehicleUnit
+VEHICLEUNIT_SHOULD_NOT_USE = 0x0
+VEHICLEUNIT_METER_PER_SEC = 0x1
+VEHICLEUNIT_RPM = 0x2
+VEHICLEUNIT_HERTZ = 0x3
+VEHICLEUNIT_PERCENTILE = 0x10
+VEHICLEUNIT_MILLIMETER = 0x20
+VEHICLEUNIT_METER = 0x21
+VEHICLEUNIT_KILOMETER = 0x23
+VEHICLEUNIT_MILE = 0x24
+VEHICLEUNIT_CELSIUS = 0x30
+VEHICLEUNIT_FAHRENHEIT = 0x31
+VEHICLEUNIT_KELVIN = 0x32
+VEHICLEUNIT_MILLILITER = 0x40
+VEHICLEUNIT_LITER = 0x41
+VEHICLEUNIT_GALLON = 0x42
+VEHICLEUNIT_US_GALLON = 0x42
+VEHICLEUNIT_IMPERIAL_GALLON = 0x43
+VEHICLEUNIT_NANO_SECS = 0x50
+VEHICLEUNIT_SECS = 0x53
+VEHICLEUNIT_YEAR = 0x59
+VEHICLEUNIT_WATT_HOUR = 0x60
+VEHICLEUNIT_MILLIAMPERE = 0x61
+VEHICLEUNIT_MILLIVOLT = 0x62
+VEHICLEUNIT_MILLIWATTS = 0x63
+VEHICLEUNIT_AMPERE_HOURS = 0x64
+VEHICLEUNIT_KILOWATT_HOUR = 0x65
+VEHICLEUNIT_KILOPASCAL = 0x70
+VEHICLEUNIT_PSI = 0x71
+VEHICLEUNIT_BAR = 0x72
+VEHICLEUNIT_DEGREES = 0x80
+VEHICLEUNIT_MILES_PER_HOUR = 0x90
+VEHICLEUNIT_KILOMETERS_PER_HOUR = 0x91
+
+# VehiclePropertyChangeMode
+VEHICLEPROPERTYCHANGEMODE_STATIC = 0x0
+VEHICLEPROPERTYCHANGEMODE_ON_CHANGE = 0x1
+VEHICLEPROPERTYCHANGEMODE_CONTINUOUS = 0x2
+
+# VehiclePropertyAccess
+VEHICLEPROPERTYACCESS_NONE = 0x0
+VEHICLEPROPERTYACCESS_READ = 0x1
+VEHICLEPROPERTYACCESS_WRITE = 0x2
+VEHICLEPROPERTYACCESS_READ_WRITE = 0x3
+
+# VehiclePropertyStatus
+VEHICLEPROPERTYSTATUS_AVAILABLE = 0x0
+VEHICLEPROPERTYSTATUS_UNAVAILABLE = 0x1
+VEHICLEPROPERTYSTATUS_ERROR = 0x2
+
+# VehicleGear
+VEHICLEGEAR_GEAR_UNKNOWN = 0x0
+VEHICLEGEAR_GEAR_NEUTRAL = 0x1
+VEHICLEGEAR_GEAR_REVERSE = 0x2
+VEHICLEGEAR_GEAR_PARK = 0x4
+VEHICLEGEAR_GEAR_DRIVE = 0x8
+VEHICLEGEAR_GEAR_1 = 0x10
+VEHICLEGEAR_GEAR_2 = 0x20
+VEHICLEGEAR_GEAR_3 = 0x40
+VEHICLEGEAR_GEAR_4 = 0x80
+VEHICLEGEAR_GEAR_5 = 0x100
+VEHICLEGEAR_GEAR_6 = 0x200
+VEHICLEGEAR_GEAR_7 = 0x400
+VEHICLEGEAR_GEAR_8 = 0x800
+VEHICLEGEAR_GEAR_9 = 0x1000
+
+# VehicleAreaSeat
+VEHICLEAREASEAT_ROW_1_LEFT = 0x1
+VEHICLEAREASEAT_ROW_1_CENTER = 0x2
+VEHICLEAREASEAT_ROW_1_RIGHT = 0x4
+VEHICLEAREASEAT_ROW_2_LEFT = 0x10
+VEHICLEAREASEAT_ROW_2_CENTER = 0x20
+VEHICLEAREASEAT_ROW_2_RIGHT = 0x40
+VEHICLEAREASEAT_ROW_3_LEFT = 0x100
+VEHICLEAREASEAT_ROW_3_CENTER = 0x200
+VEHICLEAREASEAT_ROW_3_RIGHT = 0x400
+
+# VehicleAreaWindow
+VEHICLEAREAWINDOW_FRONT_WINDSHIELD = 0x1
+VEHICLEAREAWINDOW_REAR_WINDSHIELD = 0x2
+VEHICLEAREAWINDOW_ROW_1_LEFT = 0x10
+VEHICLEAREAWINDOW_ROW_1_RIGHT = 0x40
+VEHICLEAREAWINDOW_ROW_2_LEFT = 0x100
+VEHICLEAREAWINDOW_ROW_2_RIGHT = 0x400
+VEHICLEAREAWINDOW_ROW_3_LEFT = 0x1000
+VEHICLEAREAWINDOW_ROW_3_RIGHT = 0x4000
+VEHICLEAREAWINDOW_ROOF_TOP_1 = 0x10000
+VEHICLEAREAWINDOW_ROOF_TOP_2 = 0x20000
+
+# VehicleAreaDoor
+VEHICLEAREADOOR_ROW_1_LEFT = 0x1
+VEHICLEAREADOOR_ROW_1_RIGHT = 0x4
+VEHICLEAREADOOR_ROW_2_LEFT = 0x10
+VEHICLEAREADOOR_ROW_2_RIGHT = 0x40
+VEHICLEAREADOOR_ROW_3_LEFT = 0x100
+VEHICLEAREADOOR_ROW_3_RIGHT = 0x400
+VEHICLEAREADOOR_HOOD = 0x10000000
+VEHICLEAREADOOR_REAR = 0x20000000
+
+# VehicleAreaMirror
+VEHICLEAREAMIRROR_DRIVER_LEFT = 0x1
+VEHICLEAREAMIRROR_DRIVER_RIGHT = 0x2
+VEHICLEAREAMIRROR_DRIVER_CENTER = 0x4
+
+# VehicleTurnSignal
+VEHICLETURNSIGNAL_NONE = 0x0
+VEHICLETURNSIGNAL_RIGHT = 0x1
+VEHICLETURNSIGNAL_LEFT = 0x2
+
+# VehicleIgnitionState
+VEHICLEIGNITIONSTATE_UNDEFINED = 0x0
+VEHICLEIGNITIONSTATE_LOCK = 0x1
+VEHICLEIGNITIONSTATE_OFF = 0x2
+VEHICLEIGNITIONSTATE_ACC = 0x3
+VEHICLEIGNITIONSTATE_ON = 0x4
+VEHICLEIGNITIONSTATE_START = 0x5
+
+# SubscribeFlags
+SUBSCRIBEFLAGS_UNDEFINED = 0x0
+SUBSCRIBEFLAGS_EVENTS_FROM_CAR = 0x1
+SUBSCRIBEFLAGS_EVENTS_FROM_ANDROID = 0x2
+
+# StatusCode
+STATUSCODE_OK = 0x0
+STATUSCODE_TRY_AGAIN = 0x1
+STATUSCODE_INVALID_ARG = 0x2
+STATUSCODE_NOT_AVAILABLE = 0x3
+STATUSCODE_ACCESS_DENIED = 0x4
+STATUSCODE_INTERNAL_ERROR = 0x5
+
+# VehicleAreaWheel
+VEHICLEAREAWHEEL_UNKNOWN = 0x0
+VEHICLEAREAWHEEL_LEFT_FRONT = 0x1
+VEHICLEAREAWHEEL_RIGHT_FRONT = 0x2
+VEHICLEAREAWHEEL_LEFT_REAR = 0x4
+VEHICLEAREAWHEEL_RIGHT_REAR = 0x8
+
+# Obd2FuelSystemStatus
+OBD2FUELSYSTEMSTATUS_OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 0x1
+OBD2FUELSYSTEMSTATUS_CLOSED_LOOP = 0x2
+OBD2FUELSYSTEMSTATUS_OPEN_ENGINE_LOAD_OR_DECELERATION = 0x4
+OBD2FUELSYSTEMSTATUS_OPEN_SYSTEM_FAILURE = 0x8
+OBD2FUELSYSTEMSTATUS_CLOSED_LOOP_BUT_FEEDBACK_FAULT = 0x10
+
+# Obd2IgnitionMonitorKind
+OBD2IGNITIONMONITORKIND_SPARK = 0x0
+OBD2IGNITIONMONITORKIND_COMPRESSION = 0x1
+
+# Obd2CommonIgnitionMonitors
+OBD2COMMONIGNITIONMONITORS_COMPONENTS_AVAILABLE = 0x1
+OBD2COMMONIGNITIONMONITORS_COMPONENTS_INCOMPLETE = 0x2
+OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_AVAILABLE = 0x4
+OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_INCOMPLETE = 0x8
+OBD2COMMONIGNITIONMONITORS_MISFIRE_AVAILABLE = 0x10
+OBD2COMMONIGNITIONMONITORS_MISFIRE_INCOMPLETE = 0x20
+
+# Obd2SparkIgnitionMonitors
+OBD2SPARKIGNITIONMONITORS_EGR_AVAILABLE = 0x40
+OBD2SPARKIGNITIONMONITORS_EGR_INCOMPLETE = 0x80
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_AVAILABLE = 0x100
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x200
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_AVAILABLE = 0x400
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_INCOMPLETE = 0x800
+OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_AVAILABLE = 0x1000
+OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_INCOMPLETE = 0x2000
+OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_AVAILABLE = 0x4000
+OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x8000
+OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_AVAILABLE = 0x10000
+OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_INCOMPLETE = 0x20000
+OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_AVAILABLE = 0x40000
+OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_INCOMPLETE = 0x80000
+OBD2SPARKIGNITIONMONITORS_CATALYST_AVAILABLE = 0x100000
+OBD2SPARKIGNITIONMONITORS_CATALYST_INCOMPLETE = 0x200000
+
+# Obd2CompressionIgnitionMonitors
+OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_AVAILABLE = 0x40
+OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_INCOMPLETE = 0x80
+OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_AVAILABLE = 0x100
+OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_INCOMPLETE = 0x200
+OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_AVAILABLE = 0x400
+OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_INCOMPLETE = 0x800
+OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_AVAILABLE = 0x1000
+OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_INCOMPLETE = 0x2000
+OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_AVAILABLE = 0x4000
+OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_INCOMPLETE = 0x8000
+OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_AVAILABLE = 0x10000
+OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_INCOMPLETE = 0x20000
+
+# Obd2SecondaryAirStatus
+OBD2SECONDARYAIRSTATUS_UPSTREAM = 0x1
+OBD2SECONDARYAIRSTATUS_DOWNSTREAM_OF_CATALYCIC_CONVERTER = 0x2
+OBD2SECONDARYAIRSTATUS_FROM_OUTSIDE_OR_OFF = 0x4
+OBD2SECONDARYAIRSTATUS_PUMP_ON_FOR_DIAGNOSTICS = 0x8
# Obd2FuelType
OBD2FUELTYPE_NOT_AVAILABLE = 0x0
@@ -558,17 +552,40 @@
OBD2FUELTYPE_HYBRID_REGENERATIVE = 0x16
OBD2FUELTYPE_BIFUEL_RUNNING_DIESEL = 0x17
-# VehicleAreaWindow
-VEHICLEAREAWINDOW_FRONT_WINDSHIELD = 0x1
-VEHICLEAREAWINDOW_REAR_WINDSHIELD = 0x2
-VEHICLEAREAWINDOW_ROW_1_LEFT = 0x10
-VEHICLEAREAWINDOW_ROW_1_RIGHT = 0x40
-VEHICLEAREAWINDOW_ROW_2_LEFT = 0x100
-VEHICLEAREAWINDOW_ROW_2_RIGHT = 0x400
-VEHICLEAREAWINDOW_ROW_3_LEFT = 0x1000
-VEHICLEAREAWINDOW_ROW_3_RIGHT = 0x4000
-VEHICLEAREAWINDOW_ROOF_TOP_1 = 0x10000
-VEHICLEAREAWINDOW_ROOF_TOP_2 = 0x20000
+# DiagnosticIntegerSensorIndex
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_SYSTEM_STATUS = 0x0
+DIAGNOSTICINTEGERSENSORINDEX_MALFUNCTION_INDICATOR_LIGHT_ON = 0x1
+DIAGNOSTICINTEGERSENSORINDEX_IGNITION_MONITORS_SUPPORTED = 0x2
+DIAGNOSTICINTEGERSENSORINDEX_IGNITION_SPECIFIC_MONITORS = 0x3
+DIAGNOSTICINTEGERSENSORINDEX_INTAKE_AIR_TEMPERATURE = 0x4
+DIAGNOSTICINTEGERSENSORINDEX_COMMANDED_SECONDARY_AIR_STATUS = 0x5
+DIAGNOSTICINTEGERSENSORINDEX_NUM_OXYGEN_SENSORS_PRESENT = 0x6
+DIAGNOSTICINTEGERSENSORINDEX_RUNTIME_SINCE_ENGINE_START = 0x7
+DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 0x8
+DIAGNOSTICINTEGERSENSORINDEX_WARMUPS_SINCE_CODES_CLEARED = 0x9
+DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 0xa
+DIAGNOSTICINTEGERSENSORINDEX_ABSOLUTE_BAROMETRIC_PRESSURE = 0xb
+DIAGNOSTICINTEGERSENSORINDEX_CONTROL_MODULE_VOLTAGE = 0xc
+DIAGNOSTICINTEGERSENSORINDEX_AMBIENT_AIR_TEMPERATURE = 0xd
+DIAGNOSTICINTEGERSENSORINDEX_TIME_WITH_MALFUNCTION_LIGHT_ON = 0xe
+DIAGNOSTICINTEGERSENSORINDEX_TIME_SINCE_TROUBLE_CODES_CLEARED = 0xf
+DIAGNOSTICINTEGERSENSORINDEX_MAX_FUEL_AIR_EQUIVALENCE_RATIO = 0x10
+DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_VOLTAGE = 0x11
+DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_CURRENT = 0x12
+DIAGNOSTICINTEGERSENSORINDEX_MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 0x13
+DIAGNOSTICINTEGERSENSORINDEX_MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 0x14
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_TYPE = 0x15
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_RAIL_ABSOLUTE_PRESSURE = 0x16
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_OIL_TEMPERATURE = 0x17
+DIAGNOSTICINTEGERSENSORINDEX_DRIVER_DEMAND_PERCENT_TORQUE = 0x18
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_ACTUAL_PERCENT_TORQUE = 0x19
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_REFERENCE_PERCENT_TORQUE = 0x1a
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_IDLE = 0x1b
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT1 = 0x1c
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT2 = 0x1d
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT3 = 0x1e
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT4 = 0x1f
+DIAGNOSTICINTEGERSENSORINDEX_LAST_SYSTEM_INDEX = 0x1f
# DiagnosticFloatSensorIndex
DIAGNOSTICFLOATSENSORINDEX_CALCULATED_ENGINE_LOAD = 0x0
@@ -644,19 +661,116 @@
DIAGNOSTICFLOATSENSORINDEX_ENGINE_FUEL_RATE = 0x46
DIAGNOSTICFLOATSENSORINDEX_LAST_SYSTEM_INDEX = 0x46
-# VehicleArea
-VEHICLEAREA_GLOBAL = 0x1000000
-VEHICLEAREA_WINDOW = 0x3000000
-VEHICLEAREA_MIRROR = 0x4000000
-VEHICLEAREA_SEAT = 0x5000000
-VEHICLEAREA_DOOR = 0x6000000
-VEHICLEAREA_WHEEL = 0x7000000
-VEHICLEAREA_MASK = 0xf000000
+# VmsMessageType
+VMSMESSAGETYPE_SUBSCRIBE = 0x1
+VMSMESSAGETYPE_SUBSCRIBE_TO_PUBLISHER = 0x2
+VMSMESSAGETYPE_UNSUBSCRIBE = 0x3
+VMSMESSAGETYPE_UNSUBSCRIBE_TO_PUBLISHER = 0x4
+VMSMESSAGETYPE_OFFERING = 0x5
+VMSMESSAGETYPE_AVAILABILITY_REQUEST = 0x6
+VMSMESSAGETYPE_SUBSCRIPTIONS_REQUEST = 0x7
+VMSMESSAGETYPE_AVAILABILITY_RESPONSE = 0x8
+VMSMESSAGETYPE_AVAILABILITY_CHANGE = 0x9
+VMSMESSAGETYPE_SUBSCRIPTIONS_RESPONSE = 0xa
+VMSMESSAGETYPE_SUBSCRIPTIONS_CHANGE = 0xb
+VMSMESSAGETYPE_DATA = 0xc
+VMSMESSAGETYPE_PUBLISHER_ID_REQUEST = 0xd
+VMSMESSAGETYPE_PUBLISHER_ID_RESPONSE = 0xe
+VMSMESSAGETYPE_PUBLISHER_INFORMATION_REQUEST = 0xf
+VMSMESSAGETYPE_PUBLISHER_INFORMATION_RESPONSE = 0x10
+VMSMESSAGETYPE_START_SESSION = 0x11
+VMSMESSAGETYPE_LAST_VMS_MESSAGE_TYPE = 0x11
-# VehiclePropertyStatus
-VEHICLEPROPERTYSTATUS_AVAILABLE = 0x0
-VEHICLEPROPERTYSTATUS_UNAVAILABLE = 0x1
-VEHICLEPROPERTYSTATUS_ERROR = 0x2
+# VmsBaseMessageIntegerValuesIndex
+VMSBASEMESSAGEINTEGERVALUESINDEX_MESSAGE_TYPE = 0x0
+
+# VmsStartSessionMessageIntegerValuesIndex
+VMSSTARTSESSIONMESSAGEINTEGERVALUESINDEX_SERVICE_ID = 0x1
+VMSSTARTSESSIONMESSAGEINTEGERVALUESINDEX_CLIENT_ID = 0x2
+
+# VmsMessageWithLayerIntegerValuesIndex
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_TYPE = 0x1
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_SUBTYPE = 0x2
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_VERSION = 0x3
+
+# VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
+VMSMESSAGEWITHLAYERANDPUBLISHERIDINTEGERVALUESINDEX_PUBLISHER_ID = 0x4
+
+# VmsOfferingMessageIntegerValuesIndex
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_NUMBER_OF_OFFERS = 0x2
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_OFFERING_START = 0x3
+
+# VmsSubscriptionsStateIntegerValuesIndex
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_LAYERS = 0x2
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x3
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SUBSCRIPTIONS_START = 0x4
+
+# VmsAvailabilityStateIntegerValuesIndex
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x2
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_LAYERS_START = 0x3
+
+# VmsPublisherInformationIntegerValuesIndex
+VMSPUBLISHERINFORMATIONINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
+
+# UserFlags
+USERFLAGS_NONE = 0x0
+USERFLAGS_SYSTEM = 0x1
+USERFLAGS_GUEST = 0x2
+USERFLAGS_EPHEMERAL = 0x4
+USERFLAGS_ADMIN = 0x8
+USERFLAGS_DISABLED = 0x10
+USERFLAGS_PROFILE = 0x20
+
+# InitialUserInfoRequestType
+INITIALUSERINFOREQUESTTYPE_FIRST_BOOT = 0x1
+INITIALUSERINFOREQUESTTYPE_FIRST_BOOT_AFTER_OTA = 0x2
+INITIALUSERINFOREQUESTTYPE_COLD_BOOT = 0x3
+INITIALUSERINFOREQUESTTYPE_RESUME = 0x4
+
+# InitialUserInfoResponseAction
+INITIALUSERINFORESPONSEACTION_DEFAULT = 0x0
+INITIALUSERINFORESPONSEACTION_SWITCH = 0x1
+INITIALUSERINFORESPONSEACTION_CREATE = 0x2
+
+# SwitchUserMessageType
+SWITCHUSERMESSAGETYPE_LEGACY_ANDROID_SWITCH = 0x1
+SWITCHUSERMESSAGETYPE_ANDROID_SWITCH = 0x2
+SWITCHUSERMESSAGETYPE_VEHICLE_RESPONSE = 0x3
+SWITCHUSERMESSAGETYPE_VEHICLE_REQUEST = 0x4
+SWITCHUSERMESSAGETYPE_ANDROID_POST_SWITCH = 0x5
+
+# SwitchUserStatus
+SWITCHUSERSTATUS_SUCCESS = 0x1
+SWITCHUSERSTATUS_FAILURE = 0x2
+
+# CreateUserStatus
+CREATEUSERSTATUS_SUCCESS = 0x1
+CREATEUSERSTATUS_FAILURE = 0x2
+
+# UserIdentificationAssociationType
+USERIDENTIFICATIONASSOCIATIONTYPE_KEY_FOB = 0x1
+USERIDENTIFICATIONASSOCIATIONTYPE_CUSTOM_1 = 0x65
+USERIDENTIFICATIONASSOCIATIONTYPE_CUSTOM_2 = 0x66
+USERIDENTIFICATIONASSOCIATIONTYPE_CUSTOM_3 = 0x67
+USERIDENTIFICATIONASSOCIATIONTYPE_CUSTOM_4 = 0x68
+
+# UserIdentificationAssociationValue
+USERIDENTIFICATIONASSOCIATIONVALUE_UNKNOWN = 0x1
+USERIDENTIFICATIONASSOCIATIONVALUE_ASSOCIATED_CURRENT_USER = 0x2
+USERIDENTIFICATIONASSOCIATIONVALUE_ASSOCIATED_ANOTHER_USER = 0x3
+USERIDENTIFICATIONASSOCIATIONVALUE_NOT_ASSOCIATED_ANY_USER = 0x4
+
+# UserIdentificationAssociationSetValue
+USERIDENTIFICATIONASSOCIATIONSETVALUE_ASSOCIATE_CURRENT_USER = 0x1
+USERIDENTIFICATIONASSOCIATIONSETVALUE_DISASSOCIATE_CURRENT_USER = 0x2
+USERIDENTIFICATIONASSOCIATIONSETVALUE_DISASSOCIATE_ALL_USERS = 0x3
+
+# RotaryInputType
+ROTARYINPUTTYPE_ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION = 0x0
+ROTARYINPUTTYPE_ROTARY_INPUT_TYPE_AUDIO_VOLUME = 0x1
# Create a container of value_type constants to be used by vhal_emulator
class vhal_types_2_0:
diff --git a/tools/emulator/vhal_emulator_test.py b/tools/emulator/vhal_emulator_test.py
index 6c56a1a..db17262 100755
--- a/tools/emulator/vhal_emulator_test.py
+++ b/tools/emulator/vhal_emulator_test.py
@@ -125,6 +125,12 @@
# Truncate float to 5 decimal places
value = "%.5f" % value
value = float(value)
+ elif valType in self._types.TYPE_MIXED:
+ # Quick stub to unblock most tests
+ # Todo: proper implement according to VehiclePropertyType in types.hal
+ value = rxMsg.value[0].float_values[0]
+ value = "%.5f" % value
+ value = float(value)
else:
self._log.error("getValueFromMsg: valType=0x%X is not handled", valType)
value = None
diff --git a/tools/hidl_parser/parser.py b/tools/hidl_parser/parser.py
index 6ef19d5..c660cdb 100644
--- a/tools/hidl_parser/parser.py
+++ b/tools/hidl_parser/parser.py
@@ -29,14 +29,14 @@
import ply
-tokens = ('package', 'import', 'enum', 'struct',
+tokens = ('package', 'import', 'enum', 'struct', 'typedef',
'COLON', 'IDENTIFIER', 'COMMENT', 'NUMBER', 'HEX', 'OR', 'EQUALS',
'LPAREN', 'RPAREN', 'LBRACE', 'RBRACE', 'DOT', 'SEMICOLON', 'VERSION',
'COMMA', 'SHIFT', 'LESSTHAN', 'GREATERTHAN')
t_COLON = r':'
t_NUMBER = r'[0-9]+'
-t_HEX = r'0x[0-9A-Fa-f]+'
+t_HEX = r'0[x|X][0-9A-Fa-f]+'
t_OR = r'\|'
t_EQUALS = r'='
t_LPAREN = r'\('
@@ -67,6 +67,8 @@
t.type = 'enum'
elif t.value == 'struct':
t.type = 'struct'
+ elif t.value == 'typedef':
+ t.type = 'typedef'
return t
def t_error(t):
@@ -111,6 +113,13 @@
def __str__(self):
return 'struct %s' % self.name
+class TypedefHeader(object):
+ def __init__(self, name):
+ self.name = name
+
+ def __str__(self):
+ return 'typedef %s' % self.name
+
class EnumDecl(object):
def __init__(self, header, cases):
self.header = header
@@ -150,6 +159,18 @@
def __repr__(self):
return self.__str__()
+class TypedefDecl(object):
+ def __init__(self, header, name):
+ self.header = header
+ self.name = name
+
+ def __str__(self):
+ return '%s {\n%s\n}' % (self.header,
+ self.name)
+
+ def __repr__(self):
+ return self.__str__()
+
class StructElement(object):
pass
@@ -220,7 +241,7 @@
return self.value
def resolve(self, enum, document):
- if self.value.startswith("0x"):
+ if self.value.lower().startswith("0x"):
return int(self.value, 16)
else:
return int(self.value, 10)
@@ -284,6 +305,14 @@
enum = document['enums'][self.where]
return EnumValueLocalRef(self.ref).resolve(enum, document)
+class Typedef(object):
+ def __init__(self, header, name):
+ self.header = header
+ self.name = name
+
+ def __str__(self):
+ return 'typedef %s %s' % (self.typename, self.name)
+
# Error rule for syntax errors
def p_error(p):
print("Syntax error in input: %s" % p)
@@ -297,13 +326,18 @@
'document : header type_decls'
enums = {}
structs = {}
+ typedefs = {}
for enum in t[2]:
if not isinstance(enum, EnumDecl): continue
enums[enum.header.name] = enum
for struct in t[2]:
if not isinstance(struct, StructDecl): continue
structs[struct.header.name] = struct
- t[0] = {'header' : t[1], 'enums' : enums, 'structs' : structs}
+ for typedef in t[2]:
+ if not isinstance(typedef, TypedefDecl): continue
+ typedefs[typedef.header.name] = typedef
+
+ t[0] = {'header' : t[1], 'enums' : enums, 'structs' : structs, 'typedefs' : typedef}
def p_type_decls_1(t):
'type_decls : type_decl'
@@ -318,6 +352,9 @@
def p_type_decl_s(t):
'type_decl : struct_decl'
t[0] = t[1]
+def p_type_decl_t(t):
+ 'type_decl : typedef_decl'
+ t[0] = t[1]
def p_enum_cases_1(t):
'enum_cases : enum_case'
@@ -340,6 +377,10 @@
'enum_base : IDENTIFIER'
t[0] = t[1]
+def p_typedef_name(t):
+ 'typedef_name : IDENTIFIER'
+ t[0] = t[1]
+
def p_struct_header(t):
'struct_header : struct IDENTIFIER'
t[0] = StructHeader(t[2])
@@ -351,6 +392,10 @@
'enum_header : enum IDENTIFIER COLON enum_base'
t[0] = EnumHeader(t[2], t[4])
+def p_typedef_header(t):
+ 'typedef_header : typedef IDENTIFIER'
+ t[0] = TypedefHeader(t[2])
+
def p_struct_decl(t):
'struct_decl : struct_header LBRACE struct_elements RBRACE SEMICOLON'
t[0] = StructDecl(t[1], t[3])
@@ -362,6 +407,10 @@
'enum_decl : enum_header LBRACE enum_cases COMMA RBRACE SEMICOLON'
t[0] = EnumDecl(t[1], t[3])
+def p_typedef_decl(t):
+ 'typedef_decl : typedef_header typedef_name SEMICOLON'
+ t[0] = TypedefDecl(t[1], t[2])
+
def p_enum_value_1(t):
'''enum_value : NUMBER
| HEX'''
@@ -442,6 +491,8 @@
class SilentLogger(object):
def warning(*args):
pass
+ def error(*args):
+ print(args)
import ply.yacc as yacc
parser = yacc.yacc(debug=False, write_tables=False, errorlog=SilentLogger())
diff --git a/user/car-user-lib/Android.bp b/user/car-user-lib/Android.bp
index 12bc950..5fc5efc 100644
--- a/user/car-user-lib/Android.bp
+++ b/user/car-user-lib/Android.bp
@@ -17,9 +17,9 @@
srcs: [
"src/**/*.java",
],
- static_libs: [
- "android.car.settings",
+ libs: [
"android.hardware.automotive.vehicle-V2.0-java",
+ "android.car.settings",
],
product_variables: {
pdk: {
diff --git a/user/car-user-lib/src/android/car/userlib/InitialUserSetter.java b/user/car-user-lib/src/android/car/userlib/InitialUserSetter.java
index 10b642b..aea4f3d 100644
--- a/user/car-user-lib/src/android/car/userlib/InitialUserSetter.java
+++ b/user/car-user-lib/src/android/car/userlib/InitialUserSetter.java
@@ -89,10 +89,18 @@
*/
public static final int TYPE_CREATE = 2;
+ /**
+ * Creates a new guest user and switches to it, if current user is unlocked guest user.
+ * Does not fallback if any of these steps fails. falling back to
+ * {@link #fallbackDefaultBehavior(String) if any of these steps fails
+ */
+ public static final int TYPE_REPLACE_GUEST = 3;
+
@IntDef(prefix = { "TYPE_" }, value = {
TYPE_DEFAULT_BEHAVIOR,
TYPE_SWITCH,
TYPE_CREATE,
+ TYPE_REPLACE_GUEST
})
@Retention(RetentionPolicy.SOURCE)
public @interface InitialUserInfoType { }
@@ -153,12 +161,11 @@
* Constructor for the given type.
*
* @param type {@link #TYPE_DEFAULT_BEHAVIOR}, {@link #TYPE_SWITCH},
- * or {@link #TYPE_CREATE}.
+ * {@link #TYPE_CREATE} or {@link #TYPE_REPLACE_GUEST}.
*/
public Builder(@InitialUserInfoType int type) {
- Preconditions.checkArgument(
- type == TYPE_DEFAULT_BEHAVIOR || type == TYPE_SWITCH || type == TYPE_CREATE,
- "invalid builder type");
+ Preconditions.checkArgument(type == TYPE_DEFAULT_BEHAVIOR || type == TYPE_SWITCH
+ || type == TYPE_CREATE || type == TYPE_REPLACE_GUEST, "invalid builder type");
mType = type;
}
@@ -289,11 +296,42 @@
+ e);
}
break;
+ case TYPE_REPLACE_GUEST:
+ try {
+ replaceUser(info, /* fallback= */ true);
+ } catch (Exception e) {
+ fallbackDefaultBehavior(info, /* fallback= */ true,
+ "Exception replace guest user: " + e);
+ }
+ break;
default:
throw new IllegalArgumentException("invalid InitialUserInfo type: " + info.type);
}
}
+ private void replaceUser(InitialUserInfo info, boolean fallback) {
+ int currentUserId = ActivityManager.getCurrentUser();
+ UserInfo currentUser = mUm.getUserInfo(currentUserId);
+
+ UserInfo newUser = replaceGuestIfNeeded(currentUser);
+ if (newUser == null) {
+ fallbackDefaultBehavior(info, fallback,
+ "could not replace guest " + currentUser.toFullString());
+ return;
+ }
+
+ switchUser(new Builder(TYPE_SWITCH)
+ .setSwitchUserId(newUser.id)
+ .build(), fallback);
+
+ if (newUser.id != currentUser.id) {
+ Slog.i(TAG, "Removing old guest " + currentUser.id);
+ if (!mUm.removeUser(currentUser.id)) {
+ Slog.w(TAG, "Could not remove old guest " + currentUser.id);
+ }
+ }
+ }
+
private void executeDefaultBehavior(@NonNull InitialUserInfo info, boolean fallback) {
if (!mHelper.hasInitialUser()) {
if (DBG) Log.d(TAG, "executeDefaultBehavior(): no initial user, creating it");
@@ -385,6 +423,23 @@
}
}
+ /**
+ * Check if the user is a guest and can be replaced.
+ */
+ public boolean canReplaceGuestUser(UserInfo user) {
+ if (!user.isGuest()) return false;
+
+ if (mLockPatternUtils.isSecure(user.id)) {
+ if (DBG) {
+ Log.d(TAG, "replaceGuestIfNeeded(), skipped, since user "
+ + user.id + " has secure lock pattern");
+ }
+ return false;
+ }
+
+ return true;
+ }
+
// TODO(b/151758646): move to CarUserManagerHelper
/**
* Replaces {@code user} by a new guest, if necessary.
@@ -394,17 +449,13 @@
* <p>Otherwise, it marks the current guest for deletion, creates a new one, and returns the
* new guest (or {@code null} if a new guest could not be created).
*/
+
+ @VisibleForTesting
@Nullable
- public UserInfo replaceGuestIfNeeded(@NonNull UserInfo user) {
+ UserInfo replaceGuestIfNeeded(@NonNull UserInfo user) {
Preconditions.checkArgument(user != null, "user cannot be null");
- if (!user.isGuest()) return user;
-
- if (mLockPatternUtils.isSecure(user.id)) {
- if (DBG) {
- Log.d(TAG, "replaceGuestIfNeeded(), skipped, since user "
- + user.id + " has secure lock pattern");
- }
+ if (!canReplaceGuestUser(user)) {
return user;
}
diff --git a/user/car-user-lib/src/android/car/userlib/UserHelper.java b/user/car-user-lib/src/android/car/userlib/UserHelper.java
index 9535ffb..ba3d679 100644
--- a/user/car-user-lib/src/android/car/userlib/UserHelper.java
+++ b/user/car-user-lib/src/android/car/userlib/UserHelper.java
@@ -15,16 +15,34 @@
*/
package android.car.userlib;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
import android.os.UserHandle;
import android.os.UserManager;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.UserIcons;
+
+import com.google.android.collect.Sets;
+
+import java.util.Set;
+
/**
* Provides utility methods for generic user-related functionalities that don't require a manager.
*/
public final class UserHelper {
+ /**
+ * Default set of restrictions for Non-Admin users.
+ */
+ private static final Set<String> DEFAULT_NON_ADMIN_RESTRICTIONS = Sets.newArraySet(
+ UserManager.DISALLOW_FACTORY_RESET
+ );
+
private UserHelper() {
throw new UnsupportedOperationException("contains only static methods");
}
@@ -43,4 +61,41 @@
public static boolean isHeadlessSystemUser(@UserIdInt int userId) {
return userId == UserHandle.USER_SYSTEM && UserManager.isHeadlessSystemUserMode();
}
+
+ /**
+ * Sets the values of default Non-Admin restrictions to the passed in value.
+ *
+ * @param context Current application context
+ * @param user User to set restrictions on.
+ * @param enable If true, restriction is ON, If false, restriction is OFF.
+ */
+ public static void setDefaultNonAdminRestrictions(@NonNull Context context,
+ @NonNull UserInfo user, boolean enable) {
+ Preconditions.checkArgument(context != null, "Context cannot be null");
+ Preconditions.checkArgument(user != null, "User cannot be null");
+
+ UserManager userManager = UserManager.get(context);
+ for (String restriction : DEFAULT_NON_ADMIN_RESTRICTIONS) {
+ userManager.setUserRestriction(restriction, enable, user.getUserHandle());
+ }
+ }
+
+ /**
+ * Assigns a default icon to a user according to the user's id.
+ *
+ * @param context Current application context
+ * @param user User whose avatar is set to default icon.
+ * @return Bitmap of the user icon.
+ */
+ @NonNull
+ public static Bitmap assignDefaultIcon(@NonNull Context context, @NonNull UserInfo user) {
+ Preconditions.checkArgument(context != null, "Context cannot be null");
+ Preconditions.checkArgument(user != null, "User cannot be null");
+
+ int idForIcon = user.isGuest() ? UserHandle.USER_NULL : user.id;
+ Bitmap bitmap = UserIcons.convertToBitmap(
+ UserIcons.getDefaultUserIcon(context.getResources(), idForIcon, false));
+ UserManager.get(context).setUserIcon(user.id, bitmap);
+ return bitmap;
+ }
}
diff --git a/watchdog/server/src/IoPerfCollection.cpp b/watchdog/server/src/IoPerfCollection.cpp
index 2799417..bb7b04d 100644
--- a/watchdog/server/src/IoPerfCollection.cpp
+++ b/watchdog/server/src/IoPerfCollection.cpp
@@ -414,13 +414,9 @@
return {};
}
-Result<void> IoPerfCollection::dump(int fd, const Vector<String16>& args) {
+Result<void> IoPerfCollection::onCustomCollection(int fd, const Vector<String16>& args) {
if (args.empty()) {
- const auto& ret = dumpCollection(fd);
- if (!ret) {
- return ret;
- }
- return {};
+ return Error(BAD_VALUE) << "No I/O perf collection dump arguments";
}
if (args[0] == String16(kStartCustomCollectionFlag)) {
@@ -494,26 +490,7 @@
<< kEndCustomCollectionFlag << " flags";
}
-bool IoPerfCollection::dumpHelpText(int fd) {
- long periodicCacheMinutes =
- (std::chrono::duration_cast<std::chrono::seconds>(mPeriodicCollection.interval)
- .count() *
- mPeriodicCollection.maxCacheSize) /
- 60;
- return WriteStringToFd(StringPrintf(kHelpText, kStartCustomCollectionFlag, kIntervalFlag,
- std::chrono::duration_cast<std::chrono::seconds>(
- kCustomCollectionInterval)
- .count(),
- kMaxDurationFlag,
- std::chrono::duration_cast<std::chrono::minutes>(
- kCustomCollectionDuration)
- .count(),
- kFilterPackagesFlag, mTopNStatsPerCategory,
- kEndCustomCollectionFlag, periodicCacheMinutes),
- fd);
-}
-
-Result<void> IoPerfCollection::dumpCollection(int fd) {
+Result<void> IoPerfCollection::onDump(int fd) {
Mutex::Autolock lock(mMutex);
if (mCurrCollectionEvent == CollectionEvent::TERMINATED) {
ALOGW("I/O performance data collection not active. Dumping cached data");
@@ -545,6 +522,25 @@
return {};
}
+bool IoPerfCollection::dumpHelpText(int fd) {
+ long periodicCacheMinutes =
+ (std::chrono::duration_cast<std::chrono::seconds>(mPeriodicCollection.interval)
+ .count() *
+ mPeriodicCollection.maxCacheSize) /
+ 60;
+ return WriteStringToFd(StringPrintf(kHelpText, kStartCustomCollectionFlag, kIntervalFlag,
+ std::chrono::duration_cast<std::chrono::seconds>(
+ kCustomCollectionInterval)
+ .count(),
+ kMaxDurationFlag,
+ std::chrono::duration_cast<std::chrono::minutes>(
+ kCustomCollectionDuration)
+ .count(),
+ kFilterPackagesFlag, mTopNStatsPerCategory,
+ kEndCustomCollectionFlag, periodicCacheMinutes),
+ fd);
+}
+
Result<void> IoPerfCollection::dumpCollectorsStatusLocked(int fd) {
if (!mUidIoStats->enabled() &&
!WriteStringToFd(StringPrintf("UidIoStats collector failed to access the file %s",
diff --git a/watchdog/server/src/IoPerfCollection.h b/watchdog/server/src/IoPerfCollection.h
index 4cccb05..d516216 100644
--- a/watchdog/server/src/IoPerfCollection.h
+++ b/watchdog/server/src/IoPerfCollection.h
@@ -184,19 +184,18 @@
virtual android::base::Result<void> onBootFinished();
// Depending the arguments, it either:
- // 1. Generates a dump from the boot-time and periodic collection events.
- // 2. Starts custom collection.
- // 3. Ends custom collection and dumps the collected data.
+ // 1. Starts custom collection.
+ // 2. Ends custom collection and dumps the collected data.
// Returns any error observed during the dump generation.
- virtual android::base::Result<void> dump(int fd, const Vector<String16>& args);
+ virtual android::base::Result<void> onCustomCollection(int fd, const Vector<String16>& args);
+
+ // Generates a dump from the boot-time and periodic collection events.
+ virtual android::base::Result<void> onDump(int fd);
// Dumps the help text.
bool dumpHelpText(int fd);
private:
- // Generates a dump from the boot-time and periodic collection events.
- android::base::Result<void> dumpCollection(int fd);
-
// Dumps the collectors' status when they are disabled.
android::base::Result<void> dumpCollectorsStatusLocked(int fd);
diff --git a/watchdog/server/src/WatchdogBinderMediator.cpp b/watchdog/server/src/WatchdogBinderMediator.cpp
index 0a482fd..fd0dd8e 100644
--- a/watchdog/server/src/WatchdogBinderMediator.cpp
+++ b/watchdog/server/src/WatchdogBinderMediator.cpp
@@ -21,6 +21,7 @@
#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <android/automotive/watchdog/BootPhase.h>
#include <android/automotive/watchdog/PowerCycle.h>
#include <android/automotive/watchdog/UserState.h>
@@ -36,6 +37,7 @@
using android::defaultServiceManager;
using android::base::Error;
+using android::base::Join;
using android::base::ParseUint;
using android::base::Result;
using android::base::StringPrintf;
@@ -52,7 +54,7 @@
"%s or %s: Displays this help text.\n"
"When no options are specified, carwatchdog report is generated.\n";
-Status checkSystemPermission() {
+Status checkSystemUser() {
if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
return Status::fromExceptionCode(Status::EX_SECURITY,
"Calling process does not have proper privilege");
@@ -91,31 +93,18 @@
}
status_t WatchdogBinderMediator::dump(int fd, const Vector<String16>& args) {
- if (args.empty()) {
- auto ret = mWatchdogProcessService->dump(fd, args);
- if (!ret.ok()) {
- ALOGW("Failed to dump carwatchdog process service: %s", ret.error().message().c_str());
- return ret.error().code();
- }
- ret = mIoPerfCollection->dump(fd, args);
- if (!ret.ok()) {
- ALOGW("Failed to dump I/O perf collection: %s", ret.error().message().c_str());
- return ret.error().code();
- }
- return OK;
- }
-
- if (args[0] == String16(kHelpFlag) || args[0] == String16(kHelpShortFlag)) {
+ int numArgs = args.size();
+ if (numArgs == 1 && (args[0] == String16(kHelpFlag) || args[0] == String16(kHelpShortFlag))) {
if (!dumpHelpText(fd, "")) {
ALOGW("Failed to write help text to fd");
return FAILED_TRANSACTION;
}
return OK;
}
-
- if (args[0] == String16(kStartCustomCollectionFlag) ||
- args[0] == String16(kEndCustomCollectionFlag)) {
- auto ret = mIoPerfCollection->dump(fd, args);
+ if (numArgs >= 1 &&
+ (args[0] == String16(kStartCustomCollectionFlag) ||
+ args[0] == String16(kEndCustomCollectionFlag))) {
+ auto ret = mIoPerfCollection->onCustomCollection(fd, args);
if (!ret.ok()) {
std::string mode = args[0] == String16(kStartCustomCollectionFlag) ? "start" : "end";
std::string errorMsg = StringPrintf("Failed to %s custom I/O perf collection: %s",
@@ -129,8 +118,23 @@
}
return OK;
}
- dumpHelpText(fd, "Invalid dump arguments");
- return INVALID_OPERATION;
+
+ if (numArgs > 0) {
+ ALOGW("Car watchdog cannot recognize the given option(%s). Dumping the current state...",
+ Join(args, " ").c_str());
+ }
+
+ auto ret = mWatchdogProcessService->dump(fd, args);
+ if (!ret.ok()) {
+ ALOGW("Failed to dump carwatchdog process service: %s", ret.error().message().c_str());
+ return ret.error().code();
+ }
+ ret = mIoPerfCollection->onDump(fd);
+ if (!ret.ok()) {
+ ALOGW("Failed to dump I/O perf collection: %s", ret.error().message().c_str());
+ return ret.error().code();
+ }
+ return OK;
}
bool WatchdogBinderMediator::dumpHelpText(int fd, std::string errorMsg) {
@@ -147,7 +151,7 @@
}
Status WatchdogBinderMediator::registerMediator(const sp<ICarWatchdogClient>& mediator) {
- Status status = checkSystemPermission();
+ Status status = checkSystemUser();
if (!status.isOk()) {
return status;
}
@@ -155,29 +159,47 @@
}
Status WatchdogBinderMediator::unregisterMediator(const sp<ICarWatchdogClient>& mediator) {
- Status status = checkSystemPermission();
+ Status status = checkSystemUser();
if (!status.isOk()) {
return status;
}
return mWatchdogProcessService->unregisterMediator(mediator);
}
Status WatchdogBinderMediator::registerMonitor(const sp<ICarWatchdogMonitor>& monitor) {
- Status status = checkSystemPermission();
+ Status status = checkSystemUser();
if (!status.isOk()) {
return status;
}
return mWatchdogProcessService->registerMonitor(monitor);
}
Status WatchdogBinderMediator::unregisterMonitor(const sp<ICarWatchdogMonitor>& monitor) {
- Status status = checkSystemPermission();
+ Status status = checkSystemUser();
if (!status.isOk()) {
return status;
}
return mWatchdogProcessService->unregisterMonitor(monitor);
}
+Status WatchdogBinderMediator::tellMediatorAlive(const sp<ICarWatchdogClient>& mediator,
+ const std::vector<int32_t>& clientsNotResponding,
+ int32_t sessionId) {
+ Status status = checkSystemUser();
+ if (!status.isOk()) {
+ return status;
+ }
+ return mWatchdogProcessService->tellMediatorAlive(mediator, clientsNotResponding, sessionId);
+}
+Status WatchdogBinderMediator::tellDumpFinished(const android::sp<ICarWatchdogMonitor>& monitor,
+ int32_t pid) {
+ Status status = checkSystemUser();
+ if (!status.isOk()) {
+ return status;
+ }
+ return mWatchdogProcessService->tellDumpFinished(monitor, pid);
+}
+
Status WatchdogBinderMediator::notifySystemStateChange(StateType type, int32_t arg1, int32_t arg2) {
- Status status = checkSystemPermission();
+ Status status = checkSystemUser();
if (!status.isOk()) {
return status;
}
diff --git a/watchdog/server/src/WatchdogBinderMediator.h b/watchdog/server/src/WatchdogBinderMediator.h
index 530659b..dbc26a3 100644
--- a/watchdog/server/src/WatchdogBinderMediator.h
+++ b/watchdog/server/src/WatchdogBinderMediator.h
@@ -61,14 +61,9 @@
}
binder::Status tellMediatorAlive(const sp<ICarWatchdogClient>& mediator,
const std::vector<int32_t>& clientsNotResponding,
- int32_t sessionId) override {
- return mWatchdogProcessService->tellMediatorAlive(mediator, clientsNotResponding,
- sessionId);
- }
+ int32_t sessionId) override;
binder::Status tellDumpFinished(const android::sp<ICarWatchdogMonitor>& monitor,
- int32_t pid) override {
- return mWatchdogProcessService->tellDumpFinished(monitor, pid);
- }
+ int32_t pid) override;
binder::Status notifySystemStateChange(StateType type, int32_t arg1, int32_t arg2) override;
protected:
diff --git a/watchdog/server/tests/IoPerfCollectionTest.cpp b/watchdog/server/tests/IoPerfCollectionTest.cpp
index 82287bf..9b46e0d 100644
--- a/watchdog/server/tests/IoPerfCollectionTest.cpp
+++ b/watchdog/server/tests/IoPerfCollectionTest.cpp
@@ -556,7 +556,7 @@
args.push_back(String16(kMaxDurationFlag));
args.push_back(String16(std::to_string(kTestCustomCollectionDuration.count()).c_str()));
- ret = collector->dump(-1, args);
+ ret = collector->onCustomCollection(-1, args);
ASSERT_TRUE(ret.ok()) << ret.error().message();
uidIoStatsStub->push({
{1009, {.uid = 1009, .ios = {0, 13000, 0, 15000, 0, 100}}},
@@ -691,7 +691,7 @@
args.clear();
args.push_back(String16(kEndCustomCollectionFlag));
TemporaryFile customDump;
- ret = collector->dump(customDump.fd, args);
+ ret = collector->onCustomCollection(customDump.fd, args);
ASSERT_TRUE(ret.ok()) << ret.error().message();
ret = looperStub->pollCache();
ASSERT_TRUE(ret) << ret.error().message();
@@ -773,7 +773,7 @@
<< "Boot-time records not persisted until collector termination";
TemporaryFile bugreportDump;
- ret = collector->dump(bugreportDump.fd, {});
+ ret = collector->onDump(bugreportDump.fd);
ASSERT_TRUE(ret.ok()) << ret.error().message();
collector->terminate();
@@ -869,7 +869,7 @@
args.push_back(String16(kFilterPackagesFlag));
args.push_back(String16("android.car.cts,system_server"));
- ret = collector->dump(-1, args);
+ ret = collector->onCustomCollection(-1, args);
ASSERT_TRUE(ret.ok()) << ret.error().message();
// Custom collection
@@ -1028,7 +1028,7 @@
args.push_back(String16(kMaxDurationFlag));
args.push_back(String16(std::to_string(kTestCustomCollectionDuration.count()).c_str()));
- ret = collector->dump(-1, args);
+ ret = collector->onCustomCollection(-1, args);
ASSERT_TRUE(ret.ok()) << ret.error().message();
// Maximum custom collection iterations during |kTestCustomCollectionDuration|.
int maxIterations =
@@ -1493,29 +1493,29 @@
args.push_back(String16(kStartCustomCollectionFlag));
args.push_back(String16("Invalid flag"));
args.push_back(String16("Invalid value"));
- ASSERT_FALSE(collector->dump(-1, args).ok());
+ ASSERT_FALSE(collector->onCustomCollection(-1, args).ok());
args.clear();
args.push_back(String16(kStartCustomCollectionFlag));
args.push_back(String16(kIntervalFlag));
args.push_back(String16("Invalid interval"));
- ASSERT_FALSE(collector->dump(-1, args).ok());
+ ASSERT_FALSE(collector->onCustomCollection(-1, args).ok());
args.clear();
args.push_back(String16(kStartCustomCollectionFlag));
args.push_back(String16(kMaxDurationFlag));
args.push_back(String16("Invalid duration"));
- ASSERT_FALSE(collector->dump(-1, args).ok());
+ ASSERT_FALSE(collector->onCustomCollection(-1, args).ok());
args.clear();
args.push_back(String16(kEndCustomCollectionFlag));
args.push_back(String16(kMaxDurationFlag));
args.push_back(String16(std::to_string(kTestCustomCollectionDuration.count()).c_str()));
- ASSERT_FALSE(collector->dump(-1, args).ok());
+ ASSERT_FALSE(collector->onCustomCollection(-1, args).ok());
args.clear();
args.push_back(String16("Invalid flag"));
- ASSERT_FALSE(collector->dump(-1, args).ok());
+ ASSERT_FALSE(collector->onCustomCollection(-1, args).ok());
collector->terminate();
}
diff --git a/watchdog/server/tests/WatchdogBinderMediatorTest.cpp b/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
index 0d1cf05..7e44893 100644
--- a/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
+++ b/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
@@ -69,7 +69,9 @@
public:
MockIoPerfCollection() {}
MOCK_METHOD(Result<void>, onBootFinished, (), (override));
- MOCK_METHOD(Result<void>, dump, (int fd, const Vector<String16>& args), (override));
+ MOCK_METHOD(Result<void>, onCustomCollection, (int fd, const Vector<String16>& args),
+ (override));
+ MOCK_METHOD(Result<void>, onDump, (int fd), (override));
};
class MockICarWatchdogClient : public ICarWatchdogClient {
@@ -153,12 +155,12 @@
TEST_F(WatchdogBinderMediatorTest, TestHandlesEmptyDumpArgs) {
EXPECT_CALL(*mMockWatchdogProcessService, dump(-1, _)).WillOnce(Return(Result<void>()));
- EXPECT_CALL(*mMockIoPerfCollection, dump(-1, _)).WillOnce(Return(Result<void>()));
+ EXPECT_CALL(*mMockIoPerfCollection, onDump(-1)).WillOnce(Return(Result<void>()));
mWatchdogBinderMediator->dump(-1, Vector<String16>());
}
TEST_F(WatchdogBinderMediatorTest, TestHandlesStartCustomIoPerfCollection) {
- EXPECT_CALL(*mMockIoPerfCollection, dump(-1, _)).WillOnce(Return(Result<void>()));
+ EXPECT_CALL(*mMockIoPerfCollection, onCustomCollection(-1, _)).WillOnce(Return(Result<void>()));
Vector<String16> args;
args.push_back(String16(kStartCustomCollectionFlag));
@@ -166,7 +168,7 @@
}
TEST_F(WatchdogBinderMediatorTest, TestHandlesStopCustomIoPerfCollection) {
- EXPECT_CALL(*mMockIoPerfCollection, dump(-1, _)).WillOnce(Return(Result<void>()));
+ EXPECT_CALL(*mMockIoPerfCollection, onCustomCollection(-1, _)).WillOnce(Return(Result<void>()));
Vector<String16> args;
args.push_back(String16(kEndCustomCollectionFlag));
@@ -176,7 +178,7 @@
TEST_F(WatchdogBinderMediatorTest, TestErrorOnInvalidDumpArgs) {
Vector<String16> args;
args.push_back(String16("--invalid_option"));
- ASSERT_NE(mWatchdogBinderMediator->dump(-1, args), OK) << "No error on invalid args";
+ ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK) << "Error returned on invalid args";
}
TEST_F(WatchdogBinderMediatorTest, TestRegisterClient) {
@@ -268,7 +270,16 @@
ASSERT_TRUE(status.isOk()) << status;
}
+TEST_F(WatchdogBinderMediatorTest, TestErrorOnTellMediatorAliveWithNonSystemCallingUid) {
+ sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
+ std::vector clientsNotResponding = {123};
+ EXPECT_CALL(*mMockWatchdogProcessService, tellMediatorAlive(_, _, _)).Times(0);
+ Status status = mWatchdogBinderMediator->tellMediatorAlive(mediator, clientsNotResponding, 456);
+ ASSERT_FALSE(status.isOk()) << status;
+}
+
TEST_F(WatchdogBinderMediatorTest, TestTellMediatorAlive) {
+ setSystemCallingUid();
sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
std::vector clientsNotResponding = {123};
EXPECT_CALL(*mMockWatchdogProcessService,
@@ -278,7 +289,15 @@
ASSERT_TRUE(status.isOk()) << status;
}
+TEST_F(WatchdogBinderMediatorTest, TestErrorOnTellDumpFinishedWithNonSystemCallingUid) {
+ sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
+ EXPECT_CALL(*mMockWatchdogProcessService, tellDumpFinished(_, _)).Times(0);
+ Status status = mWatchdogBinderMediator->tellDumpFinished(monitor, 456);
+ ASSERT_FALSE(status.isOk()) << status;
+}
+
TEST_F(WatchdogBinderMediatorTest, TestTellDumpFinished) {
+ setSystemCallingUid();
sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
EXPECT_CALL(*mMockWatchdogProcessService, tellDumpFinished(monitor, 456))
.WillOnce(Return(Status::ok()));