Merge "Support passing multiple res folders" into tm-qpr-dev am: 9f2c906504 am: 231ea90f79
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Car/systemlibs/+/20480634
Change-Id: I6d0086ef6f2a92316baeb291a72143acf25314e9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/car-qc-lib/res/color/qc_seekbar_thumb_selector.xml b/car-qc-lib/res/color/qc_seekbar_thumb_selector.xml
new file mode 100644
index 0000000..bf94a61
--- /dev/null
+++ b/car-qc-lib/res/color/qc_seekbar_thumb_selector.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 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_enabled="false"
+ android:color="@color/qc_seekbar_thumb_disabled_on_dark"/>
+ <item android:color="@color/qc_seekbar_thumb"/>
+</selector>
diff --git a/car-qc-lib/res/color/qc_switch_thumb_selector.xml b/car-qc-lib/res/color/qc_switch_thumb_selector.xml
new file mode 100644
index 0000000..e0bfc22
--- /dev/null
+++ b/car-qc-lib/res/color/qc_switch_thumb_selector.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 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_enabled="false"
+ android:color="@color/qc_switch_thumb_color_disabled_on_dark"/>
+ <item android:color="@color/qc_switch_thumb_color"/>
+</selector>
diff --git a/car-qc-lib/res/drawable/qc_toggle_background.xml b/car-qc-lib/res/drawable/qc_toggle_background.xml
index 3688175..4e30cf4 100644
--- a/car-qc-lib/res/drawable/qc_toggle_background.xml
+++ b/car-qc-lib/res/drawable/qc_toggle_background.xml
@@ -16,8 +16,8 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
- android:width="@dimen/qc_toggle_size"
- android:height="@dimen/qc_toggle_size"
+ android:width="@dimen/qc_toggle_background_size"
+ android:height="@dimen/qc_toggle_background_size"
android:start="@dimen/qc_toggle_background_padding"
android:top="@dimen/qc_toggle_background_padding"
android:drawable="@drawable/qc_toggle_button_background">
diff --git a/car-qc-lib/res/drawable/qc_toggle_unavailable_background.xml b/car-qc-lib/res/drawable/qc_toggle_unavailable_background.xml
index e9f2e12..185b801 100644
--- a/car-qc-lib/res/drawable/qc_toggle_unavailable_background.xml
+++ b/car-qc-lib/res/drawable/qc_toggle_unavailable_background.xml
@@ -16,8 +16,8 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
- android:width="@dimen/qc_toggle_size"
- android:height="@dimen/qc_toggle_size"
+ android:width="@dimen/qc_toggle_background_size"
+ android:height="@dimen/qc_toggle_background_size"
android:start="@dimen/qc_toggle_background_padding"
android:top="@dimen/qc_toggle_background_padding">
<shape android:shape="rectangle">
diff --git a/car-qc-lib/res/layout/qc_row_view.xml b/car-qc-lib/res/layout/qc_row_view.xml
index 2d95888..a4af032 100644
--- a/car-qc-lib/res/layout/qc_row_view.xml
+++ b/car-qc-lib/res/layout/qc_row_view.xml
@@ -119,7 +119,7 @@
app:layout_constraintTop_toBottomOf="@+id/barrier2"
app:layout_constraintBottom_toBottomOf="parent">
<com.android.car.qc.view.QCSeekBarView
- android:id="@+id/seekbar"
+ android:id="@+id/qc_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.QC.SeekBar"/>
diff --git a/car-qc-lib/res/values/colors.xml b/car-qc-lib/res/values/colors.xml
index 62bcfdc..a2b85ff 100644
--- a/car-qc-lib/res/values/colors.xml
+++ b/car-qc-lib/res/values/colors.xml
@@ -20,4 +20,12 @@
<color name="qc_toggle_unavailable_background_color">@android:color/transparent</color>
<color name="qc_toggle_unavailable_color">#37FFFFFF</color>
<color name="qc_toggle_rotary_shadow_color">#C7000000</color>
-</resources>
\ No newline at end of file
+ <!-- The SeekBar thumb color. -->
+ <color name="qc_seekbar_thumb">#FFFFFF</color>
+ <!-- The SeekBar thumb color when disabled. Use for the dark theme. -->
+ <color name="qc_seekbar_thumb_disabled_on_dark">#757575</color>
+ <!-- The Switch thumb color. -->
+ <color name="qc_switch_thumb_color">#FFFFFF</color>
+ <!-- The Switch thumb color when disabled. Use for the dark theme. -->
+ <color name="qc_switch_thumb_color_disabled_on_dark">#757575</color>
+</resources>
diff --git a/car-qc-lib/res/values/dimens.xml b/car-qc-lib/res/values/dimens.xml
index b973774..912891f 100644
--- a/car-qc-lib/res/values/dimens.xml
+++ b/car-qc-lib/res/values/dimens.xml
@@ -24,7 +24,8 @@
<dimen name="qc_row_content_margin">16dp</dimen>
<dimen name="qc_action_items_horizontal_margin">32dp</dimen>
- <dimen name="qc_toggle_size">72dp</dimen>
+ <dimen name="qc_toggle_size">80dp</dimen>
+ <dimen name="qc_toggle_background_size">72dp</dimen>
<dimen name="qc_toggle_margin">12dp</dimen>
<dimen name="qc_row_horizontal_margin">16dp</dimen>
<dimen name="qc_toggle_background_radius">16dp</dimen>
diff --git a/car-qc-lib/res/values/overlayable.xml b/car-qc-lib/res/values/overlayable.xml
new file mode 100644
index 0000000..d5b405a
--- /dev/null
+++ b/car-qc-lib/res/values/overlayable.xml
@@ -0,0 +1,87 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ ~ Copyright (C) 2022 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 FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY.
+REGENERATE USING packages/apps/Car/tests/tools/rro/generate-overlayable.py
+-->
+<resources>
+ <overlayable name="car-qc-lib">
+ <policy type="system|product|signature">
+ <item type="attr" name="state_toggle_unavailable"/>
+ <item type="color" name="qc_start_icon_color"/>
+ <item type="color" name="qc_toggle_background_color"/>
+ <item type="color" name="qc_toggle_icon_fill_color"/>
+ <item type="color" name="qc_toggle_off_background_color"/>
+ <item type="color" name="qc_toggle_rotary_shadow_color"/>
+ <item type="color" name="qc_toggle_unavailable_background_color"/>
+ <item type="color" name="qc_toggle_unavailable_color"/>
+ <item type="dimen" name="qc_action_items_horizontal_margin"/>
+ <item type="dimen" name="qc_row_content_margin"/>
+ <item type="dimen" name="qc_row_horizontal_margin"/>
+ <item type="dimen" name="qc_row_icon_margin_end"/>
+ <item type="dimen" name="qc_row_icon_size"/>
+ <item type="dimen" name="qc_row_margin_vertical"/>
+ <item type="dimen" name="qc_row_min_height"/>
+ <item type="dimen" name="qc_row_padding_end"/>
+ <item type="dimen" name="qc_row_padding_start"/>
+ <item type="dimen" name="qc_seekbar_padding_top"/>
+ <item type="dimen" name="qc_toggle_background_padding"/>
+ <item type="dimen" name="qc_toggle_background_radius"/>
+ <item type="dimen" name="qc_toggle_foreground_icon_inset"/>
+ <item type="dimen" name="qc_toggle_margin"/>
+ <item type="dimen" name="qc_toggle_rotary_highlight_radius"/>
+ <item type="dimen" name="qc_toggle_rotary_highlight_size"/>
+ <item type="dimen" name="qc_toggle_rotary_shadow_padding"/>
+ <item type="dimen" name="qc_toggle_rotary_shadow_radius"/>
+ <item type="dimen" name="qc_toggle_rotary_shadow_size"/>
+ <item type="dimen" name="qc_toggle_rotary_shadow_width"/>
+ <item type="dimen" name="qc_toggle_background_size"/>
+ <item type="dimen" name="qc_toggle_size"/>
+ <item type="dimen" name="qc_toggle_unavailable_outline_width"/>
+ <item type="drawable" name="qc_row_action_divider"/>
+ <item type="drawable" name="qc_seekbar_wrapper_background"/>
+ <item type="drawable" name="qc_toggle_background"/>
+ <item type="drawable" name="qc_toggle_button_background"/>
+ <item type="drawable" name="qc_toggle_rotary_background"/>
+ <item type="drawable" name="qc_toggle_rotary_highlight"/>
+ <item type="drawable" name="qc_toggle_rotary_shadow"/>
+ <item type="drawable" name="qc_toggle_unavailable_background"/>
+ <item type="id" name="barrier1"/>
+ <item type="id" name="barrier2"/>
+ <item type="id" name="qc_icon"/>
+ <item type="id" name="qc_row_content"/>
+ <item type="id" name="qc_row_end_items"/>
+ <item type="id" name="qc_row_start_items"/>
+ <item type="id" name="qc_seekbar"/>
+ <item type="id" name="qc_seekbar_wrapper"/>
+ <item type="id" name="qc_summary"/>
+ <item type="id" name="qc_tile_toggle_button"/>
+ <item type="id" name="qc_tile_wrapper"/>
+ <item type="id" name="qc_title"/>
+ <item type="id" name="qc_toggle_button"/>
+ <item type="layout" name="qc_action_switch"/>
+ <item type="layout" name="qc_action_toggle"/>
+ <item type="layout" name="qc_row_view"/>
+ <item type="layout" name="qc_tile_view"/>
+ <item type="style" name="TextAppearance.QC"/>
+ <item type="style" name="TextAppearance.QC.Subtitle"/>
+ <item type="style" name="TextAppearance.QC.Title"/>
+ <item type="style" name="Widget.QC"/>
+ <item type="style" name="Widget.QC.SeekBar"/>
+ </policy>
+ </overlayable>
+</resources>
\ No newline at end of file
diff --git a/car-qc-lib/src/com/android/car/qc/provider/BaseQCProvider.java b/car-qc-lib/src/com/android/car/qc/provider/BaseQCProvider.java
index 61db361..8e9e550 100644
--- a/car-qc-lib/src/com/android/car/qc/provider/BaseQCProvider.java
+++ b/car-qc-lib/src/com/android/car/qc/provider/BaseQCProvider.java
@@ -172,7 +172,11 @@
try {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
- .penaltyDeath()
+
+ // TODO(268275789): Revert back to penaltyDeath and ensure it works in
+ // presubmit
+ .penaltyLog()
+
.build());
return onBind(uri);
} finally {
diff --git a/car-qc-lib/src/com/android/car/qc/view/QCRowView.java b/car-qc-lib/src/com/android/car/qc/view/QCRowView.java
index 1e10e4b..c374602 100644
--- a/car-qc-lib/src/com/android/car/qc/view/QCRowView.java
+++ b/car-qc-lib/src/com/android/car/qc/view/QCRowView.java
@@ -193,7 +193,7 @@
mStartItemsContainer = findViewById(R.id.qc_row_start_items);
mEndItemsContainer = findViewById(R.id.qc_row_end_items);
mSeekBarContainer = findViewById(R.id.qc_seekbar_wrapper);
- mSeekBar = findViewById(R.id.seekbar);
+ mSeekBar = findViewById(R.id.qc_seekbar);
}
void setActionListener(QCActionListener listener) {
@@ -311,6 +311,8 @@
(action.isEnabled() || action.isClickableWhileDisabled()) && action.isAvailable();
switchView.setOnCheckedChangeListener(null);
switchView.setEnabled(shouldEnableView);
+ switchView.setThumbTintList(getContext().getColorStateList(
+ R.color.qc_switch_thumb_selector));
switchView.setChecked(action.isChecked());
switchView.setOnTouchListener((v, event) -> {
if (!action.isEnabled()) {
@@ -397,13 +399,15 @@
// remove current action view
root.removeView(actionView);
}
- actionView = mLayoutInflater.inflate(resId, /* root= */ null);
+ actionView = mLayoutInflater.inflate(resId, root, /* attachToRoot= */ false);
root.addView(actionView);
return actionView;
}
private void initSlider(QCSlider slider) {
mQCSlider = slider;
+ CarUiUtils.makeAllViewsEnabled(mSeekBar, slider.isEnabled());
+
mSeekBar.setOnSeekBarChangeListener(null);
mSeekBar.setMin(slider.getMin());
mSeekBar.setMax(slider.getMax());
@@ -411,6 +415,8 @@
mSeekBar.setEnabled(slider.isEnabled());
mSeekBar.setClickableWhileDisabled(slider.isClickableWhileDisabled());
mSeekBar.setDisabledClickListener(seekBar -> fireAction(slider, new Intent()));
+ mSeekBar.setThumbTintList(getContext().getColorStateList(
+ R.color.qc_seekbar_thumb_selector));
if (!slider.isEnabled() && mInDirectManipulationMode) {
setInDirectManipulationMode(mSeekBarContainer, mSeekBar, false);
}
diff --git a/car-qc-lib/tests/unit/src/com/android/car/qc/view/QCRowViewTest.java b/car-qc-lib/tests/unit/src/com/android/car/qc/view/QCRowViewTest.java
index 647317a..9c1aa79 100644
--- a/car-qc-lib/tests/unit/src/com/android/car/qc/view/QCRowViewTest.java
+++ b/car-qc-lib/tests/unit/src/com/android/car/qc/view/QCRowViewTest.java
@@ -30,12 +30,14 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
import android.graphics.drawable.Icon;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
+import android.widget.Switch;
import android.widget.TextView;
import androidx.test.annotation.UiThreadTest;
@@ -203,11 +205,50 @@
.addSlider(new QCSlider.Builder().setInputAction(action).build())
.build();
mView.setRow(row);
- SeekBar seekBar = mView.findViewById(R.id.seekbar);
+ SeekBar seekBar = mView.findViewById(R.id.qc_seekbar);
seekBar.setProgress(50);
MotionEvent motionEvent = ExtendedMockito.mock(MotionEvent.class);
ExtendedMockito.when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_UP);
seekBar.onTouchEvent(motionEvent);
verify(action).send(any(Context.class), anyInt(), any(Intent.class));
}
+
+ @Test
+ @UiThreadTest
+ public void setRow_switchViewThumbTintList() {
+ PendingIntent action = mock(PendingIntent.class);
+ QCRow row = new QCRow.Builder()
+ .addEndItem(
+ new QCActionItem.Builder(QC_TYPE_ACTION_SWITCH).setAction(action).build())
+ .build();
+ mView.setRow(row);
+ LinearLayout endContainer = mView.findViewById(R.id.qc_row_end_items);
+ assertThat(endContainer.getChildCount()).isEqualTo(1);
+ Switch switchView = (Switch) endContainer.getChildAt(0);
+ assertThat(switchView.getThumbTintList()).isNotNull();
+
+ ColorStateList switchColorStateList = switchView.getThumbTintList();
+ int[] enabledState = {android.R.attr.state_enabled};
+ int[] disabledState = {-android.R.attr.state_enabled};
+ assertThat(switchColorStateList.getColorForState(enabledState, 0)).isNotEqualTo(
+ switchColorStateList.getColorForState(disabledState, 0));
+ }
+
+ @Test
+ @UiThreadTest
+ public void setRow_sliderViewThumbTintList() {
+ PendingIntent action = mock(PendingIntent.class);
+ QCRow row = new QCRow.Builder()
+ .addSlider(new QCSlider.Builder().setInputAction(action).build())
+ .build();
+ mView.setRow(row);
+ SeekBar seekBar = mView.findViewById(R.id.qc_seekbar);
+ assertThat(seekBar.getThumbTintList()).isNotNull();
+
+ ColorStateList seekBarColorStateList = seekBar.getThumbTintList();
+ int[] enabledState = {android.R.attr.state_enabled};
+ int[] disabledState = {-android.R.attr.state_enabled};
+ assertThat(seekBarColorStateList.getColorForState(enabledState, 0)).isNotEqualTo(
+ seekBarColorStateList.getColorForState(disabledState, 0));
+ }
}
diff --git a/tools/rro/resource_utils.py b/tools/rro/resource_utils.py
index 5f35e1a..fe4c52c 100644
--- a/tools/rro/resource_utils.py
+++ b/tools/rro/resource_utils.py
@@ -15,7 +15,11 @@
import os
import re
-import lxml.etree as etree
+try:
+ import lxml.etree as etree
+except ImportError:
+ print("Please install 'lxml' python package and retry.")
+ sys.exit(1)
class ResourceLocation:
def __init__(self, file, line=None):