diff options
5 files changed, 77 insertions, 0 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index b360c82374d0..3574f8d05055 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -5790,6 +5790,7 @@ public class Activity extends ContextThemeWrapper * * @return True if this is the root activity, else false. */ + @Override public boolean isTaskRoot() { try { return ActivityManager.getService().getTaskForActivity(mToken, true) >= 0; @@ -7207,6 +7208,9 @@ public class Activity extends ContextThemeWrapper "dispatchPictureInPictureModeChanged " + this + ": " + isInPictureInPictureMode + " " + newConfig); mFragments.dispatchPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); + if (mWindow != null) { + mWindow.onPictureInPictureModeChanged(isInPictureInPictureMode); + } onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 6dd8ecfa12e3..0d5c0754dca7 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -624,6 +624,9 @@ public abstract class Window { /** Returns the current stack Id for the window. */ int getWindowStackId() throws RemoteException; + + /** Returns whether the window belongs to the task root. */ + boolean isTaskRoot(); } /** @@ -2271,6 +2274,12 @@ public abstract class Window { public abstract void onMultiWindowModeChanged(); /** + * Called when the activity changes to/from picture-in-picture mode. + * @hide + */ + public abstract void onPictureInPictureModeChanged(boolean isInPictureInPictureMode); + + /** * Called when the activity just relaunched. * @hide */ diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index ba3aa36067d5..60fbbe9778e7 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -16,6 +16,8 @@ package com.android.internal.policy; +import android.graphics.Outline; +import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.R; import com.android.internal.policy.PhoneWindow.PanelFeatureState; @@ -135,6 +137,16 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind com.android.internal.R.id.navigationBarBackground, 0 /* hideWindowFlag */); + // This is used to workaround an issue where the PiP shadow can be transparent if the window + // background is transparent + private static final ViewOutlineProvider PIP_OUTLINE_PROVIDER = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRect(0, 0, view.getWidth(), view.getHeight()); + outline.setAlpha(1f); + } + }; + // Cludge to address b/22668382: Set the shadow size to the maximum so that the layer // size calculation takes the shadow size into account. We set the elevation currently // to max until the first layout command has been executed. @@ -142,6 +154,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private boolean mElevationAdjustedForStack = false; + // Keeps track of the picture-in-picture mode for the view shadow + private boolean mIsInPictureInPictureMode; + + // Stores the previous outline provider prior to applying PIP_OUTLINE_PROVIDER + private ViewOutlineProvider mLastOutlineProvider; + int mDefaultOpacity = PixelFormat.OPAQUE; /** The feature ID of the panel, or -1 if this is the application's DecorView */ @@ -1404,6 +1422,41 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } } + /** + * Overrides the view outline when the activity enters picture-in-picture to ensure that it has + * an opaque shadow even if the window background is completely transparent. This only applies + * to activities that are currently the task root. + */ + public void updatePictureInPictureOutlineProvider(boolean isInPictureInPictureMode) { + if (mIsInPictureInPictureMode == isInPictureInPictureMode) { + return; + } + + if (isInPictureInPictureMode) { + final Window.WindowControllerCallback callback = + mWindow.getWindowControllerCallback(); + if (callback != null && callback.isTaskRoot()) { + // Call super implementation directly as we don't want to save the PIP outline + // provider to be restored + super.setOutlineProvider(PIP_OUTLINE_PROVIDER); + } + } else { + // Restore the previous outline provider + if (getOutlineProvider() != mLastOutlineProvider) { + setOutlineProvider(mLastOutlineProvider); + } + } + mIsInPictureInPictureMode = isInPictureInPictureMode; + } + + @Override + public void setOutlineProvider(ViewOutlineProvider provider) { + super.setOutlineProvider(provider); + + // Save the outline provider set to ensure that we can restore when the activity leaves PiP + mLastOutlineProvider = provider; + } + private void drawableChanged() { if (mChanging) { return; diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 243916b4ade2..8fe9100d2011 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -729,6 +729,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } @Override + public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) { + if (mDecor != null) { + mDecor.updatePictureInPictureOutlineProvider(isInPictureInPictureMode); + } + } + + @Override public void reportActivityRelaunched() { if (mDecor != null && mDecor.getViewRootImpl() != null) { mDecor.getViewRootImpl().reportActivityRelaunched(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 236e008d4296..f58a91b8b369 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -722,6 +722,10 @@ public class StatusBarWindowView extends FrameLayout { } @Override + public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) { + } + + @Override public void reportActivityRelaunched() { } }; |