Merge "Workaround to ensure that PIP activities have a visible shadow." into oc-dev

This commit is contained in:
TreeHugger Robot
2017-06-03 20:41:10 +00:00
committed by Android (Google) Code Review
5 changed files with 77 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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();
}
/**
@@ -2270,6 +2273,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

View File

@@ -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;

View File

@@ -728,6 +728,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) {

View File

@@ -721,6 +721,10 @@ public class StatusBarWindowView extends FrameLayout {
public void onMultiWindowModeChanged() {
}
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
}
@Override
public void reportActivityRelaunched() {
}