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

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

Merge "Do not show RDM EDU dialog in certain cases" into main

parents 1427fca4 0d5b4721
Loading
Loading
Loading
Loading
+48 −14
Original line number Original line Diff line number Diff line
@@ -19,17 +19,19 @@ package com.android.server.devicestate;
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_DUAL_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_DUAL_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_REAR_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_REAR_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
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;
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_INNER_PRIMARY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_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;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
@@ -98,7 +100,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Optional;
import java.util.Set;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.WeakHashMap;
@@ -854,7 +855,7 @@ public final class DeviceStateManagerService extends SystemService {
        }
        }
    }
    }


    private void requestStateInternal(int state, int flags, int callingPid, int callingUid,
    private void requestStateInternal(int requestedState, int flags, int callingPid, int callingUid,
            @NonNull IBinder token, boolean hasControlDeviceStatePermission) {
            @NonNull IBinder token, boolean hasControlDeviceStatePermission) {
        synchronized (mLock) {
        synchronized (mLock) {
            final ProcessRecord processRecord = mProcessRecords.get(callingPid);
            final ProcessRecord processRecord = mProcessRecords.get(callingPid);
@@ -869,19 +870,30 @@ public final class DeviceStateManagerService extends SystemService {
                        + " token: " + token);
                        + " token: " + token);
            }
            }


            final Optional<DeviceState> deviceState = getStateLocked(state);
            final Optional<DeviceState> requestedDeviceState = getStateLocked(requestedState);
            if (!deviceState.isPresent()) {
            if (requestedDeviceState.isEmpty()) {
                throw new IllegalArgumentException("Requested state: " + state
                throw new IllegalArgumentException("Requested state: " + requestedState
                        + " is not supported.");
                        + " is not supported.");
            }
            }


            OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
            final OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
                    deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
                    requestedDeviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);


            if (Flags.deviceStatePropertyMigration()) {
            if (Flags.deviceStatePropertyMigration()) {
                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
                final boolean isRequestingRdm = requestedDeviceState.get()
                if (!hasControlDeviceStatePermission && deviceState.get().hasProperty(
                        .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY);
                        PROPERTY_FEATURE_REAR_DISPLAY)) {
                final boolean isRequestingRdmOuterDefault = requestedDeviceState.get()
                        .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT);

                final boolean isDeviceClosed = mCommittedState.isEmpty() ? false
                        : mCommittedState.get().hasProperty(
                                PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED);

                final boolean shouldShowRdmEduDialog = isRequestingRdm && shouldShowRdmEduDialog(
                        hasControlDeviceStatePermission, isRequestingRdmOuterDefault,
                        isDeviceClosed);

                if (shouldShowRdmEduDialog) {
                    showRearDisplayEducationalOverlayLocked(request);
                    showRearDisplayEducationalOverlayLocked(request);
                } else {
                } else {
                    mOverrideRequestController.addRequest(request);
                    mOverrideRequestController.addRequest(request);
@@ -889,7 +901,7 @@ public final class DeviceStateManagerService extends SystemService {
            } else {
            } else {
                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
                if (!hasControlDeviceStatePermission && mRearDisplayState != null
                if (!hasControlDeviceStatePermission && mRearDisplayState != null
                        && state == mRearDisplayState.getIdentifier()) {
                        && requestedState == mRearDisplayState.getIdentifier()) {
                    showRearDisplayEducationalOverlayLocked(request);
                    showRearDisplayEducationalOverlayLocked(request);
                } else {
                } else {
                    mOverrideRequestController.addRequest(request);
                    mOverrideRequestController.addRequest(request);
@@ -898,6 +910,28 @@ public final class DeviceStateManagerService extends SystemService {
        }
        }
    }
    }


    /**
     * Determines if the system should show an educational dialog before entering rear display mode
     * @param hasControlDeviceStatePermission If the app has the CONTROL_DEVICE_STATE permission, we
     *                                        don't need to show the overlay
     * @param requestingRdmOuterDefault True if the system is requesting
     *                                  PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT
     * @param isDeviceClosed True if the device is closed (folded) when the request was made
     */
    @VisibleForTesting
    static boolean shouldShowRdmEduDialog(boolean hasControlDeviceStatePermission,
            boolean requestingRdmOuterDefault, boolean isDeviceClosed) {
        if (hasControlDeviceStatePermission) {
            return false;
        }

        if (requestingRdmOuterDefault) {
            return isDeviceClosed;
        } else {
            return true;
        }
    }

    /**
    /**
     * If we get a request to enter rear display  mode, we need to display an educational
     * If we get a request to enter rear display  mode, we need to display an educational
     * overlay to let the user know what will happen. This calls into the
     * overlay to let the user know what will happen. This calls into the
+37 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ import static com.android.compatibility.common.util.PollingCheck.waitFor;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertEquals;
@@ -921,6 +923,41 @@ public final class DeviceStateManagerServiceTest {
        });
        });
    }
    }


    @Test
    public void shouldShowRdmEduDialog1() {
        // RDM V1 Cases
        assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
                false /* hasControlDeviceStatePermission */,
                false /* requestingRdmOuterDefault */,
                false /* isDeviceClosed (no-op) */));

        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
                true /* hasControlDeviceStatePermission */,
                false /* requestingRdmOuterDefault */,
                true /* isDeviceClosed (no-op) */));

        // RDM V2 Cases
        // hasControlDeviceStatePermission = false
        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
                false /* hasControlDeviceStatePermission */,
                true /* requestingRdmOuterDefault */,
                false /* isDeviceClosed */));
        assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
                false /* hasControlDeviceStatePermission */,
                true /* requestingRdmOuterDefault */,
                true /* isDeviceClosed */));

        // hasControlDeviceStatePermission = true
        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
                true /* hasControlDeviceStatePermission */,
                true /* requestingRdmOuterDefault */,
                false /* isDeviceClosed */));
        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
                true /* hasControlDeviceStatePermission */,
                true /* requestingRdmOuterDefault */,
                true /* isDeviceClosed */));
    }

    /**
    /**
     * Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
     * Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
     *
     *