Merge "Bugfix: dnd icon overlapping media volume icon" into main
diff --git a/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml b/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
index bddcb6a..cf301c9 100644
--- a/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout-land-television/volume_dialog_row.xml
@@ -79,7 +79,4 @@
android:tint="@color/accent_tint_color_selector"
android:soundEffectsEnabled="false" />
</LinearLayout>
-
- <include layout="@layout/volume_dnd_icon"/>
-
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index 3b70dc0..5ce2601 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -70,12 +70,6 @@
android:tint="?android:attr/textColorPrimary"
android:layout_gravity="center"
android:soundEffectsEnabled="false" />
-
- <include layout="@layout/volume_dnd_icon"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/volume_dialog_stream_padding"
- android:layout_marginTop="6dp"/>
</FrameLayout>
<LinearLayout
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 6a192d4..39a1f1f 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -69,12 +69,6 @@
android:tint="?android:attr/textColorPrimary"
android:layout_gravity="center"
android:soundEffectsEnabled="false" />
-
- <include layout="@layout/volume_dnd_icon"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/volume_dialog_stream_padding"
- android:layout_marginTop="6dp"/>
</FrameLayout>
<LinearLayout
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index c9256ae..f35de05 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -62,7 +62,6 @@
android:background="@null"
android:layoutDirection="ltr"
android:rotation="270" />
- <include layout="@layout/volume_dnd_icon"/>
</FrameLayout>
<com.android.keyguard.AlphaOptimizedImageButton
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 0ff308e..280c66a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -99,7 +99,6 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
-import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -256,7 +255,6 @@
private CaptionsToggleImageButton mODICaptionsIcon;
private View mSettingsView;
private ImageButton mSettingsIcon;
- private FrameLayout mZenIcon;
private final List<VolumeRow> mRows = new ArrayList<>();
private ConfigurableTexts mConfigurableTexts;
private final SparseBooleanArray mDynamic = new SparseBooleanArray();
@@ -633,7 +631,6 @@
mRinger = mDialog.findViewById(R.id.ringer);
if (mRinger != null) {
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
- mZenIcon = mRinger.findViewById(R.id.dnd_icon);
}
mSelectedRingerIcon = mDialog.findViewById(R.id.volume_new_ringer_active_icon);
@@ -847,7 +844,6 @@
if (stream == STREAM_ACCESSIBILITY) {
row.header.setFilters(new InputFilter[] {new InputFilter.LengthFilter(13)});
}
- row.dndIcon = row.view.findViewById(R.id.dnd_icon);
row.slider = row.view.findViewById(R.id.volume_row_slider);
row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
row.number = row.view.findViewById(R.id.volume_number);
@@ -1791,27 +1787,13 @@
}
/**
- * Toggles enable state of views in a VolumeRow (not including seekbar or icon)
- * Hides/shows zen icon
- * @param enable whether to enable volume row views and hide dnd icon
- */
- private void enableVolumeRowViewsH(VolumeRow row, boolean enable) {
- boolean showDndIcon = !enable;
- row.dndIcon.setVisibility(showDndIcon ? VISIBLE : GONE);
- }
-
- /**
* Toggles enable state of footer/ringer views
- * Hides/shows zen icon
- * @param enable whether to enable ringer views and hide dnd icon
+ * @param enable whether to enable ringer views
*/
private void enableRingerViewsH(boolean enable) {
if (mRingerIcon != null) {
mRingerIcon.setEnabled(enable);
}
- if (mZenIcon != null) {
- mZenIcon.setVisibility(enable ? GONE : VISIBLE);
- }
}
private void trimObsoleteH() {
@@ -1937,9 +1919,11 @@
// update icon
final boolean iconEnabled = (mAutomute || ss.muteSupported) && !zenMuted;
final int iconRes;
- if (isRingVibrate) {
+ if (zenMuted) {
+ iconRes = com.android.internal.R.drawable.ic_qs_dnd;
+ } else if (isRingVibrate) {
iconRes = R.drawable.ic_volume_ringer_vibrate;
- } else if (isRingSilent || zenMuted) {
+ } else if (isRingSilent) {
iconRes = row.iconMuteRes;
} else if (ss.routedToBluetooth) {
if (isVoiceCallStream) {
@@ -2011,7 +1995,6 @@
if (zenMuted) {
row.tracking = false;
}
- enableVolumeRowViewsH(row, !zenMuted);
// update slider
final boolean enableSlider = !zenMuted;
@@ -2582,7 +2565,6 @@
private ObjectAnimator anim; // slider progress animation for non-touch-related updates
private int animTargetProgress;
private int lastAudibleLevel = 1;
- private FrameLayout dndIcon;
void setIcon(int iconRes, Resources.Theme theme) {
if (icon != null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index c4c7472..7456e00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -26,6 +26,8 @@
import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertTrue;
@@ -40,6 +42,9 @@
import android.app.KeyguardManager;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.SystemClock;
import android.provider.Settings;
@@ -52,6 +57,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageButton;
import androidx.test.core.view.MotionEventBuilder;
import androidx.test.filters.SmallTest;
@@ -90,6 +96,7 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
import java.util.function.Predicate;
@SmallTest
@@ -757,6 +764,86 @@
foundCaptionLog);
}
+ @Test
+ public void turnOnDnD_volumeSliderIconChangesToDnd() {
+ State state = createShellState();
+ state.zenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+ mDialog.onStateChangedH(state);
+ mTestableLooper.processAllMessages();
+
+ boolean foundDnDIcon = findDndIconAmongVolumeRows();
+ assertTrue(foundDnDIcon);
+ }
+
+ @Test
+ public void turnOffDnD_volumeSliderIconIsNotDnd() {
+ State state = createShellState();
+ state.zenMode = Settings.Global.ZEN_MODE_OFF;
+
+ mDialog.onStateChangedH(state);
+ mTestableLooper.processAllMessages();
+
+ boolean foundDnDIcon = findDndIconAmongVolumeRows();
+ assertFalse(foundDnDIcon);
+ }
+
+ /**
+ * @return true if at least one volume row has the DND icon
+ */
+ private boolean findDndIconAmongVolumeRows() {
+ ViewGroup volumeDialogRows = mDialog.getDialogView().findViewById(R.id.volume_dialog_rows);
+ assumeNotNull(volumeDialogRows);
+ Drawable expected = getContext().getDrawable(com.android.internal.R.drawable.ic_qs_dnd);
+ boolean foundDnDIcon = false;
+ final int rowCount = volumeDialogRows.getChildCount();
+ // we don't make assumptions about the position of the dnd row
+ for (int i = 0; i < rowCount && !foundDnDIcon; i++) {
+ View volumeRow = volumeDialogRows.getChildAt(i);
+ ImageButton rowIcon = volumeRow.findViewById(R.id.volume_row_icon);
+ assertNotNull(rowIcon);
+
+ // VolumeDialogImpl changes tint and alpha in a private method, so we clear those here.
+ rowIcon.setImageTintList(null);
+ rowIcon.setAlpha(0xFF);
+
+ Drawable actual = rowIcon.getDrawable();
+ foundDnDIcon |= areDrawablesEqual(expected, actual);
+ }
+ return foundDnDIcon;
+ }
+
+ private boolean areDrawablesEqual(Drawable drawable1, Drawable drawable2) {
+ int size = 100;
+ Bitmap bm1 = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+ Bitmap bm2 = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+
+ Canvas canvas1 = new Canvas(bm1);
+ Canvas canvas2 = new Canvas(bm2);
+
+ drawable1.setBounds(0, 0, size, size);
+ drawable2.setBounds(0, 0, size, size);
+
+ drawable1.draw(canvas1);
+ drawable2.draw(canvas2);
+
+ boolean areBitmapsEqual = areBitmapsEqual(bm1, bm2);
+ bm1.recycle();
+ bm2.recycle();
+ return areBitmapsEqual;
+ }
+
+ private boolean areBitmapsEqual(Bitmap a, Bitmap b) {
+ if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) return false;
+ int w = a.getWidth();
+ int h = a.getHeight();
+ int[] aPix = new int[w * h];
+ int[] bPix = new int[w * h];
+ a.getPixels(aPix, 0, w, 0, 0, w, h);
+ b.getPixels(bPix, 0, w, 0, 0, w, h);
+ return Arrays.equals(aPix, bPix);
+ }
+
@After
public void teardown() {
// Detailed logs to track down timeout issues in b/299491332