StatusBar: Catch OOM caused by third-party icons

Bug: 31825355
Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
Change-Id: I3e2a8c3da43a572a026ea0bbe1d39234035a4801
This commit is contained in:
Adrian Roos
2017-01-31 15:10:00 -08:00
parent 6ba95dab42
commit fb2d0cc090
2 changed files with 64 additions and 12 deletions

View File

@@ -256,9 +256,16 @@ public class StatusBarIconView extends AnimatedImageView {
if (mIcon == null) {
return false;
}
Drawable drawable = getIcon(mIcon);
Drawable drawable;
try {
drawable = getIcon(mIcon);
} catch (OutOfMemoryError e) {
Log.w(TAG, "OOM while inflating " + mIcon.icon + " for slot " + mSlot);
return false;
}
if (drawable == null) {
Log.w(TAG, "No icon for slot " + mSlot);
Log.w(TAG, "No icon for slot " + mSlot + "; " + mIcon.icon);
return false;
}
if (withClear) {

View File

@@ -16,36 +16,74 @@
package com.android.systemui.statusbar;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Debug;
import android.os.UserHandle;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import static junit.framework.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.mockito.ArgumentMatcher;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class StatusBarIconViewTest extends SysuiTestCase {
@Rule
public ExpectedException mThrown = ExpectedException.none();
private StatusBarIconView mIconView;
private StatusBarIcon mStatusBarIcon = mock(StatusBarIcon.class);
private PackageManager mPackageManagerSpy;
private Context mContext;
private Resources mMockResources;
@Before
public void setUp() {
mIconView = new StatusBarIconView(getContext(), "slot", null);
mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, getContext().getPackageName(),
Icon.createWithResource(getContext(), R.drawable.ic_android), 0, 0, "");
public void setUp() throws Exception {
// Set up context such that asking for "mockPackage" resources returns mMockResources.
mMockResources = mock(Resources.class);
mPackageManagerSpy = spy(getContext().getPackageManager());
doReturn(mMockResources).when(mPackageManagerSpy)
.getResourcesForApplicationAsUser(eq("mockPackage"), anyInt());
doReturn(mMockResources).when(mPackageManagerSpy)
.getResourcesForApplication(eq("mockPackage"));
doReturn(mMockResources).when(mPackageManagerSpy).getResourcesForApplication(argThat(
(ArgumentMatcher<ApplicationInfo>) o -> "mockPackage".equals(o.packageName)));
mContext = new ContextWrapper(getContext()) {
@Override
public PackageManager getPackageManager() {
return mPackageManagerSpy;
}
};
mIconView = new StatusBarIconView(mContext, "test_slot", null);
mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
Icon.createWithResource(mContext, R.drawable.ic_android), 0, 0, "");
}
@Test
@@ -55,4 +93,11 @@ public class StatusBarIconViewTest extends SysuiTestCase {
assertNull(mIconView.getTag(R.id.icon_is_grayscale));
}
@Test
public void testSettingOomingIconDoesNotThrowOom() {
when(mMockResources.getDrawable(anyInt(), any())).thenThrow(new OutOfMemoryError("mocked"));
mStatusBarIcon.icon = Icon.createWithResource("mockPackage", R.drawable.ic_android);
assertFalse(mIconView.set(mStatusBarIcon));
}
}