diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index d3277ded6c5ba..1fe2760e5b102 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -123,7 +123,6 @@
- com.android.systemui.volume.VolumeUI
- com.android.systemui.statusbar.phone.StatusBar
- com.android.systemui.keyboard.KeyboardUI
- - com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- com.android.systemui.LatencyTester
- com.android.systemui.globalactions.GlobalActionsComponent
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
index 1a6fdfa9c996f..51855dc648e91 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
@@ -20,7 +20,6 @@ import com.android.systemui.dagger.DependencyProvider;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.SystemUIModule;
-import com.android.systemui.pip.phone.dagger.PipModule;
import dagger.Subcomponent;
@@ -31,7 +30,6 @@ import dagger.Subcomponent;
@Subcomponent(modules = {
CarComponentBinder.class,
DependencyProvider.class,
- PipModule.class,
SystemUIModule.class,
CarSystemUIModule.class,
CarSystemUIBinder.class})
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 3971e18bb968b..616e56288392e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -29,7 +29,6 @@ import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.onehanded.OneHandedUI;
-import com.android.systemui.pip.PipUI;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
@@ -101,12 +100,6 @@ public abstract class CarSystemUIBinder {
@ClassKey(OneHandedUI.class)
public abstract SystemUI bindOneHandedUI(OneHandedUI sysui);
- /** Inject into PipUI. */
- @Binds
- @IntoMap
- @ClassKey(PipUI.class)
- public abstract SystemUI bindPipUI(PipUI sysui);
-
/** Inject into PowerUI. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 7f4f580abf94e..6db3d0b8dff2e 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -516,7 +516,7 @@
android:excludeFromRecents="true"
android:visibleToInstantApps="true"/>
-
+
com.android.systemui.power.PowerUI
- com.android.systemui.media.RingtonePlayer
- com.android.systemui.keyboard.KeyboardUI
- - com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- @string/config_systemUIVendorServiceComponent
- com.android.systemui.SliceBroadcastRelayHandler
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 130bb4fc90b9e..7faa2a44bb6cc 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -306,7 +306,6 @@
- com.android.systemui.power.PowerUI
- com.android.systemui.media.RingtonePlayer
- com.android.systemui.keyboard.KeyboardUI
- - com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- @string/config_systemUIVendorServiceComponent
- com.android.systemui.util.leak.GarbageMonitor$Service
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 2622593880ba4..4bea0674e8bf1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -22,7 +22,6 @@ import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
-import com.android.systemui.pip.phone.dagger.PipModule;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
@@ -36,7 +35,6 @@ import dagger.Subcomponent;
@Subcomponent(modules = {
DefaultComponentBinder.class,
DependencyProvider.class,
- PipModule.class,
SystemUIBinder.class,
SystemUIModule.class,
SystemUIDefaultModule.class})
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 9dfd9f8fd9bfd..c331bd377eecc 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -29,7 +29,6 @@ import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.onehanded.OneHandedUI;
-import com.android.systemui.pip.PipUI;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
@@ -97,12 +96,6 @@ public abstract class SystemUIBinder {
@ClassKey(OneHandedUI.class)
public abstract SystemUI bindOneHandedUI(OneHandedUI sysui);
- /** Inject into PipUI. */
- @Binds
- @IntoMap
- @ClassKey(PipUI.class)
- public abstract SystemUI bindPipUI(PipUI sysui);
-
/** Inject into PowerUI. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
deleted file mode 100644
index 38744fe1b670e..0000000000000
--- a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import android.content.res.Configuration;
-
-import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
-
-import java.io.PrintWriter;
-
-
-public interface BasePipManager {
- void showPictureInPictureMenu();
- default void expandPip() {}
- default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
- void onConfigurationChanged(Configuration newConfig);
- default void setShelfHeight(boolean visible, int height) {}
- default void setPinnedStackAnimationType(int animationType) {}
- default void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) {}
- default void dump(PrintWriter pw) {}
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/Pip.java b/packages/SystemUI/src/com/android/systemui/pip/Pip.java
new file mode 100644
index 0000000000000..b068370da9e3a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/Pip.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.content.res.Configuration;
+import android.media.session.MediaController;
+
+import com.android.systemui.pip.tv.PipController;
+import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
+
+import java.io.PrintWriter;
+
+/**
+ * Interface to engage picture in picture feature.
+ */
+public interface Pip {
+ /**
+ * Called when showing Pip menu.
+ */
+ void showPictureInPictureMenu();
+
+ /**
+ * Registers {@link com.android.systemui.pip.tv.PipController.Listener} that gets called.
+ * whenever receiving notification on changes in PIP.
+ */
+ default void addListener(PipController.Listener listener) {
+ }
+
+ /**
+ * Registers a {@link com.android.systemui.pip.tv.PipController.MediaListener} to PipController.
+ */
+ default void addMediaListener(PipController.MediaListener listener) {
+ }
+
+ /**
+ * Closes PIP (PIPed activity and PIP system UI).
+ */
+ default void closePip() {
+ }
+
+ /**
+ * Expand PIP, it's possible that specific request to activate the window via Alt-tab.
+ */
+ default void expandPip() {
+ }
+
+ /**
+ * Get current play back state. (e.g: Used in TV)
+ *
+ * @return The state of defined in PipController.
+ */
+ default int getPlaybackState() {
+ return 0;
+ }
+
+ /**
+ * Get MediaController.
+ *
+ * @return The MediaController instance.
+ */
+ default MediaController getMediaController() {
+ return null;
+ }
+
+ /**
+ * Hides the PIP menu.
+ */
+ void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback);
+
+ /**
+ * Returns {@code true} if PIP is shown.
+ */
+ default boolean isPipShown() {
+ return false;
+ }
+
+ /**
+ * Moves the PIPed activity to the fullscreen and closes PIP system UI.
+ */
+ default void movePipToFullscreen() {
+ }
+
+ /**
+ * Called when configuration change invoked.
+ */
+ void onConfigurationChanged(Configuration newConfig);
+
+ /**
+ * Removes a {@link PipController.Listener} from PipController.
+ */
+ default void removeListener(PipController.Listener listener) {
+ }
+
+ /**
+ * Removes a {@link com.android.systemui.pip.tv.PipController.MediaListener} from PipController.
+ */
+ default void removeMediaListener(PipController.MediaListener listener) {
+ }
+
+ /**
+ * Resize the Pip to the appropriate size for the input state.
+ *
+ * @param state In Pip state also used to determine the new size for the Pip.
+ */
+ default void resizePinnedStack(int state) {
+ }
+
+ /**
+ * Resumes resizing operation on the Pip that was previously suspended.
+ *
+ * @param reason The reason resizing operations on the Pip was suspended.
+ */
+ default void resumePipResizing(int reason) {
+ }
+
+ /**
+ * Sets both shelf visibility and its height.
+ *
+ * @param visible visibility of shelf.
+ * @param height to specify the height for shelf.
+ */
+ default void setShelfHeight(boolean visible, int height) {
+ }
+
+ /**
+ * Set the pinned stack with {@link PipAnimationController.AnimationType}
+ *
+ * @param animationType The pre-defined {@link PipAnimationController.AnimationType}
+ */
+ default void setPinnedStackAnimationType(int animationType) {
+ }
+
+ /**
+ * Registers the pinned stack animation listener.
+ *
+ * @param listener The listener of pinned stack animation.
+ */
+ default void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) {
+ }
+
+ /**
+ * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called.
+ *
+ * @param reason The reason for suspending resizing operations on the Pip.
+ */
+ default void suspendPipResizing(int reason) {
+ }
+
+ /**
+ * Dump the current state and information if need.
+ *
+ * @param pw The stream to dump information to.
+ */
+ default void dump(PrintWriter pw) {
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
deleted file mode 100644
index 2cd1e202125df..0000000000000
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
-import com.android.systemui.statusbar.CommandQueue;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import javax.inject.Inject;
-
-/**
- * Controls the picture-in-picture window.
- */
-@SysUISingleton
-public class PipUI extends SystemUI implements CommandQueue.Callbacks {
-
- private final CommandQueue mCommandQueue;
- private BasePipManager mPipManager;
-
- @Inject
- public PipUI(Context context, CommandQueue commandQueue,
- BasePipManager pipManager) {
- super(context);
- mCommandQueue = commandQueue;
- mPipManager = pipManager;
- }
-
- @Override
- public void start() {
- PackageManager pm = mContext.getPackageManager();
- boolean supportsPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
- if (!supportsPip) {
- return;
- }
-
- // Ensure that we are the primary user's SystemUI.
- final int processUser = UserManager.get(mContext).getUserHandle();
- if (processUser != UserHandle.USER_SYSTEM) {
- throw new IllegalStateException("Non-primary Pip component not currently supported.");
- }
-
- mCommandQueue.addCallback(this);
- }
-
- @Override
- public void showPictureInPictureMenu() {
- mPipManager.showPictureInPictureMenu();
- }
-
- public void expandPip() {
- mPipManager.expandPip();
- }
-
- public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
- mPipManager.hidePipMenu(onStartCallback, onEndCallback);
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (mPipManager == null) {
- return;
- }
-
- mPipManager.onConfigurationChanged(newConfig);
- }
-
- public void setShelfHeight(boolean visible, int height) {
- if (mPipManager == null) {
- return;
- }
-
- mPipManager.setShelfHeight(visible, height);
- }
-
- public void setPinnedStackAnimationType(int animationType) {
- if (mPipManager != null) {
- mPipManager.setPinnedStackAnimationType(animationType);
- }
- }
-
- public void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) {
- if (mPipManager != null) {
- mPipManager.setPinnedStackAnimationListener(listener);
- }
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mPipManager == null) {
- return;
- }
-
- mPipManager.dump(pw);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
rename to packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java
index 5ef5b902327e9..1a805daef77ec 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.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 static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
@@ -28,11 +29,14 @@ 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;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import android.util.Pair;
import android.view.DisplayInfo;
@@ -44,7 +48,7 @@ import com.android.systemui.UiOffloadThread;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.pip.BasePipManager;
+import com.android.systemui.pip.Pip;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSurfaceTransactionHelper;
import com.android.systemui.pip.PipTaskOrganizer;
@@ -55,25 +59,20 @@ import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
-import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
import java.io.PrintWriter;
-import java.util.Optional;
-
-import javax.inject.Inject;
/**
* Manages the picture-in-picture (PIP) UI and states for Phones.
*/
@SysUISingleton
-public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitionCallback {
- private static final String TAG = "PipManager";
+public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallback {
+ private static final String TAG = "PipController";
private Context mContext;
private IActivityManager mActivityManager;
@@ -87,15 +86,15 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
private DisplayController mDisplayController;
private InputConsumerController mInputConsumerController;
private PipAppOpsListener mAppOpsListener;
+ private PipBoundsHandler mPipBoundsHandler;
private PipMediaController mMediaController;
private PipTouchHandler mTouchHandler;
- private PipTaskOrganizer mPipTaskOrganizer;
private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
private IPinnedStackAnimationListener mPinnedStackAnimationRecentsListener;
private boolean mIsInFixedRotation;
- protected PipBoundsHandler mPipBoundsHandler;
protected PipMenuActivityController mMenuController;
+ protected PipTaskOrganizer mPipTaskOrganizer;
/**
* Handler for display rotation changes.
@@ -127,7 +126,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
// not during the fixed rotation. In fixed rotation case, app is about to enter PiP
// and we need the offsets preserved to calculate the destination bounds.
if (!mIsInFixedRotation) {
- mPipBoundsHandler.setShelfHeight(false , 0);
+ mPipBoundsHandler.setShelfHeight(false, 0);
mPipBoundsHandler.onImeVisibilityChanged(false, 0);
mTouchHandler.onShelfVisibilityChanged(false, 0);
mTouchHandler.onImeVisibilityChanged(false, 0);
@@ -201,7 +200,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
/**
* Handler for messages from the PIP controller.
*/
- private class PipManagerPinnedStackListener extends PinnedStackListener {
+ private class PipControllerPinnedStackListener extends PinnedStackListener {
@Override
public void onListenerRegistered(IPinnedStackController controller) {
mHandler.post(() -> mTouchHandler.setPinnedStackController(controller));
@@ -253,44 +252,55 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
public ConfigurationController.ConfigurationListener mOverlayChangedListener =
new ConfigurationController.ConfigurationListener() {
- @Override
- public void onOverlayChanged() {
- mHandler.post(() -> {
- mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay());
- updateMovementBounds(null /* toBounds */,
- false /* fromRotation */, false /* fromImeAdjustment */,
- false /* fromShelfAdjustment */, null /* windowContainerTransaction */);
- });
- }
- };
+ @Override
+ public void onOverlayChanged() {
+ mHandler.post(() -> {
+ mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay());
+ updateMovementBounds(null /* toBounds */,
+ false /* fromRotation */, false /* fromImeAdjustment */,
+ false /* fromShelfAdjustment */,
+ null /* windowContainerTransaction */);
+ });
+ }
+ };
- @Inject
- public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
+ public PipController(Context context, BroadcastDispatcher broadcastDispatcher,
ConfigurationController configController,
DeviceConfigProxy deviceConfig,
DisplayController displayController,
- Optional splitScreenOptional,
FloatingContentCoordinator floatingContentCoordinator,
SysUiState sysUiState,
- PipUiEventLogger pipUiEventLogger,
- ShellTaskOrganizer shellTaskOrganizer) {
+ PipBoundsHandler pipBoundsHandler,
+ PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
+ PipTaskOrganizer pipTaskOrganizer,
+ PipUiEventLogger pipUiEventLogger) {
mContext = context;
mActivityManager = ActivityManager.getService();
+ PackageManager pm = context.getPackageManager();
+ boolean supportsPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+ if (!supportsPip) {
+ return;
+ }
+
+ // Ensure that we are the primary user's SystemUI.
+ final int processUser = UserManager.get(context).getUserHandle();
+ if (processUser != UserHandle.USER_SYSTEM) {
+ throw new IllegalStateException("Non-primary Pip component not currently supported.");
+ }
+
try {
WindowManagerWrapper.getInstance().addPinnedStackListener(
- new PipManagerPinnedStackListener());
+ new PipControllerPinnedStackListener());
} catch (RemoteException e) {
Log.e(TAG, "Failed to register pinned stack listener", e);
}
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
mDisplayController = displayController;
- mPipBoundsHandler = new PipBoundsHandler(mContext);
- mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController);
- mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler,
- mPipSurfaceTransactionHelper, splitScreenOptional, mDisplayController,
- pipUiEventLogger, shellTaskOrganizer);
+ mPipBoundsHandler = pipBoundsHandler;
+ mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper;
+ mPipTaskOrganizer = pipTaskOrganizer;
mPipTaskOrganizer.registerPipTransitionCallback(this);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
@@ -450,6 +460,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mTmpDisplayInfo.rotation);
}
+ @Override
public void dump(PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipModule.java b/packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipModule.java
deleted file mode 100644
index c8b6982a2eba5..0000000000000
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 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.dagger;
-
-import com.android.systemui.pip.BasePipManager;
-import com.android.systemui.pip.phone.PipManager;
-
-import dagger.Binds;
-import dagger.Module;
-
-/**
- * Dagger Module for Phone PIP.
- */
-@Module
-public abstract class PipModule {
-
- /** Binds PipManager as the default BasePipManager. */
- @Binds
- public abstract BasePipManager providePipManager(PipManager pipManager);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
index a388fa324a2e2..3b3235f1e63c0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
@@ -20,7 +20,6 @@ import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import android.annotation.NonNull;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityTaskManager;
@@ -51,34 +50,31 @@ import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.pip.BasePipManager;
+import com.android.systemui.pip.Pip;
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.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
-import javax.inject.Inject;
-
/**
* Manages the picture-in-picture (PIP) UI and states.
*/
@SysUISingleton
-public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitionCallback {
- private static final String TAG = "PipManager";
+public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallback {
+ private static final String TAG = "PipController";
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ /**
+ * Unknown or invalid state
+ */
+ public static final int STATE_UNKNOWN = -1;
/**
* State when there's no PIP.
*/
@@ -147,7 +143,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
private boolean mImeVisible;
private int mImeHeightAdjustment;
- private final PinnedStackListener mPinnedStackListener = new PipManagerPinnedStackListener();
+ private final PinnedStackListener mPinnedStackListener = new PipControllerPinnedStackListener();
private final Runnable mResizePinnedStackRunnable = new Runnable() {
@Override
@@ -189,7 +185,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
/**
* Handler for messages from the PIP controller.
*/
- private class PipManagerPinnedStackListener extends PinnedStackListener {
+ private class PipControllerPinnedStackListener extends PinnedStackListener {
@Override
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
mHandler.post(() -> {
@@ -231,20 +227,19 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
}
}
- @Inject
- public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
- ConfigurationController configController,
- DisplayController displayController,
- Optional splitScreenOptional,
- @NonNull PipUiEventLogger pipUiEventLogger,
- ShellTaskOrganizer shellTaskOrganizer) {
+ public PipController(Context context, BroadcastDispatcher broadcastDispatcher,
+ PipBoundsHandler pipBoundsHandler,
+ PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
+ PipTaskOrganizer pipTaskOrganizer) {
if (mInitialized) {
return;
}
mInitialized = true;
mContext = context;
- mPipBoundsHandler = new PipBoundsHandler(mContext);
+ mPipNotification = new PipNotification(context, broadcastDispatcher,
+ Optional.of(this).get());
+ mPipBoundsHandler = pipBoundsHandler;
// Ensure that we have the display info in case we get calls to update the bounds before the
// listener calls back
final DisplayInfo displayInfo = new DisplayInfo();
@@ -253,10 +248,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mResizeAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);
- mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController);
- mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler,
- mPipSurfaceTransactionHelper, splitScreenOptional, displayController,
- pipUiEventLogger, shellTaskOrganizer);
+ mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper;
+ mPipTaskOrganizer = pipTaskOrganizer;
mPipTaskOrganizer.registerPipTransitionCallback(this);
mActivityTaskManager = ActivityTaskManager.getService();
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
@@ -278,8 +271,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
} catch (RemoteException | UnsupportedOperationException e) {
Log.e(TAG, "Failed to register pinned stack listener", e);
}
-
- mPipNotification = new PipNotification(context, broadcastDispatcher, this);
}
private void loadConfigurationsAndApply(Configuration newConfig) {
@@ -359,7 +350,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
/**
* Moves the PIPed activity to the fullscreen and closes PIP system UI.
*/
- void movePipToFullscreen() {
+ public void movePipToFullscreen() {
if (DEBUG) Log.d(TAG, "movePipToFullscreen(), current state=" + getStateDescription());
mPipTaskId = TASK_ID_NO_PIP;
@@ -372,34 +363,41 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
/**
* Suspends resizing operation on the Pip until {@link #resumePipResizing} is called
+ *
* @param reason The reason for suspending resizing operations on the Pip.
*/
public void suspendPipResizing(int reason) {
- if (DEBUG) Log.d(TAG,
- "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+ if (DEBUG) {
+ Log.d(TAG,
+ "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+ }
mSuspendPipResizingReason |= reason;
}
/**
* Resumes resizing operation on the Pip that was previously suspended.
+ *
* @param reason The reason resizing operations on the Pip was suspended.
*/
public void resumePipResizing(int reason) {
if ((mSuspendPipResizingReason & reason) == 0) {
return;
}
- if (DEBUG) Log.d(TAG,
- "resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+ if (DEBUG) {
+ Log.d(TAG,
+ "resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+ }
mSuspendPipResizingReason &= ~reason;
mHandler.post(mResizePinnedStackRunnable);
}
/**
* Resize the Pip to the appropriate size for the input state.
+ *
* @param state In Pip state also used to determine the new size for the Pip.
*/
- void resizePinnedStack(int state) {
+ public void resizePinnedStack(int state) {
if (DEBUG) {
Log.d(TAG, "resizePinnedStack() state=" + stateToName(state) + ", current state="
+ getStateDescription(), new Exception());
@@ -411,10 +409,12 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
}
if (mSuspendPipResizingReason != 0) {
mResumeResizePinnedStackRunnableState = state;
- if (DEBUG) Log.d(TAG, "resizePinnedStack() deferring"
- + " mSuspendPipResizingReason=" + mSuspendPipResizingReason
- + " mResumeResizePinnedStackRunnableState="
- + stateToName(mResumeResizePinnedStackRunnableState));
+ if (DEBUG) {
+ Log.d(TAG, "resizePinnedStack() deferring"
+ + " mSuspendPipResizingReason=" + mSuspendPipResizingReason
+ + " mResumeResizePinnedStackRunnableState="
+ + stateToName(mResumeResizePinnedStackRunnableState));
+ }
return;
}
mState = state;
@@ -471,28 +471,28 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
}
/**
- * Adds a {@link Listener} to PipManager.
+ * Adds a {@link Listener} to PipController.
*/
public void addListener(Listener listener) {
mListeners.add(listener);
}
/**
- * Removes a {@link Listener} from PipManager.
+ * Removes a {@link Listener} from PipController.
*/
public void removeListener(Listener listener) {
mListeners.remove(listener);
}
/**
- * Adds a {@link MediaListener} to PipManager.
+ * Adds a {@link MediaListener} to PipController.
*/
public void addMediaListener(MediaListener listener) {
mMediaListeners.add(listener);
}
/**
- * Removes a {@link MediaListener} from PipManager.
+ * Removes a {@link MediaListener} from PipController.
*/
public void removeMediaListener(MediaListener listener) {
mMediaListeners.remove(listener);
@@ -568,16 +568,21 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
/**
* Gets the {@link android.media.session.MediaController} for the PIPed activity.
*/
- MediaController getMediaController() {
+ public MediaController getMediaController() {
return mPipMediaController;
}
+ @Override
+ public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
+
+ }
+
/**
* Returns the PIPed activity's playback state.
* This returns one of {@link #PLAYBACK_STATE_PLAYING}, {@link #PLAYBACK_STATE_PAUSED},
* or {@link #PLAYBACK_STATE_UNAVAILABLE}.
*/
- int getPlaybackState() {
+ public int getPlaybackState() {
if (mPipMediaController == null || mPipMediaController.getPlaybackState() == null) {
return PLAYBACK_STATE_UNAVAILABLE;
}
@@ -673,7 +678,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
};
@Override
- public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) { }
+ public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) {
+ }
@Override
public void onPipTransitionFinished(ComponentName activity, int direction) {
@@ -701,7 +707,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
* Invoked when an activity is pinned and PIP manager is set corresponding information.
* Classes must use this instead of {@link android.app.ITaskStackListener.onActivityPinned}
* because there's no guarantee for the PIP manager be return relavent information
- * correctly. (e.g. {@link isPipShown}).
+ * correctly. (e.g. {@link Pip.isPipShown}).
*/
void onPipEntered(String packageName);
/** Invoked when a PIPed activity is closed. */
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java
index 05bb882ea52e7..4ecd52f8adf5c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java
@@ -27,12 +27,14 @@ import android.view.LayoutInflater;
import android.view.View;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.pip.Pip;
import com.android.wm.shell.R;
import java.util.ArrayList;
import java.util.List;
-
-import javax.inject.Inject;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Controller for {@link PipControlsView}.
@@ -43,9 +45,9 @@ public class PipControlsViewController {
private static final float DISABLED_ACTION_ALPHA = 0.54f;
private final PipControlsView mView;
- private final PipManager mPipManager;
private final LayoutInflater mLayoutInflater;
private final Handler mHandler;
+ private final Optional mPipOptional;
private final PipControlButtonView mPlayPauseButtonView;
private MediaController mMediaController;
private PipControlButtonView mFocusedChild;
@@ -73,12 +75,14 @@ public class PipControlsViewController {
@Override
public void onViewAttachedToWindow(View v) {
updateMediaController();
- mPipManager.addMediaListener(mPipMediaListener);
+ mPipOptional.ifPresent(
+ pip -> pip.addMediaListener(mPipMediaListener));
}
@Override
public void onViewDetachedFromWindow(View v) {
- mPipManager.removeMediaListener(mPipMediaListener);
+ mPipOptional.ifPresent(
+ pip -> pip.removeMediaListener(mPipMediaListener));
}
};
@@ -89,7 +93,7 @@ public class PipControlsViewController {
}
};
- private final PipManager.MediaListener mPipMediaListener = this::updateMediaController;
+ private final PipController.MediaListener mPipMediaListener = this::updateMediaController;
private final View.OnFocusChangeListener
mFocusChangeListener =
@@ -105,12 +109,11 @@ public class PipControlsViewController {
};
- @Inject
- public PipControlsViewController(PipControlsView view, PipManager pipManager,
+ public PipControlsViewController(PipControlsView view, Optional pipOptional,
LayoutInflater layoutInflater, @Main Handler handler) {
super();
mView = view;
- mPipManager = pipManager;
+ mPipOptional = pipOptional;
mLayoutInflater = layoutInflater;
mHandler = handler;
@@ -121,12 +124,14 @@ public class PipControlsViewController {
View fullButtonView = mView.getFullButtonView();
fullButtonView.setOnFocusChangeListener(mFocusChangeListener);
- fullButtonView.setOnClickListener(v -> mPipManager.movePipToFullscreen());
+ fullButtonView.setOnClickListener(
+ v -> mPipOptional.ifPresent(pip -> pip.movePipToFullscreen())
+ );
View closeButtonView = mView.getCloseButtonView();
closeButtonView.setOnFocusChangeListener(mFocusChangeListener);
closeButtonView.setOnClickListener(v -> {
- mPipManager.closePip();
+ mPipOptional.ifPresent(pip -> pip.closePip());
if (mListener != null) {
mListener.onClosed();
}
@@ -139,24 +144,29 @@ public class PipControlsViewController {
if (mMediaController == null || mMediaController.getPlaybackState() == null) {
return;
}
- if (mPipManager.getPlaybackState() == PipManager.PLAYBACK_STATE_PAUSED) {
- mMediaController.getTransportControls().play();
- } else if (mPipManager.getPlaybackState() == PipManager.PLAYBACK_STATE_PLAYING) {
- mMediaController.getTransportControls().pause();
- }
+ mPipOptional.ifPresent(pip -> {
+ if (pip.getPlaybackState() == PipController.PLAYBACK_STATE_PAUSED) {
+ mMediaController.getTransportControls().play();
+ } else if (pip.getPlaybackState() == PipController.PLAYBACK_STATE_PLAYING) {
+ mMediaController.getTransportControls().pause();
+ }
+ });
+
// View will be updated later in {@link mMediaControllerCallback}
});
}
private void updateMediaController() {
- MediaController newController = mPipManager.getMediaController();
- if (mMediaController == newController) {
+ AtomicReference newController = new AtomicReference<>();
+ mPipOptional.ifPresent(pip -> newController.set(pip.getMediaController()));
+
+ if (newController.get() == null || mMediaController == newController.get()) {
return;
}
if (mMediaController != null) {
mMediaController.unregisterCallback(mMediaControllerCallback);
}
- mMediaController = newController;
+ mMediaController = newController.get();
if (mMediaController != null) {
mMediaController.registerCallback(mMediaControllerCallback);
}
@@ -210,12 +220,14 @@ public class PipControlsViewController {
// Hide the media session buttons
mPlayPauseButtonView.setVisibility(View.GONE);
} else {
- int state = mPipManager.getPlaybackState();
- if (state == PipManager.PLAYBACK_STATE_UNAVAILABLE) {
+ AtomicInteger state = new AtomicInteger(PipController.STATE_UNKNOWN);
+ mPipOptional.ifPresent(pip -> state.set(pip.getPlaybackState()));
+ if (state.get() == PipController.STATE_UNKNOWN
+ || state.get() == PipController.PLAYBACK_STATE_UNAVAILABLE) {
mPlayPauseButtonView.setVisibility(View.GONE);
} else {
mPlayPauseButtonView.setVisibility(View.VISIBLE);
- if (state == PipManager.PLAYBACK_STATE_PLAYING) {
+ if (state.get() == PipController.PLAYBACK_STATE_PLAYING) {
mPlayPauseButtonView.setImageResource(R.drawable.pip_ic_pause_white);
mPlayPauseButtonView.setText(R.string.pip_pause);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 70374036ef146..7e812d9ca8a19 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -25,17 +25,20 @@ import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.util.Log;
+import com.android.systemui.pip.Pip;
import com.android.systemui.pip.tv.dagger.TvPipComponent;
import com.android.wm.shell.R;
import java.util.Collections;
+import java.util.Optional;
import javax.inject.Inject;
/**
* Activity to show the PIP menu to control PIP.
*/
-public class PipMenuActivity extends Activity implements PipManager.Listener {
+
+public class PipMenuActivity extends Activity implements PipController.Listener {
private static final String TAG = "PipMenuActivity";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -43,7 +46,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
private final TvPipComponent.Builder mPipComponentBuilder;
private TvPipComponent mTvPipComponent;
- private final PipManager mPipManager;
+ private final Optional mPipOptional;
private Animator mFadeInAnimation;
private Animator mFadeOutAnimation;
@@ -51,10 +54,11 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
private PipControlsViewController mPipControlsViewController;
@Inject
- public PipMenuActivity(TvPipComponent.Builder pipComponentBuilder, PipManager pipManager) {
+ public PipMenuActivity(TvPipComponent.Builder pipComponentBuilder,
+ Optional pipOptional) {
super();
mPipComponentBuilder = pipComponentBuilder;
- mPipManager = pipManager;
+ mPipOptional = pipOptional;
}
@Override
@@ -62,15 +66,17 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
if (DEBUG) Log.d(TAG, "onCreate()");
super.onCreate(bundle);
- if (!mPipManager.isPipShown()) {
- finish();
- }
+ mPipOptional.ifPresent(pip -> {
+ if (!pip.isPipShown()) {
+ finish();
+ }
+ });
setContentView(R.layout.tv_pip_menu);
mTvPipComponent = mPipComponentBuilder.pipControlsView(
findViewById(R.id.pip_controls)).build();
mPipControlsViewController = mTvPipComponent.getPipControlsViewController();
- mPipManager.addListener(this);
+ mPipOptional.ifPresent(pip -> pip.addListener(this));
mRestorePipSizeWhenClose = true;
mFadeInAnimation = AnimatorInflater.loadAnimator(
@@ -98,7 +104,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
if (DEBUG) Log.d(TAG, " > restoring to the default position");
// When PIP menu activity is closed, restore to the default position.
- mPipManager.resizePinnedStack(PipManager.STATE_PIP);
+ mPipOptional.ifPresent(pip -> pip.resizePinnedStack(PipController.STATE_PIP));
}
finish();
}
@@ -125,9 +131,9 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
if (DEBUG) Log.d(TAG, "onDestroy()");
super.onDestroy();
- mPipManager.removeListener(this);
- mPipManager.resumePipResizing(
- PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
+ mPipOptional.ifPresent(pip -> pip.removeListener(this));
+ mPipOptional.ifPresent(pip -> pip.resumePipResizing(
+ PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH));
}
@Override
@@ -178,8 +184,8 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
if (DEBUG) Log.d(TAG, "onPipResizeAboutToStart()");
finish();
- mPipManager.suspendPipResizing(
- PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
+ mPipOptional.ifPresent(pip -> pip.suspendPipResizing(
+ PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
index 5e5de58da2f61..78569edf009d2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -48,14 +48,14 @@ import com.android.wm.shell.R;
public class PipNotification {
private static final String TAG = "PipNotification";
private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName();
- private static final boolean DEBUG = PipManager.DEBUG;
+ private static final boolean DEBUG = PipController.DEBUG;
private static final String ACTION_MENU = "PipNotification.menu";
private static final String ACTION_CLOSE = "PipNotification.close";
private final PackageManager mPackageManager;
- private final PipManager mPipManager;
+ private final PipController mPipController;
private final NotificationManager mNotificationManager;
private final Notification.Builder mNotificationBuilder;
@@ -70,7 +70,7 @@ public class PipNotification {
private String mMediaTitle;
private Bitmap mArt;
- private PipManager.Listener mPipListener = new PipManager.Listener() {
+ private PipController.Listener mPipListener = new PipController.Listener() {
@Override
public void onPipEntered(String packageName) {
mPackageName = packageName;
@@ -124,26 +124,27 @@ public class PipNotification {
}
};
- private final PipManager.MediaListener mPipMediaListener = new PipManager.MediaListener() {
- @Override
- public void onMediaControllerChanged() {
- MediaController newController = mPipManager.getMediaController();
- if (mMediaController == newController) {
- return;
- }
- if (mMediaController != null) {
- mMediaController.unregisterCallback(mMediaControllerCallback);
- }
- mMediaController = newController;
- if (mMediaController != null) {
- mMediaController.registerCallback(mMediaControllerCallback);
- }
- if (updateMediaControllerMetadata() && mNotified) {
- // update notification
- notifyPipNotification();
- }
- }
- };
+ private final PipController.MediaListener mPipMediaListener =
+ new PipController.MediaListener() {
+ @Override
+ public void onMediaControllerChanged() {
+ MediaController newController = mPipController.getMediaController();
+ if (newController == null || mMediaController == newController) {
+ return;
+ }
+ if (mMediaController != null) {
+ mMediaController.unregisterCallback(mMediaControllerCallback);
+ }
+ mMediaController = newController;
+ if (mMediaController != null) {
+ mMediaController.registerCallback(mMediaControllerCallback);
+ }
+ if (updateMediaControllerMetadata() && mNotified) {
+ // update notification
+ notifyPipNotification();
+ }
+ }
+ };
private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() {
@Override
@@ -153,17 +154,17 @@ public class PipNotification {
}
switch (intent.getAction()) {
case ACTION_MENU:
- mPipManager.showPictureInPictureMenu();
+ mPipController.showPictureInPictureMenu();
break;
case ACTION_CLOSE:
- mPipManager.closePip();
+ mPipController.closePip();
break;
}
}
};
public PipNotification(Context context, BroadcastDispatcher broadcastDispatcher,
- PipManager pipManager) {
+ PipController pipController) {
mPackageManager = context.getPackageManager();
mNotificationManager = (NotificationManager) context.getSystemService(
@@ -177,9 +178,9 @@ public class PipNotification {
.setContentIntent(createPendingIntent(context, ACTION_MENU))
.setDeleteIntent(createPendingIntent(context, ACTION_CLOSE)));
- mPipManager = pipManager;
- mPipManager.addListener(mPipListener);
- mPipManager.addMediaListener(mPipMediaListener);
+ mPipController = pipController;
+ pipController.addListener(mPipListener);
+ pipController.addMediaListener(mPipMediaListener);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_MENU);
@@ -190,7 +191,7 @@ public class PipNotification {
}
/**
- * Called by {@link PipManager} when the configuration is changed.
+ * Called by {@link PipController} when the configuration is changed.
*/
void onConfigurationChanged(Context context) {
Resources res = context.getResources();
@@ -227,8 +228,8 @@ public class PipNotification {
private boolean updateMediaControllerMetadata() {
String title = null;
Bitmap art = null;
- if (mPipManager.getMediaController() != null) {
- MediaMetadata metadata = mPipManager.getMediaController().getMetadata();
+ if (mPipController.getMediaController() != null) {
+ MediaMetadata metadata = mPipController.getMediaController().getMetadata();
if (metadata != null) {
title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE);
if (TextUtils.isEmpty(title)) {
@@ -248,6 +249,7 @@ public class PipNotification {
return false;
}
+
private String getNotificationTitle() {
if (!TextUtils.isEmpty(mMediaTitle)) {
return mMediaTitle;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/PipModule.java b/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/PipModule.java
deleted file mode 100644
index 52b38a91a58f9..0000000000000
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/PipModule.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 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.tv.dagger;
-
-import android.app.Activity;
-
-import com.android.systemui.pip.BasePipManager;
-import com.android.systemui.pip.tv.PipManager;
-import com.android.systemui.pip.tv.PipMenuActivity;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-
-/**
- * Dagger module for TV Pip.
- */
-@Module(subcomponents = {TvPipComponent.class})
-public abstract class PipModule {
-
- /** Binds PipManager as the default BasePipManager. */
- @Binds
- public abstract BasePipManager providePipManager(PipManager pipManager);
-
-
- /** Inject into PipMenuActivity. */
- @Binds
- @IntoMap
- @ClassKey(PipMenuActivity.class)
- public abstract Activity providePipMenuActivity(PipMenuActivity activity);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 263bbdbf7c351..62b35f9f5e2d0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -75,8 +75,8 @@ import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.onehanded.OneHandedUI;
+import com.android.systemui.pip.Pip;
import com.android.systemui.pip.PipAnimationController;
-import com.android.systemui.pip.PipUI;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.shared.recents.IOverviewProxy;
@@ -122,7 +122,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
private final Context mContext;
- private final PipUI mPipUI;
+ private final Optional mPipOptional;
private final Optional> mStatusBarOptionalLazy;
private final Optional mSplitScreenOptional;
private SysUiState mSysUiState;
@@ -388,7 +388,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
long token = Binder.clearCallingIdentity();
try {
- mPipUI.setShelfHeight(visible, shelfHeight);
+ mPipOptional.ifPresent(
+ pip -> pip.setShelfHeight(visible, shelfHeight));
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -413,7 +414,9 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
long token = Binder.clearCallingIdentity();
try {
- mPipUI.setPinnedStackAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
+ mPipOptional.ifPresent(
+ pip -> pip.setPinnedStackAnimationType(
+ PipAnimationController.ANIM_TYPE_ALPHA));
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -426,7 +429,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
long token = Binder.clearCallingIdentity();
try {
- mPipUI.setPinnedStackAnimationListener(listener);
+ mPipOptional.ifPresent(
+ pip -> pip.setPinnedStackAnimationListener(listener));
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -603,14 +607,16 @@ public class OverviewProxyService extends CurrentUserTracker implements
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyService(Context context, CommandQueue commandQueue,
- Lazy navBarControllerLazy, NavigationModeController navModeController,
+ Lazy navBarControllerLazy,
+ NavigationModeController navModeController,
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
- PipUI pipUI, Optional splitScreenOptional,
+ Optional pipOptional,
+ Optional splitScreenOptional,
Optional> statusBarOptionalLazy, OneHandedUI oneHandedUI,
BroadcastDispatcher broadcastDispatcher) {
super(broadcastDispatcher);
mContext = context;
- mPipUI = pipUI;
+ mPipOptional = pipOptional;
mStatusBarOptionalLazy = statusBarOptionalLazy;
mHandler = new Handler();
mNavBarControllerLazy = navBarControllerLazy;
@@ -916,6 +922,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
/**
* Notifies the Launcher of split screen size changes
+ *
* @param secondaryWindowBounds Bounds of the secondary window including the insets
* @param secondaryWindowInsets stable insets received by the secondary window
*/
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
index 9a44bf12a3ef4..22fa0106795ad 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
@@ -17,12 +17,11 @@
package com.android.systemui.tv;
import com.android.systemui.dagger.GlobalRootComponent;
-import com.android.systemui.pip.tv.dagger.PipModule;
import dagger.Binds;
import dagger.Module;
-@Module(includes = {PipModule.class})
+@Module()
interface TvSystemUIBinder {
@Binds
GlobalRootComponent bindGlobalRootComponent(TvGlobalRootComponent globalRootComponent);
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index d727bfbdf48a2..c5bb9c1b6f48f 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -62,7 +62,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.wmshell.WMShellModule;
+import com.android.systemui.wmshell.TvWMShellModule;
import javax.inject.Named;
@@ -76,7 +76,7 @@ import dagger.Provides;
*/
@Module(includes = {
QSModule.class,
- WMShellModule.class
+ TvWMShellModule.class,
},
subcomponents = {
})
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
new file mode 100644
index 0000000000000..d8cb280bc7e04
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
@@ -0,0 +1,108 @@
+/*
+ * 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.wmshell;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.IWindowManager;
+
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.pip.Pip;
+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.pip.tv.PipController;
+import com.android.systemui.pip.tv.PipNotification;
+import com.android.systemui.pip.tv.dagger.TvPipComponent;
+import com.android.systemui.stackdivider.SplitScreen;
+import com.android.systemui.stackdivider.SplitScreenController;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
+
+import java.util.Optional;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Provides dependencies from {@link com.android.wm.shell} which could be customized among different
+ * branches of SystemUI.
+ */
+// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
+@Module(includes = WMShellBaseModule.class, subcomponents = {TvPipComponent.class})
+public class TvWMShellModule {
+ @SysUISingleton
+ @Provides
+ static DisplayImeController provideDisplayImeController(IWindowManager wmService,
+ DisplayController displayController, @Main Handler mainHandler,
+ TransactionPool transactionPool) {
+ return new DisplayImeController(wmService, displayController, mainHandler, transactionPool);
+ }
+
+ @SysUISingleton
+ @Provides
+ static Pip providePipController(Context context,
+ BroadcastDispatcher broadcastDispatcher,
+ PipBoundsHandler pipBoundsHandler,
+ PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
+ PipTaskOrganizer pipTaskOrganizer) {
+ return new PipController(context, broadcastDispatcher, pipBoundsHandler,
+ pipSurfaceTransactionHelper, pipTaskOrganizer);
+ }
+
+ @SysUISingleton
+ @Provides
+ static SplitScreen provideSplitScreen(Context context,
+ DisplayController displayController, SystemWindows systemWindows,
+ DisplayImeController displayImeController, @Main Handler handler,
+ TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer) {
+ return new SplitScreenController(context, displayController, systemWindows,
+ displayImeController, handler, transactionPool, shellTaskOrganizer);
+ }
+
+ @SysUISingleton
+ @Provides
+ static PipNotification providePipNotification(Context context,
+ BroadcastDispatcher broadcastDispatcher,
+ PipController pipController) {
+ return new PipNotification(context, broadcastDispatcher, pipController);
+ }
+
+ @SysUISingleton
+ @Provides
+ static PipBoundsHandler providesPipBoundsHandler(Context context) {
+ return new PipBoundsHandler(context);
+ }
+
+ @SysUISingleton
+ @Provides
+ static PipTaskOrganizer providesPipTaskOrganizer(Context context,
+ PipBoundsHandler pipBoundsHandler,
+ PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
+ Optional splitScreenOptional, DisplayController displayController,
+ PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
+ return new PipTaskOrganizer(context, pipBoundsHandler,
+ pipSurfaceTransactionHelper, splitScreenOptional, displayController,
+ pipUiEventLogger, shellTaskOrganizer);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index ee404ca980b20..e1e18a22af51b 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -25,10 +25,12 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.pip.Pip;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.stackdivider.SplitScreen;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
import com.android.wm.shell.common.DisplayImeController;
@@ -46,20 +48,27 @@ import javax.inject.Inject;
* Proxy in SysUiScope to delegate events to controllers in WM Shell library.
*/
@SysUISingleton
-public final class WMShell extends SystemUI implements ProtoTraceable {
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+public final class WMShell extends SystemUI implements ProtoTraceable,
+ CommandQueue.Callbacks {
+ private final CommandQueue mCommandQueue;
private final DisplayImeController mDisplayImeController;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final Optional mPipOptional;
private final Optional mSplitScreenOptional;
private final ProtoTracer mProtoTracer;
@Inject
- WMShell(Context context, KeyguardUpdateMonitor keyguardUpdateMonitor,
+ public WMShell(Context context, CommandQueue commandQueue,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
DisplayImeController displayImeController,
+ Optional pipOptional,
Optional splitScreenOptional,
ProtoTracer protoTracer) {
super(context);
+ mCommandQueue = commandQueue;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mDisplayImeController = displayImeController;
+ mPipOptional = pipOptional;
mSplitScreenOptional = splitScreenOptional;
mProtoTracer = protoTracer;
mProtoTracer.add(this);
@@ -70,11 +79,22 @@ public final class WMShell extends SystemUI implements ProtoTraceable splitScreenOptional, DisplayController displayController,
+ PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
+ return new PipTaskOrganizer(context, pipBoundsHandler,
+ pipSurfaceTransactionHelper, splitScreenOptional, displayController,
+ pipUiEventLogger, shellTaskOrganizer);
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
new file mode 100644
index 0000000000000..2f3c86dfc8ae5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.wmshell;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.pip.Pip;
+import com.android.systemui.pip.tv.PipController;
+import com.android.systemui.stackdivider.SplitScreen;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.tracing.ProtoTracer;
+import com.android.wm.shell.common.DisplayImeController;
+
+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;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WMShellTest extends SysuiTestCase {
+
+ Instrumentation mInstrumentation;
+ WMShell mWMShell;
+ @Mock Context mContext;
+ @Mock CommandQueue mCommandQueue;
+ @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock DisplayImeController mDisplayImeController;
+ @Mock Optional mPipOptional;
+ @Mock Optional mSplitScreenOptional;
+ @Mock PipController mPipController;
+ @Mock ProtoTracer mProtoTracer;
+
+ @Before
+ public void setUp() throws Exception {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ MockitoAnnotations.initMocks(this);
+ mWMShell = new WMShell(mContext, mCommandQueue, mKeyguardUpdateMonitor,
+ mDisplayImeController, mPipOptional, mSplitScreenOptional, mProtoTracer);
+ mWMShell.start();
+ when(mPipOptional.get()).thenReturn(mPipController);
+ }
+
+ @Test
+ public void testWMShellRegisterCommandQueue() {
+ verify(mCommandQueue, times(1)).addCallback(mWMShell);
+ }
+}