/*
 * 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

}
