diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 9ca5f2a0dfd12..d33cf2f79e8b0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -62,6 +62,7 @@ import com.android.internal.os.SomeArgs; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.pip.phone.PipMenuActivityController; import com.android.systemui.pip.phone.PipUpdateThread; +import com.android.systemui.pip.phone.PipUtils; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; @@ -260,6 +261,11 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; mSplitScreenOptional = splitScreenOptional; mTaskOrganizer = shellTaskOrganizer; + + if (!PipUtils.hasSystemFeature(context)) { + Log.w(TAG, "Device not support PIP feature"); + return; + } mTaskOrganizer.addListener(this, WINDOWING_MODE_PINNED); displayController.addDisplayWindowListener(this); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java index 5bb179484e5d9..8a2e9e23343cb 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java @@ -18,7 +18,6 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static com.android.systemui.pip.PipAnimationController.isOutPipDirection; @@ -30,7 +29,6 @@ import android.app.IActivityManager; import android.app.RemoteAction; import android.content.ComponentName; import android.content.Context; -import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.graphics.Rect; @@ -278,9 +276,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mContext = context; mActivityManager = ActivityManager.getService(); - PackageManager pm = context.getPackageManager(); - boolean supportsPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); - if (supportsPip) { + if (PipUtils.hasSystemFeature(mContext)) { initController(context, broadcastDispatcher, configController, deviceConfig, displayController, floatingContentCoordinator, sysUiState, pipBoundsHandler, pipSurfaceTransactionHelper, pipTaskOrganizer, pipUiEventLogger); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java index baa8f118f362a..1bf6dd7bb9ef4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java @@ -18,6 +18,7 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; @@ -57,4 +58,14 @@ public class PipUtils { } return new Pair<>(null, 0); } + + /** + * The util to check if device has PIP feature + * + * @param context application context + * @return true if device has PIP feature, false otherwise. + */ + public static boolean hasSystemFeature(Context context) { + return context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 2a976f546ba42..ed8da7c3d80bb 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -16,7 +16,6 @@ package com.android.systemui.recents; -import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; @@ -65,6 +64,7 @@ import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.Dumpable; @@ -77,6 +77,7 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipAnimationController; +import com.android.systemui.pip.phone.PipUtils; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.recents.IOverviewProxy; @@ -155,7 +156,8 @@ public class OverviewProxyService extends CurrentUserTracker implements private boolean mSupportsRoundedCornersOnWindows; private int mNavBarMode = NAV_BAR_MODE_3BUTTON; - private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() { + @VisibleForTesting + public ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() { @Override public void startScreenPinning(int taskId) { @@ -624,7 +626,7 @@ public class OverviewProxyService extends CurrentUserTracker implements super(broadcastDispatcher); mContext = context; mPipOptional = pipOptional; - mHasPipFeature = mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); + mHasPipFeature = PipUtils.hasSystemFeature(mContext); mStatusBarOptionalLazy = statusBarOptionalLazy; mHandler = new Handler(); mNavBarControllerLazy = navBarControllerLazy; diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index ce125f3fdce07..a2d6ac8f8511f 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -40,6 +40,7 @@ import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.pip.Pip; +import com.android.systemui.pip.phone.PipUtils; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.tracing.ProtoTraceable; @@ -57,7 +58,6 @@ import com.android.wm.shell.protolog.ShellProtoLogImpl; import com.android.wm.shell.splitscreen.SplitScreen; import java.io.FileDescriptor; -import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.Optional; @@ -103,7 +103,6 @@ public final class WMShell extends SystemUI ProtoTracer protoTracer) { super(context); mCommandQueue = commandQueue; - mCommandQueue.addCallback(this); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mActivityManagerWrapper = activityManagerWrapper; mDisplayImeController = displayImeController; @@ -120,6 +119,7 @@ public final class WMShell extends SystemUI @Override public void start() { + mCommandQueue.addCallback(this); // This is to prevent circular init problem by separating registration step out of its // constructor. And make sure the initialization of DisplayImeController won't depend on // specific feature anymore. @@ -131,6 +131,9 @@ public final class WMShell extends SystemUI @VisibleForTesting void initPip(Pip pip) { + if (!PipUtils.hasSystemFeature(mContext)) { + return; + } mCommandQueue.addCallback(new CommandQueue.Callbacks() { @Override public void showPictureInPictureMenu() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java new file mode 100644 index 0000000000000..b04349521205a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.pip.phone; + +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.pm.PackageManager; +import android.os.RemoteException; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableContext; +import android.testing.TestableLooper; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.model.SysUiState; +import com.android.systemui.pip.PipBoundsHandler; +import com.android.systemui.pip.PipSurfaceTransactionHelper; +import com.android.systemui.pip.PipTaskOrganizer; +import com.android.systemui.pip.PipUiEventLogger; +import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.util.FloatingContentCoordinator; +import com.android.wm.shell.common.DisplayController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit tests for {@link PipController} + */ +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class PipControllerTest extends SysuiTestCase { + private PipController mPipController; + private TestableContext mSpiedContext; + + @Mock private ActivityManagerWrapper mMockActivityManagerWrapper; + @Mock private BroadcastDispatcher mMockBroadcastDispatcher; + @Mock private ConfigurationController mMockConfigurationController; + @Mock private DeviceConfigProxy mMockDeviceConfigProxy; + @Mock private DisplayController mMockdDisplayController; + @Mock private FloatingContentCoordinator mMockFloatingContentCoordinator; + @Mock private PackageManager mPackageManager; + @Mock private PipBoundsHandler mMockPipBoundsHandler; + @Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper; + @Mock private PipTaskOrganizer mMockPipTaskOrganizer; + @Mock private PipUiEventLogger mPipUiEventLogger; + @Mock private SysUiState mMockSysUiState; + + @Before + public void setUp() throws RemoteException { + MockitoAnnotations.initMocks(this); + + mSpiedContext = spy(mContext); + + when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); + when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager); + + mPipController = new PipController(mSpiedContext, mMockBroadcastDispatcher, + mMockConfigurationController, mMockDeviceConfigProxy, mMockdDisplayController, + mMockFloatingContentCoordinator, mMockSysUiState, mMockPipBoundsHandler, + mMockPipSurfaceTransactionHelper, mMockPipTaskOrganizer, mPipUiEventLogger); + } + + @Test + public void testNonPipDevice_shouldNotRegisterTaskStackListener() { + verify(mMockActivityManagerWrapper, never()).registerTaskStackListener(any()); + } + + @Test + public void testNonPipDevice_shouldNotRegisterPipTransitionCallback() { + verify(mMockPipTaskOrganizer, never()).registerPipTransitionCallback(any()); + } + + @Test + public void testNonPipDevice_shouldNotAddDisplayChangingController() { + verify(mMockdDisplayController, never()).addDisplayChangingController(any()); + } + + @Test + public void testNonPipDevice_shouldNotAddDisplayWindowListener() { + verify(mMockdDisplayController, never()).addDisplayWindowListener(any()); + } + + @Test + public void testNonPipDevice_shouldNotAddCallback() { + verify(mMockConfigurationController, never()).addCallback(any()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTaskOrganizerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTaskOrganizerTest.java new file mode 100644 index 0000000000000..b1a7df83fa9f7 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTaskOrganizerTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.pip.phone; + +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.pm.PackageManager; +import android.os.RemoteException; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableContext; +import android.testing.TestableLooper; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.pip.PipBoundsHandler; +import com.android.systemui.pip.PipSurfaceTransactionHelper; +import com.android.systemui.pip.PipTaskOrganizer; +import com.android.systemui.pip.PipUiEventLogger; +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.splitscreen.SplitScreen; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Optional; + +/** + * Unit tests for {@link PipTaskOrganizer} + */ +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class PipTaskOrganizerTest extends SysuiTestCase { + private PipTaskOrganizer mSpiedPipTaskOrganizer; + private TestableContext mSpiedContext; + + @Mock private DisplayController mMockdDisplayController; + @Mock private PackageManager mPackageManager; + @Mock private PipBoundsHandler mMockPipBoundsHandler; + @Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper; + @Mock private PipUiEventLogger mMockPipUiEventLogger; + @Mock private Optional mMockOptionalSplitScreen; + @Mock private ShellTaskOrganizer mMockShellTaskOrganizer; + + @Before + public void setUp() throws RemoteException { + MockitoAnnotations.initMocks(this); + + mSpiedContext = spy(mContext); + + when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); + when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager); + + mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mSpiedContext, mMockPipBoundsHandler, + mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, mMockdDisplayController, + mMockPipUiEventLogger, mMockShellTaskOrganizer)); + } + + @Test + public void testNonPipDevice_shellTaskOrganizer_shouldNotAddListener() { + verify(mMockShellTaskOrganizer, never()).addListener(any(), anyInt()); + } + + @Test + public void testNonPipDevice_displayController_shouldNotAddDisplayWindowListener() { + verify(mMockdDisplayController, never()).addDisplayWindowListener(any()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java new file mode 100644 index 0000000000000..727f91c589dfb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.recents; + +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.pm.PackageManager; +import android.os.RemoteException; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableContext; +import android.testing.TestableLooper; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.model.SysUiState; +import com.android.systemui.navigationbar.NavigationBarController; +import com.android.systemui.navigationbar.NavigationModeController; +import com.android.systemui.pip.Pip; +import com.android.systemui.shared.recents.IPinnedStackAnimationListener; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.NotificationShadeWindowController; +import com.android.systemui.statusbar.phone.StatusBar; +import com.android.wm.shell.splitscreen.SplitScreen; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Optional; + +import dagger.Lazy; + +/** + * Unit tests for {@link com.android.systemui.recents.OverviewProxyService} + */ +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class OverviewProxyServiceTest extends SysuiTestCase { + private OverviewProxyService mSpiedOverviewProxyService; + private TestableContext mSpiedContext; + + @Mock private BroadcastDispatcher mMockBroadcastDispatcher; + @Mock private CommandQueue mMockCommandQueue; + @Mock private Lazy mMockNavBarControllerLazy; + @Mock private IPinnedStackAnimationListener mMockPinnedStackAnimationListener; + @Mock private NavigationModeController mMockNavModeController; + @Mock private NotificationShadeWindowController mMockStatusBarWinController; + @Mock private Optional mMockPipOptional; + @Mock private Optional mMockSplitScreenOptional; + @Mock private Optional> mMockStatusBarOptionalLazy; + @Mock private Optional mMockOneHandedOptional; + @Mock private PackageManager mPackageManager; + @Mock private SysUiState mMockSysUiState; + + @Before + public void setUp() throws RemoteException { + MockitoAnnotations.initMocks(this); + + mSpiedContext = spy(mContext); + + when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); + when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager); + + mSpiedOverviewProxyService = spy(new OverviewProxyService(mSpiedContext, mMockCommandQueue, + mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController, + mMockSysUiState, mMockPipOptional, mMockSplitScreenOptional, + mMockStatusBarOptionalLazy, mMockOneHandedOptional, + mMockBroadcastDispatcher)); + } + + @Test + public void testNonPipDevice_shouldNotNotifySwipeToHomeFinished() throws RemoteException { + mSpiedOverviewProxyService.mSysUiProxy.notifySwipeToHomeFinished(); + + verify(mMockPipOptional, never()).ifPresent(any()); + } + + @Test + public void testNonPipDevice_shouldNotSetPinnedStackAnimationListener() throws RemoteException { + mSpiedOverviewProxyService.mSysUiProxy.setPinnedStackAnimationListener( + mMockPinnedStackAnimationListener); + + verify(mMockPipOptional, never()).ifPresent(any()); + } + + @Test + public void testNonPipDevice_shouldNotSetShelfHeight() throws RemoteException { + mSpiedOverviewProxyService.mSysUiProxy.setShelfHeight(true /* visible */, + 100 /* shelfHeight */); + + verify(mMockPipOptional, never()).ifPresent(any()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index ef4d1078b8b92..280423fca202d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -16,12 +16,17 @@ package com.android.systemui.wmshell; +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; + import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.pm.PackageManager; import android.test.suitebuilder.annotation.SmallTest; +import android.testing.TestableContext; import androidx.test.runner.AndroidJUnit4; @@ -68,6 +73,7 @@ public class WMShellTest extends SysuiTestCase { @Mock OneHanded mOneHanded; @Mock ShellTaskOrganizer mTaskOrganizer; @Mock ProtoTracer mProtoTracer; + @Mock PackageManager mMockPackageManager; @Before public void setUp() { @@ -89,8 +95,23 @@ public class WMShellTest extends SysuiTestCase { public void initPip_registersCommandQueueCallback() { mWMShell.initPip(mPip); - // Once for the shell, once for pip - verify(mCommandQueue, times(2)).addCallback(any(CommandQueue.Callbacks.class)); + verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class)); + } + + @Test + public void nonPipDevice_shouldNotInitPip() { + TestableContext spiedContext = spy(mContext); + when(mMockPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); + when(spiedContext.getPackageManager()).thenReturn(mMockPackageManager); + + final WMShell nonPipWMShell = new WMShell(spiedContext, mCommandQueue, + mKeyguardUpdateMonitor, + mActivityManagerWrapper, mDisplayImeController, mNavigationModeController, + mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen), + Optional.of(mOneHanded), mTaskOrganizer, mProtoTracer); + nonPipWMShell.initPip(mPip); + + verify(mCommandQueue, never()).addCallback(any()); } @Test @@ -108,8 +129,7 @@ public class WMShellTest extends SysuiTestCase { mWMShell.initOneHanded(mOneHanded); verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class)); - // Once for the shell, once for the one handed mode - verify(mCommandQueue, times(2)).addCallback(any(CommandQueue.Callbacks.class)); + verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class)); verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class)); verify(mNavigationModeController).addListener( any(NavigationModeController.ModeChangedListener.class));