Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ec53346 authored by Chris Li's avatar Chris Li Committed by Automerger Merge Worker
Browse files

Merge "Register remote animation in JetpackTaskFragmentOrganizer" into sc-v2-dev am: 7861b3bd

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15560522

Change-Id: I0fd8dc497072f0368121ddaa31392bbfcb511026
parents 02deea27 7861b3bd
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
    final Map<IBinder, Configuration> mFragmentParentConfigs = new ArrayMap<>();

    private final TaskFragmentCallback mCallback;
    private TaskFragmentAnimationController mAnimationController;

    /**
     * Callback that notifies the controller about changes to task fragments.
@@ -83,6 +84,25 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
        mCallback = callback;
    }

    @Override
    public void registerOrganizer() {
        if (mAnimationController != null) {
            throw new IllegalStateException("Must unregister the organizer before re-register.");
        }
        super.registerOrganizer();
        mAnimationController = new TaskFragmentAnimationController(this);
        mAnimationController.registerRemoteAnimations();
    }

    @Override
    public void unregisterOrganizer() {
        if (mAnimationController != null) {
            mAnimationController.unregisterRemoteAnimations();
            mAnimationController = null;
        }
        super.unregisterOrganizer();
    }

    /**
     * Starts a new Activity and puts it into split with an existing Activity side-by-side.
     * @param launchingFragmentToken    token for the launching TaskFragment. If it exists, it will
+61 −0
Original line number Diff line number Diff line
/*
 * 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 androidx.window.extensions.organizer;

import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;

import android.util.Log;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.window.TaskFragmentOrganizer;

/** Controls the TaskFragment remote animations. */
class TaskFragmentAnimationController {

    private static final String TAG = "TaskFragAnimationCtrl";
    // TODO(b/196173550) turn off when finalize
    static final boolean DEBUG = false;

    private final TaskFragmentOrganizer mOrganizer;
    private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();

    TaskFragmentAnimationController(TaskFragmentOrganizer organizer) {
        mOrganizer = organizer;
    }

    void registerRemoteAnimations() {
        if (DEBUG) {
            Log.v(TAG, "registerRemoteAnimations");
        }
        final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
        final RemoteAnimationAdapter animationAdapter =
                new RemoteAnimationAdapter(mRemoteRunner, 0, 0);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
        mOrganizer.registerRemoteAnimations(definition);
    }

    void unregisterRemoteAnimations() {
        if (DEBUG) {
            Log.v(TAG, "unregisterRemoteAnimations");
        }
        mOrganizer.unregisterRemoteAnimations();
    }
}
+93 −0
Original line number Diff line number Diff line
/*
 * 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 androidx.window.extensions.organizer;

import static android.view.RemoteAnimationTarget.MODE_OPENING;

import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.WindowManager;

import androidx.annotation.Nullable;

/** To run the TaskFragment animations. */
class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {

    private static final String TAG = "TaskFragAnimationRunner";
    private final Handler mHandler = new Handler(Looper.myLooper());

    @Nullable
    private IRemoteAnimationFinishedCallback mFinishedCallback;

    @Override
    public void onAnimationStart(@WindowManager.TransitionOldType int transit,
            RemoteAnimationTarget[] apps,
            RemoteAnimationTarget[] wallpapers,
            RemoteAnimationTarget[] nonApps,
            IRemoteAnimationFinishedCallback finishedCallback) {
        if (wallpapers.length != 0 || nonApps.length != 0) {
            throw new IllegalArgumentException("TaskFragment shouldn't handle animation with"
                    + "wallpaper or non-app windows.");
        }
        if (TaskFragmentAnimationController.DEBUG) {
            Log.v(TAG, "onAnimationStart transit=" + transit);
        }
        mHandler.post(() -> startAnimation(apps, finishedCallback));
    }

    @Override
    public void onAnimationCancelled() {
        if (TaskFragmentAnimationController.DEBUG) {
            Log.v(TAG, "onAnimationCancelled");
        }
        mHandler.post(this::onAnimationFinished);
    }

    private void startAnimation(RemoteAnimationTarget[] targets,
            IRemoteAnimationFinishedCallback finishedCallback) {
        // TODO(b/196173550) replace with actual animations
        mFinishedCallback = finishedCallback;
        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        for (RemoteAnimationTarget target : targets) {
            if (target.mode == MODE_OPENING) {
                t.show(target.leash);
                t.setAlpha(target.leash, 1);
            }
            t.setPosition(target.leash, target.localBounds.left, target.localBounds.top);
        }
        t.apply();
        onAnimationFinished();
    }

    private void onAnimationFinished() {
        if (mFinishedCallback == null) {
            return;
        }
        try {
            mFinishedCallback.onAnimationFinished();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        mFinishedCallback = null;
    }
}