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

Commit d9efcf06 authored by Shivangi Dubey's avatar Shivangi Dubey
Browse files

Add DeviceState to device state callback

The device state callback currently accepts only the `wm.DeviceStateController.DeviceState` enum as a parameter.
However, the `hardware.devicestates.DeviceState` object is used extensively globally.

This change adds the `hardware.devicestates.DeviceState` object to the device state callback's parameter list.
This allows listeners to receive the `hardware.devicestates.DeviceState` object directly, instead of relying solely on the `wm.DeviceStateController.DeviceState` enum, which is limited to WM.

This is necessary because `DeviceStateAutoRotateSettingController` will require device state updates as `hardware.devicestates.DeviceState.identifier` to align with incoming IPC calls, as the `wm.DeviceStateController.DeviceState` enum is not available across processes.

Fixes: 407772602
Test: atest DeviceStateControllerTests DisplayContentTests DisplayRotationTests DeviceStateAutoRotateSettingControllerTest
Flag: EXEMPT refactor
Change-Id: Ie033caaf1bb810200689fa08db5c334f8c00f200
parent 5caaf025
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.server.wm;

import android.annotation.NonNull;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.devicestate.DeviceState;
import android.os.Handler;
import android.provider.Settings;

@@ -54,7 +56,7 @@ public class DeviceStateAutoRotateSettingController {
    }

    /** Notify controller device state has changed */
    public void onDeviceStateChange(DeviceStateController.DeviceStateEnum deviceStateEnum) {
    public void onDeviceStateChange(@NonNull DeviceState deviceState) {
        if (Flags.enableDeviceStateAutoRotateSettingLogging()) {
            mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange();
        }
+19 −9
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.devicestate.feature.flags.FeatureFlags;
import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
@@ -39,10 +40,10 @@ import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Class that listens for a callback from display manager and responds to device state
@@ -64,10 +65,11 @@ final class DeviceStateController {
    private final List<Integer> mConcurrentDisplayDeviceStates;
    @NonNull
    private final List<Integer> mReverseRotationAroundZAxisStates;
    private final Map<Integer, DeviceState> mIdentifierToDeviceState = new HashMap<>();
    @GuardedBy("mWmLock")
    @NonNull
    @VisibleForTesting
    final Map<Consumer<DeviceStateEnum>, Executor> mDeviceStateCallbacks = new ArrayMap<>();
    final Map<DeviceStateListener, Executor> mDeviceStateCallbacks = new ArrayMap<>();

    private final boolean mMatchBuiltInDisplayOrientationToDefaultDisplay;

@@ -102,6 +104,7 @@ final class DeviceStateController {

            for (int i = 0; i < deviceStates.size(); i++) {
                final android.hardware.devicestate.DeviceState state = deviceStates.get(i);
                mIdentifierToDeviceState.put(state.getIdentifier(), state);
                if (state.hasProperty(
                        PROPERTY_FEATURE_REAR_DISPLAY)) {
                    mRearDisplayDeviceStates.add(state.getIdentifier());
@@ -146,14 +149,14 @@ final class DeviceStateController {
     * post the work onto their own worker thread to avoid holding the WindowManagerGlobalLock for
     * an extended period of time.
     */
    void registerDeviceStateCallback(@NonNull Consumer<DeviceStateEnum> callback,
    void registerDeviceStateCallback(@NonNull DeviceStateListener callback,
            @NonNull @CallbackExecutor Executor executor) {
        synchronized (mWmLock) {
            mDeviceStateCallbacks.put(callback, executor);
        }
    }

    void unregisterDeviceStateCallback(@NonNull Consumer<DeviceStateEnum> callback) {
    void unregisterDeviceStateCallback(@NonNull DeviceStateListener callback) {
        synchronized (mWmLock) {
            mDeviceStateCallbacks.remove(callback);
        }
@@ -217,20 +220,21 @@ final class DeviceStateController {
            // ConcurrentModificationException. Note that cannot use a List<Map.Entry> because the
            // entries are tied to the backing map. So, if a client removes a callback while
            // we are notifying clients, we will get a NPE.
            final List<Pair<Consumer<DeviceStateEnum>, Executor>> entries =
            final List<Pair<DeviceStateListener, Executor>> entries =
                    copyDeviceStateCallbacks();

            for (int i = 0; i < entries.size(); i++) {
                final Pair<Consumer<DeviceStateEnum>, Executor> entry = entries.get(i);
                entry.second.execute(() -> entry.first.accept(deviceStateEnum));
                final Pair<DeviceStateListener, Executor> entry = entries.get(i);
                entry.second.execute(() -> entry.first.onDeviceStateChanged(deviceStateEnum,
                        mIdentifierToDeviceState.get(state)));
            }
        }
    }

    @VisibleForTesting
    @NonNull
    List<Pair<Consumer<DeviceStateEnum>, Executor>> copyDeviceStateCallbacks() {
        final List<Pair<Consumer<DeviceStateEnum>, Executor>> entries = new ArrayList<>();
    List<Pair<DeviceStateListener, Executor>> copyDeviceStateCallbacks() {
        final List<Pair<DeviceStateListener, Executor>> entries = new ArrayList<>();

        synchronized (mWmLock) {
            mDeviceStateCallbacks.forEach((deviceStateConsumer, executor) -> {
@@ -251,4 +255,10 @@ final class DeviceStateController {
        }
        return valueList;
    }

    public interface DeviceStateListener {
        // TODO(b/409761673): Remove DeviceStateEnum from the callback
        void onDeviceStateChanged(DeviceStateEnum deviceStateEnum,
                @NonNull DeviceState deviceState);
    }
}
+8 −7
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region.Op;
import android.hardware.HardwareBuffer;
import android.hardware.devicestate.DeviceState;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.VirtualDisplayConfig;
import android.metrics.LogMaker;
@@ -615,7 +616,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    @VisibleForTesting
    final DeviceStateController mDeviceStateController;
    final Consumer<DeviceStateController.DeviceStateEnum> mDeviceStateConsumer;
    final DeviceStateController.DeviceStateListener mDeviceStateListener;
    final RemoteDisplayChangeController mRemoteDisplayChangeController;

    /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
@@ -1204,11 +1205,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address,
                mDeviceStateController, root.getDisplayRotationCoordinator());

        mDeviceStateConsumer =
                (@NonNull DeviceStateController.DeviceStateEnum newFoldState) -> {
                    mDisplayRotation.foldStateChanged(newFoldState);
                };
        mDeviceStateController.registerDeviceStateCallback(mDeviceStateConsumer,
        mDeviceStateListener =
                (@NonNull DeviceStateController.DeviceStateEnum deviceStateEnum,
                        @NonNull DeviceState deviceState) -> mDisplayRotation.foldStateChanged(
                        deviceStateEnum, deviceState);
        mDeviceStateController.registerDeviceStateCallback(mDeviceStateListener,
                new HandlerExecutor(mWmService.mH));

        mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
@@ -3427,7 +3428,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            }
            mUnknownAppVisibilityController.clear();
            mTransitionController.unregisterLegacyListener(mFixedRotationTransitionListener);
            mDeviceStateController.unregisterDeviceStateCallback(mDeviceStateConsumer);
            mDeviceStateController.unregisterDeviceStateCallback(mDeviceStateListener);
            super.removeImmediately();
            if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
            mPointerEventDispatcher.dispose();
+8 −2
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.devicestate.DeviceState;
import android.hardware.power.Boost;
import android.os.Handler;
import android.os.SystemClock;
@@ -1587,12 +1588,14 @@ public class DisplayRotation {
     * that in case of physical display change the {@link DisplayRotation#physicalDisplayChanged}
     * method will be invoked *after* this one.
     */
    void foldStateChanged(DeviceStateController.DeviceStateEnum deviceStateEnum) {
    // TODO(b/409761673) Migrate to only using android.hardware.devicestate.DeviceState
    void foldStateChanged(DeviceStateController.DeviceStateEnum deviceStateEnum,
            DeviceState deviceState) {
        if (mFoldController != null) {
            synchronized (mLock) {
                mFoldController.foldStateChanged(deviceStateEnum);
                if (mDeviceStateAutoRotateSettingController != null) {
                    mDeviceStateAutoRotateSettingController.onDeviceStateChange(deviceStateEnum);
                    mDeviceStateAutoRotateSettingController.onDeviceStateChange(deviceState);
                }
            }
        }
@@ -1649,6 +1652,9 @@ public class DisplayRotation {
        private final boolean mPauseAutorotationDuringUnfolding;
        @Surface.Rotation
        private int mHalfFoldSavedRotation = -1; // No saved rotation

        // TODO(b/409761673) Migrate DeviceStateController.DeviceStateEnum to
        //  android.hardware.devicestate.DeviceState
        private DeviceStateController.DeviceStateEnum mDeviceStateEnum =
                DeviceStateController.DeviceStateEnum.UNKNOWN;
        private long mLastHingeAngleEventTime = 0;
+3 −4
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest;

import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
import com.android.server.wm.utils.DeviceStateTestUtils;
import com.android.window.flags.Flags;

import org.junit.Before;
@@ -85,8 +86,7 @@ public class DeviceStateAutoRotateSettingControllerTests {
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_LOGGING)
    public void loggingFlagEnabled_onDeviceStateChanged_loggerNotified() {
        mDeviceStateAutoRotateSettingController.onDeviceStateChange(
                DeviceStateController.DeviceStateEnum.FOLDED);
        mDeviceStateAutoRotateSettingController.onDeviceStateChange(DeviceStateTestUtils.FOLDED);

        verify(mMockLogger, times(1)).onDeviceStateChange();
    }
@@ -94,8 +94,7 @@ public class DeviceStateAutoRotateSettingControllerTests {
    @Test
    @DisableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_LOGGING)
    public void loggingFlagDisabled_onDeviceStateChanged_loggerNotNotified() {
        mDeviceStateAutoRotateSettingController.onDeviceStateChange(
                DeviceStateController.DeviceStateEnum.FOLDED);
        mDeviceStateAutoRotateSettingController.onDeviceStateChange(DeviceStateTestUtils.FOLDED);

        verify(mMockLogger, never()).onDeviceStateChange();
    }
Loading