diff options
21 files changed, 239 insertions, 44 deletions
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java index 9d363c806f5f..3af36ebb08ca 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -28,6 +28,7 @@ import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static android.os.UserHandle.USER_CURRENT; import static android.os.UserHandle.USER_NULL; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_ID; import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_SIZE; import static com.android.server.blob.BlobStoreConfig.LOGV; @@ -1915,7 +1916,7 @@ public class BlobStoreManagerService extends SystemService { mStatsManager.setPullAtomCallback( FrameworkStatsLog.BLOB_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java index eb1848d666f0..7e110eb741dd 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java @@ -16,6 +16,7 @@ package com.android.server.alarm; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__LISTENER; @@ -31,7 +32,6 @@ import android.app.StatsManager; import android.content.Context; import android.os.SystemClock; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.FrameworkStatsLog; import java.util.function.Supplier; @@ -51,7 +51,7 @@ class MetricsHelper { void registerPuller(Supplier<AlarmStore> alarmStoreSupplier) { final StatsManager statsManager = mContext.getSystemService(StatsManager.class); statsManager.setPullAtomCallback(FrameworkStatsLog.PENDING_ALARM_INFO, null, - BackgroundThread.getExecutor(), (atomTag, data) -> { + DIRECT_EXECUTOR, (atomTag, data) -> { if (atomTag != FrameworkStatsLog.PENDING_ALARM_INFO) { throw new UnsupportedOperationException("Unknown tag" + atomTag); } diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java index be8b2a20cfb1..65f56f68ed3f 100644 --- a/core/java/android/content/pm/ServiceInfo.java +++ b/core/java/android/content/pm/ServiceInfo.java @@ -486,7 +486,7 @@ public class ServiceInfo extends ComponentInfo * Here is an example: * <pre> * <uses-permission - * android:name="android.permissions.FOREGROUND_SERVICE_SPECIAL_USE" + * android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" * /> * <service * android:name=".MySpecialForegroundService" @@ -506,7 +506,7 @@ public class ServiceInfo extends ComponentInfo * in both platforms. * <pre> * <uses-permission - * android:name="android.permissions.FOREGROUND_SERVICE_SPECIAL_USE" + * android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" * android:maxSdkVersion="last_sdk_version_without_type_foo" * /> * <service diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 7bdff8c5b858..c43962d5900c 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -7397,19 +7397,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } target = next; } - if (!childIsHit) { + if (!childIsHit && mFirstHoverTarget != null) { target = mFirstHoverTarget; + final ArrayList<View> preorderedList = buildTouchDispatchChildList(); while (notEmpty && target != null) { final HoverTarget next = target.next; final View hoveredView = target.child; - rect.set(hoveredView.mLeft, hoveredView.mTop, hoveredView.mRight, - hoveredView.mBottom); - matrix.mapRect(rect); - notEmpty = region.op(Math.round(rect.left), Math.round(rect.top), - Math.round(rect.right), Math.round(rect.bottom), Region.Op.DIFFERENCE); + if (!isOnTop(child, hoveredView, preorderedList)) { + rect.set(hoveredView.mLeft, hoveredView.mTop, hoveredView.mRight, + hoveredView.mBottom); + matrix.mapRect(rect); + notEmpty = region.op(Math.round(rect.left), Math.round(rect.top), + Math.round(rect.right), Math.round(rect.bottom), + Region.Op.DIFFERENCE); + } target = next; } + if (preorderedList != null) { + preorderedList.clear(); + } } } else { TouchTarget target = mFirstTouchTarget; @@ -7422,19 +7429,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } target = next; } - if (!childIsHit) { + if (!childIsHit && mFirstTouchTarget != null) { target = mFirstTouchTarget; + final ArrayList<View> preorderedList = buildOrderedChildList(); while (notEmpty && target != null) { final TouchTarget next = target.next; final View touchedView = target.child; - rect.set(touchedView.mLeft, touchedView.mTop, touchedView.mRight, - touchedView.mBottom); - matrix.mapRect(rect); - notEmpty = region.op(Math.round(rect.left), Math.round(rect.top), - Math.round(rect.right), Math.round(rect.bottom), Region.Op.DIFFERENCE); + if (!isOnTop(child, touchedView, preorderedList)) { + rect.set(touchedView.mLeft, touchedView.mTop, touchedView.mRight, + touchedView.mBottom); + matrix.mapRect(rect); + notEmpty = region.op(Math.round(rect.left), Math.round(rect.top), + Math.round(rect.right), Math.round(rect.bottom), + Region.Op.DIFFERENCE); + } target = next; } + if (preorderedList != null) { + preorderedList.clear(); + } } } @@ -7444,6 +7458,28 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return notEmpty; } + /** + * Return true if the given {@code view} is drawn on top of the {@code otherView}. + * Both the {@code view} and {@code otherView} must be children of this ViewGroup. + * Otherwise, the returned value is meaningless. + */ + private boolean isOnTop(View view, View otherView, ArrayList<View> preorderedList) { + final int childrenCount = mChildrenCount; + final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i = childrenCount - 1; i >= 0; i--) { + final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); + final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); + if (child == view) { + return true; + } + if (child == otherView) { + return false; + } + } + // Can't find the view and otherView in the children list. Return value is meaningless. + return false; + } private static void applyOpToRegionByBounds(Region region, View view, Region.Op op) { final int[] locationInWindow = new int[2]; diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8cec8f871829..24dbc5eaed41 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2791,7 +2791,7 @@ <!-- Base "handwriting slop" value used by ViewConfiguration as a movement threshold where stylus handwriting should begin. --> - <dimen name="config_viewConfigurationHandwritingSlop">4dp</dimen> + <dimen name="config_viewConfigurationHandwritingSlop">2dp</dimen> <!-- Base "hover slop" value used by ViewConfiguration as a movement threshold under which hover is considered "stationary". --> diff --git a/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java b/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java index 60a0a2adbbbe..c210fd631f06 100644 --- a/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java +++ b/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java @@ -90,22 +90,73 @@ public class ViewGroupGetChildLocalHitRegionTest { assertGetChildLocalHitRegionEmpty(R.id.view_cover_top, R.id.view_cover_bottom); } + @Test + public void testGetChildLocalHitRegion_topViewIsNotBlockedByBottomView() { + // In this case, two views overlap with each other and the MotionEvent is injected to the + // bottom view. It verifies that the hit region of the top view won't be blocked by the + // bottom view. + testGetChildLocalHitRegion_topViewIsNotBlockedByBottomView(/* isHover= */ true); + testGetChildLocalHitRegion_topViewIsNotBlockedByBottomView(/* isHover= */ false); + } + + private void testGetChildLocalHitRegion_topViewIsNotBlockedByBottomView(boolean isHover) { + // In this case, two views overlap with each other and the MotionEvent is injected to the + // bottom view. It verifies that the hit region of the top view won't be blocked by the + // bottom view. + mScenarioRule.getScenario().onActivity(activity -> { + View viewTop = activity.findViewById(R.id.view_overlap_top); + View viewBottom = activity.findViewById(R.id.view_overlap_bottom); + + // The viewTop covers the left side of the viewBottom. To avoid the MotionEvent gets + // blocked by viewTop, we inject MotionEvents into viewBottom's right bottom corner. + float x = viewBottom.getWidth() - 1; + float y = viewBottom.getHeight() - 1; + injectMotionEvent(viewBottom, x, y, isHover); + + Matrix actualMatrix = new Matrix(); + Region actualRegion = new Region(0, 0, viewTop.getWidth(), viewTop.getHeight()); + boolean actualNotEmpty = viewTop.getParent() + .getChildLocalHitRegion(viewTop, actualRegion, actualMatrix, isHover); + + int[] windowLocation = new int[2]; + viewTop.getLocationInWindow(windowLocation); + Matrix expectMatrix = new Matrix(); + expectMatrix.preTranslate(-windowLocation[0], -windowLocation[1]); + // Though viewTop and viewBottom overlaps, viewTop's hit region won't be blocked by + // viewBottom. + Region expectRegion = new Region(0, 0, viewTop.getWidth(), viewTop.getHeight()); + + assertThat(actualNotEmpty).isTrue(); + assertThat(actualMatrix).isEqualTo(expectMatrix); + assertThat(actualRegion).isEqualTo(expectRegion); + }); + } + private void injectMotionEvent(View view, boolean isHover) { + float x = view.getWidth() / 2f; + float y = view.getHeight() / 2f; + injectMotionEvent(view, x, y, isHover); + } + + /** + * Inject MotionEvent into the given view, at the given location specified in the view's + * coordinates. + */ + private void injectMotionEvent(View view, float x, float y, boolean isHover) { int[] location = new int[2]; view.getLocationInWindow(location); - float x = location[0] + view.getWidth() / 2f; - float y = location[1] + view.getHeight() / 2f; + float globalX = location[0] + x; + float globalY = location[1] + y; int action = isHover ? MotionEvent.ACTION_HOVER_ENTER : MotionEvent.ACTION_DOWN; MotionEvent motionEvent = MotionEvent.obtain(/* downtime= */ 0, /* eventTime= */ 0, action, - x, y, /* pressure= */ 0, /* size= */ 0, /* metaState= */ 0, + globalX, globalY, /* pressure= */ 0, /* size= */ 0, /* metaState= */ 0, /* xPrecision= */ 1, /* yPrecision= */ 1, /* deviceId= */0, /* edgeFlags= */0); View rootView = view.getRootView(); rootView.dispatchPointerEvent(motionEvent); } - private void assertGetChildLocalHitRegion(int viewId) { assertGetChildLocalHitRegion(viewId, /* isHover= */ true); assertGetChildLocalHitRegion(viewId, /* isHover= */ false); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 5b9b53e65ff4..e2855c9e7260 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -4214,7 +4214,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); final boolean previousState = mAllowFingerprintOnCurrentOccludingActivity; mAllowFingerprintOnCurrentOccludingActivity = - standardTask.topActivity != null + standardTask != null && standardTask.topActivity != null && !TextUtils.isEmpty(standardTask.topActivity.getPackageName()) && mAllowFingerprintOnOccludingActivitiesFromPackage.contains( standardTask.topActivity.getPackageName()) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt index 94b5fb2861b1..21451dc0ffdf 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt @@ -58,6 +58,7 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>( // Notification shade can be expanded but not visible (fraction: 0.0), for example // when a heads-up notification (HUN) is showing. notificationShadeVisible = event.expanded && event.fraction > 0f + notificationShadeTracking = event.tracking view.onExpansionChanged(event.fraction) updatePauseAuth() } @@ -65,6 +66,9 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>( /** If the notification shade is visible. */ var notificationShadeVisible: Boolean = false + /** If the notification shade is currently being dragged */ + var notificationShadeTracking: Boolean = false + /** * The amount of translation needed if the view currently requires the user to touch * somewhere other than the exact center of the sensor. For example, this can happen diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt index 802eea300bd4..96354c2a99ff 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt @@ -15,6 +15,7 @@ */ package com.android.systemui.biometrics +import com.android.internal.annotations.VisibleForTesting import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionStateManager @@ -39,6 +40,12 @@ class UdfpsBpViewController( override val tag = "UdfpsBpViewController" override fun shouldPauseAuth(): Boolean { - return false + // Do not auth while notification shade is being dragged + return notificationShadeTracking + } + + @VisibleForTesting + public override fun onViewAttached() { + super.onViewAttached() } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index a36870346b9a..c29f884c848d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -549,8 +549,12 @@ public class UdfpsController implements DozeReceiver, Dumpable { Log.e(TAG, "ignoring the touch injected from outside of UdfpsView"); return false; } - if (mOverlay == null) { - Log.w(TAG, "ignoring onTouch with null overlay"); + if (mOverlay == null || mOverlay.getAnimationViewController() == null) { + Log.w(TAG, "ignoring onTouch with null overlay or animation view controller"); + return false; + } + if (mOverlay.getAnimationViewController().shouldPauseAuth()) { + Log.w(TAG, "ignoring onTouch with shouldPauseAuth = true"); return false; } if (!mOverlay.matchesRequestId(requestId)) { diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt index 656411874de5..54eba34ed55c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt @@ -479,11 +479,13 @@ constructor( if (largeScreenActive) { logInstantEvent("Large screen constraints set") header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID) + systemIcons.isClickable = true systemIcons.setOnClickListener { shadeCollapseAction?.run() } } else { logInstantEvent("Small screen constraints set") header.setTransition(HEADER_TRANSITION_ID) systemIcons.setOnClickListener(null) + systemIcons.isClickable = false } header.jumpToState(header.startState) updatePosition() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index a243356c8690..e76bae5e955b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -2368,10 +2368,16 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // * When phone is unlocked: we still don't want to execute hiding of the keyguard // as the animation could prepare 'fake AOD' interface (without actually // transitioning to keyguard state) and this might reset the view states + // Log for b/290627350 + Log.d(TAG, "!shouldBeKeyguard mStatusBarStateController.isKeyguardRequested() " + + mStatusBarStateController.isKeyguardRequested() + " keyguardForDozing " + + keyguardForDozing + " wakeAndUnlocking " + wakeAndUnlocking + + " isWakingAndOccluded " + isWakingAndOccluded); if (!mScreenOffAnimationController.isKeyguardHideDelayed() // If we're animating occluded, there's an activity launching over the keyguard // UI. Wait to hide it until after the animation concludes. && !mKeyguardViewMediator.isOccludeAnimationPlaying()) { + Log.d(TAG, "hideKeyguardImpl " + forceStateChange); return hideKeyguardImpl(forceStateChange); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt index 7de78a60b73e..9be3d8201053 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt @@ -23,14 +23,19 @@ import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.shade.ShadeExpansionChangeEvent import com.android.systemui.shade.ShadeExpansionStateManager import com.android.systemui.statusbar.phone.SystemUIDialogManager +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.mockito.withArgCaptor import org.junit.Assert.assertFalse import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit @SmallTest @@ -51,6 +56,8 @@ class UdfpsBpViewControllerTest : SysuiTestCase() { @Before fun setup() { + whenever(shadeExpansionStateManager.addExpansionListener(any())) + .thenReturn(ShadeExpansionChangeEvent(0f, false, false, 0f)) udfpsBpViewController = UdfpsBpViewController( udfpsBpView, @@ -62,7 +69,32 @@ class UdfpsBpViewControllerTest : SysuiTestCase() { } @Test - fun testShouldNeverPauseAuth() { + fun testPauseAuthWhenNotificationShadeDragging() { + udfpsBpViewController.onViewAttached() + val shadeExpansionListener = withArgCaptor { + verify(shadeExpansionStateManager).addExpansionListener(capture()) + } + + // When shade is tracking, should pause auth + shadeExpansionListener.onPanelExpansionChanged( + ShadeExpansionChangeEvent( + fraction = 0f, + expanded = false, + tracking = true, + dragDownPxAmount = 10f + ) + ) + assert(udfpsBpViewController.shouldPauseAuth()) + + // When shade is not tracking, don't pause auth even if expanded + shadeExpansionListener.onPanelExpansionChanged( + ShadeExpansionChangeEvent( + fraction = 0f, + expanded = true, + tracking = false, + dragDownPxAmount = 10f + ) + ) assertFalse(udfpsBpViewController.shouldPauseAuth()) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index e56b5c7406b6..7dd88b437f17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -207,6 +207,8 @@ public class UdfpsControllerTest extends SysuiTestCase { private final UdfpsAnimationViewController mUdfpsKeyguardViewController = mock(UdfpsKeyguardViewControllerLegacy.class); @Mock + private UdfpsAnimationViewController mUdfpsAnimationViewController; + @Mock private SystemUIDialogManager mSystemUIDialogManager; @Mock private ActivityLaunchAnimator mActivityLaunchAnimator; @@ -267,6 +269,7 @@ public class UdfpsControllerTest extends SysuiTestCase { when(mSessionTracker.getSessionId(anyInt())).thenReturn( (new InstanceIdSequence(1 << 20)).newInstanceId()); when(mUdfpsView.getViewRootImpl()).thenReturn(mViewRootImpl); + when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsAnimationViewController); final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */, @@ -1380,6 +1383,50 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test + public void onTouch_withNewTouchDetection_ignoreIfAuthPaused() throws RemoteException { + final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L, + 0L); + final TouchProcessorResult processorResultDown = + new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN, + 1 /* pointerId */, touchData); + + // Enable new touch detection. + when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true); + + // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider. + initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */); + + // Configure UdfpsView to not accept the ACTION_DOWN event + when(mUdfpsView.isDisplayConfigured()).thenReturn(true); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + + // GIVEN that auth is paused + when(mUdfpsAnimationViewController.shouldPauseAuth()).thenReturn(true); + + // GIVEN that the overlay is showing and a11y touch exploration NOT enabled + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + + // WHEN ACTION_DOWN is received and touch is within sensor + when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn( + processorResultDown); + MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); + mBiometricExecutor.runAllReady(); + downEvent.recycle(); + + // THEN the touch is ignored + verify(mInputManager, never()).pilferPointers(any()); + verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), + anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), + anyBoolean()); + } + + @Test public void onTouch_withNewTouchDetection_pilferPointer() throws RemoteException { final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L, 0L); diff --git a/services/core/java/com/android/server/LogMteState.java b/services/core/java/com/android/server/LogMteState.java index 410dd8339b30..ec0492b19f89 100644 --- a/services/core/java/com/android/server/LogMteState.java +++ b/services/core/java/com/android/server/LogMteState.java @@ -16,11 +16,12 @@ package com.android.server; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.app.StatsManager; import android.content.Context; import android.util.StatsEvent; -import com.android.internal.os.BackgroundThread; import com.android.internal.os.Zygote; import com.android.internal.util.FrameworkStatsLog; @@ -32,7 +33,7 @@ public class LogMteState { .setPullAtomCallback( FrameworkStatsLog.MTE_STATE, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, new StatsManager.StatsPullAtomCallback() { @Override public int onPullAtom(int atomTag, List<StatsEvent> data) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 2c745ae3bf55..be123f36ebcc 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -27,6 +27,8 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.RequiresNoPermission; @@ -95,7 +97,6 @@ import android.util.StatsEvent; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; -import com.android.internal.os.BackgroundThread; import com.android.internal.os.BinderCallsStats; import com.android.internal.os.PowerProfile; import com.android.internal.os.RailStats; @@ -839,15 +840,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); } /** StatsPullAtomCallback for pulling BatteryUsageStats data. */ diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 80d14a21cc7e..0c9cb3bd00f8 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -25,6 +25,7 @@ import static com.android.internal.R.styleable.GameModeConfig_allowGameDownscali import static com.android.internal.R.styleable.GameModeConfig_allowGameFpsOverride; import static com.android.internal.R.styleable.GameModeConfig_supportsBatteryGameMode; import static com.android.internal.R.styleable.GameModeConfig_supportsPerformanceGameMode; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import android.Manifest; import android.annotation.NonNull; @@ -2092,17 +2093,17 @@ public final class GameManagerService extends IGameManagerService.Stub { statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_CONFIGURATION, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_LISTENER, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c24e729cbff5..e633ba6886d0 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2632,7 +2632,7 @@ public class NotificationManagerService extends SystemService { mStatsManager.setPullAtomCallback( DND_MODE_RULE, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + ConcurrentUtils.DIRECT_EXECUTOR, mPullAtomCallback ); } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index f5c5867edb53..ca0c1f98fe0d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -23,6 +23,7 @@ import static android.os.UserManager.DISALLOW_USER_SWITCH; import static android.os.UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY; import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_ABORTED; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_UNSPECIFIED; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_USER_ALREADY_AN_ADMIN; @@ -5234,12 +5235,12 @@ public class UserManagerService extends IUserManager.Stub { statsManager.setPullAtomCallback( FrameworkStatsLog.USER_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.MULTI_USER_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index 1a91d252c431..f425ba32ced0 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -16,6 +16,8 @@ package com.android.server.power.hint; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityManagerInternal; @@ -37,7 +39,6 @@ import android.util.StatsEvent; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; @@ -142,7 +143,7 @@ public final class HintManagerService extends SystemService { statsManager.setPullAtomCallback( FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 9128974fa9d3..79b2836e237d 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -1599,7 +1599,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1612,7 +1612,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1625,7 +1625,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } |