From 418ffe4a0feeeff3e29b3852bc37b3092f4c864a Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Tue, 13 Jun 2017 15:09:21 -0400 Subject: [PATCH] Change SlashDrawable semantics to fix QS crash SlashDrawable wraps a reference to Drawable in order to store the intended Drawable and optionally draw a slash over it. As such, it should probably have similar semantics to Drawable, in that it either exists or doesn't; if you set SlashImageView's drawable to `null`, you'd expect that the drawable goes away, not that the SlashDrawable's contained Drawable goes away but the slash stays. Test: runtest systemui Change-Id: I34b92716cc60ba5043ab68ae09954f5a5e97e562 Fixes: 62525439 --- .../systemui/qs/tileimpl/SlashImageView.java | 13 +++- .../systemui/qs/SlashImageViewTest.java | 76 +++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java index 603f66beca63d..315a815af1003 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java @@ -18,12 +18,14 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.widget.ImageView; +import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.qs.QSTile.SlashState; import com.android.systemui.qs.SlashDrawable; public class SlashImageView extends ImageView { - private SlashDrawable mSlash; + @VisibleForTesting + protected SlashDrawable mSlash; public SlashImageView(Context context) { super(context); @@ -38,10 +40,13 @@ public class SlashImageView extends ImageView { @Override public void setImageDrawable(Drawable drawable) { - if (mSlash != null) { - mSlash.setDrawable(drawable); - } else { + if (drawable == null) { + mSlash = null; + super.setImageDrawable(null); + } else if (mSlash == null) { super.setImageDrawable(drawable); + } else { + mSlash.setDrawable(drawable); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java new file mode 100644 index 0000000000000..aef584f8d9867 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.qs.QSTile.SlashState; +import com.android.systemui.qs.tileimpl.SlashImageView; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class SlashImageViewTest extends SysuiTestCase { + private TestableSlashImageView mSlashView; + + @Test + public void testSetSlashStateCreatesSlashDrawable() { + SlashState mockState = mock(SlashState.class); + Drawable mockDrawable = mock(Drawable.class); + mSlashView = new TestableSlashImageView(mContext); + assertTrue(mSlashView.getSlashDrawable() == null); + + mSlashView.setImageDrawable(mockDrawable); + mSlashView.setState(mockState); + + assertTrue(mSlashView.getSlashDrawable() != null); + } + + @Test + public void testSetNullDrawableRemovesSlashDrawable() { + SlashState mockState = mock(SlashState.class); + Drawable mockDrawable = mock(Drawable.class); + + mSlashView = new TestableSlashImageView(mContext); + mSlashView.setImageDrawable(mockDrawable); + mSlashView.setState(mockState); + mSlashView.setImageDrawable(null); + + assertTrue(mSlashView.getSlashDrawable() == null); + } + + // Expose getSlashDrawable + private static class TestableSlashImageView extends SlashImageView { + TestableSlashImageView(Context c) { + super(c); + } + + private SlashDrawable getSlashDrawable() { + return mSlash; + } + } +}