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

Commit 77eb2886 authored by Jamie Garside's avatar Jamie Garside
Browse files

Added device posture controller to SysUI.

This is mostly to add in the interfaces right now. This can be used to
notify surfaces about changes in the device posture when required. This
is currently implemented using the Jetpack device posture sidecar; this
needs to be used directly since androidx.window isn't available in
Gerrit right now.

Bug: 194280917
Test: Incoming.
Change-Id: I966fc5bdf43643bf570effbf6c8630abff5f86c4
parent d72a55e6
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.policy;

import static com.android.systemui.statusbar.policy.DevicePostureController.Callback;

import android.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Listener for device posture changes. This can be used to query the current posture, or register
 * for events when it changes.
 */
public interface DevicePostureController extends CallbackController<Callback> {
    @IntDef(prefix = {"DEVICE_POSTURE_"}, value = {
            DEVICE_POSTURE_UNKNOWN,
            DEVICE_POSTURE_CLOSED,
            DEVICE_POSTURE_HALF_OPENED,
            DEVICE_POSTURE_OPENED,
            DEVICE_POSTURE_FLIPPED
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface DevicePostureInt {}

    // NOTE: These constants **must** match those defined for Jetpack Sidecar. This is because we
    // use the Device State -> Jetpack Posture map in DevicePostureControllerImpl to translate
    // between the two.
    int DEVICE_POSTURE_UNKNOWN = 0;
    int DEVICE_POSTURE_CLOSED = 1;
    int DEVICE_POSTURE_HALF_OPENED = 2;
    int DEVICE_POSTURE_OPENED = 3;
    int DEVICE_POSTURE_FLIPPED = 4;

    /** Return the current device posture. */
    @DevicePostureInt int getDevicePosture();

    /** Callback to be notified about device posture changes. */
    interface Callback {
        /** Called when the posture changes. */
        void onPostureChanged(@DevicePostureInt int posture);
    }
}
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.policy;

import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.util.SparseIntArray;

import androidx.annotation.NonNull;

import com.android.internal.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

import javax.inject.Inject;

/** Implementation of {@link DevicePostureController} using the DeviceStateManager. */
@SysUISingleton
public class DevicePostureControllerImpl implements DevicePostureController {
    private final List<Callback> mListeners = new ArrayList<>();
    private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN;

    private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();

    @Inject
    public DevicePostureControllerImpl(
            Context context, DeviceStateManager deviceStateManager, @Main Executor executor) {
        // Most of this is borrowed from WindowManager/Jetpack/DeviceStateManagerPostureProducer.
        // Using the sidecar/extension libraries directly brings in a new dependency that it'd be
        // good to avoid (along with the fact that sidecar is deprecated, and extensions isn't fully
        // ready yet), and we'd have to make our own layer over the sidecar library anyway to easily
        // allow the implementation to change, so it was easier to just interface with
        // DeviceStateManager directly.
        String[] deviceStatePosturePairs = context.getResources()
                .getStringArray(R.array.config_device_state_postures);
        for (String deviceStatePosturePair : deviceStatePosturePairs) {
            String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
            if (deviceStatePostureMapping.length != 2) {
                continue;
            }

            int deviceState;
            int posture;
            try {
                deviceState = Integer.parseInt(deviceStatePostureMapping[0]);
                posture = Integer.parseInt(deviceStatePostureMapping[1]);
            } catch (NumberFormatException e) {
                continue;
            }

            mDeviceStateToPostureMap.put(deviceState, posture);
        }

        deviceStateManager.registerCallback(executor, state -> {
            mCurrentDevicePosture =
                    mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);

            mListeners.forEach(l -> l.onPostureChanged(mCurrentDevicePosture));
        });
    }

    @Override
    public void addCallback(@NonNull Callback listener) {
        mListeners.add(listener);
    }

    @Override
    public void removeCallback(@NonNull Callback listener) {
        mListeners.remove(listener);
    }

    @Override
    public int getDevicePosture() {
        return mCurrentDevicePosture;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DevicePostureControllerImpl;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionControllerImpl;
import com.android.systemui.statusbar.policy.FlashlightController;
@@ -129,6 +131,11 @@ public interface StatusBarPolicyModule {
    NetworkController.AccessPointController provideAccessPointController(
            AccessPointControllerImpl accessPointControllerImpl);

    /** */
    @Binds
    DevicePostureController provideDevicePostureController(
            DevicePostureControllerImpl devicePostureControllerImpl);

    /** */
    @SysUISingleton
    @Provides