Track falsing touches on UserSwitcherActivity

UserSwitcherActivity uses the FalsingManager, but the FalsingManager
wasn't being told about touches happening on its surface. Therefore,
the FalsingManager was relying on whatever the most recent touch
was elsewhere.

If this touch was a swipe (such as on the shade) it would not let an
owner change users because a swipe is not a tap.

Test: manual
Fixes: 238598985
Change-Id: Ic1f86d6f4b55b5a28d7db5d56afe72136dbdcef9
This commit is contained in:
Dave Mankoff
2022-07-14 21:56:34 +00:00
parent 7eef3f9ee8
commit b71ea18e15
6 changed files with 68 additions and 11 deletions

View File

@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.constraintlayout.widget.ConstraintLayout
<com.android.systemui.user.UserSwitcherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
@@ -68,4 +68,4 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_min="48dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.android.systemui.user.UserSwitcherRootView>

View File

@@ -20,6 +20,13 @@ import android.view.MotionEvent;
// ACHTUNG!
public interface Gefingerpoken {
boolean onInterceptTouchEvent(MotionEvent ev);
boolean onTouchEvent(MotionEvent ev);
/** Called when a touch is being intercepted in a ViewGroup. */
default boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
/** Called when a touch is being handled by a view. */
default boolean onTouchEvent(MotionEvent ev) {
return false;
}
}

View File

@@ -28,6 +28,7 @@ import android.os.Bundle
import android.os.UserManager
import android.provider.Settings
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
@@ -38,8 +39,10 @@ import androidx.constraintlayout.helper.widget.Flow
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.util.UserIcons
import com.android.settingslib.Utils
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
import com.android.systemui.settings.UserTracker
@@ -61,12 +64,13 @@ class UserSwitcherActivity @Inject constructor(
private val userSwitcherController: UserSwitcherController,
private val broadcastDispatcher: BroadcastDispatcher,
private val layoutInflater: LayoutInflater,
private val falsingCollector: FalsingCollector,
private val falsingManager: FalsingManager,
private val userManager: UserManager,
private val userTracker: UserTracker
) : LifecycleActivity() {
private lateinit var parent: ViewGroup
private lateinit var parent: UserSwitcherRootView
private lateinit var broadcastReceiver: BroadcastReceiver
private var popupMenu: UserSwitcherPopupMenu? = null
private lateinit var addButton: View
@@ -202,7 +206,14 @@ class UserSwitcherActivity @Inject constructor(
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
parent = requireViewById<ViewGroup>(R.id.user_switcher_root)
parent = requireViewById<UserSwitcherRootView>(R.id.user_switcher_root)
parent.touchHandler = object : Gefingerpoken {
override fun onTouchEvent(ev: MotionEvent?): Boolean {
falsingCollector.onTouchEvent(ev)
return false
}
}
requireViewById<View>(R.id.cancel).apply {
setOnClickListener {
@@ -241,7 +252,7 @@ class UserSwitcherActivity @Inject constructor(
)
popupMenuAdapter.addAll(items)
popupMenu = UserSwitcherPopupMenu(this, falsingManager).apply {
popupMenu = UserSwitcherPopupMenu(this).apply {
setAnchorView(addButton)
setAdapter(popupMenuAdapter)
setOnItemClickListener {

View File

@@ -23,16 +23,13 @@ import android.view.View.MeasureSpec
import android.widget.ListAdapter
import android.widget.ListPopupWindow
import android.widget.ListView
import com.android.systemui.R
import com.android.systemui.plugins.FalsingManager
/**
* Popup menu for displaying items on the fullscreen user switcher.
*/
class UserSwitcherPopupMenu(
private val context: Context,
private val falsingManager: FalsingManager
private val context: Context
) : ListPopupWindow(context) {
private val res = context.resources

View File

@@ -0,0 +1,38 @@
/*
* 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.user
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.constraintlayout.widget.ConstraintLayout
import com.android.systemui.Gefingerpoken
/** A simple subclass that allows for observing touch events as they happen. */
class UserSwitcherRootView(
context: Context,
attrs: AttributeSet?
) : ConstraintLayout(context, attrs) {
/** Assign this field to observer touch events. */
var touchHandler: Gefingerpoken? = null
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
touchHandler?.onTouchEvent(ev)
return super.dispatchTouchEvent(ev)
}
}

View File

@@ -23,6 +23,7 @@ import android.view.LayoutInflater
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.UserSwitcherController
@@ -46,6 +47,8 @@ class UserSwitcherActivityTest : SysuiTestCase() {
@Mock
private lateinit var layoutInflater: LayoutInflater
@Mock
private lateinit var falsingCollector: FalsingCollector
@Mock
private lateinit var falsingManager: FalsingManager
@Mock
private lateinit var userManager: UserManager
@@ -59,6 +62,7 @@ class UserSwitcherActivityTest : SysuiTestCase() {
userSwitcherController,
broadcastDispatcher,
layoutInflater,
falsingCollector,
falsingManager,
userManager,
userTracker