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

Commit 0c296801 authored by Michael Mikhail's avatar Michael Mikhail Committed by Android (Google) Code Review
Browse files

Merge "Add falsing to undo button" into tm-qpr-dev

parents e99311a4 ccd1accb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
<!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view
     is the root view of a window, we cannot change the root view's margins.) -->
<!-- Alphas start as 0 because the view will be animated in. -->
<FrameLayout
<com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    android:id="@+id/media_ttt_sender_chip"
@@ -97,4 +97,4 @@
            />

    </LinearLayout>
</FrameLayout>
</com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView>
+11 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
import com.android.systemui.plugins.FalsingManager

/**
 * A class enumerating all the possible states of the media tap-to-transfer chip on the sender
@@ -106,12 +107,15 @@ enum class ChipStateSender(
            controllerSender: MediaTttChipControllerSender,
            routeInfo: MediaRoute2Info,
            undoCallback: IUndoMediaTransferCallback?,
            uiEventLogger: MediaTttSenderUiEventLogger
            uiEventLogger: MediaTttSenderUiEventLogger,
            falsingManager: FalsingManager,
        ): View.OnClickListener? {
            if (undoCallback == null) {
                return null
            }
            return View.OnClickListener {
                if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener

                uiEventLogger.logUndoClicked(
                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
                )
@@ -141,12 +145,15 @@ enum class ChipStateSender(
            controllerSender: MediaTttChipControllerSender,
            routeInfo: MediaRoute2Info,
            undoCallback: IUndoMediaTransferCallback?,
            uiEventLogger: MediaTttSenderUiEventLogger
            uiEventLogger: MediaTttSenderUiEventLogger,
            falsingManager: FalsingManager,
        ): View.OnClickListener? {
            if (undoCallback == null) {
                return null
            }
            return View.OnClickListener {
                if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener

                uiEventLogger.logUndoClicked(
                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
                )
@@ -212,7 +219,8 @@ enum class ChipStateSender(
        controllerSender: MediaTttChipControllerSender,
        routeInfo: MediaRoute2Info,
        undoCallback: IUndoMediaTransferCallback?,
        uiEventLogger: MediaTttSenderUiEventLogger
        uiEventLogger: MediaTttSenderUiEventLogger,
        falsingManager: FalsingManager,
    ): View.OnClickListener? = null

    companion object {
+24 −2
Original line number Diff line number Diff line
@@ -22,21 +22,25 @@ import android.media.MediaRoute2Info
import android.os.PowerManager
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.widget.TextView
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.animation.ViewHierarchyAnimator
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -58,7 +62,9 @@ class MediaTttChipControllerSender @Inject constructor(
        accessibilityManager: AccessibilityManager,
        configurationController: ConfigurationController,
        powerManager: PowerManager,
        private val uiEventLogger: MediaTttSenderUiEventLogger
        private val uiEventLogger: MediaTttSenderUiEventLogger,
        private val falsingManager: FalsingManager,
        private val falsingCollector: FalsingCollector,
) : MediaTttChipControllerCommon<ChipSenderInfo>(
        context,
        logger,
@@ -70,6 +76,9 @@ class MediaTttChipControllerSender @Inject constructor(
        powerManager,
        R.layout.media_ttt_chip,
) {

    private lateinit var parent: MediaTttChipRootView

    override val windowLayoutParams = commonWindowLayoutParams.apply {
        gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
    }
@@ -121,6 +130,15 @@ class MediaTttChipControllerSender @Inject constructor(

        val chipState = newChipInfo.state

        // Detect falsing touches on the chip.
        parent = currentChipView as MediaTttChipRootView
        parent.touchHandler = object : Gefingerpoken {
            override fun onTouchEvent(ev: MotionEvent?): Boolean {
                falsingCollector.onTouchEvent(ev)
                return false
            }
        }

        // App icon
        val iconName = setIcon(currentChipView, newChipInfo.routeInfo.clientPackageName)

@@ -136,7 +154,11 @@ class MediaTttChipControllerSender @Inject constructor(
        // Undo
        val undoView = currentChipView.requireViewById<View>(R.id.undo)
        val undoClickListener = chipState.undoClickListener(
                this, newChipInfo.routeInfo, newChipInfo.undoCallback, uiEventLogger
                this,
                newChipInfo.routeInfo,
                newChipInfo.undoCallback,
                uiEventLogger,
                falsingManager,
        )
        undoView.setOnClickListener(undoClickListener)
        undoView.visibility = (undoClickListener != null).visibleIfTrue()
+38 −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.systemui.media.taptotransfer.sender

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.FrameLayout
import com.android.systemui.Gefingerpoken

/** A simple subclass that allows for observing touch events on chip. */
class MediaTttChipRootView(
        context: Context,
        attrs: AttributeSet?
) : FrameLayout(context, attrs) {

    /** Assign this field to observe touch events. */
    var touchHandler: Gefingerpoken? = null

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        touchHandler?.onTouchEvent(ev)
        return super.dispatchTouchEvent(ev)
    }
}
+43 −2
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@ import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -48,11 +50,12 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations

@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -78,6 +81,10 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
    private lateinit var viewUtil: ViewUtil
    @Mock
    private lateinit var commandQueue: CommandQueue
    @Mock
    private lateinit var falsingManager: FalsingManager
    @Mock
    private lateinit var falsingCollector: FalsingCollector
    private lateinit var commandQueueCallback: CommandQueue.Callbacks
    private lateinit var fakeAppIconDrawable: Drawable
    private lateinit var fakeClock: FakeSystemClock
@@ -115,7 +122,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
            accessibilityManager,
            configurationController,
            powerManager,
            senderUiEventLogger
            senderUiEventLogger,
            falsingManager,
            falsingCollector
        )

        val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -420,6 +429,38 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
        assertThat(undoCallbackCalled).isTrue()
    }

    @Test
    fun transferToReceiverSucceeded_withUndoRunnable_falseTap_callbackNotRun() {
        whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
        var undoCallbackCalled = false
        val undoCallback = object : IUndoMediaTransferCallback.Stub() {
            override fun onUndoTriggered() {
                undoCallbackCalled = true
            }
        }

        controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
        getChipView().getUndoButton().performClick()

        assertThat(undoCallbackCalled).isFalse()
    }

    @Test
    fun transferToReceiverSucceeded_withUndoRunnable_realTap_callbackRun() {
        whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
        var undoCallbackCalled = false
        val undoCallback = object : IUndoMediaTransferCallback.Stub() {
            override fun onUndoTriggered() {
                undoCallbackCalled = true
            }
        }

        controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
        getChipView().getUndoButton().performClick()

        assertThat(undoCallbackCalled).isTrue()
    }

    @Test
    fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() {
        val undoCallback = object : IUndoMediaTransferCallback.Stub() {