Loading packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,16 @@ class KeyguardDisplayManagerTest : SysuiTestCase() { verify(presentationFactory, never()).create(eq(secondaryDisplay)) } @Test fun testShow_rearDisplayOuterDefaultActive_occluded() { displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) whenever(deviceStateHelper.isRearDisplayOuterDefaultActive(secondaryDisplay)) .thenReturn(true) whenever(keyguardStateController.isOccluded).thenReturn(true) verify(presentationFactory, never()).create(eq(secondaryDisplay)) } @Test fun testShow_presentationCreated() { displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) Loading packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +36 −31 Original line number Diff line number Diff line Loading @@ -26,11 +26,9 @@ import android.hardware.display.DisplayManager; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.os.Trace; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayInfo; import android.view.View; import android.view.WindowManager; Loading Loading @@ -58,6 +56,9 @@ import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Provider; /** * Manages Keyguard Presentations for non-primary display(s). */ @SysUISingleton public class KeyguardDisplayManager { protected static final String TAG = "KeyguardDisplayManager"; Loading Loading @@ -170,14 +171,17 @@ public class KeyguardDisplayManager { } return false; } if (mKeyguardStateController.isOccluded() && mDeviceStateHelper.isConcurrentDisplayActive(display)) { final boolean deviceStateOccludesKeyguard = mDeviceStateHelper.isConcurrentDisplayActive(display) || mDeviceStateHelper.isRearDisplayOuterDefaultActive(display); if (mKeyguardStateController.isOccluded() && deviceStateOccludesKeyguard) { if (DEBUG) { // When activities with FLAG_SHOW_WHEN_LOCKED are shown on top of Keyguard, the // Keyguard state becomes "occluded". In this case, we should not show the // KeyguardPresentation, since the activity is presenting content onto the // non-default display. Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent" Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent or rear" + " display is active"); } return false; Loading Loading @@ -326,44 +330,45 @@ public class KeyguardDisplayManager { public static class DeviceStateHelper implements DeviceStateManager.DeviceStateCallback { @Nullable private final DisplayAddress.Physical mRearDisplayPhysicalAddress; // TODO(b/271317597): These device states should be defined in DeviceStateManager private final int mConcurrentState; private boolean mIsInConcurrentDisplayState; private DeviceState mDeviceState; @Inject DeviceStateHelper( @ShadeDisplayAware Context context, DeviceStateManager deviceStateManager, @Main Executor mainExecutor) { final String rearDisplayPhysicalAddress = context.getResources().getString( com.android.internal.R.string.config_rearDisplayPhysicalAddress); if (TextUtils.isEmpty(rearDisplayPhysicalAddress)) { mRearDisplayPhysicalAddress = null; } else { mRearDisplayPhysicalAddress = DisplayAddress .fromPhysicalDisplayId(Long.parseLong(rearDisplayPhysicalAddress)); } mConcurrentState = context.getResources().getInteger( com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay); deviceStateManager.registerCallback(mainExecutor, this); } @Override public void onDeviceStateChanged(@NonNull DeviceState state) { // When concurrent state ends, the display also turns off. This is enforced in various // ExtensionRearDisplayPresentationTest CTS tests. So, we don't need to invoke // hide() since that will happen through the onDisplayRemoved callback. mIsInConcurrentDisplayState = state.getIdentifier() == mConcurrentState; // When dual display or rear display mode ends, the display also turns off. This is // enforced in various ExtensionRearDisplayPresentationTest CTS tests. So, we don't need // to invoke hide() since that will happen through the onDisplayRemoved callback. mDeviceState = state; } boolean isConcurrentDisplayActive(Display display) { return mIsInConcurrentDisplayState && mRearDisplayPhysicalAddress != null && mRearDisplayPhysicalAddress.equals(display.getAddress()); /** * @return true if the device is in Dual Display mode, and the specified display is the * rear facing (outer) display. */ boolean isConcurrentDisplayActive(@NonNull Display display) { return mDeviceState != null && mDeviceState.hasProperty( DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT) && (display.getFlags() & Display.FLAG_REAR) != 0; } /** * @return true if the device is the updated Rear Display mode, and the specified display is * the inner display. See {@link DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT}. * Note that in this state, the outer display is the default display, while the inner * display is the "rear" display. */ boolean isRearDisplayOuterDefaultActive(@NonNull Display display) { return mDeviceState != null && mDeviceState.hasProperty( DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT) && (display.getFlags() & Display.FLAG_REAR) != 0; } } } Loading
packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,16 @@ class KeyguardDisplayManagerTest : SysuiTestCase() { verify(presentationFactory, never()).create(eq(secondaryDisplay)) } @Test fun testShow_rearDisplayOuterDefaultActive_occluded() { displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) whenever(deviceStateHelper.isRearDisplayOuterDefaultActive(secondaryDisplay)) .thenReturn(true) whenever(keyguardStateController.isOccluded).thenReturn(true) verify(presentationFactory, never()).create(eq(secondaryDisplay)) } @Test fun testShow_presentationCreated() { displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) Loading
packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +36 −31 Original line number Diff line number Diff line Loading @@ -26,11 +26,9 @@ import android.hardware.display.DisplayManager; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.os.Trace; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayInfo; import android.view.View; import android.view.WindowManager; Loading Loading @@ -58,6 +56,9 @@ import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Provider; /** * Manages Keyguard Presentations for non-primary display(s). */ @SysUISingleton public class KeyguardDisplayManager { protected static final String TAG = "KeyguardDisplayManager"; Loading Loading @@ -170,14 +171,17 @@ public class KeyguardDisplayManager { } return false; } if (mKeyguardStateController.isOccluded() && mDeviceStateHelper.isConcurrentDisplayActive(display)) { final boolean deviceStateOccludesKeyguard = mDeviceStateHelper.isConcurrentDisplayActive(display) || mDeviceStateHelper.isRearDisplayOuterDefaultActive(display); if (mKeyguardStateController.isOccluded() && deviceStateOccludesKeyguard) { if (DEBUG) { // When activities with FLAG_SHOW_WHEN_LOCKED are shown on top of Keyguard, the // Keyguard state becomes "occluded". In this case, we should not show the // KeyguardPresentation, since the activity is presenting content onto the // non-default display. Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent" Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent or rear" + " display is active"); } return false; Loading Loading @@ -326,44 +330,45 @@ public class KeyguardDisplayManager { public static class DeviceStateHelper implements DeviceStateManager.DeviceStateCallback { @Nullable private final DisplayAddress.Physical mRearDisplayPhysicalAddress; // TODO(b/271317597): These device states should be defined in DeviceStateManager private final int mConcurrentState; private boolean mIsInConcurrentDisplayState; private DeviceState mDeviceState; @Inject DeviceStateHelper( @ShadeDisplayAware Context context, DeviceStateManager deviceStateManager, @Main Executor mainExecutor) { final String rearDisplayPhysicalAddress = context.getResources().getString( com.android.internal.R.string.config_rearDisplayPhysicalAddress); if (TextUtils.isEmpty(rearDisplayPhysicalAddress)) { mRearDisplayPhysicalAddress = null; } else { mRearDisplayPhysicalAddress = DisplayAddress .fromPhysicalDisplayId(Long.parseLong(rearDisplayPhysicalAddress)); } mConcurrentState = context.getResources().getInteger( com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay); deviceStateManager.registerCallback(mainExecutor, this); } @Override public void onDeviceStateChanged(@NonNull DeviceState state) { // When concurrent state ends, the display also turns off. This is enforced in various // ExtensionRearDisplayPresentationTest CTS tests. So, we don't need to invoke // hide() since that will happen through the onDisplayRemoved callback. mIsInConcurrentDisplayState = state.getIdentifier() == mConcurrentState; // When dual display or rear display mode ends, the display also turns off. This is // enforced in various ExtensionRearDisplayPresentationTest CTS tests. So, we don't need // to invoke hide() since that will happen through the onDisplayRemoved callback. mDeviceState = state; } boolean isConcurrentDisplayActive(Display display) { return mIsInConcurrentDisplayState && mRearDisplayPhysicalAddress != null && mRearDisplayPhysicalAddress.equals(display.getAddress()); /** * @return true if the device is in Dual Display mode, and the specified display is the * rear facing (outer) display. */ boolean isConcurrentDisplayActive(@NonNull Display display) { return mDeviceState != null && mDeviceState.hasProperty( DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT) && (display.getFlags() & Display.FLAG_REAR) != 0; } /** * @return true if the device is the updated Rear Display mode, and the specified display is * the inner display. See {@link DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT}. * Note that in this state, the outer display is the default display, while the inner * display is the "rear" display. */ boolean isRearDisplayOuterDefaultActive(@NonNull Display display) { return mDeviceState != null && mDeviceState.hasProperty( DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT) && (display.getFlags() & Display.FLAG_REAR) != 0; } } }