summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java45
2 files changed, 49 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f0bc4129f4ef..e02456e81822 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4176,6 +4176,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final Runnable enterPipRunnable = () -> {
synchronized (mGlobalLock) {
+ if (r.getParent() == null) {
+ Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
+ return;
+ }
// Only update the saved args from the args that are set
r.pictureInPictureArgs.copyOnlySet(params);
final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 591ed51efdb2..f1de6e914032 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -19,15 +19,21 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.PictureInPictureParams;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.os.IBinder;
import android.view.IDisplayWindowListener;
import android.view.WindowContainerTransaction;
@@ -36,6 +42,7 @@ import androidx.test.filters.MediumTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.MockitoSession;
import java.util.ArrayList;
@@ -148,5 +155,43 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
assertEquals(0, changed.size());
assertEquals(1, removed.size());
}
+
+ /*
+ a test to verify b/144045134 - ignore PIP mode request for destroyed activity.
+ mocks r.getParent() to return null to cause NPE inside enterPipRunnable#run() in
+ ActivityTaskMangerservice#enterPictureInPictureMode(), which rebooted the device.
+ It doesn't fully simulate the issue's reproduce steps, but this should suffice.
+ */
+ @Test
+ public void testEnterPipModeWhenRecordParentChangesToNull() {
+ MockitoSession mockSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(ActivityRecord.class)
+ .startMocking();
+
+ ActivityRecord record = mock(ActivityRecord.class);
+ IBinder token = mock(IBinder.class);
+ PictureInPictureParams params = mock(PictureInPictureParams.class);
+ record.pictureInPictureArgs = params;
+
+ //mock operations in private method ensureValidPictureInPictureActivityParamsLocked()
+ when(ActivityRecord.forTokenLocked(token)).thenReturn(record);
+ doReturn(true).when(record).supportsPictureInPicture();
+ doReturn(false).when(params).hasSetAspectRatio();
+
+ //mock other operations
+ doReturn(true).when(record)
+ .checkEnterPictureInPictureState("enterPictureInPictureMode", false);
+ doReturn(false).when(mService).isInPictureInPictureMode(any());
+ doReturn(false).when(mService).isKeyguardLocked();
+
+ //to simulate NPE
+ doReturn(null).when(record).getParent();
+
+ mService.enterPictureInPictureMode(token, params);
+ //if record's null parent is not handled gracefully, test will fail with NPE
+
+ mockSession.finishMocking();
+ }
}