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

Commit 43528afc authored by Maryam Dehaini's avatar Maryam Dehaini Committed by Android (Google) Code Review
Browse files

Merge changes from topic "AppHandleReporting" into main

* changes:
  Update WindowDecorCaptionRespositoryTests
  Fix bugs found for app handle reporting
parents 07d74c4c d967a712
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -22,22 +22,26 @@ import com.android.wm.shell.desktopmode.CaptionState.AppHandle
import com.android.wm.shell.desktopmode.CaptionState.AppHeader
import com.android.wm.shell.desktopmode.CaptionState.NoCaption
import com.android.wm.shell.windowdecor.viewholder.AppHandleIdentifier
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

/** Repository to observe caption state. */
class WindowDecorCaptionRepository {
    private val _captionStateFlow = MutableStateFlow<CaptionState>(NoCaption())
    /** Observer for app handle state changes. */
    val captionStateFlow: StateFlow<CaptionState> = _captionStateFlow
    private val _captionStateFlow =
        MutableSharedFlow<CaptionState>(
            replay = 2,
            extraBufferCapacity = 5,
            onBufferOverflow = BufferOverflow.DROP_OLDEST,
        )
    /** Observer for caption state changes. */
    val captionStateFlow = _captionStateFlow
    private val _appToWebUsageFlow = MutableSharedFlow<Unit>()
    /** Observer for App-to-Web usage. */
    val appToWebUsageFlow = _appToWebUsageFlow

    /** Notifies [captionStateFlow] if there is a change to caption state. */
    fun notifyCaptionChanged(captionState: CaptionState) {
        _captionStateFlow.value = captionState
        _captionStateFlow.tryEmit(captionState)
    }

    /** Notifies [appToWebUsageFlow] if App-to-Web feature is used. */
+28 −9
Original line number Diff line number Diff line
@@ -202,12 +202,12 @@ class AppHandleController(

    private fun notifyNoCaption() {
        if (!desktopState.canEnterDesktopMode || !isEducationOrHandleReportingEnabled) return
        windowDecorHandleRepository.notifyCaptionChanged(CaptionState.NoCaption())
        windowDecorHandleRepository.notifyCaptionChanged(CaptionState.NoCaption(taskInfo.taskId))
    }

    private fun notifyCaptionStateChanged(captionLayoutResult: CaptionRelayoutResult) {
        if (!desktopState.canEnterDesktopMode || !isEducationOrHandleReportingEnabled) return
        if (!isCaptionVisible || !hasGlobalFocus) {
        if (!isCaptionVisible) {
            notifyNoCaption()
            return
        }
@@ -248,14 +248,33 @@ class AppHandleController(
        }

    /** Returns the current bounds relative to the parent task. */
    private fun getCurrentAppHandleBounds(captionLayoutResult: CaptionRelayoutResult): Rect =
    private fun getCurrentAppHandleBounds(captionLayoutResult: CaptionRelayoutResult): Rect {
        val bounds =
            Rect(
                captionLayoutResult.captionX,
                captionLayoutResult.captionY,
                captionLayoutResult.captionX + captionLayoutResult.captionWidth,
            captionLayoutResult.captionHeight,
                captionLayoutResult.captionY + captionLayoutResult.captionHeight,
            )

        if (
            splitScreenController.getSplitPosition(taskInfo.taskId) ==
                SPLIT_POSITION_BOTTOM_OR_RIGHT
        ) {
            if (splitScreenController.isLeftRightSplit) {
                // If this is the right split task, add left stage's width.
                val rightStageBounds =
                    Rect().also { splitScreenController.getStageBounds(Rect(), it) }
                bounds.offset(rightStageBounds.left, /* dy= */ 0)
            } else {
                val bottomStageBounds =
                    Rect().also { splitScreenController.getRefStageBounds(Rect(), it) }
                bounds.offset(/* dx= */ 0, bottomStageBounds.top)
            }
        }
        return bounds
    }

    /**
     * Dispose of the view used to forward inputs in status bar region. Intended to be used any time
     * handle is no longer visible.
+10 −8
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.view.SurfaceControl
import android.view.View
import android.view.View.OnLongClickListener
import android.view.WindowInsets
import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import android.window.TaskSnapshot
import android.window.WindowContainerTransaction
@@ -180,9 +181,10 @@ class AppHeaderController(
        get() = displayController.getDisplay(taskInfo.displayId)

    private val closeMaximizeWindowRunnable = Runnable { closeMaximizeMenu() }
    private val isEducationEnabled =
    private val isEducationOrHandleReportingEnabled =
        Flags.enableDesktopWindowingAppHandleEducation() ||
            Flags.enableDesktopWindowingAppToWebEducationIntegration()
            Flags.enableDesktopWindowingAppToWebEducationIntegration() ||
            DesktopExperienceFlags.ENABLE_APP_HANDLE_POSITION_REPORTING.isTrue

    private var isMaximizeMenuHovered = false
    private var isAppHeaderMaximizeButtonHovered = false
@@ -260,7 +262,7 @@ class AppHeaderController(
    }

    private fun notifyCaptionStateChanged() {
        if (!desktopState.canEnterDesktopMode || !isEducationEnabled) {
        if (!desktopState.canEnterDesktopMode || !isEducationOrHandleReportingEnabled) {
            return
        }
        if (!isCaptionVisible || !hasGlobalFocus) {
@@ -271,8 +273,8 @@ class AppHeaderController(
    }

    private fun notifyNoCaption() {
        if (!desktopState.canEnterDesktopMode || !isEducationEnabled) return
        windowDecorCaptionRepository.notifyCaptionChanged(CaptionState.NoCaption())
        if (!desktopState.canEnterDesktopMode || !isEducationOrHandleReportingEnabled) return
        windowDecorCaptionRepository.notifyCaptionChanged(CaptionState.NoCaption(taskInfo.taskId))
    }

    private fun notifyAppHeaderStateChanged() {
@@ -553,7 +555,7 @@ class AppHeaderController(
        viewHolder.onHandleMenuClosed()
        handleMenu?.close()
        handleMenu = null
        if (desktopState.canEnterDesktopMode && isEducationEnabled) {
        if (desktopState.canEnterDesktopMode && isEducationOrHandleReportingEnabled) {
            notifyCaptionStateChanged()
        }
    }
@@ -637,7 +639,7 @@ class AppHeaderController(
                val (name, icon) = taskResourceLoader.getNameAndHeaderIcon(taskInfo)
                viewHolder.setAppName(name)
                viewHolder.setAppIcon(icon)
                if (desktopState.canEnterDesktopMode && isEducationEnabled) {
                if (desktopState.canEnterDesktopMode && isEducationOrHandleReportingEnabled) {
                    notifyCaptionStateChanged()
                }
            }
@@ -731,7 +733,7 @@ class AppHeaderController(
        closeManageWindowsMenu()
        closeMaximizeMenu()
        viewHolder.close()
        if (desktopState.canEnterDesktopMode && isEducationEnabled) {
        if (desktopState.canEnterDesktopMode && isEducationOrHandleReportingEnabled) {
            notifyNoCaption()
        }
        return super.close(wct, t)
+2 −0
Original line number Diff line number Diff line
@@ -550,7 +550,9 @@ abstract class CaptionController<T>(
        // The caption height with caption padding included
        val captionHeight: Int,
        val captionWidth: Int,
        // The caption x position relative to its parent task
        val captionX: Int,
        // The caption y position relative to its parent task
        val captionY: Int,
        val captionTopPadding: Int,
        val customizableCaptionRegion: Region,
+1 −9
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
@@ -720,14 +719,7 @@ class AppHeaderViewHolder(

    fun runOnAppChipGlobalLayout(runnable: () -> Unit) {
        // Wait for app chip to be inflated before notifying repository.
        openMenuButton.viewTreeObserver.addOnGlobalLayoutListener(
            object : OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    runnable()
                    openMenuButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            }
        )
        openMenuButton.post { runnable() }
    }

    fun getAppChipLocationInWindow(): Rect {
Loading