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

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

Merge "Create BubbleTaskView" into main

parents 417fc153 41472f82
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.bubbles

import android.content.ComponentName
import android.content.Context
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
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock

@SmallTest
@RunWith(AndroidJUnit4::class)
class BubbleTaskViewTest {

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

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

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

        assertThat(bubbleTaskView.taskId).isEqualTo(123)
        assertThat(bubbleTaskView.componentName).isEqualTo(componentName)
        assertThat(bubbleTaskView.isCreated).isTrue()
    }

    @Test
    fun onTaskCreated_callsDelegateListener() {
        var actualTaskId = -1
        var actualComponentName: ComponentName? = null
        val delegateListener = object : TaskView.Listener {
            override fun onTaskCreated(taskId: Int, name: ComponentName) {
                actualTaskId = taskId
                actualComponentName = name
            }
        }
        bubbleTaskView.delegateListener = delegateListener

        val componentName = ComponentName(context, "TestClass")
        bubbleTaskView.listener.onTaskCreated(123, componentName)

        assertThat(actualTaskId).isEqualTo(123)
        assertThat(actualComponentName).isEqualTo(componentName)
    }
}
+14 −10
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ import com.android.wm.shell.R;
import com.android.wm.shell.common.AlphaOptimizedButton;
import com.android.wm.shell.common.TriangleShape;
import com.android.wm.shell.taskview.TaskView;
import com.android.wm.shell.taskview.TaskViewTaskController;

import java.io.PrintWriter;

@@ -146,7 +145,6 @@ public class BubbleExpandedView extends LinearLayout {

    private AlphaOptimizedButton mManageButton;
    private TaskView mTaskView;
    private TaskViewTaskController mTaskViewTaskController;
    private BubbleOverflowContainerView mOverflowView;

    private int mTaskId = INVALID_TASK_ID;
@@ -434,7 +432,8 @@ public class BubbleExpandedView extends LinearLayout {
     * Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need
     * to be called after view inflate.
     */
    void initialize(BubbleController controller, BubbleStackView stackView, boolean isOverflow) {
    void initialize(BubbleController controller, BubbleStackView stackView, boolean isOverflow,
            @Nullable BubbleTaskView bubbleTaskView) {
        mController = controller;
        mStackView = stackView;
        mIsOverflow = isOverflow;
@@ -451,18 +450,22 @@ public class BubbleExpandedView extends LinearLayout {
            bringChildToFront(mOverflowView);
            mManageButton.setVisibility(GONE);
        } else {
            mTaskViewTaskController = new TaskViewTaskController(mContext,
                    mController.getTaskOrganizer(),
                    mController.getTaskViewTransitions(), mController.getSyncTransactionQueue());
            mTaskView = new TaskView(mContext, mTaskViewTaskController);
            mTaskView.setListener(mController.getMainExecutor(), mTaskViewListener);
            mTaskView = bubbleTaskView.getTaskView();
            bubbleTaskView.setDelegateListener(mTaskViewListener);

            // set a fixed width so it is not recalculated as part of a rotation. the width will be
            // updated manually after the rotation.
            FrameLayout.LayoutParams lp =
                    new FrameLayout.LayoutParams(getContentWidth(), MATCH_PARENT);
            if (mTaskView.getParent() != null) {
                ((ViewGroup) mTaskView.getParent()).removeView(mTaskView);
            }
            mExpandedViewContainer.addView(mTaskView, lp);
            bringChildToFront(mTaskView);
            if (bubbleTaskView.isCreated()) {
                mTaskViewListener.onTaskCreated(
                        bubbleTaskView.getTaskId(), bubbleTaskView.getComponentName());
            }
        }
    }

@@ -876,7 +879,7 @@ public class BubbleExpandedView extends LinearLayout {
            return;
        }
        boolean isNew = mBubble == null || didBackingContentChange(bubble);
        if (isNew || bubble != null && bubble.getKey().equals(mBubble.getKey())) {
        if (isNew || bubble.getKey().equals(mBubble.getKey())) {
            mBubble = bubble;
            mManageButton.setContentDescription(getResources().getString(
                    R.string.bubbles_settings_button_description, bubble.getAppName()));
@@ -1107,7 +1110,8 @@ public class BubbleExpandedView extends LinearLayout {
     * has been removed.
     *
     * If this view should be reused after this method is called, then
     * {@link #initialize(BubbleController, BubbleStackView, boolean)} must be invoked first.
     * {@link #initialize(BubbleController, BubbleStackView, boolean, BubbleTaskView)}
     * must be invoked first.
     */
    public void cleanUpExpandedState() {
        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+13 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.PathParser
import android.view.LayoutInflater
import android.view.View.VISIBLE
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import com.android.launcher3.icons.BubbleIconFactory
import com.android.wm.shell.R
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView
@@ -57,10 +58,16 @@ class BubbleOverflow(private val context: Context, private val positioner: Bubbl
    /** Call before use and again if cleanUpExpandedState was called. */
    fun initialize(controller: BubbleController, forBubbleBar: Boolean) {
        if (forBubbleBar) {
            createBubbleBarExpandedView().initialize(controller, true /* isOverflow */)
            createBubbleBarExpandedView()
                .initialize(controller, /* isOverflow= */ true, /* bubbleTaskView= */ null)
        } else {
            createExpandedView()
                .initialize(controller, controller.stackView, true /* isOverflow */)
                .initialize(
                    controller,
                    controller.stackView,
                    /* isOverflow= */ true,
                    /* bubbleTaskView= */ null
                )
        }
    }

@@ -113,7 +120,10 @@ class BubbleOverflow(private val context: Context, private val positioner: Bubbl
                context,
                res.getDimensionPixelSize(R.dimen.bubble_size),
                res.getDimensionPixelSize(R.dimen.bubble_badge_size),
                res.getColor(com.android.launcher3.icons.R.color.important_conversation),
                ContextCompat.getColor(
                    context,
                    com.android.launcher3.icons.R.color.important_conversation
                ),
                res.getDimensionPixelSize(com.android.internal.R.dimen.importance_ring_stroke_width)
            )

+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.bubbles

import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.ComponentName
import androidx.annotation.VisibleForTesting
import com.android.wm.shell.taskview.TaskView
import java.util.concurrent.Executor

/**
 * A wrapper class around [TaskView] for bubble expanded views.
 *
 * [delegateListener] allows callers to change listeners after a task has been created.
 */
class BubbleTaskView(val taskView: TaskView, executor: Executor) {

    /** Whether the task is already created. */
    var isCreated = false
      private set

    /** The task id. */
    var taskId = INVALID_TASK_ID
      private set

    /** The component name of the application running in the task. */
    var componentName: ComponentName? = null
      private set

    /** [TaskView.Listener] for users of this class. */
    var delegateListener: TaskView.Listener? = null

    /** A [TaskView.Listener] that delegates to [delegateListener]. */
    @get:VisibleForTesting
    val listener = object : TaskView.Listener {
        override fun onInitialized() {
            delegateListener?.onInitialized()
        }

        override fun onReleased() {
            delegateListener?.onReleased()
        }

        override fun onTaskCreated(taskId: Int, name: ComponentName) {
            delegateListener?.onTaskCreated(taskId, name)
            this@BubbleTaskView.taskId = taskId
            isCreated = true
            componentName = name
        }

        override fun onTaskVisibilityChanged(taskId: Int, visible: Boolean) {
            delegateListener?.onTaskVisibilityChanged(taskId, visible)
        }

        override fun onTaskRemovalStarted(taskId: Int) {
            delegateListener?.onTaskRemovalStarted(taskId)
        }

        override fun onBackPressedOnTaskRoot(taskId: Int) {
            delegateListener?.onBackPressedOnTaskRoot(taskId)
        }
    }

    init {
        taskView.setListener(executor, listener)
    }
}
+7 −11
Original line number Diff line number Diff line
@@ -35,10 +35,7 @@ import android.view.View;

import androidx.annotation.Nullable;

import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.taskview.TaskView;
import com.android.wm.shell.taskview.TaskViewTaskController;

/**
 * Handles creating and updating the {@link TaskView} associated with a {@link Bubble}.
@@ -65,7 +62,6 @@ public class BubbleTaskViewHelper {

    private final Context mContext;
    private final BubbleController mController;
    private final @ShellMainThread ShellExecutor mMainExecutor;
    private final BubbleTaskViewHelper.Listener mListener;
    private final View mParentView;

@@ -73,7 +69,6 @@ public class BubbleTaskViewHelper {
    private Bubble mBubble;
    @Nullable
    private PendingIntent mPendingIntent;
    private TaskViewTaskController mTaskViewTaskController;
    @Nullable
    private TaskView mTaskView;
    private int mTaskId = INVALID_TASK_ID;
@@ -204,17 +199,18 @@ public class BubbleTaskViewHelper {
    public BubbleTaskViewHelper(Context context,
            BubbleController controller,
            BubbleTaskViewHelper.Listener listener,
            BubbleTaskView bubbleTaskView,
            View parent) {
        mContext = context;
        mController = controller;
        mMainExecutor = mController.getMainExecutor();
        mListener = listener;
        mParentView = parent;
        mTaskViewTaskController = new TaskViewTaskController(mContext,
                mController.getTaskOrganizer(),
                mController.getTaskViewTransitions(), mController.getSyncTransactionQueue());
        mTaskView = new TaskView(mContext, mTaskViewTaskController);
        mTaskView.setListener(mMainExecutor, mTaskViewListener);
        mTaskView = bubbleTaskView.getTaskView();
        bubbleTaskView.setDelegateListener(mTaskViewListener);
        if (bubbleTaskView.isCreated()) {
            mTaskId = bubbleTaskView.getTaskId();
            mListener.onTaskCreated();
        }
    }

    /**
Loading