Merge "Set forgiven bytes to default PerStateBytes object when resetting stats." into sc-v2-dev
diff --git a/car-lib/src/android/car/telemetry/CarTelemetryManager.java b/car-lib/src/android/car/telemetry/CarTelemetryManager.java
index 3c4c187..b0067b1 100644
--- a/car-lib/src/android/car/telemetry/CarTelemetryManager.java
+++ b/car-lib/src/android/car/telemetry/CarTelemetryManager.java
@@ -333,8 +333,9 @@
}
/**
- * Removes a MetricsConfig from {@link com.android.car.telemetry.CarTelemetryService}. If the
- * MetricsConfig does not exist, nothing will be removed.
+ * Removes a MetricsConfig from {@link com.android.car.telemetry.CarTelemetryService}. This
+ * will also remove outputs produced by the MetricsConfig. If the MetricsConfig does not exist,
+ * nothing will be removed.
* The status of this API is sent back asynchronously via {@link CarTelemetryResultsListener}.
*
* @param key the unique key to identify the MetricsConfig. Name and version must be exact.
@@ -351,7 +352,8 @@
}
/**
- * Removes all MetricsConfigs from {@link com.android.car.telemetry.CarTelemetryService}.
+ * Removes all MetricsConfigs from {@link com.android.car.telemetry.CarTelemetryService}. This
+ * will also remove all MetricsConfig outputs.
*
* @hide
*/
diff --git a/car-lib/src/android/car/telemetry/ICarTelemetryService.aidl b/car-lib/src/android/car/telemetry/ICarTelemetryService.aidl
index 49472f4..8343c34 100644
--- a/car-lib/src/android/car/telemetry/ICarTelemetryService.aidl
+++ b/car-lib/src/android/car/telemetry/ICarTelemetryService.aidl
@@ -26,12 +26,13 @@
void addMetricsConfig(in MetricsConfigKey key, in byte[] metricsConfig);
/**
- * Removes a MetricsConfig based on the key.
+ * Removes a MetricsConfig based on the key. This will also remove outputs produced by the
+ * MetricsConfig.
*/
void removeMetricsConfig(in MetricsConfigKey key);
/**
- * Removes all MetricsConfigs.
+ * Removes all MetricsConfigs. This will also remove all MetricsConfig outputs.
*/
void removeAllMetricsConfigs();
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml
new file mode 100644
index 0000000..721cec4
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ ~ Copyright (C) 2021 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>
+ <vector
+ android:width="@dimen/system_bar_icon_drawing_size"
+ android:height="@dimen/system_bar_icon_drawing_size"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,15.375l-6,-6 1.4,-1.4 4.6,4.6 4.6,-4.6 1.4,1.4z"
+ android:fillColor="@color/car_nav_minimize_icon_fill_color"/>
+ </vector>
+ </item>
+</selector>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
index de76f55..7c8b669 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
@@ -15,19 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
- <item android:state_activated="true">
+ <item android:state_selected="true">
<layer-list>
<item>
- <shape android:shape="rectangle">
- <size android:width="@dimen/system_bar_button_size"
- android:height="@dimen/system_bar_button_size"/>
- <corners
- android:radius="@dimen/system_bar_button_corner_radius"/>
- <solid
- android:color="@color/car_nav_icon_fill_color"/>
- </shape>
- </item>
- <item>
<ripple android:color="@color/car_ui_ripple_color">
<item>
<shape android:shape="rectangle">
@@ -36,26 +26,18 @@
<corners
android:radius="@dimen/system_bar_button_corner_radius"/>
<solid
- android:color="@color/car_nav_icon_fill_color"/>
+ android:color="?android:attr/colorAccent"/>
</shape>
</item>
</ripple>
</item>
+ <item android:drawable="@drawable/ic_minimize"
+ android:gravity="center"/>
</layer-list>
</item>
<item>
<layer-list>
<item>
- <shape android:shape="rectangle">
- <size android:width="@dimen/system_bar_button_size"
- android:height="@dimen/system_bar_button_size"/>
- <corners
- android:radius="@dimen/system_bar_button_corner_radius"/>
- <solid
- android:color="@color/car_nav_icon_background_color"/>
- </shape>
- </item>
- <item>
<ripple android:color="@color/car_ui_ripple_color">
<item>
<shape android:shape="rectangle">
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
index 557547a..69c3d30 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
@@ -52,8 +52,9 @@
android:id="@+id/grid_nav"
style="@style/SystemBarButton"
systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:highlightWhenSelected="true"
systemui:icon="@drawable/car_ic_apps"
+ systemui:highlightWhenSelected="true"
+ systemui:toggleSelected="true"
systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
systemui:clearBackStack="true"/>
@@ -61,23 +62,25 @@
android:id="@+id/standalone_notifications"
style="@style/SystemBarButton"
systemui:componentNames="com.android.car.notification/.CarNotificationCenterActivity"
- systemui:highlightWhenSelected="true"
+ systemui:packages="com.android.car.notification"
systemui:icon="@drawable/car_ic_notification"
+ systemui:highlightWhenSelected="true"
+ systemui:toggleSelected="true"
systemui:intent="intent:#Intent;component=com.android.car.notification/.CarNotificationCenterActivity;launchFlags=0x24000000;end"
systemui:longIntent="intent:#Intent;component=com.android.car.bugreport/.BugReportActivity;end"/>
<com.android.systemui.car.systembar.CarSystemBarButton
android:id="@+id/hvac"
style="@style/SystemBarButton"
- systemui:highlightWhenSelected="true"
systemui:icon="@drawable/car_ic_hvac"
+ systemui:highlightWhenSelected="true"
systemui:broadcast="true"/>
<com.android.systemui.car.systembar.AssitantButton
android:id="@+id/assist"
style="@style/SystemBarButton"
- systemui:highlightWhenSelected="true"
systemui:icon="@drawable/car_ic_mic"
+ systemui:highlightWhenSelected="true"
systemui:useDefaultAppIconForRole="true"/>
</LinearLayout>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
index 8792680..3f62d35 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
@@ -20,6 +20,7 @@
<color name="car_nav_icon_fill_color">#FFFFFF</color>
<color name="car_nav_icon_background_color">#282A2D</color>
+ <color name="car_nav_minimize_icon_fill_color">@android:color/black</color>
<drawable name="system_bar_background">#000000</drawable>
<color name="system_bar_text_color">#E8EAED</color>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
index 8ed622b..f900e57 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
@@ -42,6 +42,9 @@
<dimen name="system_bar_user_icon_drawing_size">44dp</dimen>
<dimen name="status_bar_system_icon_spacing">32dp</dimen>
+ <dimen name="system_bar_minimize_icon_height">17dp</dimen>
+ <dimen name="system_bar_minimize_icon_width">28dp</dimen>
+
<dimen name="hvac_panel_handle_bar_container_height">64dp</dimen>
<dimen name="hvac_panel_handle_bar_container_width">728dp</dimen>
<dimen name="hvac_panel_handle_bar_height">6dp</dimen>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
index 6e400e5..b5f46f8 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
@@ -17,12 +17,19 @@
<resources
xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--
+ Note on selected/unselected icons:
+ The icon is always tinted with @color/car_nav_icon_fill_color_selected in @layout/car_system_bar_button
+ Unselected: keep this behavior so all icons have consistent color (eg. tint a multi-colored default app icon)
+ Selected: set selected alpha 0, making icon transparent. Use state list nav_bar_button_background to show selected icon (in addition to background).
+ -->
<style name="SystemBarButton">
<item name="android:layout_width">@dimen/system_bar_button_size</item>
<item name="android:layout_height">@dimen/system_bar_button_size</item>
<item name="android:background">@drawable/nav_bar_button_background</item>
<item name="android:gravity">center</item>
<item name="unselectedAlpha">1.0</item>
+ <item name="selectedAlpha">0</item>
</style>
<style name="TextAppearance.SystemBar.Username"
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
index fecf167..92bd722 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
@@ -25,5 +25,7 @@
static_libs: [
"androidx-constraintlayout_constraintlayout",
"androidx-constraintlayout_constraintlayout-solver",
+ "car-apps-common",
+ "car-ui-lib",
],
}
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml
new file mode 100644
index 0000000..131afd5
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape
+ android:shape="oval">
+ <solid
+ android:color="@color/keypad_background_color" />
+ <size
+ android:width="@dimen/dialer_keypad_button_size"
+ android:height="@dimen/dialer_keypad_button_size"/>
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml
new file mode 100644
index 0000000..f1210dc
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="48"
+ android:viewportHeight="48"
+ android:width="44dp"
+ android:height="44dp"
+ android:tint="?attr/colorControlNormal"
+ android:autoMirrored="true">
+
+ <path android:pathData="M0-.25h48v48H0z"/>
+ <path
+ android:fillColor="?android:attr/textColorPrimary"
+ android:pathData="M17.17 32.92l9.17-9.17-9.17-9.17L20 11.75l12 12-12 12z"/>
+</vector>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml
new file mode 100644
index 0000000..6b4f369
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="44dp"
+ android:height="32dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM22,19L7.07,19L2.4,12l4.66,-7L22,5v14zM10.41,17L14,13.41 17.59,17 19,15.59 15.41,12 19,8.41 17.59,7 14,10.59 10.41,7 9,8.41 12.59,12 9,15.59z"/>
+</vector>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
index b659da1..3e2e824 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
@@ -22,7 +22,7 @@
<path
android:pathData="M0 0h24v24H0z" />
<path
- android:fillColor="#fffafafa"
+ android:fillColor="?android:attr/textColorPrimary"
android:pathData="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27 .67 -.36 1.02-.24 1.12
.37 2.33 .57 3.57 .57 .55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17
0-.55 .45 -1 1-1h3.5c.55 0 1 .45 1 1 0 1.25 .2 2.45 .57 3.57 .11 .35 .03 .74-.25
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
index 748a1d0..c07c4b3 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
@@ -22,8 +22,8 @@
android:color="#52CCB0" />
<corners android:radius="100dp"/>
<size
- android:width="424dp"
- android:height="120dp"/>
+ android:width="416dp"
+ android:height="@dimen/dialer_keypad_button_size"/>
</shape>
</item>
<item android:drawable="@drawable/ic_phone" android:gravity="center"/>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
index bf49159..131afd5 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
@@ -19,10 +19,10 @@
<shape
android:shape="oval">
<solid
- android:color="#282A2D" />
+ android:color="@color/keypad_background_color" />
<size
- android:width="120dp"
- android:height="120dp"/>
+ android:width="@dimen/dialer_keypad_button_size"
+ android:height="@dimen/dialer_keypad_button_size"/>
</shape>
</item>
</layer-list>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml
new file mode 100644
index 0000000..ea5a715
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+ <corners android:radius="4dp"/>
+ <solid android:color="@color/car_red_500a"/>
+</shape>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml
new file mode 100644
index 0000000..0185f23
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="100dp">
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="45dp"
+ android:maxLines="1"
+ android:layout_marginBottom="48dp"
+ android:textAppearance="@style/TextAppearance.DialNumber"
+ android:autoSizeMinTextSize="24sp"
+ android:autoSizeMaxTextSize="28sp"
+ android:layout_marginLeft="150dp"
+ android:layout_alignParentTop="true"/>
+
+ <com.android.car.ui.recyclerview.CarUiRecyclerView
+ android:id="@+id/list_view"
+ android:layout_width="536dp"
+ android:layout_height="266dp"
+ android:layout_marginBottom="10dp"
+ android:layout_marginLeft="70dp"
+ android:layout_below="@id/title"/>
+ <fragment
+ android:id="@+id/dialpad_fragment"
+ android:name="com.android.car.dialer.ui.dialpad.KeypadFragment"
+ android:layout_height="456dp"
+ android:layout_width="416dp"
+ android:layout_marginLeft="120dp"
+ android:layout_below="@id/list_view"/>
+
+ <RelativeLayout
+ android:layout_height="@dimen/dialer_keypad_button_size"
+ android:layout_width="0dp"
+ android:layout_below="@id/dialpad_fragment"
+ android:layout_marginTop="38dp"
+ android:layout_alignLeft="@id/dialpad_fragment"
+ android:layout_alignRight="@id/dialpad_fragment">
+
+ <ImageView
+ android:id="@+id/call_button"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:adjustViewBounds="true"
+ android:scaleType="fitXY"
+ android:src="@drawable/icon_call_button"
+ android:layout_toLeftOf="@id/delete_button"/>
+
+ <ImageButton
+ android:id="@+id/delete_button"
+ android:layout_width="@dimen/dialer_keypad_button_size"
+ android:layout_height="match_parent"
+ style="@style/DialpadSecondaryButton"
+ android:src="@drawable/ic_backspace"
+ android:layout_marginLeft="64dp"
+ android:visibility="gone"
+ android:layout_alignParentRight="true"/>
+ </RelativeLayout>
+
+ <include
+ layout="@layout/dialpad_user_profile"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginTop="10dp"
+ android:layout_below="@id/title"
+ android:layout_centerHorizontal="true"/>
+
+ <include
+ layout="@layout/restricted_dialing_mode_label"
+ android:id="@+id/restricted_dialing_mode_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="8dp"
+ android:layout_below="@id/title"
+ android:visibility="invisible"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml
new file mode 100644
index 0000000..bb4e11f
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/display_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.DialpadDisplayName"
+ android:singleLine="true"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentTop="true"/>
+
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:singleLine="true"
+ android:layout_marginTop="12dp"
+ android:layout_below="@id/display_name"
+ android:layout_centerHorizontal="true"/>
+
+ <ImageView
+ android:id="@+id/dialpad_contact_avatar"
+ android:layout_height="@dimen/dialpad_contact_avatar_size"
+ android:layout_width="@dimen/dialpad_contact_avatar_size"
+ android:layout_below="@id/label"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"/>
+
+ <TextView
+ android:id="@+id/dialpad_contact_initials"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml
new file mode 100644
index 0000000..6a23fd5
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/restricted_dialing_mode_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:padding="8dp"
+ android:textAppearance="@style/TextAppearance.Body2"
+ android:text="@string/restricted_dialing_mode_label"
+ android:alpha="0.8"
+ android:background="@drawable/restricted_dialing_mode_label_background"/>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml
new file mode 100644
index 0000000..68cf567
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/contact_result"
+ android:foreground="?android:attr/selectableItemBackground"
+ android:layout_width="match_parent"
+ android:layout_height="112dp">
+
+ <ImageView
+ android:id="@+id/contact_picture"
+ android:layout_width="72dp"
+ android:layout_height="72dp"
+ android:scaleType="centerCrop"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"/>
+
+ <TextView
+ android:id="@+id/contact_name"
+ android:layout_marginStart="24dp"
+ android:layout_marginTop="14dp"
+ android:layout_marginBottom="8dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.ContactResultTitle"
+ android:duplicateParentState="true"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/contact_picture"/>
+
+ <TextView
+ android:id="@+id/phone_number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="14dp"
+ android:theme="@style/Theme.CarUi.WithToolbar"
+ android:singleLine="true"
+ android:layout_alignParentBottom="true"
+ android:layout_alignLeft="@id/contact_name"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml
new file mode 100644
index 0000000..929bfe2
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <color name="keypad_background_color">#282A2D</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml
new file mode 100644
index 0000000..5452e77
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <color name="keypad_background_color">#E8EAED</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml
new file mode 100644
index 0000000..108cfb1
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources>
+ <dimen name="dialer_keypad_button_size">96dp</dimen>
+ <dimen name="dialpad_contact_avatar_size">64dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml
new file mode 100644
index 0000000..88b64b6
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="restricted_dialing_mode_label">Dialpad usage is restricted while driving</string>
+</resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
index 678cf0c..daeefb8 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
@@ -20,18 +20,54 @@
<item name="android:clickable">true</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
- <item name="android:layout_marginTop">16dp</item>
- <item name="android:layout_marginRight">16dp</item>
- <item name="android:layout_marginBottom">16dp</item>
- <item name="android:layout_marginLeft">16dp</item>
+ <item name="android:layout_marginTop">12dp</item>
+ <item name="android:layout_marginRight">32dp</item>
+ <item name="android:layout_marginBottom">12dp</item>
+ <item name="android:layout_marginLeft">32dp</item>
<item name="android:background">@drawable/keypad_default_background</item>
<item name="android:focusable">true</item>
</style>
- <style name="DialpadPrimaryButton">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">150dp</item>
- <item name="android:layout_marginBottom">180dp</item>
- <item name="android:scaleType">center</item>
+ <style name="TextAppearance.DialNumber" parent="android:style/TextAppearance">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textSize">32sp</item>
+ </style>
+
+ <style name="SubheaderText" parent="android:style/TextAppearance">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textSize">24sp</item>
+ <item name="android:textFontWeight">500</item>
+ <item name="android:textStyle">normal</item>
+ </style>
+
+ <style name="AddFavoriteText">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <!-- Call history -->
+ <style name="TextAppearance.CallLogTitleDefault" parent="TextAppearance.Body1">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+ <!-- Customized text color for missed calls can be added here -->
+ <style name="TextAppearance.CallLogTitleMissedCall" parent="TextAppearance.Body1">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="DialpadSecondaryButton">
+ <item name="android:background">@drawable/dialer_ripple_background</item>
+ <item name="android:scaleType">centerInside</item>
+ <item name="android:tint">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.DialpadDisplayName" parent="TextAppearance.Body1"/>
+
+ <style name="TextAppearance.ContactResultTitle" parent="TextAppearance.Body1">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.TypeDownListSpan" parent="TextAppearance.Body3">
+ <item name="android:textStyle">bold</item>
+ <item name="android:textSize">32sp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
index a404157..b75bc81 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
@@ -15,9 +15,40 @@
~ limitations under the License.
-->
<overlay>
- <item target="style/KeypadButtonStyle" value="@style/KeypadButtonStyle"/>
- <item target="style/DialpadPrimaryButton" value="@style/DialpadPrimaryButton"/>
-
<item target="drawable/ic_phone" value="@drawable/ic_phone"/>
<item target="drawable/icon_call_button" value="@drawable/icon_call_button"/>
+ <item target="drawable/ic_backspace" value="@drawable/ic_backspace"/>
+ <item target="drawable/dialer_ripple_background" value="@drawable/dialer_ripple_background"/>
+ <item target="drawable/restricted_dialing_mode_label_background" value="@drawable/restricted_dialing_mode_label_background"/>
+ <item target="drawable/ic_arrow_right" value="@drawable/ic_arrow_right"/>
+
+ <item target="id/dialpad_fragment" value="@id/dialpad_fragment" />
+ <item target="id/call_button" value="@id/call_button" />
+ <item target="id/title" value="@id/title" />
+ <item target="id/delete_button" value="@id/delete_button" />
+ <item target="id/display_name" value="@id/display_name" />
+ <item target="id/label" value="@id/label" />
+ <item target="id/dialpad_contact_avatar" value="@id/dialpad_contact_avatar" />
+ <item target="id/dialpad_contact_initials" value="@id/dialpad_contact_initials" />
+ <item target="id/list_view" value="@id/list_view" />
+ <item target="id/restricted_dialing_mode_label" value="@id/restricted_dialing_mode_label" />
+ <item target="id/contact_picture" value="@id/contact_picture" />
+ <item target="id/contact_result" value="@id/contact_result" />
+ <item target="id/contact_name" value="@id/contact_name" />
+ <item target="id/phone_number" value="@id/phone_number" />
+
+ <item target="layout/dialpad_fragment_with_type_down" value="@layout/dialpad_fragment_with_type_down"/>
+ <item target="layout/dialpad_user_profile" value="@layout/dialpad_user_profile"/>
+ <item target="layout/type_down_list_item" value="@layout/type_down_list_item"/>
+ <item target="layout/restricted_dialing_mode_label" value="@layout/restricted_dialing_mode_label"/>
+
+ <item target="style/KeypadButtonStyle" value="@style/KeypadButtonStyle"/>
+ <item target="style/TextAppearance.DialNumber" value="@style/TextAppearance.DialNumber"/>
+ <item target="style/SubheaderText" value="@style/SubheaderText"/>
+ <item target="style/AddFavoriteText" value="@style/AddFavoriteText"/>
+ <item target="style/TextAppearance.CallLogTitleDefault" value="@style/TextAppearance.CallLogTitleDefault"/>
+ <item target="style/TextAppearance.DialpadDisplayName" value="@style/TextAppearance.DialpadDisplayName"/>
+ <item target="style/TextAppearance.ContactResultTitle" value="@style/TextAppearance.ContactResultTitle"/>
+ <item target="style/TextAppearance.TypeDownListSpan" value="@style/TextAppearance.TypeDownListSpan"/>
+
</overlay>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
index 0162e5b..ffbeb18 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
@@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
- <solid android:color="#2E3134"/>
+ <solid android:color="@color/tab_background_color"/>
</shape>
</item>
<item android:state_activated="false">
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
index 39d910c..02a7320 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
@@ -75,7 +75,7 @@
android:layout_gravity="center"
android:scaleType="fitXY"
android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
- android:tint="@color/car_ui_text_color_primary"/>
+ android:tint="?android:attr/textColorPrimary"/>
<ImageView
android:id="@+id/car_ui_toolbar_logo"
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml
new file mode 100644
index 0000000..9134d34
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <color name="tab_background_color">#282A2D</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml
new file mode 100644
index 0000000..fca1ab1
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <color name="tab_background_color">#E8EAED</color>
+</resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
index 1c751f9..6db644f 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
@@ -18,6 +18,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="owner_name" msgid="3416113395996003764">"Chauffør"</string>
- <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"få kun adgang til omtrentlig placering i forgrunden"</string>
+ <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"få kun adgang til omtrentlig lokation i forgrunden"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="2093486820466005919">"Aktivér mikrofon"</string>
</resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/config.xml b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
index a1b0cd2..73326f1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
@@ -156,4 +156,10 @@
This flag should be enabled only when the product does not have any UI to toggle airplane
mode like automotive devices.-->
<bool name="config_autoResetAirplaneMode">true</bool>
+
+ <!-- The component name of the activity for the companion-device-manager notification access
+ confirmation. -->
+ <string name="config_notificationAccessConfirmationActivity" translatable="false">
+ com.android.car.settings/com.android.car.settings.notifications.NotificationAccessConfirmationActivity
+ </string>
</resources>
diff --git a/service/src/com/android/car/hal/CarPropertyUtils.java b/service/src/com/android/car/hal/CarPropertyUtils.java
index 9ac2745..146a4fb 100644
--- a/service/src/com/android/car/hal/CarPropertyUtils.java
+++ b/service/src/com/android/car/hal/CarPropertyUtils.java
@@ -260,6 +260,12 @@
int areaType = getVehicleAreaType(p.prop & VehicleArea.MASK);
Class<?> clazz = getJavaClass(p.prop & VehiclePropertyType.MASK);
+ float maxSampleRate = 0f;
+ float minSampleRate = 0f;
+ if (p.changeMode != CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_STATIC) {
+ maxSampleRate = p.maxSampleRate;
+ minSampleRate = p.minSampleRate;
+ }
if (p.areaConfigs.isEmpty()) {
return CarPropertyConfig
.newBuilder(clazz, propertyId, areaType, /* capacity */ 1)
@@ -268,8 +274,8 @@
.setChangeMode(p.changeMode)
.setConfigArray(p.configArray)
.setConfigString(p.configString)
- .setMaxSampleRate(p.maxSampleRate)
- .setMinSampleRate(p.minSampleRate)
+ .setMaxSampleRate(maxSampleRate)
+ .setMinSampleRate(minSampleRate)
.build();
} else {
CarPropertyConfig.Builder builder = CarPropertyConfig
@@ -278,8 +284,8 @@
.setChangeMode(p.changeMode)
.setConfigArray(p.configArray)
.setConfigString(p.configString)
- .setMaxSampleRate(p.maxSampleRate)
- .setMinSampleRate(p.minSampleRate);
+ .setMaxSampleRate(maxSampleRate)
+ .setMinSampleRate(minSampleRate);
for (VehicleAreaConfig area : p.areaConfigs) {
if (classMatched(Integer.class, clazz)) {
diff --git a/service/src/com/android/car/telemetry/CarTelemetryService.java b/service/src/com/android/car/telemetry/CarTelemetryService.java
index 5b78e3b..537ce45 100644
--- a/service/src/com/android/car/telemetry/CarTelemetryService.java
+++ b/service/src/com/android/car/telemetry/CarTelemetryService.java
@@ -15,7 +15,9 @@
*/
package com.android.car.telemetry;
+import static android.car.telemetry.CarTelemetryManager.ERROR_METRICS_CONFIG_NONE;
import static android.car.telemetry.CarTelemetryManager.ERROR_METRICS_CONFIG_PARSE_FAILED;
+import static android.car.telemetry.CarTelemetryManager.ERROR_METRICS_CONFIG_UNKNOWN;
import android.annotation.NonNull;
import android.app.StatsManager;
@@ -161,17 +163,27 @@
public void addMetricsConfig(@NonNull MetricsConfigKey key, @NonNull byte[] config) {
mContext.enforceCallingOrSelfPermission(
Car.PERMISSION_USE_CAR_TELEMETRY_SERVICE, "addMetricsConfig");
- // TODO(b/198797367): if an older version exists, delete its script result/error
mTelemetryHandler.post(() -> {
- TelemetryProto.MetricsConfig metricsConfig;
- int status;
+ Slog.d(CarLog.TAG_TELEMETRY, "Adding metrics config " + key.getName()
+ + " to car telemetry service");
+ // TODO(b/199540952): If config is active, add it to DataBroker
+ TelemetryProto.MetricsConfig metricsConfig = null;
+ int status = ERROR_METRICS_CONFIG_UNKNOWN;
try {
metricsConfig = TelemetryProto.MetricsConfig.parseFrom(config);
- status = mMetricsConfigStore.addMetricsConfig(metricsConfig);
} catch (InvalidProtocolBufferException e) {
Slog.e(CarLog.TAG_TELEMETRY, "Failed to parse MetricsConfig.", e);
status = ERROR_METRICS_CONFIG_PARSE_FAILED;
}
+ // if config can be parsed, add it to persistent storage
+ if (metricsConfig != null) {
+ status = mMetricsConfigStore.addMetricsConfig(metricsConfig);
+ }
+ // If no error (a config is successfully added), script results from an older version
+ // should be deleted
+ if (status == ERROR_METRICS_CONFIG_NONE) {
+ mResultStore.deleteResult(key.getName());
+ }
try {
mListener.onAddMetricsConfigStatus(key, status);
} catch (RemoteException e) {
@@ -181,19 +193,19 @@
}
/**
- * Removes a manifest based on the key.
+ * Removes a metrics config based on the key. This will also remove outputs produced by the
+ * MetricsConfig.
*/
@Override
public void removeMetricsConfig(@NonNull MetricsConfigKey key) {
mContext.enforceCallingOrSelfPermission(
Car.PERMISSION_USE_CAR_TELEMETRY_SERVICE, "removeMetricsConfig");
- // TODO(b/198797367): Delete script result/error associated with this MetricsConfig
mTelemetryHandler.post(() -> {
- if (DEBUG) {
- Slog.d(CarLog.TAG_TELEMETRY, "Removing manifest " + key.getName()
- + " from car telemetry service");
- }
+ Slog.d(CarLog.TAG_TELEMETRY, "Removing metrics config " + key.getName()
+ + " from car telemetry service");
// TODO(b/198792767): Check both config name and config version for deletion
+ // TODO(b/199540952): Stop and remove config from data broker
+ mResultStore.deleteResult(key.getName()); // delete the config's script results
boolean success = mMetricsConfigStore.deleteMetricsConfig(key.getName());
try {
mListener.onRemoveMetricsConfigStatus(key, success);
@@ -204,17 +216,18 @@
}
/**
- * Removes all manifests.
+ * Removes all MetricsConfigs. This will also remove all MetricsConfig outputs.
*/
@Override
public void removeAllMetricsConfigs() {
mContext.enforceCallingOrSelfPermission(
Car.PERMISSION_USE_CAR_TELEMETRY_SERVICE, "removeAllMetricsConfig");
mTelemetryHandler.post(() -> {
- if (DEBUG) {
- Slog.d(CarLog.TAG_TELEMETRY, "Removing all manifest from car telemetry service");
- }
- // TODO(b/184087869): Implement
+ // TODO(b/199540952): Stop and remove all configs from DataBroker
+ Slog.d(CarLog.TAG_TELEMETRY,
+ "Removing all metrics config from car telemetry service");
+ mMetricsConfigStore.deleteAllMetricsConfigs();
+ mResultStore.deleteAllResults();
});
}
@@ -228,7 +241,7 @@
mContext.enforceCallingOrSelfPermission(
Car.PERMISSION_USE_CAR_TELEMETRY_SERVICE, "sendFinishedReports");
if (DEBUG) {
- Slog.d(CarLog.TAG_TELEMETRY, "Flushing reports for a manifest");
+ Slog.d(CarLog.TAG_TELEMETRY, "Flushing reports for a metrics config");
}
}
@@ -249,4 +262,14 @@
Handler getTelemetryHandler() {
return mTelemetryHandler;
}
+
+ @VisibleForTesting
+ ResultStore getResultStore() {
+ return mResultStore;
+ }
+
+ @VisibleForTesting
+ MetricsConfigStore getMetricsConfigStore() {
+ return mMetricsConfigStore;
+ }
}
diff --git a/service/src/com/android/car/telemetry/MetricsConfigStore.java b/service/src/com/android/car/telemetry/MetricsConfigStore.java
index 9802e0e..7a5512a 100644
--- a/service/src/com/android/car/telemetry/MetricsConfigStore.java
+++ b/service/src/com/android/car/telemetry/MetricsConfigStore.java
@@ -89,6 +89,7 @@
} else if (currentVersion == metricsConfig.getVersion()) {
return ERROR_METRICS_CONFIG_ALREADY_EXISTS;
}
+ mActiveConfigs.put(metricsConfig.getName(), metricsConfig);
mNameVersionMap.put(metricsConfig.getName(), metricsConfig.getVersion());
try {
Files.write(
@@ -108,7 +109,10 @@
return new File(mConfigDirectory, metricsConfigName).delete();
}
- void deleteAllMetricsConfig() {
- // TODO(b/198784116): implement
+ void deleteAllMetricsConfigs() {
+ mActiveConfigs.clear();
+ for (File file : mConfigDirectory.listFiles()) {
+ file.delete();
+ }
}
}
diff --git a/service/src/com/android/car/telemetry/ResultStore.java b/service/src/com/android/car/telemetry/ResultStore.java
index 976ee8e..ffa3d09 100644
--- a/service/src/com/android/car/telemetry/ResultStore.java
+++ b/service/src/com/android/car/telemetry/ResultStore.java
@@ -97,27 +97,23 @@
*
* @param metricsConfigName name of the MetricsConfig.
* @param deleteResult if true, the final result will be deleted from disk.
- * @param callback for receiving the metrics output. If result does not exist, it will
- * receive a null value.
*/
- public void getFinalResult(
- String metricsConfigName, boolean deleteResult, FinalResultCallback callback) {
+ public PersistableBundle getFinalResult(String metricsConfigName, boolean deleteResult) {
File file = new File(mFinalResultDirectory, metricsConfigName);
// if no final result exists for this metrics config, return immediately
if (!file.exists()) {
- callback.onFinalResult(metricsConfigName, null);
- return;
+ return null;
}
+ PersistableBundle result = null;
try (FileInputStream fis = new FileInputStream(file)) {
- PersistableBundle bundle = PersistableBundle.readFromStream(fis);
- callback.onFinalResult(metricsConfigName, bundle);
+ result = PersistableBundle.readFromStream(fis);
} catch (IOException e) {
Slog.w(CarLog.TAG_TELEMETRY, "Failed to get final result from disk.", e);
- callback.onFinalResult(metricsConfigName, null);
}
if (deleteResult) {
file.delete();
}
+ return result;
}
/**
@@ -136,6 +132,27 @@
deleteAllStaleData(mInterimResultDirectory, mFinalResultDirectory);
}
+ /**
+ * Deletes script result associated with the given config name. If result does not exist, this
+ * method does not do anything.
+ */
+ public void deleteResult(String metricsConfigName) {
+ mInterimResultCache.remove(metricsConfigName);
+ deleteFileInDirectory(mInterimResultDirectory, metricsConfigName);
+ deleteFileInDirectory(mFinalResultDirectory, metricsConfigName);
+ }
+
+ /** Deletes all interim and final results stored in disk. */
+ public void deleteAllResults() {
+ mInterimResultCache.clear();
+ for (File interimResult : mInterimResultDirectory.listFiles()) {
+ interimResult.delete();
+ }
+ for (File finalResult : mFinalResultDirectory.listFiles()) {
+ finalResult.delete();
+ }
+ }
+
/** Writes dirty interim results to disk. */
private void writeInterimResultsToFile() {
mInterimResultCache.forEach((metricsConfigName, interimResult) -> {
@@ -180,11 +197,6 @@
file.delete();
}
- /** Callback for receiving final metrics output. */
- interface FinalResultCallback {
- void onFinalResult(String metricsConfigName, PersistableBundle result);
- }
-
/** Wrapper around a result and whether the result should be written to disk. */
static final class InterimResult {
private final PersistableBundle mBundle;
diff --git a/service/src/com/android/car/watchdog/PackageInfoHandler.java b/service/src/com/android/car/watchdog/PackageInfoHandler.java
index 5ee811d..e3f4bb8 100644
--- a/service/src/com/android/car/watchdog/PackageInfoHandler.java
+++ b/service/src/com/android/car/watchdog/PackageInfoHandler.java
@@ -292,4 +292,10 @@
}
return ComponentType.THIRD_PARTY;
}
+
+ void setVendorPackagePrefixes(List<String> vendorPackagePrefixes) {
+ synchronized (mLock) {
+ mVendorPackagePrefixes = vendorPackagePrefixes;
+ }
+ }
}
diff --git a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
index 251444e..e83288b 100644
--- a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
+++ b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
@@ -797,6 +797,8 @@
break;
case ComponentType.VENDOR:
mSafeToKillVendorPackages.addAll(internalConfigs.get(i).safeToKillPackages);
+ mPackageInfoHandler.setVendorPackagePrefixes(
+ internalConfigs.get(i).vendorPackagePrefixes);
break;
default:
// All third-party apps are killable.
@@ -804,7 +806,7 @@
}
}
if (DEBUG) {
- Slogf.d(TAG, "Fetched and synced safe to kill packages.");
+ Slogf.d(TAG, "Fetched and synced resource overuse configs.");
}
}
}
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/CarTelemetryServiceTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/CarTelemetryServiceTest.java
index a17e3fa..39389d2 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/CarTelemetryServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/CarTelemetryServiceTest.java
@@ -16,6 +16,7 @@
package com.android.car.telemetry;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.eq;
@@ -27,6 +28,7 @@
import android.car.telemetry.MetricsConfigKey;
import android.content.Context;
import android.os.Handler;
+import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
@@ -66,6 +68,8 @@
private CarTelemetryService mService;
private File mTempSystemCarDir;
private Handler mTelemetryHandler;
+ private MetricsConfigStore mMetricsConfigStore;
+ private ResultStore mResultStore;
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -96,6 +100,9 @@
return true;
});
waitForHandlerThreadToFinish();
+
+ mMetricsConfigStore = mService.getMetricsConfigStore();
+ mResultStore = mService.getResultStore();
}
@Test
@@ -123,7 +130,7 @@
@Test
public void testAddMetricsConfig_invalidMetricsConfig_shouldFail() throws Exception {
- mService.addMetricsConfig(KEY_V1, "bad manifest".getBytes());
+ mService.addMetricsConfig(KEY_V1, "bad config".getBytes());
waitForHandlerThreadToFinish();
verify(mMockListener).onAddMetricsConfigStatus(
@@ -145,34 +152,60 @@
}
@Test
- public void testAddMetricsConfig_newerMetricsConfig_shouldReplace() throws Exception {
+ public void testAddMetricsConfig_newerMetricsConfig_shouldReplaceAndDeleteOldResult()
+ throws Exception {
mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray());
+ mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle());
mService.addMetricsConfig(KEY_V2, METRICS_CONFIG_V2.toByteArray());
waitForHandlerThreadToFinish();
verify(mMockListener).onAddMetricsConfigStatus(
eq(KEY_V2), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_NONE));
+ assertThat(mMetricsConfigStore.getActiveMetricsConfigs())
+ .containsExactly(METRICS_CONFIG_V2);
+ assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull();
}
@Test
- public void testRemoveMetricsConfig_manifestExists_shouldSucceed() throws Exception {
+ public void testRemoveMetricsConfig_configExists_shouldDeleteScriptResult() throws Exception {
mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray());
+ mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle());
mService.removeMetricsConfig(KEY_V1);
waitForHandlerThreadToFinish();
verify(mMockListener).onRemoveMetricsConfigStatus(eq(KEY_V1), eq(true));
+ assertThat(mMetricsConfigStore.getActiveMetricsConfigs()).isEmpty();
+ assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull();
}
@Test
- public void testRemoveMetricsConfig_manifestDoesNotExist_shouldFail() throws Exception {
+ public void testRemoveMetricsConfig_configDoesNotExist_shouldFail() throws Exception {
mService.removeMetricsConfig(KEY_V1);
waitForHandlerThreadToFinish();
verify(mMockListener).onRemoveMetricsConfigStatus(eq(KEY_V1), eq(false));
}
+ @Test
+ public void testRemoveAllMetricsConfigs_shouldRemoveConfigsAndResults() throws Exception {
+ MetricsConfigKey key = new MetricsConfigKey("test config", 2);
+ TelemetryProto.MetricsConfig config =
+ TelemetryProto.MetricsConfig.newBuilder().setName(key.getName()).build();
+ mService.addMetricsConfig(key, config.toByteArray());
+ mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray());
+ mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle());
+ mResultStore.putFinalResult(key.getName(), new PersistableBundle());
+
+ mService.removeAllMetricsConfigs();
+
+ waitForHandlerThreadToFinish();
+ assertThat(mMetricsConfigStore.getActiveMetricsConfigs()).isEmpty();
+ assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull();
+ assertThat(mResultStore.getFinalResult(key.getName(), /* deleteResult = */ false)).isNull();
+ }
+
private void waitForHandlerThreadToFinish() throws Exception {
assertWithMessage("handler not idle in %sms", TIMEOUT_MS)
.that(mIdleHandlerLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/MetricsConfigStoreTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/MetricsConfigStoreTest.java
index 5b326ff..daf83d8 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/MetricsConfigStoreTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/MetricsConfigStoreTest.java
@@ -87,6 +87,16 @@
assertThat(new File(mTestMetricsConfigDir, NAME_BAR).exists()).isFalse();
}
+ @Test
+ public void testDeleteAllMetricsConfigs_shouldDeleteAll() throws Exception {
+ writeConfigToDisk(METRICS_CONFIG_FOO);
+ writeConfigToDisk(METRICS_CONFIG_BAR);
+
+ mMetricsConfigStore.deleteAllMetricsConfigs();
+
+ assertThat(mTestMetricsConfigDir.listFiles()).isEmpty();
+ }
+
private void writeConfigToDisk(TelemetryProto.MetricsConfig config) throws Exception {
File file = new File(mTestMetricsConfigDir, config.getName());
Files.write(file.toPath(), config.toByteArray());
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/ResultStoreTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/ResultStoreTest.java
index af0281a..ed59675 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/ResultStoreTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/ResultStoreTest.java
@@ -19,17 +19,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.verify;
-
import android.os.PersistableBundle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.ByteArrayOutputStream;
@@ -49,12 +43,6 @@
private File mTestFinalResultDir;
private ResultStore mResultStore;
- @Mock
- private ResultStore.FinalResultCallback mMockFinalResultCallback;
- @Captor
- private ArgumentCaptor<PersistableBundle> mBundleCaptor;
-
-
@Before
public void setUp() throws Exception {
TEST_INTERIM_BUNDLE.putString("test key", "interim value");
@@ -131,11 +119,9 @@
public void testGetFinalResult_whenNoData_shouldReceiveNull() throws Exception {
String metricsConfigName = "my_metrics_config";
- mResultStore.getFinalResult(metricsConfigName, true, mMockFinalResultCallback);
+ PersistableBundle bundle = mResultStore.getFinalResult(metricsConfigName, true);
- verify(mMockFinalResultCallback).onFinalResult(eq(metricsConfigName),
- mBundleCaptor.capture());
- assertThat(mBundleCaptor.getValue()).isNull();
+ assertThat(bundle).isNull();
}
@Test
@@ -144,11 +130,9 @@
Files.write(new File(mTestFinalResultDir, metricsConfigName).toPath(),
"not a bundle".getBytes(StandardCharsets.UTF_8));
- mResultStore.getFinalResult(metricsConfigName, true, mMockFinalResultCallback);
+ PersistableBundle bundle = mResultStore.getFinalResult(metricsConfigName, true);
- verify(mMockFinalResultCallback).onFinalResult(eq(metricsConfigName),
- mBundleCaptor.capture());
- assertThat(mBundleCaptor.getValue()).isNull();
+ assertThat(bundle).isNull();
}
@Test
@@ -156,12 +140,10 @@
String testFinalFileName = "my_metrics_config";
writeBundleToFile(mTestFinalResultDir, testFinalFileName, TEST_FINAL_BUNDLE);
- mResultStore.getFinalResult(testFinalFileName, true, mMockFinalResultCallback);
+ PersistableBundle bundle = mResultStore.getFinalResult(testFinalFileName, true);
- verify(mMockFinalResultCallback).onFinalResult(eq(testFinalFileName),
- mBundleCaptor.capture());
// should compare value instead of reference
- assertThat(mBundleCaptor.getValue().toString()).isEqualTo(TEST_FINAL_BUNDLE.toString());
+ assertThat(bundle.toString()).isEqualTo(TEST_FINAL_BUNDLE.toString());
assertThat(new File(mTestFinalResultDir, testFinalFileName).exists()).isFalse();
}
@@ -170,12 +152,10 @@
String testFinalFileName = "my_metrics_config";
writeBundleToFile(mTestFinalResultDir, testFinalFileName, TEST_FINAL_BUNDLE);
- mResultStore.getFinalResult(testFinalFileName, false, mMockFinalResultCallback);
+ PersistableBundle bundle = mResultStore.getFinalResult(testFinalFileName, false);
- verify(mMockFinalResultCallback).onFinalResult(eq(testFinalFileName),
- mBundleCaptor.capture());
// should compare value instead of reference
- assertThat(mBundleCaptor.getValue().toString()).isEqualTo(TEST_FINAL_BUNDLE.toString());
+ assertThat(bundle.toString()).isEqualTo(TEST_FINAL_BUNDLE.toString());
assertThat(new File(mTestFinalResultDir, testFinalFileName).exists()).isTrue();
}
@@ -236,6 +216,26 @@
assertThat(new File(mTestFinalResultDir, metricsConfigName).exists()).isTrue();
}
+ @Test
+ public void testDeleteResult_whenInterimResult_shouldDelete() throws Exception {
+ String metricsConfigName = "my_metrics_config";
+ writeBundleToFile(mTestInterimResultDir, metricsConfigName, TEST_INTERIM_BUNDLE);
+
+ mResultStore.deleteResult(metricsConfigName);
+
+ assertThat(new File(mTestInterimResultDir, metricsConfigName).exists()).isFalse();
+ }
+
+ @Test
+ public void testDeleteResult_whenFinalResult_shouldDelete() throws Exception {
+ String metricsConfigName = "my_metrics_config";
+ writeBundleToFile(mTestFinalResultDir, metricsConfigName, TEST_FINAL_BUNDLE);
+
+ mResultStore.deleteResult(metricsConfigName);
+
+ assertThat(new File(mTestFinalResultDir, metricsConfigName).exists()).isFalse();
+ }
+
private void writeBundleToFile(
File dir, String fileName, PersistableBundle persistableBundle) throws Exception {
writeBundleToFile(new File(dir, fileName), persistableBundle);
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 4b3963d..a3914d7 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
@@ -1211,10 +1211,6 @@
@Test
public void testGetPackageKillableStatesAsUserWithSafeToKillPackages() throws Exception {
mockUmGetAliveUsers(mMockUserManager, 11, 12);
- List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> configs =
- sampleInternalResourceOveruseConfigurations();
- injectResourceOveruseConfigsAndWait(configs);
-
injectPackageInfos(Arrays.asList(
constructPackageManagerPackageInfo("system_package.non_critical.A", 1102459, null),
constructPackageManagerPackageInfo("third_party_package", 1103456, null),
@@ -1223,6 +1219,10 @@
constructPackageManagerPackageInfo("third_party_package", 1203456, null),
constructPackageManagerPackageInfo("vendor_package.critical.B", 1201278, null)));
+ List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> configs =
+ sampleInternalResourceOveruseConfigurations();
+ injectResourceOveruseConfigsAndWait(configs);
+
PackageKillableStateSubject.assertThat(
mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL))
.containsExactly(
@@ -1241,6 +1241,37 @@
}
@Test
+ public void testGetPackageKillableStatesAsUserWithVendorPackagePrefixes() throws Exception {
+ mockUmGetAliveUsers(mMockUserManager, 11);
+ /* Package names which start with "system" are constructed as system packages. */
+ injectPackageInfos(Arrays.asList(
+ constructPackageManagerPackageInfo("system_package_as_vendor", 1102459, null)));
+
+ android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+ new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+ vendorConfig.componentType = ComponentType.VENDOR;
+ vendorConfig.safeToKillPackages = Collections.singletonList("system_package_as_vendor");
+ vendorConfig.vendorPackagePrefixes = Collections.singletonList(
+ "system_package_as_vendor");
+ injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
+ List<PackageKillableState> killableStates =
+ mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11));
+
+ /* When CarWatchdogService connects with the watchdog daemon, CarWatchdogService fetches
+ * resource overuse configs from watchdog daemon. The vendor package prefixes in the
+ * configs help identify vendor packages. The safe-to-kill list in the configs helps
+ * identify safe-to-kill vendor packages. |system_package_as_vendor| is a critical system
+ * package by default but with the latest resource overuse configs, this package should be
+ * classified as a safe-to-kill vendor package.
+ */
+ PackageKillableStateSubject.assertThat(killableStates)
+ .containsExactly(
+ new PackageKillableState("system_package_as_vendor", 11,
+ PackageKillableState.KILLABLE_STATE_YES));
+ }
+
+ @Test
public void testGetPackageKillableStatesAsUserWithSharedUids() throws Exception {
mockUmGetAliveUsers(mMockUserManager, 11, 12);
injectPackageInfos(Arrays.asList(
@@ -1274,13 +1305,6 @@
public void testGetPackageKillableStatesAsUserWithSharedUidsAndSafeToKillPackages()
throws Exception {
mockUmGetAliveUsers(mMockUserManager, 11);
- android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
- new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
- vendorConfig.componentType = ComponentType.VENDOR;
- vendorConfig.safeToKillPackages = Collections.singletonList(
- "vendor_package.non_critical.A");
- injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
-
injectPackageInfos(Arrays.asList(
constructPackageManagerPackageInfo(
"vendor_package.non_critical.A", 1103456, "vendor_shared_package.A"),
@@ -1293,6 +1317,14 @@
constructPackageManagerPackageInfo(
"third_party_package.D", 1105678, "third_party_shared_package")));
+ android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+ new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+ vendorConfig.componentType = ComponentType.VENDOR;
+ vendorConfig.safeToKillPackages = Collections.singletonList(
+ "vendor_package.non_critical.A");
+ vendorConfig.vendorPackagePrefixes = new ArrayList<>();
+ injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
PackageKillableStateSubject.assertThat(
mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11)))
.containsExactly(
@@ -1312,13 +1344,6 @@
public void testGetPackageKillableStatesAsUserWithSharedUidsAndSafeToKillSharedPackage()
throws Exception {
mockUmGetAliveUsers(mMockUserManager, 11);
- android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
- new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
- vendorConfig.componentType = ComponentType.VENDOR;
- vendorConfig.safeToKillPackages = Collections.singletonList(
- "shared:vendor_shared_package.B");
- injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
-
injectPackageInfos(Arrays.asList(
constructPackageManagerPackageInfo(
"vendor_package.non_critical.A", 1103456, "vendor_shared_package.B"),
@@ -1327,6 +1352,15 @@
constructPackageManagerPackageInfo(
"vendor_package.non_critical.B", 1103456, "vendor_shared_package.B")));
+ android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+ new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+ vendorConfig.componentType = ComponentType.VENDOR;
+ vendorConfig.safeToKillPackages = Collections.singletonList(
+ "shared:vendor_shared_package.B");
+ vendorConfig.vendorPackagePrefixes = new ArrayList<>();
+ injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
+
PackageKillableStateSubject.assertThat(
mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11)))
.containsExactly(
@@ -2463,6 +2497,11 @@
*/
crashWatchdogDaemon();
restartWatchdogDaemonAndAwait();
+
+ /* Method should be invoked 2 times. Once at test setup and once more after the daemon
+ * crashes and reconnects.
+ */
+ verify(mMockCarWatchdogDaemon, times(2)).getResourceOveruseConfigurations();
}
private SparseArray<PackageIoOveruseStats> injectIoOveruseStatsForPackages(