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

Commit 9399f0fd authored by Liran Binyamin's avatar Liran Binyamin Committed by Android (Google) Code Review
Browse files

Merge "Store BubbleTaskView in Bubble class" into main

parents 5946e673 6c31e934
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.taskview.TaskViewTaskController

import com.google.common.truth.Truth.assertThat
import com.google.common.util.concurrent.MoreExecutors.directExecutor
@@ -30,6 +29,8 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -37,10 +38,11 @@ class BubbleTaskViewTest {

    private lateinit var bubbleTaskView: BubbleTaskView
    private val context = ApplicationProvider.getApplicationContext<Context>()
    private lateinit var taskView: TaskView

    @Before
    fun setUp() {
        val taskView = TaskView(context, mock<TaskViewTaskController>())
        taskView = mock()
        bubbleTaskView = BubbleTaskView(taskView, directExecutor())
    }

@@ -72,4 +74,19 @@ class BubbleTaskViewTest {
        assertThat(actualTaskId).isEqualTo(123)
        assertThat(actualComponentName).isEqualTo(componentName)
    }

    @Test
    fun cleanup_invalidTaskId_doesNotRemoveTask() {
        bubbleTaskView.cleanup()
        verify(taskView, never()).removeTask()
    }

    @Test
    fun cleanup_validTaskId_removesTask() {
        val componentName = ComponentName(context, "TestClass")
        bubbleTaskView.listener.onTaskCreated(123, componentName)

        bubbleTaskView.cleanup()
        verify(taskView).removeTask()
    }
}
+44 −1
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.common.bubbles.BubbleInfo;
import com.android.wm.shell.taskview.TaskView;
import com.android.wm.shell.taskview.TaskViewTaskController;

import java.io.PrintWriter;
import java.util.List;
@@ -105,6 +107,8 @@ public class Bubble implements BubbleViewProvider {
    private BubbleExpandedView mExpandedView;
    @Nullable
    private BubbleBarExpandedView mBubbleBarExpandedView;
    @Nullable
    private BubbleTaskView mBubbleTaskView;

    private BubbleViewInfoTask mInflationTask;
    private boolean mInflateSynchronously;
@@ -393,6 +397,21 @@ public class Bubble implements BubbleViewProvider {
        return mTitle;
    }

    /**
     * Returns the existing {@link #mBubbleTaskView} if it's not {@code null}. Otherwise a new
     * instance of {@link BubbleTaskView} is created.
     */
    public BubbleTaskView getOrCreateBubbleTaskView(Context context, BubbleController controller) {
        if (mBubbleTaskView == null) {
            TaskViewTaskController taskViewTaskController = new TaskViewTaskController(context,
                    controller.getTaskOrganizer(),
                    controller.getTaskViewTransitions(), controller.getSyncTransactionQueue());
            TaskView taskView = new TaskView(context, taskViewTaskController);
            mBubbleTaskView = new BubbleTaskView(taskView, controller.getMainExecutor());
        }
        return mBubbleTaskView;
    }

    /**
     * @return the ShortcutInfo id if it exists, or the metadata shortcut id otherwise.
     */
@@ -415,6 +434,10 @@ public class Bubble implements BubbleViewProvider {
     * the bubble.
     */
    void cleanupExpandedView() {
        cleanupExpandedView(true);
    }

    private void cleanupExpandedView(boolean cleanupTaskView) {
        if (mExpandedView != null) {
            mExpandedView.cleanUpExpandedState();
            mExpandedView = null;
@@ -423,17 +446,37 @@ public class Bubble implements BubbleViewProvider {
            mBubbleBarExpandedView.cleanUpExpandedState();
            mBubbleBarExpandedView = null;
        }
        if (cleanupTaskView) {
            cleanupTaskView();
        }
        if (mIntent != null) {
            mIntent.unregisterCancelListener(mIntentCancelListener);
        }
        mIntentActive = false;
    }

    private void cleanupTaskView() {
        if (mBubbleTaskView != null) {
            mBubbleTaskView.cleanup();
            mBubbleTaskView = null;
        }
    }

    /**
     * Call when all the views should be removed/cleaned up.
     */
    void cleanupViews() {
        cleanupExpandedView();
        cleanupViews(true);
    }

    /**
     * Call when all the views should be removed/cleaned up.
     *
     * <p>If we're switching between bar and floating modes, pass {@code false} on
     * {@code cleanupTaskView} to avoid recreating it in the new mode.
     */
    void cleanupViews(boolean cleanupTaskView) {
        cleanupExpandedView(cleanupTaskView);
        mIconView = null;
    }

+3 −33
Original line number Diff line number Diff line
@@ -1366,8 +1366,9 @@ public class BubbleController implements ConfigurationChangeListener,
            mStackView.resetOverflowView();
            mStackView.removeAllViews();
        }
        // cleanup existing bubble views so they can be recreated later if needed.
        mBubbleData.getBubbles().forEach(Bubble::cleanupViews);
        // cleanup existing bubble views so they can be recreated later if needed, but retain
        // TaskView.
        mBubbleData.getBubbles().forEach(b -> b.cleanupViews(/* cleanupTaskView= */ false));

        // remove the current bubble container from window manager, null it out, and create a new
        // container based on the current mode.
@@ -1478,7 +1479,6 @@ public class BubbleController implements ConfigurationChangeListener,
     * <p>
     * Must be called from the main thread.
     */
    @VisibleForTesting
    @MainThread
    public void removeBubble(String key, int reason) {
        if (mBubbleData.hasAnyBubbleWithKey(key)) {
@@ -1486,36 +1486,6 @@ public class BubbleController implements ConfigurationChangeListener,
        }
    }

    // TODO(b/316358859): remove this method after task views are shared across modes
    /**
     * Removes the bubble with the given key after task removal, unless the task was removed as
     * a result of mode switching, in which case, the bubble isn't removed because it will be
     * re-inflated for the new mode.
     */
    @MainThread
    public void removeFloatingBubbleAfterTaskRemoval(String key, int reason) {
        // if we're floating remove the bubble. otherwise, we're here because the task was removed
        // after switching modes. See b/316358859
        if (!isShowingAsBubbleBar()) {
            removeBubble(key, reason);
        }
    }

    // TODO(b/316358859): remove this method after task views are shared across modes
    /**
     * Removes the bubble with the given key after task removal, unless the task was removed as
     * a result of mode switching, in which case, the bubble isn't removed because it will be
     * re-inflated for the new mode.
     */
    @MainThread
    public void removeBarBubbleAfterTaskRemoval(String key, int reason) {
        // if we're showing as bubble bar remove the bubble. otherwise, we're here because the task
        // was removed after switching modes. See b/316358859
        if (isShowingAsBubbleBar()) {
            removeBubble(key, reason);
        }
    }

    /**
     * Removes all the bubbles.
     * <p>
+2 −27
Original line number Diff line number Diff line
@@ -27,12 +27,10 @@ import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPAND
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -49,7 +47,6 @@ import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.IntProperty;
@@ -311,8 +308,7 @@ public class BubbleExpandedView extends LinearLayout {
                        + " bubble=" + getBubbleKey());
            }
            if (mBubble != null) {
                mController.removeFloatingBubbleAfterTaskRemoval(
                        mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
                mController.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
            }
            if (mTaskView != null) {
                // Release the surface
@@ -1105,32 +1101,11 @@ public class BubbleExpandedView extends LinearLayout {
        return ((LinearLayout.LayoutParams) mManageButton.getLayoutParams()).getMarginStart();
    }

    /**
     * Cleans up anything related to the task. The TaskView itself is released after the task
     * has been removed.
     *
     * If this view should be reused after this method is called, then
     * {@link #initialize(BubbleController, BubbleStackView, boolean, BubbleTaskView)}
     * must be invoked first.
     */
    /** Hide the task view. */
    public void cleanUpExpandedState() {
        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
            Log.d(TAG, "cleanUpExpandedState: bubble=" + getBubbleKey() + " task=" + mTaskId);
        }
        if (getTaskId() != INVALID_TASK_ID) {
            // Ensure the task is removed from WM
            if (ENABLE_SHELL_TRANSITIONS) {
                if (mTaskView != null) {
                    mTaskView.removeTask();
                }
            } else {
                try {
                    ActivityTaskManager.getService().removeTask(getTaskId());
                } catch (RemoteException e) {
                    Log.w(TAG, e.getMessage());
                }
            }
        }
        if (mTaskView != null) {
            mTaskView.setVisibility(GONE);
        }
+28 −0
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.wm.shell.bubbles

import android.app.ActivityTaskManager
import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.ComponentName
import android.os.RemoteException
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS
import java.util.concurrent.Executor

/**
@@ -78,4 +82,28 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) {
    init {
        taskView.setListener(executor, listener)
    }

    /**
     * Removes the [TaskView] from window manager.
     *
     * This should be called after all other cleanup animations have finished.
     */
    fun cleanup() {
        if (taskId != INVALID_TASK_ID) {
            // Ensure the task is removed from WM
            if (ENABLE_SHELL_TRANSITIONS) {
                taskView.removeTask()
            } else {
                try {
                    ActivityTaskManager.getService().removeTask(taskId)
                } catch (e: RemoteException) {
                    Log.w(TAG, e.message ?: "")
                }
            }
        }
    }

    private companion object {
        const val TAG = "BubbleTaskView"
    }
}
Loading