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

Commit abe32a3a authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Do not show Keyguard Presentation when in new RDM

Also updates KeyguardDisplayManager to:
1) Use the new DeviceState APIs, so we can stop relying on resource
   overlays
2) Check display using Display.FLAG_REAR, so that we do not need to
   rely on resource overlays

Fixes: 384100006
Fixes: 384089052
Test: atest KeyguardDisplayManagerTest
Flag: EXEMPT Bugfix
Change-Id: Ib52e50fe088172f04d72ac85aa238aa8823fce46
parent be8fc8e5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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)
+36 −31
Original line number Diff line number Diff line
@@ -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;
@@ -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";
@@ -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;
@@ -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;
        }
    }
}