Add support PIP for One UI 5.1 core (#4028)

This commit is contained in:
John Andrew Camu
2024-02-11 20:02:49 +08:00
committed by GitHub
parent 0149f06056
commit f20cc146cf
7 changed files with 244 additions and 11 deletions

View File

@@ -1561,9 +1561,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
? mRecentsAnimationTargets
.findTask(mGestureState.getTopRunningTaskId())
: null;
var taskInfo = mGestureState.getRunningTask().mAllCachedTasks.get(0);
final ArrayList<IBinder> cookies = Utilities.ATLEAST_S && runningTaskTarget != null
&& runningTaskTarget.taskInfo != null
? runningTaskTarget.taskInfo.launchCookies
&& taskInfo != null
? taskInfo.launchCookies
: new ArrayList<>();
boolean isTranslucent = runningTaskTarget != null && runningTaskTarget.isTranslucent;
boolean hasValidLeash = runningTaskTarget != null
@@ -1573,8 +1574,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
&& hasValidLeash
&& Utilities.ATLEAST_T
&& runningTaskTarget.allowEnterPip
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
&& runningTaskTarget.taskInfo.pictureInPictureParams.isAutoEnterEnabled();
&& taskInfo.pictureInPictureParams != null
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled();
HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(cookies, duration, isTranslucent,
appCanEnterPip,
runningTaskTarget);
@@ -1597,6 +1598,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
mRecentsAnimationController.screenshotTask(taskId));
});
if (mSwipePipToHomeAnimator == null) return;
// let SystemUi reparent the overlay leash as soon as possible
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
mSwipePipToHomeAnimator.getTaskId(),
@@ -1715,7 +1718,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
RemoteAnimationTarget runningTaskTarget, float startProgress) {
// Directly animate the app to PiP (picture-in-picture) mode
final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo;
final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask().mAllCachedTasks.get(0);
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
.getOrientationState();
final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
@@ -1731,11 +1734,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
windowToHomePositionMap.mapRect(startRect);
final Rect hotseatKeepClearArea = getKeepClearAreaForHotseat();
if (taskInfo == null) return null;
final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
.startSwipePipToHome(taskInfo.topActivity,
taskInfo.topActivityInfo,
runningTaskTarget.taskInfo.pictureInPictureParams,
taskInfo.pictureInPictureParams,
homeRotation,
mDp.hotseatBarSizePx,
hotseatKeepClearArea);
if (destinationBounds == null) {
// No destination bounds returned from SystemUI, bail early.
@@ -1759,7 +1764,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
.setAppIconSizePx(mDp.iconSizePx)
.setLeash(runningTaskTarget.leash)
.setSourceRectHint(
runningTaskTarget.taskInfo.pictureInPictureParams.getSourceRectHint())
taskInfo.pictureInPictureParams.getSourceRectHint())
.setAppBounds(appBounds)
.setHomeToWindowPositionMap(homeToWindowPositionMap)
.setStartBounds(startRect)
@@ -2214,7 +2219,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, Q extends
* This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
*/
private void maybeFinishSwipePipToHome() {
if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null && mRecentsAnimationController != null) {
mRecentsAnimationController.setFinishTaskTransaction(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getFinishTransaction(),

View File

@@ -83,6 +83,7 @@ import com.android.wm.shell.desktopmode.IDesktopMode;
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import com.android.wm.shell.draganddrop.IDragAndDrop;
import com.android.wm.shell.onehanded.IOneHanded;
import com.android.wm.shell.pip.PipData;
import com.android.wm.shell.pip.IPip;
import com.android.wm.shell.pip.IPipAnimationListener;
import com.android.wm.shell.recents.IRecentTasks;
@@ -625,14 +626,19 @@ public class SystemUiProxy implements ISystemUiProxy {
*/
@Nullable
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
PictureInPictureParams pictureInPictureParams, int launcherRotation,
PictureInPictureParams pictureInPictureParams, int launcherRotation, int hotseatBarSize,
Rect hotseatKeepClearArea) {
if (mPip != null) {
try {
return mPip.startSwipePipToHome(componentName, activityInfo,
pictureInPictureParams, launcherRotation, hotseatKeepClearArea);
pictureInPictureParams, launcherRotation, new PipData(hotseatBarSize));
} catch (Throwable e) {
Log.w(TAG, "Failed call startSwipePipToHome", e);
try {
return mPip.startSwipePipToHome(componentName, activityInfo,
pictureInPictureParams, launcherRotation, new PipData(hotseatKeepClearArea));
} catch (Throwable t) {
Log.w(TAG, "Failed call startSwipePipToHome", e);
}
}
}
return null;

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2021 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.wm.shell.pip;
import android.app.PictureInPictureParams;
import android.view.SurfaceControl;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import com.android.wm.shell.pip.IPipAnimationListener;
import com.android.wm.shell.pip.PipData;
/**
* Interface that is exposed to remote callers to manipulate the Pip feature.
*/
interface IPip {
/**
* Notifies that Activity is about to be swiped to home with entering PiP transition and
* queries the destination bounds for PiP depends on Launcher's rotation and shelf height.
*
* @param componentName ComponentName represents the Activity
* @param activityInfo ActivityInfo tied to the Activity
* @param pictureInPictureParams PictureInPictureParams tied to the Activity
* @param launcherRotation Launcher rotation to calculate the PiP destination bounds
* @param hotseatKeepClearArea Bounds of Hotseat to avoid used to calculate PiP destination
bounds
* @return destination bounds the PiP window should land into
*/
Rect startSwipePipToHome(in ComponentName componentName, in ActivityInfo activityInfo,
in PictureInPictureParams pictureInPictureParams,
int launcherRotation, in PipData hotseatKeepClearArea) = 1;
/**
* Notifies the swiping Activity to PiP onto home transition is finished
*
* @param taskId the Task id that the Activity and overlay are currently in.
* @param componentName ComponentName represents the Activity
* @param destinationBounds the destination bounds the PiP window lands into
* @param overlay an optional overlay to fade out after entering PiP
*/
oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
in Rect destinationBounds, in SurfaceControl overlay) = 2;
/**
* Notifies the swiping Activity to PiP onto home transition is aborted
*
* @param taskId the Task id that the Activity and overlay are currently in.
* @param componentName ComponentName represents the Activity
*/
oneway void abortSwipePipToHome(int taskId, in ComponentName componentName) = 3;
/**
* Sets listener to get pinned stack animation callbacks.
*/
oneway void setPipAnimationListener(IPipAnimationListener listener) = 4;
/**
* Sets the shelf height and visibility.
*/
oneway void setShelfHeight(boolean visible, int shelfHeight) = 5;
/**
* Sets the next pip animation type to be the alpha animation.
*/
oneway void setPipAnimationTypeToAlpha() = 6;
/**
* Sets the height and visibility of the Launcher keep clear area.
*/
oneway void setLauncherKeepClearAreaHeight(boolean visible, int height) = 7;
/**
* Sets the app icon size in pixel used by Launcher
*/
oneway void setLauncherAppIconSize(int iconSizePx) = 8;
}

View File

@@ -0,0 +1,41 @@
/*
* 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.wm.shell.pip;
/**
* Listener interface that Launcher attaches to SystemUI to get Pip animation callbacks.
*/
oneway interface IPipAnimationListener {
/**
* Notifies the listener that the Pip animation is started.
*/
void onPipAnimationStarted();
/**
* Notifies the listener about PiP resource dimensions changed.
* Listener can expect an immediate callback the first time they attach.
*
* @param cornerRadius the pixel value of the corner radius, zero means it's disabled.
* @param shadowRadius the pixel value of the shadow radius, zero means it's disabled.
*/
void onPipResourceDimensionsChanged(int cornerRadius, int shadowRadius);
/**
* Notifies the listener that user leaves PiP by tapping on the expand button.
*/
void onExpandPip();
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2024 Lawnchair Launcher
*
* 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.wm.shell.pip;
parcelable PipData;

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2024 Lawnchair Launcher
*
* 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.wm.shell.pip;
import android.os.Parcel;
import android.os.Parcelable;
import android.graphics.Rect;
public class PipData implements Parcelable {
private Rect rect;
private int intValue;
public PipData(Rect rect) {
this.rect = rect;
}
public PipData(int intValue) {
this.intValue = intValue;
}
protected PipData(Parcel in) {
rect = in.readParcelable(Rect.class.getClassLoader());
intValue = in.readInt();
}
public static final Creator<PipData> CREATOR = new Creator<>() {
@Override
public PipData createFromParcel(Parcel in) {
return new PipData (in);
}
@Override
public PipData[] newArray(int size) {
return new PipData[size];
}
};
public Rect getRect() {
return rect;
}
public int getIntValue() {
return intValue;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(rect, flags);
dest.writeInt(intValue);
}
@Override
public int describeContents() {
return 0;
}
}