Snap for 10453563 from 713d469f0193a991a8ce5acd0415692d34b9658d to mainline-tzdata5-release

Change-Id: Ie7a3106a92a14cf40eb58786dc698f237a1a141e
diff --git a/car-qc-lib/src/com/android/car/qc/QCActionItem.java b/car-qc-lib/src/com/android/car/qc/QCActionItem.java
index c476e09..b7b9cd1 100644
--- a/car-qc-lib/src/com/android/car/qc/QCActionItem.java
+++ b/car-qc-lib/src/com/android/car/qc/QCActionItem.java
@@ -17,11 +17,13 @@
 package com.android.car.qc;
 
 import android.app.PendingIntent;
+import android.content.Context;
 import android.graphics.drawable.Icon;
 import android.os.Parcel;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
 
 /**
  * Quick Control Action that are includes as either start or end actions in {@link QCRow}
@@ -32,14 +34,17 @@
     private Icon mIcon;
     private PendingIntent mAction;
     private PendingIntent mDisabledClickAction;
+    private String mContentDescription;
 
     public QCActionItem(@NonNull @QCItemType String type, boolean isChecked, boolean isEnabled,
             boolean isAvailable, boolean isClickableWhileDisabled, @Nullable Icon icon,
-            @Nullable PendingIntent action, @Nullable PendingIntent disabledClickAction) {
+            @Nullable String contentDescription, @Nullable PendingIntent action,
+            @Nullable PendingIntent disabledClickAction) {
         super(type, isEnabled, isClickableWhileDisabled);
         mIsChecked = isChecked;
         mIsAvailable = isAvailable;
         mIcon = icon;
+        mContentDescription = contentDescription;
         mAction = action;
         mDisabledClickAction = disabledClickAction;
     }
@@ -52,6 +57,10 @@
         if (hasIcon) {
             mIcon = Icon.CREATOR.createFromParcel(in);
         }
+        boolean hasContentDescription = in.readBoolean();
+        if (hasContentDescription) {
+            mContentDescription = in.readString();
+        }
         boolean hasAction = in.readBoolean();
         if (hasAction) {
             mAction = PendingIntent.CREATOR.createFromParcel(in);
@@ -72,6 +81,11 @@
         if (includeIcon) {
             mIcon.writeToParcel(dest, flags);
         }
+        boolean hasContentDescription = mContentDescription != null;
+        dest.writeBoolean(hasContentDescription);
+        if (hasContentDescription) {
+            dest.writeString(mContentDescription);
+        }
         boolean hasAction = mAction != null;
         dest.writeBoolean(hasAction);
         if (hasAction) {
@@ -107,6 +121,11 @@
         return mIcon;
     }
 
+    @Nullable
+    public String getContentDescription() {
+        return mContentDescription;
+    }
+
     public static Creator<QCActionItem> CREATOR = new Creator<QCActionItem>() {
         @Override
         public QCActionItem createFromParcel(Parcel source) {
@@ -131,6 +150,7 @@
         private Icon mIcon;
         private PendingIntent mAction;
         private PendingIntent mDisabledClickAction;
+        private String mContentDescription;
 
         public Builder(@NonNull @QCItemType String type) {
             if (!isValidType(type)) {
@@ -180,6 +200,23 @@
         }
 
         /**
+         * Sets the content description
+         */
+        public Builder setContentDescription(@Nullable String contentDescription) {
+            mContentDescription = contentDescription;
+            return this;
+        }
+
+        /**
+         * Sets the string resource to use for content description
+         */
+        public Builder setContentDescription(@NonNull Context context,
+                @StringRes int contentDescriptionResId) {
+            mContentDescription = context.getString(contentDescriptionResId);
+            return this;
+        }
+
+        /**
          * Sets the PendingIntent to be sent when the action item is clicked.
          */
         public Builder setAction(@Nullable PendingIntent action) {
@@ -200,7 +237,8 @@
          */
         public QCActionItem build() {
             return new QCActionItem(mType, mIsChecked, mIsEnabled, mIsAvailable,
-                    mIsClickableWhileDisabled, mIcon, mAction, mDisabledClickAction);
+                    mIsClickableWhileDisabled, mIcon, mContentDescription, mAction,
+                    mDisabledClickAction);
         }
 
         private boolean isValidType(String type) {
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 c374602..2b6b7a5 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
@@ -314,6 +314,7 @@
         switchView.setThumbTintList(getContext().getColorStateList(
                 R.color.qc_switch_thumb_selector));
         switchView.setChecked(action.isChecked());
+        switchView.setContentDescription(action.getContentDescription());
         switchView.setOnTouchListener((v, event) -> {
             if (!action.isEnabled()) {
                 if (event.getActionMasked() == MotionEvent.ACTION_UP) {
@@ -347,6 +348,7 @@
         toggleButton.setOnCheckedChangeListener(null);
         Drawable icon = QCViewUtils.getInstance(mContext).getToggleIcon(
                 action.getIcon(), action.isAvailable());
+        toggleButton.setContentDescription(action.getContentDescription());
         toggleButton.setButtonDrawable(icon);
         toggleButton.setChecked(action.isChecked());
         toggleButton.setEnabled(shouldEnableView);
diff --git a/car-qc-lib/tests/unit/src/com/android/car/qc/QCActionItemTest.java b/car-qc-lib/tests/unit/src/com/android/car/qc/QCActionItemTest.java
index ff70540..c945301 100644
--- a/car-qc-lib/tests/unit/src/com/android/car/qc/QCActionItemTest.java
+++ b/car-qc-lib/tests/unit/src/com/android/car/qc/QCActionItemTest.java
@@ -33,32 +33,34 @@
 
 @RunWith(AndroidJUnit4.class)
 public class QCActionItemTest extends QCItemTestCase<QCActionItem> {
+    private static final String TEST_CONTENT_DESCRIPTION = "test_content_description";
 
     @Test
     public void onCreate_invalidType_throwsException() {
         assertThrows(IllegalArgumentException.class,
                 () -> createAction("INVALID_TYPE", /* action= */ null,
-                        /* disabledAction= */ null, /* icon= */ null));
+                        /* disabledAction= */ null, /* icon= */ null, /* contentDescription=*/
+                        null));
     }
 
     @Test
     public void onCreateSwitch_hasCorrectType() {
         QCActionItem action = createAction(QC_TYPE_ACTION_SWITCH, /* action= */ null,
-                /* disabledAction= */ null, /* icon= */null);
+                /* disabledAction= */ null, /* icon= */null, /* contentDescription=*/ null);
         assertThat(action.getType()).isEqualTo(QC_TYPE_ACTION_SWITCH);
     }
 
     @Test
     public void onCreateToggle_hasCorrectType() {
         QCActionItem action = createAction(QC_TYPE_ACTION_TOGGLE, /* action= */ null,
-                /* disabledAction= */ null, /* icon= */ null);
+                /* disabledAction= */ null, /* icon= */ null, /* contentDescription=*/ null);
         assertThat(action.getType()).isEqualTo(QC_TYPE_ACTION_TOGGLE);
     }
 
     @Test
     public void onBundle_nullActions_noCrash() {
         QCActionItem action = createAction(QC_TYPE_ACTION_TOGGLE, /* action= */ null,
-                /* disabledAction= */ null, mDefaultIcon);
+                /* disabledAction= */ null, mDefaultIcon, /* contentDescription=*/ null);
         writeAndLoadFromBundle(action);
         // Test passes if this doesn't crash
     }
@@ -66,7 +68,7 @@
     @Test
     public void onBundle_nullIcon_noCrash() {
         QCActionItem action = createAction(QC_TYPE_ACTION_TOGGLE, mDefaultAction,
-                mDefaultDisabledAction, /* icon= */ null);
+                mDefaultDisabledAction, /* icon= */ null, /* contentDescription=*/ null);
         writeAndLoadFromBundle(action);
         // Test passes if this doesn't crash
     }
@@ -74,7 +76,7 @@
     @Test
     public void onBundle_switch_accurateData() {
         QCActionItem action = createAction(QC_TYPE_ACTION_SWITCH, mDefaultAction,
-                mDefaultDisabledAction, /* icon= */ null);
+                mDefaultDisabledAction, /* icon= */ null, TEST_CONTENT_DESCRIPTION);
         QCActionItem newAction = writeAndLoadFromBundle(action);
         assertThat(newAction.getType()).isEqualTo(QC_TYPE_ACTION_SWITCH);
         assertThat(newAction.isChecked()).isTrue();
@@ -82,12 +84,13 @@
         assertThat(newAction.isClickableWhileDisabled()).isFalse();
         assertThat(newAction.getPrimaryAction()).isNotNull();
         assertThat(newAction.getIcon()).isNull();
+        assertThat(newAction.getContentDescription()).isEqualTo(TEST_CONTENT_DESCRIPTION);
     }
 
     @Test
     public void onBundle_toggle_accurateDate() {
         QCActionItem action = createAction(QC_TYPE_ACTION_TOGGLE, mDefaultAction,
-                mDefaultDisabledAction, mDefaultIcon);
+                mDefaultDisabledAction, mDefaultIcon, TEST_CONTENT_DESCRIPTION);
         QCActionItem newAction = writeAndLoadFromBundle(action);
         assertThat(newAction.getType()).isEqualTo(QC_TYPE_ACTION_TOGGLE);
         assertThat(newAction.isChecked()).isTrue();
@@ -95,16 +98,18 @@
         assertThat(newAction.isClickableWhileDisabled()).isFalse();
         assertThat(newAction.getPrimaryAction()).isNotNull();
         assertThat(newAction.getIcon()).isNotNull();
+        assertThat(newAction.getContentDescription()).isEqualTo(TEST_CONTENT_DESCRIPTION);
     }
 
     private QCActionItem createAction(String type, PendingIntent action,
-            PendingIntent disabledAction, Icon icon) {
+            PendingIntent disabledAction, Icon icon, String contentDescription) {
         return new QCActionItem.Builder(type)
                 .setChecked(true)
                 .setEnabled(true)
                 .setAction(action)
                 .setDisabledClickAction(disabledAction)
                 .setIcon(icon)
+                .setContentDescription(contentDescription)
                 .build();
     }
 }