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:
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user