| /* |
| * 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.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; |
| import static android.view.WindowManager.TRANSIT_CHANGE; |
| import static android.view.WindowManager.TRANSIT_CLOSE; |
| import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; |
| import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; |
| import static android.view.WindowManager.TRANSIT_OPEN; |
| import static android.view.WindowManager.TRANSIT_TO_BACK; |
| import static android.view.WindowManager.TRANSIT_TO_FRONT; |
| import static android.window.TransitionFilter.CONTAINER_ORDER_TOP; |
| |
| import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS; |
| import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; |
| |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SuppressLint; |
| import android.app.ActivityManager; |
| import android.app.ActivityTaskManager; |
| import android.app.IApplicationThread; |
| import android.content.ComponentName; |
| import android.graphics.Rect; |
| import android.os.IBinder; |
| import android.os.Parcelable; |
| import android.os.RemoteException; |
| import android.util.ArrayMap; |
| import android.util.Log; |
| import android.util.SparseArray; |
| import android.view.IRecentsAnimationController; |
| import android.view.SurfaceControl; |
| import android.window.IRemoteTransition; |
| import android.window.IRemoteTransitionFinishedCallback; |
| import android.window.PictureInPictureSurfaceTransaction; |
| import android.window.RemoteTransition; |
| import android.window.TaskSnapshot; |
| import android.window.TransitionFilter; |
| import android.window.TransitionInfo; |
| import android.window.WindowContainerToken; |
| import android.window.WindowContainerTransaction; |
| |
| import com.android.internal.annotations.VisibleForTesting; |
| import com.android.internal.util.DataClass; |
| import com.android.systemui.shared.recents.model.ThumbnailData; |
| |
| import java.util.ArrayList; |
| import java.util.concurrent.Executor; |
| |
| /** |
| * Wrapper to expose RemoteTransition (shell transitions) to Launcher. |
| * |
| * @see IRemoteTransition |
| * @see TransitionFilter |
| */ |
| @DataClass |
| public class RemoteTransitionCompat implements Parcelable { |
| private static final String TAG = "RemoteTransitionCompat"; |
| |
| @NonNull final RemoteTransition mTransition; |
| @Nullable TransitionFilter mFilter = null; |
| |
| RemoteTransitionCompat(RemoteTransition transition) { |
| mTransition = transition; |
| } |
| |
| public RemoteTransitionCompat(@NonNull RemoteTransitionRunner runner, |
| @NonNull Executor executor, @Nullable IApplicationThread appThread) { |
| IRemoteTransition remote = new IRemoteTransition.Stub() { |
| @Override |
| public void startAnimation(IBinder transition, TransitionInfo info, |
| SurfaceControl.Transaction t, |
| IRemoteTransitionFinishedCallback finishedCallback) { |
| final Runnable finishAdapter = () -> { |
| try { |
| finishedCallback.onTransitionFinished(null /* wct */, null /* sct */); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Failed to call transition finished callback", e); |
| } |
| }; |
| executor.execute(() -> runner.startAnimation(transition, info, t, finishAdapter)); |
| } |
| |
| @Override |
| public void mergeAnimation(IBinder transition, TransitionInfo info, |
| SurfaceControl.Transaction t, IBinder mergeTarget, |
| IRemoteTransitionFinishedCallback finishedCallback) { |
| final Runnable finishAdapter = () -> { |
| try { |
| finishedCallback.onTransitionFinished(null /* wct */, null /* sct */); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Failed to call transition finished callback", e); |
| } |
| }; |
| executor.execute(() -> runner.mergeAnimation(transition, info, t, mergeTarget, |
| finishAdapter)); |
| } |
| }; |
| mTransition = new RemoteTransition(remote, appThread); |
| } |
| |
| /** Constructor specifically for recents animation */ |
| public RemoteTransitionCompat(RecentsAnimationListener recents, |
| RecentsAnimationControllerCompat controller, IApplicationThread appThread) { |
| IRemoteTransition remote = new IRemoteTransition.Stub() { |
| final RecentsControllerWrap mRecentsSession = new RecentsControllerWrap(); |
| IBinder mToken = null; |
| |
| @Override |
| public void startAnimation(IBinder transition, TransitionInfo info, |
| SurfaceControl.Transaction t, |
| IRemoteTransitionFinishedCallback finishedCallback) { |
| final ArrayMap<SurfaceControl, SurfaceControl> leashMap = new ArrayMap<>(); |
| final RemoteAnimationTargetCompat[] apps = |
| RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */, t, leashMap); |
| final RemoteAnimationTargetCompat[] wallpapers = |
| RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */, t, leashMap); |
| // TODO(b/177438007): Move this set-up logic into launcher's animation impl. |
| mToken = transition; |
| // This transition is for opening recents, so recents is on-top. We want to draw |
| // the current going-away tasks on top of recents, though, so move them to front. |
| // Note that we divide up the "layer space" into 3 regions each the size of |
| // the change count. This way we can easily move changes into above/below/between |
| // while maintaining their relative ordering. |
| final ArrayList<WindowContainerToken> pausingTasks = new ArrayList<>(); |
| WindowContainerToken pipTask = null; |
| WindowContainerToken recentsTask = null; |
| for (int i = apps.length - 1; i >= 0; --i) { |
| final ActivityManager.RunningTaskInfo taskInfo = apps[i].taskInfo; |
| if (apps[i].mode == MODE_CLOSING) { |
| t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i); |
| if (taskInfo == null) { |
| continue; |
| } |
| // Add to front since we are iterating backwards. |
| pausingTasks.add(0, taskInfo.token); |
| if (taskInfo.pictureInPictureParams != null |
| && taskInfo.pictureInPictureParams.isAutoEnterEnabled()) { |
| pipTask = taskInfo.token; |
| } |
| } else if (taskInfo != null |
| && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) { |
| // This task is for recents, keep it on top. |
| t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i); |
| recentsTask = taskInfo.token; |
| } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { |
| recentsTask = taskInfo.token; |
| } |
| } |
| // Also make all the wallpapers opaque since we want the visible from the start |
| for (int i = wallpapers.length - 1; i >= 0; --i) { |
| t.setAlpha(wallpapers[i].leash, 1); |
| } |
| t.apply(); |
| mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask, |
| recentsTask, leashMap, mToken, |
| (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0); |
| recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0), |
| new Rect()); |
| } |
| |
| @Override |
| public void mergeAnimation(IBinder transition, TransitionInfo info, |
| SurfaceControl.Transaction t, IBinder mergeTarget, |
| IRemoteTransitionFinishedCallback finishedCallback) { |
| if (!mergeTarget.equals(mToken)) return; |
| if (!mRecentsSession.merge(info, t, recents)) return; |
| try { |
| finishedCallback.onTransitionFinished(null /* wct */, null /* sct */); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Error merging transition.", e); |
| } |
| // commit taskAppeared after merge transition finished. |
| mRecentsSession.commitTasksAppearedIfNeeded(recents); |
| } |
| }; |
| mTransition = new RemoteTransition(remote, appThread); |
| } |
| |
| /** Adds a filter check that restricts this remote transition to home open transitions. */ |
| public void addHomeOpenCheck(ComponentName homeActivity) { |
| if (mFilter == null) { |
| mFilter = new TransitionFilter(); |
| } |
| // No need to handle the transition that also dismisses keyguard. |
| mFilter.mNotFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY; |
| mFilter.mRequirements = |
| new TransitionFilter.Requirement[]{new TransitionFilter.Requirement(), |
| new TransitionFilter.Requirement()}; |
| mFilter.mRequirements[0].mActivityType = ACTIVITY_TYPE_HOME; |
| mFilter.mRequirements[0].mTopActivity = homeActivity; |
| mFilter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; |
| mFilter.mRequirements[0].mOrder = CONTAINER_ORDER_TOP; |
| mFilter.mRequirements[1].mActivityType = ACTIVITY_TYPE_STANDARD; |
| mFilter.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; |
| } |
| |
| /** |
| * Wrapper to hook up parts of recents animation to shell transition. |
| * TODO(b/177438007): Remove this once Launcher handles shell transitions directly. |
| */ |
| @VisibleForTesting |
| static class RecentsControllerWrap extends RecentsAnimationControllerCompat { |
| private RecentsAnimationControllerCompat mWrapped = null; |
| private IRemoteTransitionFinishedCallback mFinishCB = null; |
| private ArrayList<WindowContainerToken> mPausingTasks = null; |
| private WindowContainerToken mPipTask = null; |
| private WindowContainerToken mRecentsTask = null; |
| private TransitionInfo mInfo = null; |
| private ArrayList<SurfaceControl> mOpeningLeashes = null; |
| private boolean mOpeningHome = false; |
| private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; |
| private PictureInPictureSurfaceTransaction mPipTransaction = null; |
| private IBinder mTransition = null; |
| private boolean mKeyguardLocked = false; |
| private RemoteAnimationTargetCompat[] mAppearedTargets; |
| |
| void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info, |
| IRemoteTransitionFinishedCallback finishCB, |
| ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask, |
| WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap, |
| IBinder transition, boolean keyguardLocked) { |
| if (mInfo != null) { |
| throw new IllegalStateException("Trying to run a new recents animation while" |
| + " recents is already active."); |
| } |
| mWrapped = wrapped; |
| mInfo = info; |
| mFinishCB = finishCB; |
| mPausingTasks = pausingTasks; |
| mPipTask = pipTask; |
| mRecentsTask = recentsTask; |
| mLeashMap = leashMap; |
| mTransition = transition; |
| mKeyguardLocked = keyguardLocked; |
| } |
| |
| @SuppressLint("NewApi") |
| boolean merge(TransitionInfo info, SurfaceControl.Transaction t, |
| RecentsAnimationListener recents) { |
| SparseArray<TransitionInfo.Change> openingTasks = null; |
| mAppearedTargets = null; |
| boolean cancelRecents = false; |
| boolean homeGoingAway = false; |
| boolean hasChangingApp = false; |
| for (int i = info.getChanges().size() - 1; i >= 0; --i) { |
| final TransitionInfo.Change change = info.getChanges().get(i); |
| if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { |
| final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); |
| if (taskInfo != null) { |
| if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { |
| // canceling recents animation |
| cancelRecents = true; |
| } |
| if (openingTasks == null) { |
| openingTasks = new SparseArray<>(); |
| } |
| if (taskInfo.hasParentTask()) { |
| // Collects opening leaf tasks only since Launcher monitors leaf task |
| // ids to perform recents animation. |
| openingTasks.remove(taskInfo.parentTaskId); |
| } |
| openingTasks.put(taskInfo.taskId, change); |
| } |
| } else if (change.getMode() == TRANSIT_CLOSE |
| || change.getMode() == TRANSIT_TO_BACK) { |
| if (mRecentsTask.equals(change.getContainer())) { |
| homeGoingAway = true; |
| } |
| } else if (change.getMode() == TRANSIT_CHANGE) { |
| hasChangingApp = true; |
| } |
| } |
| if (hasChangingApp && homeGoingAway) { |
| // This happens when a visible app is expanding (usually PiP). In this case, |
| // The transition probably has a special-purpose animation, so finish recents |
| // now and let it do its animation (since recents is going to be occluded). |
| if (!recents.onSwitchToScreenshot(() -> { |
| finish(true /* toHome */, false /* userLeaveHint */); |
| })) { |
| Log.w(TAG, "Recents callback doesn't support support switching to screenshot" |
| + ", there might be a flicker."); |
| finish(true /* toHome */, false /* userLeaveHint */); |
| } |
| return false; |
| } |
| if (openingTasks == null) return false; |
| int pauseMatches = 0; |
| if (!cancelRecents) { |
| for (int i = 0; i < openingTasks.size(); ++i) { |
| if (mPausingTasks.contains(openingTasks.valueAt(i).getContainer())) { |
| ++pauseMatches; |
| } |
| } |
| } |
| if (pauseMatches > 0) { |
| if (pauseMatches != mPausingTasks.size()) { |
| // We are not really "returning" properly... something went wrong. |
| throw new IllegalStateException("\"Concelling\" a recents transitions by " |
| + "unpausing " + pauseMatches + " apps after pausing " |
| + mPausingTasks.size() + " apps."); |
| } |
| // In this case, we are "returning" to an already running app, so just consume |
| // the merge and do nothing. |
| return true; |
| } |
| final int layer = mInfo.getChanges().size() * 3; |
| mOpeningLeashes = new ArrayList<>(); |
| mOpeningHome = cancelRecents; |
| final RemoteAnimationTargetCompat[] targets = |
| new RemoteAnimationTargetCompat[openingTasks.size()]; |
| for (int i = 0; i < openingTasks.size(); ++i) { |
| final TransitionInfo.Change change = openingTasks.valueAt(i); |
| mOpeningLeashes.add(change.getLeash()); |
| // We are receiving new opening tasks, so convert to onTasksAppeared. |
| final RemoteAnimationTargetCompat target = new RemoteAnimationTargetCompat( |
| change, layer, info, t); |
| mLeashMap.put(mOpeningLeashes.get(i), target.leash); |
| t.reparent(target.leash, mInfo.getRootLeash()); |
| t.setLayer(target.leash, layer); |
| targets[i] = target; |
| } |
| t.apply(); |
| mAppearedTargets = targets; |
| return true; |
| } |
| |
| private void commitTasksAppearedIfNeeded(RecentsAnimationListener recents) { |
| if (mAppearedTargets != null) { |
| recents.onTasksAppeared(mAppearedTargets); |
| mAppearedTargets = null; |
| } |
| } |
| |
| @Override public ThumbnailData screenshotTask(int taskId) { |
| try { |
| final TaskSnapshot snapshot = |
| ActivityTaskManager.getService().takeTaskSnapshot(taskId); |
| if (snapshot != null) { |
| return new ThumbnailData(snapshot); |
| } |
| } catch (RemoteException e) { |
| Log.e(TAG, "Failed to screenshot task", e); |
| } |
| return null; |
| } |
| |
| @Override public void setInputConsumerEnabled(boolean enabled) { |
| if (mWrapped != null) mWrapped.setInputConsumerEnabled(enabled); |
| } |
| |
| @Override public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) { |
| if (mWrapped != null) mWrapped.setAnimationTargetsBehindSystemBars(behindSystemBars); |
| } |
| |
| @Override public void hideCurrentInputMethod() { |
| mWrapped.hideCurrentInputMethod(); |
| } |
| |
| @Override public void setFinishTaskTransaction(int taskId, |
| PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) { |
| mPipTransaction = finishTransaction; |
| if (mWrapped != null) { |
| mWrapped.setFinishTaskTransaction(taskId, finishTransaction, overlay); |
| } |
| } |
| |
| @Override |
| @SuppressLint("NewApi") |
| public void finish(boolean toHome, boolean sendUserLeaveHint) { |
| if (mFinishCB == null) { |
| Log.e(TAG, "Duplicate call to finish", new RuntimeException()); |
| return; |
| } |
| if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint); |
| final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); |
| final WindowContainerTransaction wct = new WindowContainerTransaction(); |
| |
| if (mKeyguardLocked && mRecentsTask != null) { |
| if (toHome) wct.reorder(mRecentsTask, true /* toTop */); |
| else wct.restoreTransientOrder(mRecentsTask); |
| } |
| if (!toHome && mPausingTasks != null && mOpeningLeashes == null) { |
| // The gesture went back to opening the app rather than continuing with |
| // recents, so end the transition by moving the app back to the top (and also |
| // re-showing it's task). |
| for (int i = mPausingTasks.size() - 1; i >= 0; --i) { |
| // reverse order so that index 0 ends up on top |
| wct.reorder(mPausingTasks.get(i), true /* onTop */); |
| t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash()); |
| } |
| if (!mKeyguardLocked && mRecentsTask != null) { |
| wct.restoreTransientOrder(mRecentsTask); |
| } |
| } else if (toHome && mOpeningHome && mPausingTasks != null) { |
| // Special situaition where 3p launcher was changed during recents (this happens |
| // during tapltests...). Here we get both "return to home" AND "home opening". |
| // This is basically going home, but we have to restore recents order and also |
| // treat the home "pausing" task properly. |
| for (int i = mPausingTasks.size() - 1; i >= 0; --i) { |
| final TransitionInfo.Change change = mInfo.getChange(mPausingTasks.get(i)); |
| final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); |
| if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { |
| // Treat as opening (see above) |
| wct.reorder(mPausingTasks.get(i), true /* onTop */); |
| t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash()); |
| } else { |
| // Treat as hiding (see below) |
| t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash()); |
| } |
| } |
| if (!mKeyguardLocked && mRecentsTask != null) { |
| wct.restoreTransientOrder(mRecentsTask); |
| } |
| } else { |
| for (int i = 0; i < mPausingTasks.size(); ++i) { |
| if (!sendUserLeaveHint) { |
| // This means recents is not *actually* finishing, so of course we gotta |
| // do special stuff in WMCore to accommodate. |
| wct.setDoNotPip(mPausingTasks.get(i)); |
| } |
| // Since we will reparent out of the leashes, pre-emptively hide the child |
| // surface to match the leash. Otherwise, there will be a flicker before the |
| // visibility gets committed in Core when using split-screen (in splitscreen, |
| // the leaf-tasks are not "independent" so aren't hidden by normal setup). |
| t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash()); |
| } |
| if (mPipTask != null && mPipTransaction != null && sendUserLeaveHint) { |
| t.show(mInfo.getChange(mPipTask).getLeash()); |
| PictureInPictureSurfaceTransaction.apply(mPipTransaction, |
| mInfo.getChange(mPipTask).getLeash(), t); |
| mPipTask = null; |
| mPipTransaction = null; |
| } |
| } |
| try { |
| mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t); |
| } catch (RemoteException e) { |
| Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e); |
| t.apply(); |
| } |
| // Only release the non-local created surface references. The animator is responsible |
| // for releasing the leashes created by local. |
| for (int i = 0; i < mInfo.getChanges().size(); ++i) { |
| mInfo.getChanges().get(i).getLeash().release(); |
| } |
| // Reset all members. |
| mWrapped = null; |
| mFinishCB = null; |
| mPausingTasks = null; |
| mInfo = null; |
| mOpeningLeashes = null; |
| mOpeningHome = false; |
| mLeashMap = null; |
| mTransition = null; |
| } |
| |
| @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) { |
| if (mWrapped != null) mWrapped.setDeferCancelUntilNextTransition(defer, screenshot); |
| } |
| |
| @Override public void cleanupScreenshot() { |
| if (mWrapped != null) mWrapped.cleanupScreenshot(); |
| } |
| |
| @Override public void setWillFinishToHome(boolean willFinishToHome) { |
| if (mWrapped != null) mWrapped.setWillFinishToHome(willFinishToHome); |
| } |
| |
| /** |
| * @see IRecentsAnimationController#removeTask |
| */ |
| @Override public boolean removeTask(int taskId) { |
| return mWrapped != null ? mWrapped.removeTask(taskId) : false; |
| } |
| |
| /** |
| * @see IRecentsAnimationController#detachNavigationBarFromApp |
| */ |
| @Override public void detachNavigationBarFromApp(boolean moveHomeToTop) { |
| try { |
| ActivityTaskManager.getService().detachNavigationBarFromApp(mTransition); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Failed to detach the navigation bar from app", e); |
| } |
| } |
| |
| /** |
| * @see IRecentsAnimationController#animateNavigationBarToApp(long) |
| */ |
| @Override public void animateNavigationBarToApp(long duration) { |
| } |
| } |
| |
| |
| |
| // Code below generated by codegen v1.0.23. |
| // |
| // 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 RemoteTransition 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 RemoteTransition 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.writeTypedObject(mTransition, flags); |
| 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(); |
| RemoteTransition transition = (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR); |
| 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 RemoteTransition mTransition; |
| private @Nullable TransitionFilter mFilter; |
| |
| private long mBuilderFieldsSet = 0L; |
| |
| public Builder( |
| @NonNull RemoteTransition transition) { |
| mTransition = transition; |
| com.android.internal.util.AnnotationValidations.validate( |
| NonNull.class, null, mTransition); |
| } |
| |
| @DataClass.Generated.Member |
| public @NonNull Builder setTransition(@NonNull RemoteTransition 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 = 1629321609807L, |
| codegenVersion = "1.0.23", |
| sourceFile = "frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java", |
| inputSignatures = "private static final java.lang.String TAG\nfinal @android.annotation.NonNull android.window.RemoteTransition mTransition\n @android.annotation.Nullable android.window.TransitionFilter mFilter\npublic void addHomeOpenCheck(android.content.ComponentName)\nclass RemoteTransitionCompat extends java.lang.Object implements [android.os.Parcelable]\nprivate com.android.systemui.shared.system.RecentsAnimationControllerCompat mWrapped\nprivate android.window.IRemoteTransitionFinishedCallback mFinishCB\nprivate android.window.WindowContainerToken mPausingTask\nprivate android.window.WindowContainerToken mPipTask\nprivate android.window.TransitionInfo mInfo\nprivate android.view.SurfaceControl mOpeningLeash\nprivate android.util.ArrayMap<android.view.SurfaceControl,android.view.SurfaceControl> mLeashMap\nprivate android.window.PictureInPictureSurfaceTransaction mPipTransaction\nprivate android.os.IBinder mTransition\n void setup(com.android.systemui.shared.system.RecentsAnimationControllerCompat,android.window.TransitionInfo,android.window.IRemoteTransitionFinishedCallback,android.window.WindowContainerToken,android.window.WindowContainerToken,android.util.ArrayMap<android.view.SurfaceControl,android.view.SurfaceControl>,android.os.IBinder)\n @android.annotation.SuppressLint boolean merge(android.window.TransitionInfo,android.view.SurfaceControl.Transaction,com.android.systemui.shared.system.RecentsAnimationListener)\npublic @java.lang.Override com.android.systemui.shared.recents.model.ThumbnailData screenshotTask(int)\npublic @java.lang.Override void setInputConsumerEnabled(boolean)\npublic @java.lang.Override void setAnimationTargetsBehindSystemBars(boolean)\npublic @java.lang.Override void hideCurrentInputMethod()\npublic @java.lang.Override void setFinishTaskTransaction(int,android.window.PictureInPictureSurfaceTransaction,android.view.SurfaceControl)\npublic @java.lang.Override @android.annotation.SuppressLint void finish(boolean,boolean)\npublic @java.lang.Override void setDeferCancelUntilNextTransition(boolean,boolean)\npublic @java.lang.Override void cleanupScreenshot()\npublic @java.lang.Override void setWillFinishToHome(boolean)\npublic @java.lang.Override boolean removeTask(int)\npublic @java.lang.Override void detachNavigationBarFromApp(boolean)\npublic @java.lang.Override void animateNavigationBarToApp(long)\nclass RecentsControllerWrap extends com.android.systemui.shared.system.RecentsAnimationControllerCompat implements []\n@com.android.internal.util.DataClass") |
| @Deprecated |
| private void __metadata() {} |
| |
| |
| //@formatter:on |
| // End of generated code |
| |
| } |