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

Commit 7f1a4101 authored by Abel Tesfaye's avatar Abel Tesfaye
Browse files

Update QS rotation tile text to display when smart-auto-rotate is enabled

Bug: 196079067

Test: locally with flame & atest RotationLockTileTest
Change-Id: Ie6bbbb65b14b37a1785baeb1d34345d19984bf4e
parent e1fced07
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1277,6 +1277,10 @@

    <!-- [CHAR LIMIT=NONE] Importance Tuner setting title -->
    <string name="tuner_full_importance_settings">Power notification controls</string>

    <!-- [CHAR LIMIT=NONE] Notification camera based rotation enabled description -->
    <string name="rotation_lock_camera_rotation_on">On - Face-based</string>

    <string name="power_notification_controls_description">With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications.
        \n\n<b>Level 5</b>
        \n- Show at the top of the notification list
+80 −2
Original line number Diff line number Diff line
@@ -16,12 +16,18 @@

package com.android.systemui.qs.tiles;

import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;

import static com.android.systemui.statusbar.policy.RotationLockControllerImpl.hasSufficientPermission;

import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.service.quicksettings.Tile;
import android.view.View;
import android.widget.Switch;
@@ -38,18 +44,25 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.SettingObserver;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
import com.android.systemui.util.settings.SecureSettings;

import javax.inject.Inject;

/** Quick settings tile: Rotation **/
public class RotationLockTile extends QSTileImpl<BooleanState> {
public class RotationLockTile extends QSTileImpl<BooleanState> implements
        BatteryController.BatteryStateChangeCallback {

    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_auto_rotate);
    private final RotationLockController mController;
    private final SensorPrivacyManager mPrivacyManager;
    private final BatteryController mBatteryController;
    private final SettingObserver mSetting;

    @Inject
    public RotationLockTile(
@@ -61,12 +74,41 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
            StatusBarStateController statusBarStateController,
            ActivityStarter activityStarter,
            QSLogger qsLogger,
            RotationLockController rotationLockController
            RotationLockController rotationLockController,
            SensorPrivacyManager privacyManager,
            BatteryController batteryController,
            SecureSettings secureSettings
    ) {
        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
        mController = rotationLockController;
        mController.observe(this, mCallback);
        mPrivacyManager = privacyManager;
        mBatteryController = batteryController;
        int currentUser = host.getUserContext().getUserId();
        mSetting = new SettingObserver(
                secureSettings,
                mHandler,
                Secure.CAMERA_AUTOROTATE,
                currentUser
        ) {
            @Override
            protected void handleValueChanged(int value, boolean observedChange) {
                // mHandler is the background handler so calling this is OK
                handleRefreshState(null);
            }
        };
        mBatteryController.observe(getLifecycle(), this);
    }

    @Override
    protected void handleInitialize() {
        mPrivacyManager.addSensorPrivacyListener(CAMERA, mSensorPrivacyChangedListener);
    }

    @Override
    public void onPowerSaveChanged(boolean isPowerSave) {
        refreshState();
    }

    @Override
@@ -95,14 +137,46 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
    protected void handleUpdateState(BooleanState state, Object arg) {
        final boolean rotationLocked = mController.isRotationLocked();

        final boolean powerSave = mBatteryController.isPowerSave();
        final boolean cameraLocked = mPrivacyManager.isSensorPrivacyEnabled(CAMERA);
        final boolean cameraRotation =
                !powerSave && !cameraLocked && hasSufficientPermission(mContext)
                        && mController.isCameraRotationEnabled();
        state.value = !rotationLocked;
        state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
        state.icon = mIcon;
        state.contentDescription = getAccessibilityString(rotationLocked);
        if (!rotationLocked && cameraRotation) {
            state.secondaryLabel = mContext.getResources().getString(
                    R.string.rotation_lock_camera_rotation_on);
        } else {
            state.secondaryLabel = "";
        }
        state.stateDescription = state.secondaryLabel;

        state.expandedAccessibilityClassName = Switch.class.getName();
        state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
    }

    @Override
    protected void handleDestroy() {
        super.handleDestroy();
        mSetting.setListening(false);
        mPrivacyManager.removeSensorPrivacyListener(CAMERA, mSensorPrivacyChangedListener);
    }

    @Override
    public void handleSetListening(boolean listening) {
        super.handleSetListening(listening);
        mSetting.setListening(listening);
    }

    @Override
    protected void handleUserSwitch(int newUserId) {
        mSetting.setUserId(newUserId);
        handleRefreshState(null);
    }

    public static boolean isCurrentOrientationLockPortrait(RotationLockController controller,
            Resources resources) {
        int lockOrientation = controller.getRotationLockOrientation();
@@ -140,4 +214,8 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
            refreshState(rotationLocked);
        }
    };

    private final SensorPrivacyManager.OnSensorPrivacyChangedListener
            mSensorPrivacyChangedListener =
            (sensor, enabled) -> refreshState();
}
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ public interface RotationLockController extends Listenable,
    int getRotationLockOrientation();
    boolean isRotationLockAffordanceVisible();
    boolean isRotationLocked();
    boolean isCameraRotationEnabled();
    void setRotationLocked(boolean locked);
    void setRotationLockedAtAngle(boolean locked, int rotation);

+16 −1
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.systemui.statusbar.policy;

import static com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule.DEVICE_STATE_ROTATION_LOCK_DEFAULTS;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;

import androidx.annotation.NonNull;
@@ -34,6 +37,7 @@ import javax.inject.Named;
/** Platform implementation of the rotation lock controller. **/
@SysUISingleton
public final class RotationLockControllerImpl implements RotationLockController {

    private final CopyOnWriteArrayList<RotationLockControllerCallback> mCallbacks =
            new CopyOnWriteArrayList<>();

@@ -86,6 +90,10 @@ public final class RotationLockControllerImpl implements RotationLockController
        return mRotationPolicy.isRotationLocked();
    }

    public boolean isCameraRotationEnabled() {
        return mRotationPolicy.isCameraRotationEnabled();
    }

    public void setRotationLocked(boolean locked) {
        mRotationPolicy.setRotationLock(locked);
    }
@@ -121,4 +129,11 @@ public final class RotationLockControllerImpl implements RotationLockController
        callback.onRotationLockStateChanged(mRotationPolicy.isRotationLocked(),
                mRotationPolicy.isRotationLockToggleVisible());
    }

    public static boolean hasSufficientPermission(Context context) {
        final PackageManager packageManager = context.getPackageManager();
        final String rotationPackage = packageManager.getRotationResolverPackageName();
        return rotationPackage != null && packageManager.checkPermission(
                Manifest.permission.CAMERA, rotationPackage) == PackageManager.PERMISSION_GRANTED;
    }
}
+11 −2
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.systemui.util.wrapper

import android.content.Context
import android.provider.Settings.Secure.CAMERA_AUTOROTATE
import com.android.internal.view.RotationPolicy
import com.android.internal.view.RotationPolicy.RotationPolicyListener
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject

/**
@@ -30,11 +32,15 @@ interface RotationPolicyWrapper {
    fun getRotationLockOrientation(): Int
    fun isRotationLockToggleVisible(): Boolean
    fun isRotationLocked(): Boolean
    fun isCameraRotationEnabled(): Boolean
    fun registerRotationPolicyListener(listener: RotationPolicyListener, userHandle: Int)
    fun unregisterRotationPolicyListener(listener: RotationPolicyListener)
}

class RotationPolicyWrapperImpl @Inject constructor(private val context: Context) :
class RotationPolicyWrapperImpl @Inject constructor(
    private val context: Context,
    private val secureSettings: SecureSettings
) :
        RotationPolicyWrapper {

    override fun setRotationLock(enabled: Boolean) {
@@ -54,6 +60,9 @@ class RotationPolicyWrapperImpl @Inject constructor(private val context: Context
    override fun isRotationLocked(): Boolean =
        RotationPolicy.isRotationLocked(context)

    override fun isCameraRotationEnabled(): Boolean =
            secureSettings.getInt(CAMERA_AUTOROTATE, 0) == 1

    override fun registerRotationPolicyListener(
        listener: RotationPolicyListener,
        userHandle: Int
Loading