Add sysui support for remote transitions in shell transitions
This is the sysui portion of the changes. Bug: 169035082 Test: launch app from launcher and observe the icon animation Change-Id: Ia3866bda975ce99bd8307df625b49f8cad3b87ed
This commit is contained in:
@@ -24,9 +24,11 @@ import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.window.TransitionFilter;
|
||||
|
||||
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.RemoteTransitionCompat;
|
||||
|
||||
/**
|
||||
* Temporary callbacks into SystemUI.
|
||||
@@ -192,4 +194,13 @@ interface ISystemUiProxy {
|
||||
* @param destinationBounds the destination bounds the PiP window lands into
|
||||
*/
|
||||
void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 31;
|
||||
|
||||
/**
|
||||
* Registers a RemoteTransitionCompat that will handle transitions. This parameter bundles an
|
||||
* IRemoteTransition and a filter that must pass for it.
|
||||
*/
|
||||
void registerRemoteTransition(in RemoteTransitionCompat remoteTransition) = 32;
|
||||
|
||||
/** Unegisters a RemoteTransitionCompat that will handle transitions. */
|
||||
void unregisterRemoteTransition(in RemoteTransitionCompat remoteTransition) = 33;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,8 @@ public abstract class ActivityOptionsCompat {
|
||||
|
||||
public static ActivityOptions makeRemoteAnimation(
|
||||
RemoteAnimationAdapterCompat remoteAnimationAdapter) {
|
||||
return ActivityOptions.makeRemoteAnimation(remoteAnimationAdapter.getWrapped());
|
||||
return ActivityOptions.makeRemoteAnimation(remoteAnimationAdapter.getWrapped(),
|
||||
remoteAnimationAdapter.getRemoteTransition().getTransition());
|
||||
}
|
||||
|
||||
public static ActivityOptions makeCustomAnimation(Context context, int enterResId,
|
||||
|
||||
@@ -16,12 +16,21 @@
|
||||
|
||||
package com.android.systemui.shared.system;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.IRemoteAnimationFinishedCallback;
|
||||
import android.view.IRemoteAnimationRunner;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.IRemoteTransition;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
/**
|
||||
* @see RemoteAnimationAdapter
|
||||
@@ -29,17 +38,28 @@ import android.view.RemoteAnimationTarget;
|
||||
public class RemoteAnimationAdapterCompat {
|
||||
|
||||
private final RemoteAnimationAdapter mWrapped;
|
||||
private final RemoteTransitionCompat mRemoteTransition;
|
||||
|
||||
public RemoteAnimationAdapterCompat(RemoteAnimationRunnerCompat runner, long duration,
|
||||
long statusBarTransitionDelay) {
|
||||
mWrapped = new RemoteAnimationAdapter(wrapRemoteAnimationRunner(runner), duration,
|
||||
statusBarTransitionDelay);
|
||||
mRemoteTransition = buildRemoteTransition(runner);
|
||||
}
|
||||
|
||||
RemoteAnimationAdapter getWrapped() {
|
||||
return mWrapped;
|
||||
}
|
||||
|
||||
/** Helper to just build a remote transition. Use this if the legacy adapter isn't needed. */
|
||||
public static RemoteTransitionCompat buildRemoteTransition(RemoteAnimationRunnerCompat runner) {
|
||||
return new RemoteTransitionCompat(wrapRemoteTransition(runner));
|
||||
}
|
||||
|
||||
public RemoteTransitionCompat getRemoteTransition() {
|
||||
return mRemoteTransition;
|
||||
}
|
||||
|
||||
private static IRemoteAnimationRunner.Stub wrapRemoteAnimationRunner(
|
||||
final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
|
||||
return new IRemoteAnimationRunner.Stub() {
|
||||
@@ -72,4 +92,63 @@ public class RemoteAnimationAdapterCompat {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static IRemoteTransition.Stub wrapRemoteTransition(
|
||||
final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
|
||||
return new IRemoteTransition.Stub() {
|
||||
@Override
|
||||
public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t,
|
||||
IRemoteAnimationFinishedCallback finishCallback) {
|
||||
final RemoteAnimationTargetCompat[] appsCompat =
|
||||
RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */);
|
||||
final RemoteAnimationTargetCompat[] wallpapersCompat =
|
||||
RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */);
|
||||
final Runnable animationFinishedCallback = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
finishCallback.onAnimationFinished();
|
||||
} catch (RemoteException e) {
|
||||
Log.e("ActivityOptionsCompat", "Failed to call app controlled animation"
|
||||
+ " finished callback", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(b/177438007): Move this set-up logic into launcher's animation impl.
|
||||
boolean isReturnToHome = false;
|
||||
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||
if (change.getTaskInfo() != null
|
||||
&& change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME) {
|
||||
isReturnToHome = change.getMode() == TRANSIT_OPEN
|
||||
|| change.getMode() == TRANSIT_TO_FRONT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isReturnToHome) {
|
||||
// Need to "boost" the closing things since that's what launcher expects.
|
||||
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||
final SurfaceControl leash = change.getLeash();
|
||||
final int mode = info.getChanges().get(i).getMode();
|
||||
// Only deal with roots
|
||||
if (change.getParent() != null) continue;
|
||||
if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
|
||||
t.setLayer(leash, info.getChanges().size() * 3 - i);
|
||||
}
|
||||
}
|
||||
// Make wallpaper visible immediately since launcher apparently won't do this.
|
||||
for (int i = wallpapersCompat.length - 1; i >= 0; --i) {
|
||||
t.show(wallpapersCompat[i].leash.getSurfaceControl());
|
||||
t.setAlpha(wallpapersCompat[i].leash.getSurfaceControl(), 1.f);
|
||||
}
|
||||
}
|
||||
t.apply();
|
||||
remoteAnimationAdapter.onAnimationStart(appsCompat, wallpapersCompat,
|
||||
animationFinishedCallback);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @see RemoteAnimationTarget
|
||||
@@ -73,6 +77,45 @@ public class RemoteAnimationTargetCompat {
|
||||
mStartLeash = app.startLeash;
|
||||
}
|
||||
|
||||
private static int newModeToLegacyMode(int newMode) {
|
||||
switch (newMode) {
|
||||
case WindowManager.TRANSIT_OPEN:
|
||||
case WindowManager.TRANSIT_TO_FRONT:
|
||||
return MODE_OPENING;
|
||||
case WindowManager.TRANSIT_CLOSE:
|
||||
case WindowManager.TRANSIT_TO_BACK:
|
||||
return MODE_CLOSING;
|
||||
default:
|
||||
return 2; // MODE_CHANGING
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteAnimationTargetCompat(TransitionInfo.Change change, int order) {
|
||||
taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1;
|
||||
mode = newModeToLegacyMode(change.getMode());
|
||||
leash = new SurfaceControlCompat(change.getLeash());
|
||||
isTranslucent = (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0
|
||||
|| (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0;
|
||||
clipRect = null;
|
||||
position = null;
|
||||
localBounds = new Rect(change.getEndAbsBounds());
|
||||
localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);
|
||||
sourceContainerBounds = null;
|
||||
screenSpaceBounds = change.getEndAbsBounds();
|
||||
prefixOrderIndex = order;
|
||||
// TODO(shell-transitions): I guess we need to send content insets? evaluate how its used.
|
||||
contentInsets = new Rect(0, 0, 0, 0);
|
||||
if (change.getTaskInfo() != null) {
|
||||
isNotInRecents = !change.getTaskInfo().isRunning;
|
||||
activityType = change.getTaskInfo().getActivityType();
|
||||
} else {
|
||||
isNotInRecents = true;
|
||||
activityType = ACTIVITY_TYPE_UNDEFINED;
|
||||
}
|
||||
pictureInPictureParams = null;
|
||||
mStartLeash = null;
|
||||
}
|
||||
|
||||
public static RemoteAnimationTargetCompat[] wrap(RemoteAnimationTarget[] apps) {
|
||||
final RemoteAnimationTargetCompat[] appsCompat =
|
||||
new RemoteAnimationTargetCompat[apps != null ? apps.length : 0];
|
||||
@@ -82,6 +125,24 @@ public class RemoteAnimationTargetCompat {
|
||||
return appsCompat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a TransitionInfo object as an array of old-style targets
|
||||
*
|
||||
* @param wallpapers If true, this will return wallpaper targets; otherwise it returns
|
||||
* non-wallpaper targets.
|
||||
*/
|
||||
public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers) {
|
||||
final ArrayList<RemoteAnimationTargetCompat> out = new ArrayList<>();
|
||||
for (int i = 0; i < info.getChanges().size(); i++) {
|
||||
boolean changeIsWallpaper =
|
||||
(info.getChanges().get(i).getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
|
||||
if (wallpapers != changeIsWallpaper) continue;
|
||||
out.add(new RemoteAnimationTargetCompat(info.getChanges().get(i),
|
||||
info.getChanges().size() - i));
|
||||
}
|
||||
return out.toArray(new RemoteAnimationTargetCompat[out.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SurfaceControl#release()
|
||||
*/
|
||||
@@ -91,4 +152,4 @@ public class RemoteAnimationTargetCompat {
|
||||
mStartLeash.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.shared.system;
|
||||
|
||||
parcelable RemoteTransitionCompat;
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.shared.system;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcelable;
|
||||
import android.window.IRemoteTransition;
|
||||
import android.window.TransitionFilter;
|
||||
|
||||
import com.android.internal.util.DataClass;
|
||||
|
||||
/**
|
||||
* Wrapper to expose RemoteTransition (shell transitions) to Launcher.
|
||||
*
|
||||
* @see IRemoteTransition
|
||||
* @see TransitionFilter
|
||||
*/
|
||||
@DataClass
|
||||
public class RemoteTransitionCompat implements Parcelable {
|
||||
@NonNull final IRemoteTransition mTransition;
|
||||
@Nullable TransitionFilter mFilter = null;
|
||||
|
||||
RemoteTransitionCompat(IRemoteTransition transition) {
|
||||
mTransition = transition;
|
||||
}
|
||||
|
||||
/** Adds a filter check that restricts this remote transition to home open transitions. */
|
||||
public void addHomeOpenCheck() {
|
||||
if (mFilter == null) {
|
||||
mFilter = new TransitionFilter();
|
||||
}
|
||||
mFilter.mRequirements =
|
||||
new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()};
|
||||
mFilter.mRequirements[0].mActivityType = ACTIVITY_TYPE_HOME;
|
||||
mFilter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.21.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
//@formatter:off
|
||||
|
||||
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ RemoteTransitionCompat(
|
||||
@NonNull IRemoteTransition transition,
|
||||
@Nullable TransitionFilter filter) {
|
||||
this.mTransition = transition;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mTransition);
|
||||
this.mFilter = filter;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull IRemoteTransition getTransition() {
|
||||
return mTransition;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable TransitionFilter getFilter() {
|
||||
return mFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (mFilter != null) flg |= 0x2;
|
||||
dest.writeByte(flg);
|
||||
dest.writeStrongInterface(mTransition);
|
||||
if (mFilter != null) dest.writeTypedObject(mFilter, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
protected RemoteTransitionCompat(@NonNull android.os.Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
byte flg = in.readByte();
|
||||
IRemoteTransition transition = IRemoteTransition.Stub.asInterface(in.readStrongBinder());
|
||||
TransitionFilter filter = (flg & 0x2) == 0 ? null : (TransitionFilter) in.readTypedObject(TransitionFilter.CREATOR);
|
||||
|
||||
this.mTransition = transition;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mTransition);
|
||||
this.mFilter = filter;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static final @NonNull Parcelable.Creator<RemoteTransitionCompat> CREATOR
|
||||
= new Parcelable.Creator<RemoteTransitionCompat>() {
|
||||
@Override
|
||||
public RemoteTransitionCompat[] newArray(int size) {
|
||||
return new RemoteTransitionCompat[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteTransitionCompat createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new RemoteTransitionCompat(in);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A builder for {@link RemoteTransitionCompat}
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@DataClass.Generated.Member
|
||||
public static class Builder {
|
||||
|
||||
private @NonNull IRemoteTransition mTransition;
|
||||
private @Nullable TransitionFilter mFilter;
|
||||
|
||||
private long mBuilderFieldsSet = 0L;
|
||||
|
||||
public Builder(
|
||||
@NonNull IRemoteTransition transition) {
|
||||
mTransition = transition;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mTransition);
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setTransition(@NonNull IRemoteTransition value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x1;
|
||||
mTransition = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setFilter(@NonNull TransitionFilter value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x2;
|
||||
mFilter = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the instance. This builder should not be touched after calling this! */
|
||||
public @NonNull RemoteTransitionCompat build() {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x4; // Mark builder used
|
||||
|
||||
if ((mBuilderFieldsSet & 0x2) == 0) {
|
||||
mFilter = null;
|
||||
}
|
||||
RemoteTransitionCompat o = new RemoteTransitionCompat(
|
||||
mTransition,
|
||||
mFilter);
|
||||
return o;
|
||||
}
|
||||
|
||||
private void checkNotUsed() {
|
||||
if ((mBuilderFieldsSet & 0x4) != 0) {
|
||||
throw new IllegalStateException(
|
||||
"This Builder should not be reused. Use a new Builder instance instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1606862689344L,
|
||||
codegenVersion = "1.0.21",
|
||||
sourceFile = "frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java",
|
||||
inputSignatures = "final @android.annotation.NonNull com.android.systemui.shared.system.IRemoteTransition mTransition\n @android.annotation.Nullable android.window.TransitionFilter mFilter\npublic void addHomeOpenCheck()\nclass RemoteTransitionCompat extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import com.android.systemui.dagger.SysUIComponent;
|
||||
import com.android.systemui.dagger.WMComponent;
|
||||
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
|
||||
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -113,7 +114,8 @@ public class SystemUIFactory {
|
||||
.setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
|
||||
.setShellCommandHandler(mWMComponent.getShellCommandHandler())
|
||||
.setAppPairs(mWMComponent.getAppPairs())
|
||||
.setTaskViewFactory(mWMComponent.getTaskViewFactory());
|
||||
.setTaskViewFactory(mWMComponent.getTaskViewFactory())
|
||||
.setTransitions(mWMComponent.getTransitions());
|
||||
} else {
|
||||
// TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
|
||||
// is separating this logic into newly creating SystemUITestsFactory.
|
||||
@@ -126,7 +128,8 @@ public class SystemUIFactory {
|
||||
.setHideDisplayCutout(Optional.ofNullable(null))
|
||||
.setShellCommandHandler(Optional.ofNullable(null))
|
||||
.setAppPairs(Optional.ofNullable(null))
|
||||
.setTaskViewFactory(Optional.ofNullable(null));
|
||||
.setTaskViewFactory(Optional.ofNullable(null))
|
||||
.setTransitions(Transitions.createEmptyForTesting());
|
||||
}
|
||||
mSysUIComponent = builder.build();
|
||||
if (initializeComponents) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -84,6 +85,9 @@ public interface SysUIComponent {
|
||||
@BindsInstance
|
||||
Builder setShellCommandHandler(Optional<ShellCommandHandler> shellDump);
|
||||
|
||||
@BindsInstance
|
||||
Builder setTransitions(Transitions t);
|
||||
|
||||
SysUIComponent build();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -87,4 +88,8 @@ public interface WMComponent {
|
||||
|
||||
@WMSingleton
|
||||
Optional<TaskViewFactory> getTaskViewFactory();
|
||||
|
||||
/** Gets transitions */
|
||||
@WMSingleton
|
||||
Transitions getTransitions();
|
||||
}
|
||||
|
||||
@@ -56,12 +56,14 @@ import android.os.Looper;
|
||||
import android.os.PatternMatcher;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.view.InputMonitor;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.window.IRemoteTransition;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -86,6 +88,7 @@ import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
import com.android.systemui.shared.system.RemoteTransitionCompat;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
@@ -96,6 +99,7 @@ import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.onehanded.OneHandedEvents;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.pip.PipAnimationController;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -142,6 +146,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
private final ScreenshotHelper mScreenshotHelper;
|
||||
private final Optional<OneHanded> mOneHandedOptional;
|
||||
private final CommandQueue mCommandQueue;
|
||||
private final Transitions mShellTransitions;
|
||||
|
||||
private Region mActiveNavBarRegion;
|
||||
|
||||
@@ -158,6 +163,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
private float mWindowCornerRadius;
|
||||
private boolean mSupportsRoundedCornersOnWindows;
|
||||
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
|
||||
private final ArraySet<IRemoteTransition> mRemoteTransitions = new ArraySet<>();
|
||||
|
||||
@VisibleForTesting
|
||||
public ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
|
||||
@@ -530,6 +536,31 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRemoteTransition(RemoteTransitionCompat remoteTransition) {
|
||||
if (!verifyCaller("registerRemoteTransition")) return;
|
||||
final long binderToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mRemoteTransitions.add(remoteTransition.getTransition());
|
||||
mShellTransitions.registerRemote(
|
||||
remoteTransition.getFilter(), remoteTransition.getTransition());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(binderToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) {
|
||||
if (!verifyCaller("registerRemoteTransition")) return;
|
||||
final long binderToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mRemoteTransitions.remove(remoteTransition.getTransition());
|
||||
mShellTransitions.unregisterRemote(remoteTransition.getTransition());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(binderToken);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean verifyCaller(String reason) {
|
||||
final int callerId = Binder.getCallingUserHandle().getIdentifier();
|
||||
if (callerId != mCurrentBoundedUserId) {
|
||||
@@ -639,7 +670,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
Optional<LegacySplitScreen> splitScreenOptional,
|
||||
Optional<Lazy<StatusBar>> statusBarOptionalLazy,
|
||||
Optional<OneHanded> oneHandedOptional,
|
||||
BroadcastDispatcher broadcastDispatcher) {
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
Transitions shellTransitions) {
|
||||
super(broadcastDispatcher);
|
||||
mContext = context;
|
||||
mPipOptional = pipOptional;
|
||||
@@ -658,6 +690,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
mSysUiState = sysUiState;
|
||||
mSysUiState.addCallback(this::notifySystemUiStateFlags);
|
||||
mOneHandedOptional = oneHandedOptional;
|
||||
mShellTransitions = shellTransitions;
|
||||
|
||||
// Assumes device always starts with back button until launcher tells it that it does not
|
||||
mNavBarButtonAlpha = 1.0f;
|
||||
@@ -806,6 +839,12 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
// Clean up the minimized state if launcher dies
|
||||
mSplitScreenOptional.ifPresent(
|
||||
splitScreen -> splitScreen.setMinimized(false));
|
||||
|
||||
// Clean up any registered remote transitions
|
||||
for (int i = mRemoteTransitions.size() - 1; i >= 0; --i) {
|
||||
mShellTransitions.unregisterRemote(mRemoteTransitions.valueAt(i));
|
||||
}
|
||||
mRemoteTransitions.clear();
|
||||
}
|
||||
|
||||
public void startConnectionToCurrentUser() {
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -75,6 +76,7 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
|
||||
@Mock private Optional<com.android.wm.shell.onehanded.OneHanded> mMockOneHandedOptional;
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@Mock private SysUiState mMockSysUiState;
|
||||
@Mock private Transitions mMockTransitions;
|
||||
|
||||
@Before
|
||||
public void setUp() throws RemoteException {
|
||||
@@ -89,7 +91,7 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
|
||||
mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController,
|
||||
mMockSysUiState, mMockPipOptional, mMockSplitScreenOptional,
|
||||
mMockStatusBarOptionalLazy, mMockOneHandedOptional,
|
||||
mMockBroadcastDispatcher));
|
||||
mMockBroadcastDispatcher, mMockTransitions));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user