Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb2d0cc0 authored by Adrian Roos's avatar Adrian Roos
Browse files

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
parent 6ba95dab
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -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) {
+55 −10
Original line number Diff line number Diff line
@@ -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));
    }
}
 No newline at end of file