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

Commit 18eb83c2 authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge "Add DEVICE_STATE_REAR_DISPLAY_OUTER_DEFAULT" into main

parents fb4046d1 30ac01b7
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -172,6 +172,23 @@ public final class DeviceState {
     */
    public static final int PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = 17;

    /**
     * Property that indicates that this state corresponds to the device state for rear display
     * mode, where both the inner and outer displays are on. In this state, the outer display
     * is the default display where the app is shown, and the inner display is used by the system to
     * show a UI affordance for exiting the mode.
     *
     * Note that this value should generally not be used, and may be removed in the future (e.g.
     * if or when it becomes the only type of rear display mode when
     * {@link android.hardware.devicestate.feature.flags.Flags#deviceStateRdmV2} is removed).
     *
     * As such, clients should strongly consider relying on {@link #PROPERTY_FEATURE_REAR_DISPLAY}
     * instead.
     *
     * @hide
     */
    public static final int PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT = 1001;

    /** @hide */
    @IntDef(prefix = {"PROPERTY_"}, flag = false, value = {
            PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED,
@@ -190,7 +207,8 @@ public final class DeviceState {
            PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE,
            PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY,
            PROPERTY_FEATURE_REAR_DISPLAY,
            PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT
            PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT,
            PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT
    })
    @Retention(RetentionPolicy.SOURCE)
    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+9 −0
Original line number Diff line number Diff line
@@ -30,3 +30,12 @@ flag {
      purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "device_state_rdm_v2"
    is_exported: true
    namespace: "windowing_sdk"
    description: "Enables Rear Display Mode V2, where the inner display shows the user a UI affordance for exiting the state"
    bug: "372486634"
    is_fixed_read_only: true
}
 No newline at end of file
+29 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package androidx.window.extensions.area;
import static android.hardware.devicestate.DeviceState.PROPERTY_EMULATED_ONLY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
@@ -104,6 +105,30 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
    @GuardedBy("mLock")
    private int mLastReportedRearDisplayPresentationStatus;

    @VisibleForTesting
    static int getRdmV1Identifier(List<DeviceState> currentSupportedDeviceStates) {
        for (int i = 0; i < currentSupportedDeviceStates.size(); i++) {
            DeviceState state = currentSupportedDeviceStates.get(i);
            if (state.hasProperty(PROPERTY_FEATURE_REAR_DISPLAY)
                    && !state.hasProperty(PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT)) {
                return state.getIdentifier();
            }
        }
        return INVALID_DEVICE_STATE_IDENTIFIER;
    }

    @VisibleForTesting
    static int getRdmV2Identifier(List<DeviceState> currentSupportedDeviceStates) {
        for (int i = 0; i < currentSupportedDeviceStates.size(); i++) {
            DeviceState state = currentSupportedDeviceStates.get(i);
            if (state.hasProperties(PROPERTY_FEATURE_REAR_DISPLAY,
                    PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT)) {
                return state.getIdentifier();
            }
        }
        return INVALID_DEVICE_STATE_IDENTIFIER;
    }

    public WindowAreaComponentImpl(@NonNull Context context) {
        mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
        mDisplayManager = context.getSystemService(DisplayManager.class);
@@ -112,12 +137,10 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
        mCurrentSupportedDeviceStates = mDeviceStateManager.getSupportedDeviceStates();

        if (Flags.deviceStatePropertyMigration()) {
            for (int i = 0; i < mCurrentSupportedDeviceStates.size(); i++) {
                DeviceState state = mCurrentSupportedDeviceStates.get(i);
                if (state.hasProperty(PROPERTY_FEATURE_REAR_DISPLAY)) {
                    mRearDisplayState = state.getIdentifier();
                    break;
                }
            if (Flags.deviceStateRdmV2()) {
                mRearDisplayState = getRdmV2Identifier(mCurrentSupportedDeviceStates);
            } else {
                mRearDisplayState = getRdmV1Identifier(mCurrentSupportedDeviceStates);
            }
        } else {
            mFoldedDeviceStates = context.getResources().getIntArray(
+61 −0
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@

package androidx.window.extensions.area;

import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;

import static org.junit.Assert.assertEquals;

import android.hardware.devicestate.DeviceState;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.Surface;
@@ -29,11 +34,34 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class WindowAreaComponentImplTests {

    private static final DeviceState REAR_DISPLAY_STATE_V1 = new DeviceState(
            new DeviceState.Configuration.Builder(1, "STATE_0")
                    .setSystemProperties(
                            Set.of(PROPERTY_FEATURE_REAR_DISPLAY))
                    .build());
    private static final DeviceState REAR_DISPLAY_STATE_V2 = new DeviceState(
            new DeviceState.Configuration.Builder(2, "STATE_0")
                    .setSystemProperties(
                            Set.of(PROPERTY_FEATURE_REAR_DISPLAY,
                                    PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT))
                    .build());
    // The PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT state must be present together with the
    // PROPERTY_FEATURE_REAR_DISPLAY state in order to be a valid state.
    private static final DeviceState INVALID_REAR_DISPLAY_STATE = new DeviceState(
            new DeviceState.Configuration.Builder(2, "STATE_0")
                    .setSystemProperties(
                            Set.of(PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT))
                    .build());

    private final DisplayMetrics mTestDisplayMetrics = new DisplayMetrics();

    @Before
@@ -93,4 +121,37 @@ public class WindowAreaComponentImplTests {
                Surface.ROTATION_270, Surface.ROTATION_0, mTestDisplayMetrics);
        assertEquals(expectedMetrics, mTestDisplayMetrics);
    }

    @Test
    public void testRdmV1Identifier() {
        final List<DeviceState> supportedStates = new ArrayList<>();
        supportedStates.add(REAR_DISPLAY_STATE_V2);
        assertEquals(INVALID_DEVICE_STATE_IDENTIFIER,
                WindowAreaComponentImpl.getRdmV1Identifier(supportedStates));

        supportedStates.add(REAR_DISPLAY_STATE_V1);
        assertEquals(REAR_DISPLAY_STATE_V1.getIdentifier(),
                WindowAreaComponentImpl.getRdmV1Identifier(supportedStates));
    }

    @Test
    public void testRdmV2Identifier_whenStateIsImproperlyConfigured() {
        final List<DeviceState> supportedStates = new ArrayList<>();
        supportedStates.add(INVALID_REAR_DISPLAY_STATE);
        assertEquals(INVALID_DEVICE_STATE_IDENTIFIER,
                WindowAreaComponentImpl.getRdmV2Identifier(supportedStates));
    }

    @Test
    public void testRdmV2Identifier_whenStateIsProperlyConfigured() {
        final List<DeviceState> supportedStates = new ArrayList<>();

        supportedStates.add(REAR_DISPLAY_STATE_V1);
        assertEquals(INVALID_DEVICE_STATE_IDENTIFIER,
                WindowAreaComponentImpl.getRdmV2Identifier(supportedStates));

        supportedStates.add(REAR_DISPLAY_STATE_V2);
        assertEquals(REAR_DISPLAY_STATE_V2.getIdentifier(),
                WindowAreaComponentImpl.getRdmV2Identifier(supportedStates));
    }
}
+33 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.policy;
import static android.hardware.devicestate.DeviceState.PROPERTY_EMULATED_ONLY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
@@ -71,6 +72,7 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements
    private static final int DEVICE_STATE_OPENED = 2;
    private static final int DEVICE_STATE_REAR_DISPLAY = 3;
    private static final int DEVICE_STATE_CONCURRENT_INNER_DEFAULT = 4;
    private static final int DEVICE_STATE_REAR_DISPLAY_OUTER_DEFAULT = 5;
    private static final int TENT_MODE_SWITCH_ANGLE_DEGREES = 90;
    private static final int TABLE_TOP_MODE_SWITCH_ANGLE_DEGREES = 125;
    private static final int MIN_CLOSED_ANGLE_DEGREES = 0;
@@ -130,14 +132,17 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements
                            return hingeAngle >= MAX_CLOSED_ANGLE_DEGREES
                                    && hingeAngle <= TABLE_TOP_MODE_SWITCH_ANGLE_DEGREES;
                        }),
                createConfig(getOpenedDeviceState(), /* activeStatePredicate= */
                        ALLOWED),
                createConfig(getRearDisplayDeviceState(), /* activeStatePredicate= */
                        NOT_ALLOWED),
                createConfig(getDualDisplayDeviceState(), /* activeStatePredicate= */
                        NOT_ALLOWED, /* availabilityPredicate= */
                        provider -> !mIsDualDisplayBlockingEnabled
                                || provider.hasNoConnectedExternalDisplay())};
                createConfig(getOpenedDeviceState(),
                        /* activeStatePredicate= */ ALLOWED),
                createConfig(getRearDisplayDeviceState(),
                        /* activeStatePredicate= */ NOT_ALLOWED),
                createConfig(getDualDisplayDeviceState(),
                        /* activeStatePredicate= */ NOT_ALLOWED,
                        /* availabilityPredicate= */ provider -> !mIsDualDisplayBlockingEnabled
                                || provider.hasNoConnectedExternalDisplay()),
                createConfig(getRearDisplayOuterDefaultState(),
                        /* activeStatePredicate= */ NOT_ALLOWED)
        };
    }

    private DeviceStatePredicateWrapper createClosedConfiguration(
@@ -266,4 +271,24 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements
                .setSystemProperties(systemProperties)
                .build());
    }

    /**
     * Returns the {link DeviceState.Configuration} that represents the new rear display state
     * where the inner display is also enabled, showing a system affordance to exit the state.
     */
    @NonNull
    private DeviceState getRearDisplayOuterDefaultState() {
        Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>(
                List.of(PROPERTY_EMULATED_ONLY,
                        PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY,
                        PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST,
                        PROPERTY_FEATURE_REAR_DISPLAY,
                        PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT));

        return new DeviceState(new DeviceState.Configuration.Builder(
                DEVICE_STATE_REAR_DISPLAY_OUTER_DEFAULT,
                "REAR_DISPLAY_OUTER_DEFAULT")
                .setSystemProperties(systemProperties)
                .build());
    }
}