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

Commit e458d1ec authored by Kenneth Ford's avatar Kenneth Ford
Browse files

Creates DeviceState objects with display properties

DeviceStateManagerGlobal can create DeviceState objects
to support the updated DeviceState based DeviceStateManager
API's. The objects created provide support for the
foldable display configuration properties.

Also updates FoldStateListener to use the new DeviceState API

Bug: 293636629
Test: DeviceStateManagerTests
Change-Id: Iba41e1565f9cd816c8c4afc72fb2bbad7cf19843
parent ddb2e801
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -323,6 +323,7 @@ public final class DeviceStateManager {
    public static class FoldStateListener implements DeviceStateCallback {
        private final int[] mFoldedDeviceStates;
        private final Consumer<Boolean> mDelegate;
        private final android.hardware.devicestate.feature.flags.FeatureFlags mFeatureFlags;

        @Nullable
        private Boolean lastResult;
@@ -335,11 +336,23 @@ public final class DeviceStateManager {
            mFoldedDeviceStates = context.getResources().getIntArray(
                    com.android.internal.R.array.config_foldedDeviceStates);
            mDelegate = listener;
            mFeatureFlags = new android.hardware.devicestate.feature.flags.FeatureFlagsImpl();
        }

        @Override
        public final void onStateChanged(int state) {
            final boolean folded = ArrayUtils.contains(mFoldedDeviceStates, state);
        public final void onStateChanged(int state) {}

        @Override
        public final void onDeviceStateChanged(@NonNull DeviceState deviceState) {
            final boolean folded;
            if (mFeatureFlags.deviceStatePropertyApi()) {
                // TODO(b/325124054): Update when system server refactor is completed
                folded = deviceState.hasProperty(
                        DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)
                        || ArrayUtils.contains(mFoldedDeviceStates, deviceState.getIdentifier());
            } else {
                folded = ArrayUtils.contains(mFoldedDeviceStates, deviceState.getIdentifier());
            }

            if (lastResult == null || !lastResult.equals(folded)) {
                lastResult = folded;
+92 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.hardware.devicestate;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityThread;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
import android.os.Binder;
@@ -32,9 +33,13 @@ import android.util.ArrayMap;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;

/**
@@ -50,12 +55,18 @@ public final class DeviceStateManagerGlobal {
    private static final String TAG = "DeviceStateManagerGlobal";
    private static final boolean DEBUG = Build.IS_DEBUGGABLE;

    // TODO(b/325124054): Remove when system server refactor is completed
    private static int[] sFoldedDeviceStates = new int[0];

    /**
     * Returns an instance of {@link DeviceStateManagerGlobal}. May return {@code null} if a
     * connection with the device state service couldn't be established.
     */
    @Nullable
    public static DeviceStateManagerGlobal getInstance() {
        // TODO(b/325124054): Remove when system server refactor is completed
        instantiateFoldedStateArray();

        synchronized (DeviceStateManagerGlobal.class) {
            if (sInstance == null) {
                IBinder b = ServiceManager.getService(Context.DEVICE_STATE_SERVICE);
@@ -68,6 +79,16 @@ public final class DeviceStateManagerGlobal {
        }
    }

    // TODO(b/325124054): Remove when system server refactor is completed
    // TODO(b/325330654): Investigate if we need a Context passed in to DSMGlobal
    private static void instantiateFoldedStateArray() {
        Context context = ActivityThread.currentApplication();
        if (context != null) {
            sFoldedDeviceStates = context.getResources().getIntArray(
                    com.android.internal.R.array.config_foldedDeviceStates);
        }
    }

    private final Object mLock = new Object();
    @NonNull
    private final IDeviceStateManager mDeviceStateManager;
@@ -115,6 +136,32 @@ public final class DeviceStateManagerGlobal {
        }
    }

    /**
     * Returns the {@link List} of supported device states.
     *
     * @see DeviceStateManager#getSupportedDeviceStates()
     */
    public List<DeviceState> getSupportedDeviceStates() {
        synchronized (mLock) {
            final DeviceStateInfo currentInfo;
            if (mLastReceivedInfo != null) {
                // If we have mLastReceivedInfo a callback is registered for this instance and it
                // is receiving the most recent info from the server. Use that info here.
                currentInfo = mLastReceivedInfo;
            } else {
                // If mLastReceivedInfo is null there is no registered callback so we manually
                // fetch the current info.
                try {
                    currentInfo = mDeviceStateManager.getDeviceStateInfo();
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }

            return createDeviceStateList(currentInfo.supportedStates);
        }
    }

    /**
     * Submits a {@link DeviceStateRequest request} to modify the device state.
     *
@@ -241,8 +288,10 @@ public final class DeviceStateManagerGlobal {
                final int[] supportedStates = Arrays.copyOf(mLastReceivedInfo.supportedStates,
                        mLastReceivedInfo.supportedStates.length);
                wrapper.notifySupportedStatesChanged(supportedStates);
                wrapper.notifySupportedDeviceStatesChanged(createDeviceStateList(supportedStates));
                wrapper.notifyBaseStateChanged(mLastReceivedInfo.baseState);
                wrapper.notifyStateChanged(mLastReceivedInfo.currentState);
                wrapper.notifyDeviceStateChanged(createDeviceState(mLastReceivedInfo.currentState));
            }
        }
    }
@@ -327,6 +376,8 @@ public final class DeviceStateManagerGlobal {
                final int[] supportedStates = Arrays.copyOf(info.supportedStates,
                        info.supportedStates.length);
                callbacks.get(i).notifySupportedStatesChanged(supportedStates);
                callbacks.get(i).notifySupportedDeviceStatesChanged(
                        createDeviceStateList(supportedStates));
            }
        }
        if ((diff & DeviceStateInfo.CHANGED_BASE_STATE) > 0) {
@@ -337,6 +388,7 @@ public final class DeviceStateManagerGlobal {
        if ((diff & DeviceStateInfo.CHANGED_CURRENT_STATE) > 0) {
            for (int i = 0; i < callbacks.size(); i++) {
                callbacks.get(i).notifyStateChanged(info.currentState);
                callbacks.get(i).notifyDeviceStateChanged(createDeviceState(info.currentState));
            }
        }
    }
@@ -369,6 +421,36 @@ public final class DeviceStateManagerGlobal {
        }
    }

    /**
     * Creates a {@link DeviceState} object from a device state identifier, with the
     * {@link DeviceState} property that corresponds to what display is primary.
     *
     */
    // TODO(b/325124054): Remove when system server refactor is completed
    @NonNull
    private DeviceState createDeviceState(int stateIdentifier) {
        final Set<@DeviceState.DeviceStateProperties Integer> properties = new HashSet<>();
        if (ArrayUtils.contains(sFoldedDeviceStates, stateIdentifier)) {
            properties.add(DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
        } else {
            properties.add(DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY);
        }
        return new DeviceState(stateIdentifier, "" /* name */, properties);
    }

    /**
     * Creates a list of {@link DeviceState} objects from an array of state identifiers.
     */
    // TODO(b/325124054): Remove when system server refactor is completed
    @NonNull
    private List<DeviceState> createDeviceStateList(int[] supportedStates) {
        List<DeviceState> deviceStateList = new ArrayList<>();
        for (int i = 0; i < supportedStates.length; i++) {
            deviceStateList.add(createDeviceState(supportedStates[i]));
        }
        return deviceStateList;
    }

    private final class DeviceStateManagerCallback extends IDeviceStateManagerCallback.Stub {
        @Override
        public void onDeviceStateInfoChanged(DeviceStateInfo info) {
@@ -403,6 +485,11 @@ public final class DeviceStateManagerGlobal {
                    mDeviceStateCallback.onSupportedStatesChanged(newSupportedStates));
        }

        void notifySupportedDeviceStatesChanged(List<DeviceState> newSupportedDeviceStates) {
            mExecutor.execute(() ->
                    mDeviceStateCallback.onSupportedStatesChanged(newSupportedDeviceStates));
        }

        void notifyBaseStateChanged(int newBaseState) {
            execute("notifyBaseStateChanged",
                    () -> mDeviceStateCallback.onBaseStateChanged(newBaseState));
@@ -413,6 +500,11 @@ public final class DeviceStateManagerGlobal {
                    () -> mDeviceStateCallback.onStateChanged(newDeviceState));
        }

        void notifyDeviceStateChanged(DeviceState newDeviceState) {
            execute("notifyDeviceStateChanged",
                    () -> mDeviceStateCallback.onDeviceStateChanged(newDeviceState));
        }

        private void execute(String traceName, Runnable r) {
            mExecutor.execute(() -> {
                if (DEBUG) {