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

Commit b5b32d47 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Fix NPE in WakeLock#finalize for unit test

The stubbed method of "mock(PowerManager.WakeLock.class)" will
lose effect after clearInlineMocks. And then finalizer runs
the real method finalize() that cause NPE because the mocked
object didn't initialize fields.

Bug: 219640050
Test: atest WmTests

Change-Id: If8ee4fbc98c9e33d6ab6ba75a65ba177fa06f09c
parent c67b2ca3
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -267,7 +267,8 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
    @Test
    public void testUpdateSleep() {
        doCallRealMethod().when(mWm.mRoot).hasAwakeDisplay();
        mSupervisor.mGoingToSleepWakeLock = mock(PowerManager.WakeLock.class);
        mSupervisor.mGoingToSleepWakeLock =
                mSystemServicesTestRule.createStubbedWakeLock(true /* needVerification */);
        final Task rootHomeTask = mWm.mRoot.getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
        final ActivityRecord homeActivity = new ActivityBuilder(mAtm).setTask(rootHomeTask).build();
        final ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+17 −2
Original line number Diff line number Diff line
@@ -102,6 +102,10 @@ public class SystemServicesTestRule implements TestRule {
    static int sNextTaskId = 100;

    private static final int[] TEST_USER_PROFILE_IDS = {};
    /** Use a real static object so there won't be NPE in finalize() after clearInlineMocks(). */
    private static final PowerManager.WakeLock sWakeLock = getInstrumentation().getContext()
            .getSystemService(PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    private PowerManager.WakeLock mStubbedWakeLock;

    private Description mDescription;
    private Context mContext;
@@ -196,7 +200,8 @@ public class SystemServicesTestRule implements TestRule {
        // Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
        final PowerManager pm = mock(PowerManager.class);
        doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
        doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString());
        mStubbedWakeLock = createStubbedWakeLock(false /* needVerification */);
        doReturn(mStubbedWakeLock).when(pm).newWakeLock(anyInt(), anyString());

        // DisplayManagerInternal
        final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
@@ -403,6 +408,16 @@ public class SystemServicesTestRule implements TestRule {
        return mPowerManagerWrapper;
    }

    /** Creates a no-op wakelock object. */
    PowerManager.WakeLock createStubbedWakeLock(boolean needVerification) {
        if (needVerification) {
            return mock(PowerManager.WakeLock.class, Mockito.withSettings()
                    .spiedInstance(sWakeLock).defaultAnswer(Mockito.RETURNS_DEFAULTS));
        }
        return mock(PowerManager.WakeLock.class, Mockito.withSettings()
                .spiedInstance(sWakeLock).stubOnly());
    }

    void setSurfaceFactory(Supplier<Surface> factory) {
        mSurfaceFactory = factory;
    }
@@ -558,7 +573,7 @@ public class SystemServicesTestRule implements TestRule {
            // unit test version does not handle launch wake lock
            doNothing().when(this).acquireLaunchWakelock();

            mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
            mLaunchingActivityWakeLock = mStubbedWakeLock;

            initialize();