diff options
18 files changed, 150 insertions, 103 deletions
diff --git a/apex/extservices/apex_manifest.json b/apex/extservices/apex_manifest.json index fd6c01b939a7..1a328461dbae 100644 --- a/apex/extservices/apex_manifest.json +++ b/apex/extservices/apex_manifest.json @@ -1,4 +1,4 @@ { "name": "com.android.extservices", - "version": 300900500 + "version": 300900600 } diff --git a/apex/permission/apex_manifest.json b/apex/permission/apex_manifest.json index 1806fc4249c4..7875bc1509d0 100644 --- a/apex/permission/apex_manifest.json +++ b/apex/permission/apex_manifest.json @@ -1,4 +1,4 @@ { "name": "com.android.permission", - "version": 300900500 + "version": 300900600 } diff --git a/apex/statsd/apex_manifest.json b/apex/statsd/apex_manifest.json index 0616cd6f552d..42f129711878 100644 --- a/apex/statsd/apex_manifest.json +++ b/apex/statsd/apex_manifest.json @@ -1,5 +1,5 @@ { "name": "com.android.os.statsd", - "version": 300900500 + "version": 300900600 } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index f3c9e9435417..241e9399be0a 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -1951,7 +1951,8 @@ public class LocationManager { } try { - return mGnssStatusListenerManager.addListener(listener, Runnable::run); + return mGnssStatusListenerManager.addListener(listener, + new HandlerExecutor(new Handler())); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2086,7 +2087,7 @@ public class LocationManager { @Deprecated @RequiresPermission(ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) { - return addNmeaListener(Runnable::run, listener); + return addNmeaListener(listener, null); } /** diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DummyNotificationShadeWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DummyNotificationShadeWindowController.java index a4230032858e..13f2b7ed45db 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DummyNotificationShadeWindowController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DummyNotificationShadeWindowController.java @@ -23,6 +23,7 @@ import android.view.WindowManager; import com.android.systemui.car.window.SystemUIOverlayWindowController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.DozeParameters; @@ -49,12 +50,14 @@ public class DummyNotificationShadeWindowController extends NotificationShadeWin DozeParameters dozeParameters, StatusBarStateController statusBarStateController, ConfigurationController configurationController, + KeyguardViewMediator keyguardViewMediator, KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor, DumpManager dumpManager, SystemUIOverlayWindowController overlayWindowController) { super(context, windowManager, activityManager, dozeParameters, statusBarStateController, - configurationController, keyguardBypassController, colorExtractor, dumpManager); + configurationController, keyguardViewMediator, keyguardBypassController, + colorExtractor, dumpManager); mOverlayWindowController = overlayWindowController; } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 127c5dd54d72..e12b7dd259a5 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.content.res.Configuration import android.graphics.Color import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS +import android.util.Log import android.util.MathUtils import android.view.LayoutInflater import android.view.View @@ -25,6 +26,7 @@ import javax.inject.Inject import javax.inject.Provider import javax.inject.Singleton +private const val TAG = "MediaCarouselController" private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS) /** @@ -236,7 +238,9 @@ class MediaCarouselController @Inject constructor( val oldData = mediaPlayers[oldKey] if (oldData != null) { val oldData = mediaPlayers.remove(oldKey) - mediaPlayers.put(key, oldData!!) + mediaPlayers.put(key, oldData!!)?.let { + Log.wtf(TAG, "new key $key already exists when migrating from $oldKey") + } } var existingPlayer = mediaPlayers[key] if (existingPlayer == null) { @@ -271,6 +275,11 @@ class MediaCarouselController @Inject constructor( updatePageIndicator() mediaCarouselScrollHandler.onPlayersChanged() mediaCarousel.requiresRemeasuring = true + // Check postcondition: mediaContent should have the same number of children as there are + // elements in mediaPlayers. + if (mediaPlayers.size != mediaContent.childCount) { + Log.wtf(TAG, "Size of players list and number of views in carousel are out of sync") + } } private fun removePlayer(key: String) { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 8cb93bfc6d4d..299ae5b50aa9 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -517,22 +517,36 @@ class MediaDataManager( fun onNotificationRemoved(key: String) { Assert.isMainThread() - if (useMediaResumption && mediaEntries.get(key)?.resumeAction != null) { + val removed = mediaEntries.remove(key) + if (useMediaResumption && removed?.resumeAction != null) { Log.d(TAG, "Not removing $key because resumable") - // Move to resume key aka package name - val data = mediaEntries.remove(key)!! - val resumeAction = getResumeMediaAction(data.resumeAction!!) - val updated = data.copy(token = null, actions = listOf(resumeAction), + // Move to resume key (aka package name) if that key doesn't already exist. + val resumeAction = getResumeMediaAction(removed.resumeAction!!) + val updated = removed.copy(token = null, actions = listOf(resumeAction), actionsToShowInCompact = listOf(0), active = false, resumption = true) - mediaEntries.put(data.packageName, updated) - // Notify listeners of "new" controls + val pkg = removed?.packageName + val migrate = mediaEntries.put(pkg, updated) == null + // Notify listeners of "new" controls when migrating or removed and update when not val listenersCopy = listeners.toSet() - listenersCopy.forEach { - it.onMediaDataLoaded(data.packageName, key, updated) + if (migrate) { + listenersCopy.forEach { + it.onMediaDataLoaded(pkg, key, updated) + } + } else { + // Since packageName is used for the key of the resumption controls, it is + // possible that another notification has already been reused for the resumption + // controls of this package. In this case, rather than renaming this player as + // packageName, just remove it and then send a update to the existing resumption + // controls. + listenersCopy.forEach { + it.onMediaDataRemoved(key) + } + listenersCopy.forEach { + it.onMediaDataLoaded(pkg, pkg, updated) + } } return } - val removed = mediaEntries.remove(key) if (removed != null) { val listenersCopy = listeners.toSet() listenersCopy.forEach { diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index d7cc11b7fd15..a8130a1e6d1a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -171,7 +171,6 @@ public class PipTouchHandler { private float mSavedSnapFraction = -1f; private boolean mSendingHoverAccessibilityEvents; private boolean mMovementWithinDismiss; - private boolean mHideMenuAfterShown = false; private PipAccessibilityInteractionConnection mConnection; // Touch state @@ -726,7 +725,6 @@ public class PipTouchHandler { // on and changing MotionEvents into HoverEvents. // Let's not enable menu show/hide for a11y services. if (!mAccessibilityManager.isTouchExplorationEnabled()) { - mHideMenuAfterShown = true; mTouchState.scheduleHoverExitTimeoutCallback(); } if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) { @@ -813,9 +811,6 @@ public class PipTouchHandler { mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds, mMovementBounds, mExpandedMovementBounds, callback); } - if (mHideMenuAfterShown) { - mMenuController.hideMenu(); - } } else if (menuState == MENU_STATE_NONE && mMenuState == MENU_STATE_FULL) { // Try and restore the PiP to the closest edge, using the saved snap fraction // if possible @@ -853,7 +848,6 @@ public class PipTouchHandler { } } mMenuState = menuState; - mHideMenuAfterShown = false; updateMovementBounds(); // If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip // as well, or it can't handle a11y focus and pip menu can't perform any action. diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 6f554e698c58..b6c6afd523b3 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -675,6 +675,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, } private void notifySplitScreenBoundsChanged() { + if (mSplitLayout.mPrimary == null || mSplitLayout.mSecondary == null) { + return; + } mOtherTaskRect.set(mSplitLayout.mSecondary); mTmpRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), mHandle.getBottom()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java index 2e4a929ded5b..5164440c1463 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java @@ -84,6 +84,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, private final boolean mKeyguardScreenRotation; private final long mLockScreenDisplayTimeout; private final Display.Mode mKeyguardDisplayMode; + private final KeyguardViewMediator mKeyguardViewMediator; private final KeyguardBypassController mKeyguardBypassController; private ViewGroup mNotificationShadeView; private LayoutParams mLp; @@ -104,6 +105,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, IActivityManager activityManager, DozeParameters dozeParameters, StatusBarStateController statusBarStateController, ConfigurationController configurationController, + KeyguardViewMediator keyguardViewMediator, KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor, DumpManager dumpManager) { mContext = context; @@ -113,6 +115,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, mDozeParameters = dozeParameters; mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze(); mLpChanged = new LayoutParams(); + mKeyguardViewMediator = keyguardViewMediator; mKeyguardBypassController = keyguardBypassController; mColorExtractor = colorExtractor; dumpManager.registerDumpable(getClass().getName(), this); @@ -202,6 +205,11 @@ public class NotificationShadeWindowController implements Callback, Dumpable, mWindowManager.addView(mNotificationShadeView, mLp); mLpChanged.copyFrom(mLp); onThemeChanged(); + + // Make the state consistent with KeyguardViewMediator#setupLocked during initialization. + if (mKeyguardViewMediator.isShowingAndNotOccluded()) { + setKeyguardShowing(true); + } } public void setNotificationShadeView(ViewGroup view) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 5b46b7fa4d9f..15828b41cc7c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -63,6 +63,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.system.QuickStepContract; @@ -135,6 +136,8 @@ public class BubbleControllerTest extends SysuiTestCase { @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock + private KeyguardViewMediator mKeyguardViewMediator; + @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private FloatingContentCoordinator mFloatingContentCoordinator; @@ -198,8 +201,8 @@ public class BubbleControllerTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowController(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, - mConfigurationController, mKeyguardBypassController, mColorExtractor, - mDumpManager); + mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, + mColorExtractor, mDumpManager); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 52c64cc40e79..b318e45eda86 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -60,6 +60,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.FeatureFlags; @@ -132,6 +133,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock + private KeyguardViewMediator mKeyguardViewMediator; + @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private FloatingContentCoordinator mFloatingContentCoordinator; @@ -194,8 +197,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Bubbles get added to status bar window view mNotificationShadeWindowController = new NotificationShadeWindowController(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, - mConfigurationController, mKeyguardBypassController, mColorExtractor, - mDumpManager); + mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, + mColorExtractor, mDumpManager); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index 6761b282b26a..59c2d0e86c56 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -31,6 +31,7 @@ import org.mockito.junit.MockitoJUnit import org.mockito.Mockito.`when` as whenever private const val KEY = "KEY" +private const val KEY_2 = "KEY_2" private const val PACKAGE_NAME = "com.android.systemui" private const val APP_NAME = "SystemUI" private const val SESSION_ARTIST = "artist" @@ -156,8 +157,43 @@ class MediaDataManagerTest : SysuiTestCase() { mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {})) // WHEN the notification is removed mediaDataManager.onNotificationRemoved(KEY) - // THEN the media data indicates that it is + // THEN the media data indicates that it is for resumption + assertThat(listener.data!!.resumption).isTrue() + // AND the new key is the package name + assertThat(listener.key!!).isEqualTo(PACKAGE_NAME) + assertThat(listener.oldKey!!).isEqualTo(KEY) + assertThat(listener.removedKey).isNull() + } + + @Test + fun testOnNotificationRemoved_twoWithResumption() { + // GIVEN that the manager has two notifications with resume actions + val listener = TestListener() + mediaDataManager.addListener(listener) + whenever(controller.metadata).thenReturn(metadataBuilder.build()) + mediaDataManager.onNotificationAdded(KEY, mediaNotification) + mediaDataManager.onNotificationAdded(KEY_2, mediaNotification) + assertThat(backgroundExecutor.runAllReady()).isEqualTo(2) + assertThat(foregroundExecutor.runAllReady()).isEqualTo(2) + val data = listener.data!! + assertThat(data.resumption).isFalse() + val resumableData = data.copy(resumeAction = Runnable {}) + mediaDataManager.onMediaDataLoaded(KEY, null, resumableData) + mediaDataManager.onMediaDataLoaded(KEY_2, null, resumableData) + // WHEN the first is removed + mediaDataManager.onNotificationRemoved(KEY) + // THEN the data is for resumption and the key is migrated to the package name + assertThat(listener.data!!.resumption).isTrue() + assertThat(listener.key!!).isEqualTo(PACKAGE_NAME) + assertThat(listener.oldKey!!).isEqualTo(KEY) + assertThat(listener.removedKey).isNull() + // WHEN the second is removed + mediaDataManager.onNotificationRemoved(KEY_2) + // THEN the data is for resumption and the second key is removed assertThat(listener.data!!.resumption).isTrue() + assertThat(listener.key!!).isEqualTo(PACKAGE_NAME) + assertThat(listener.oldKey!!).isEqualTo(PACKAGE_NAME) + assertThat(listener.removedKey!!).isEqualTo(KEY_2) } @Test @@ -190,6 +226,7 @@ class MediaDataManagerTest : SysuiTestCase() { var data: MediaData? = null var key: String? = null var oldKey: String? = null + var removedKey: String? = null override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { this.key = key @@ -198,9 +235,7 @@ class MediaDataManagerTest : SysuiTestCase() { } override fun onMediaDataRemoved(key: String) { - this.key = key - oldKey = null - data = null + removedKey = key } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java index ca6c16f91ad8..8c37cf1514fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static com.google.common.truth.Truth.assertThat; @@ -41,6 +42,7 @@ import com.android.internal.colorextraction.ColorExtractor; import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -63,6 +65,7 @@ public class NotificationShadeWindowControllerTest extends SysuiTestCase { @Mock private IActivityManager mActivityManager; @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock private ConfigurationController mConfigurationController; + @Mock private KeyguardViewMediator mKeyguardViewMediator; @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private SysuiColorExtractor mColorExtractor; @Mock ColorExtractor.GradientColors mGradientColors; @@ -79,8 +82,8 @@ public class NotificationShadeWindowControllerTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowController(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, - mConfigurationController, mKeyguardBypassController, mColorExtractor, - mDumpManager); + mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, + mColorExtractor, mDumpManager); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); @@ -120,6 +123,17 @@ public class NotificationShadeWindowControllerTest extends SysuiTestCase { } @Test + public void attach_visibleWithWallpaper() { + clearInvocations(mWindowManager); + when(mKeyguardViewMediator.isShowingAndNotOccluded()).thenReturn(true); + mNotificationShadeWindowController.attach(); + + verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE)); + verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture()); + assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue(); + } + + @Test public void setBackgroundBlurRadius_expandedWithBlurs() { mNotificationShadeWindowController.setBackgroundBlurRadius(10); verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE)); diff --git a/packages/Tethering/apex/manifest.json b/packages/Tethering/apex/manifest.json index c1a5b05fc9d9..ded3e07a39b5 100644 --- a/packages/Tethering/apex/manifest.json +++ b/packages/Tethering/apex/manifest.json @@ -1,4 +1,4 @@ { "name": "com.android.tethering", - "version": 300900500 + "version": 300900600 } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2da2c2980231..e8a4234f44a7 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3719,12 +3719,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE, true); final WindowState visibleNotDrawnWindow = getWindow(w -> { - boolean isVisible = w.mViewVisibility == View.VISIBLE && !w.mObscured; - boolean hasDrawn = w.isDrawnLw() && w.hasDrawnLw(); - if (isVisible && !hasDrawn) { + final boolean isVisible = w.isVisible() && !w.mObscured; + final boolean isDrawn = w.isDrawnLw(); + if (isVisible && !isDrawn) { return true; } - if (hasDrawn) { + if (isDrawn) { switch (w.mAttrs.type) { case TYPE_BOOT_PROGRESS: case TYPE_BASE_APPLICATION: diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 3e88566449fe..8734b5efa45d 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -19,13 +19,10 @@ package com.android.server.wm; import static android.os.Process.myPid; import static android.os.Process.myUid; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; -import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.INPUT_CONSUMER_PIP; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER; -import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; -import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS; @@ -480,11 +477,12 @@ final class InputMonitor { mService.getRecentsAnimationController(); final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null && recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord); - if (inputWindowHandle == null || w.mRemoved) { + if (inputChannel == null || inputWindowHandle == null || w.mRemoved + || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) { if (w.mWinAnimator.hasSurface()) { mInputTransaction.setInputWindowInfo( - w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), - mInvalidInputWindow); + w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), + mInvalidInputWindow); } // Skip this window because it cannot possibly receive input. return; @@ -493,23 +491,9 @@ final class InputMonitor { final int flags = w.mAttrs.flags; final int privateFlags = w.mAttrs.privateFlags; final int type = w.mAttrs.type; + final boolean hasFocus = w.isFocused(); final boolean isVisible = w.isVisibleLw(); - // Assign an InputInfo with type to the overlay window which can't receive input event. - // This is used to omit Surfaces from occlusion detection. - if (inputChannel == null - || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) { - if (!w.mWinAnimator.hasSurface()) { - return; - } - populateOverlayInputInfo(inputWindowHandle, w.getName(), type, isVisible); - mInputTransaction.setInputWindowInfo( - w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), - inputWindowHandle); - return; - } - - final boolean hasFocus = w.isFocused(); if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) { if (recentsAnimationController.updateInputConsumerForApp( mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) { @@ -571,28 +555,6 @@ final class InputMonitor { } } - // This would reset InputWindowHandle fields to prevent it could be found by input event. - // We need to check if any new field of InputWindowHandle could impact the result. - private static void populateOverlayInputInfo(final InputWindowHandle inputWindowHandle, - final String name, final int type, final boolean isVisible) { - inputWindowHandle.name = name; - inputWindowHandle.layoutParamsType = type; - inputWindowHandle.dispatchingTimeoutNanos = - WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; - inputWindowHandle.visible = isVisible; - inputWindowHandle.canReceiveKeys = false; - inputWindowHandle.hasFocus = false; - inputWindowHandle.ownerPid = myPid(); - inputWindowHandle.ownerUid = myUid(); - inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL; - inputWindowHandle.scaleFactor = 1; - inputWindowHandle.layoutParamsFlags = - FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE; - inputWindowHandle.portalToDisplayId = INVALID_DISPLAY; - inputWindowHandle.touchableRegion.setEmpty(); - inputWindowHandle.setTouchableRegionCrop(null); - } - /** * Helper function to generate an InputInfo with type SECURE_SYSTEM_OVERLAY. This input * info will not have an input channel or be touchable, but is used to omit Surfaces @@ -602,7 +564,16 @@ final class InputMonitor { static void setTrustedOverlayInputInfo(SurfaceControl sc, SurfaceControl.Transaction t, int displayId, String name) { InputWindowHandle inputWindowHandle = new InputWindowHandle(null, displayId); - populateOverlayInputInfo(inputWindowHandle, name, TYPE_SECURE_SYSTEM_OVERLAY, true); + inputWindowHandle.name = name; + inputWindowHandle.layoutParamsType = TYPE_SECURE_SYSTEM_OVERLAY; + inputWindowHandle.dispatchingTimeoutNanos = -1; + inputWindowHandle.visible = true; + inputWindowHandle.canReceiveKeys = false; + inputWindowHandle.hasFocus = false; + inputWindowHandle.ownerPid = myPid(); + inputWindowHandle.ownerUid = myUid(); + inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL; + inputWindowHandle.scaleFactor = 1; t.setInputWindowInfo(sc, inputWindowHandle); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 23029017bac9..77e3c597311c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -482,12 +482,17 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked(); final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay, TYPE_WALLPAPER, TYPE_APPLICATION); + final WindowState wallpaper = windows[0]; + assertTrue(wallpaper.mIsWallpaper); + // By default WindowState#mWallpaperVisible is false. + assertFalse(wallpaper.isVisible()); // Verify waiting for windows to be drawn. assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); - // Verify not waiting for drawn windows. - makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN); + // Verify not waiting for drawn window and invisible wallpaper. + setDrawnState(WindowStateAnimator.READY_TO_SHOW, wallpaper); + setDrawnState(WindowStateAnimator.HAS_DRAWN, windows[1]); assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); } @@ -508,26 +513,10 @@ public class DisplayContentTests extends WindowTestsBase { assertTrue(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot()); // Verify not waiting for drawn windows on display with system decorations. - makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN); + setDrawnState(WindowStateAnimator.HAS_DRAWN, windows); assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot()); } - @Test - public void testShouldWaitForSystemDecorWindowsOnBoot_OnWindowReadyToShowAndDrawn() { - mWm.mSystemBooted = true; - final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked(); - final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay, - TYPE_WALLPAPER, TYPE_APPLICATION); - - // Verify waiting for windows to be drawn. - makeWindowsDrawnState(windows, WindowStateAnimator.READY_TO_SHOW); - assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); - - // Verify not waiting for drawn windows. - makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN); - assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot()); - } - private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) { final WindowState[] windows = new WindowState[types.length]; for (int i = 0; i < types.length; i++) { @@ -538,9 +527,9 @@ public class DisplayContentTests extends WindowTestsBase { return windows; } - private static void makeWindowsDrawnState(WindowState[] windows, int state) { + private static void setDrawnState(int state, WindowState... windows) { for (WindowState window : windows) { - window.mHasSurface = true; + window.mHasSurface = state != WindowStateAnimator.NO_SURFACE; window.mWinAnimator.mDrawState = state; } } |