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

Commit b6cca29b authored by Chris Li's avatar Chris Li
Browse files

Add ActivityEmbedding transition handler in Shell

Jumpcut for transitions that are all embedded.

Bug: 207070762
Test: pass existing
Change-Id: I8da7647477d24b895ff1b140fca7c8774918c531
parent 661d0530
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -110,8 +110,11 @@ public final class TransitionInfo implements Parcelable {
    /** The container is an input-method window. */
    public static final int FLAG_IS_INPUT_METHOD = 1 << 8;

    /** The container is ActivityEmbedding embedded. */
    public static final int FLAG_IS_EMBEDDED = 1 << 9;

    /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
    public static final int FLAG_FIRST_CUSTOM = 1 << 9;
    public static final int FLAG_FIRST_CUSTOM = 1 << 10;

    /** @hide */
    @IntDef(prefix = { "FLAG_" }, value = {
@@ -125,6 +128,7 @@ public final class TransitionInfo implements Parcelable {
            FLAG_OCCLUDES_KEYGUARD,
            FLAG_DISPLAY_HAS_ALERT_WINDOWS,
            FLAG_IS_INPUT_METHOD,
            FLAG_IS_EMBEDDED,
            FLAG_FIRST_CUSTOM
    })
    public @interface ChangeFlags {}
@@ -325,6 +329,9 @@ public final class TransitionInfo implements Parcelable {
        if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) {
            sb.append((sb.length() == 0 ? "" : "|") + "DISPLAY_HAS_ALERT_WINDOWS");
        }
        if ((flags & FLAG_IS_EMBEDDED) != 0) {
            sb.append((sb.length() == 0 ? "" : "|") + "IS_EMBEDDED");
        }
        if ((flags & FLAG_FIRST_CUSTOM) != 0) {
            sb.append((sb.length() == 0 ? "" : "|") + "FIRST_CUSTOM");
        }
+5 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.Pair;
import androidx.annotation.VisibleForTesting;

import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
@@ -72,6 +73,7 @@ public class ShellInitImpl {
    private final Transitions mTransitions;
    private final StartingWindowController mStartingWindow;
    private final Optional<RecentTasksController> mRecentTasks;
    private final Optional<ActivityEmbeddingController> mActivityEmbeddingOptional;

    private final InitImpl mImpl = new InitImpl();
    // An ordered list of init callbacks to be made once shell is first started
@@ -93,6 +95,7 @@ public class ShellInitImpl {
            Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
            Optional<FreeformTaskListener<?>> freeformTaskListenerOptional,
            Optional<RecentTasksController> recentTasks,
            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
            Transitions transitions,
            StartingWindowController startingWindow,
            ShellExecutor mainExecutor) {
@@ -110,6 +113,7 @@ public class ShellInitImpl {
        mUnfoldTransitionHandler = unfoldTransitionHandler;
        mFreeformTaskListenerOptional = freeformTaskListenerOptional;
        mRecentTasks = recentTasks;
        mActivityEmbeddingOptional = activityEmbeddingOptional;
        mTransitions = transitions;
        mMainExecutor = mainExecutor;
        mStartingWindow = startingWindow;
@@ -139,6 +143,7 @@ public class ShellInitImpl {

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            mTransitions.register(mShellTaskOrganizer);
            mActivityEmbeddingOptional.ifPresent(ActivityEmbeddingController::init);
            mUnfoldTransitionHandler.ifPresent(UnfoldTransitionHandler::init);
            if (mSplitScreenOptional.isPresent() && mPipTouchHandlerOptional.isPresent()) {
                final DefaultMixedHandler mixedHandler = new DefaultMixedHandler(mTransitions,
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.activityembedding;

import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;

import android.content.Context;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.wm.shell.transition.Transitions;

/**
 * Responsible for handling ActivityEmbedding related transitions.
 */
public class ActivityEmbeddingController implements Transitions.TransitionHandler {

    private final Context mContext;
    private final Transitions mTransitions;

    public ActivityEmbeddingController(Context context, Transitions transitions) {
        mContext = context;
        mTransitions = transitions;
    }

    /** Registers to handle transitions. */
    public void init() {
        mTransitions.addHandler(this);
    }

    @Override
    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        // TODO(b/207070762) Handle AE animation as a part of other transitions.
        // Only handle the transition if all containers are embedded.
        for (TransitionInfo.Change change : info.getChanges()) {
            if (!isEmbedded(change)) {
                return false;
            }
        }

        // TODO(b/207070762) Implement AE animation.
        startTransaction.apply();
        finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
        return true;
    }

    @Nullable
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        return null;
    }

    private static boolean isEmbedded(@NonNull TransitionInfo.Change change) {
        return (change.getFlags() & FLAG_IS_EMBEDDED) != 0;
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.wm.shell.TaskViewFactory;
import com.android.wm.shell.TaskViewFactoryController;
import com.android.wm.shell.TaskViewTransitions;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.back.BackAnimationController;
import com.android.wm.shell.bubbles.BubbleController;
@@ -621,6 +622,18 @@ public abstract class WMShellBaseModule {
                taskViewTransitions);
    }


    //
    // ActivityEmbedding
    //

    @WMSingleton
    @Provides
    static Optional<ActivityEmbeddingController> provideActivityEmbeddingController(
            Context context, Transitions transitions) {
        return Optional.of(new ActivityEmbeddingController(context, transitions));
    }

    //
    // Misc
    //
@@ -647,6 +660,7 @@ public abstract class WMShellBaseModule {
            Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
            Optional<FreeformTaskListener<?>> freeformTaskListener,
            Optional<RecentTasksController> recentTasksOptional,
            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
            Transitions transitions,
            StartingWindowController startingWindow,
            @ShellMainThread ShellExecutor mainExecutor) {
@@ -664,6 +678,7 @@ public abstract class WMShellBaseModule {
                unfoldTransitionHandler,
                freeformTaskListener,
                recentTasksOptional,
                activityEmbeddingOptional,
                transitions,
                startingWindow,
                mainExecutor);
+4 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.testing.TestableLooper;

import androidx.test.filters.SmallTest;

import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
@@ -69,6 +70,7 @@ public class ShellInitImplTest extends ShellTestCase {
    @Mock private Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler;
    @Mock private Optional<FreeformTaskListener<?>> mFreeformTaskListenerOptional;
    @Mock private Optional<RecentTasksController> mRecentTasks;
    @Mock private Optional<ActivityEmbeddingController> mActivityEmbeddingController;
    @Mock private Transitions mTransitions;
    @Mock private StartingWindowController mStartingWindow;
    @Mock private ShellExecutor mMainExecutor;
@@ -82,8 +84,8 @@ public class ShellInitImplTest extends ShellTestCase {
                mDisplayInsetsController, mDragAndDropController, mShellTaskOrganizer,
                mKidsModeTaskOrganizer, mBubblesOptional, mSplitScreenOptional,
                mPipTouchHandlerOptional, mFullscreenTaskListener, mUnfoldAnimationController,
                mUnfoldTransitionHandler, mFreeformTaskListenerOptional, mRecentTasks, mTransitions,
                mStartingWindow, mMainExecutor);
                mUnfoldTransitionHandler, mFreeformTaskListenerOptional, mRecentTasks,
                mActivityEmbeddingController, mTransitions, mStartingWindow, mMainExecutor);
    }

    @Test
Loading