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

Commit 00575d6d authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Allow location when Car mode is active." into rvc-dev am: 969e1e27

Change-Id: I153b32c0f532163eec8f1463bb7cea3b355907c5
parents 981a7ddf 969e1e27
Loading
Loading
Loading
Loading
+146 −52
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@
package com.android.server.power.batterysaver;

import android.annotation.IntDef;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatterySaverPolicyConfig;
@@ -182,19 +187,16 @@ public class BatterySaverPolicy extends ContentObserver {
    @GuardedBy("mLock")
    private String mEventLogKeys;

    /**
     * Whether vibration should *really* be disabled -- i.e. {@link Policy#disableVibration}
     * is true *and* {@link #mAccessibilityEnabled} is false.
     */
    @GuardedBy("mLock")
    private boolean mDisableVibrationEffective;

    /**
     * Whether accessibility is currently enabled or not.
     */
    @GuardedBy("mLock")
    private boolean mAccessibilityEnabled;

    /** Whether the phone is projecting in car mode or not. */
    @GuardedBy("mLock")
    private boolean mCarModeEnabled;

    /** The current default adaptive policy. */
    @GuardedBy("mLock")
    private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;
@@ -207,6 +209,13 @@ public class BatterySaverPolicy extends ContentObserver {
    @GuardedBy("mLock")
    private Policy mFullPolicy = DEFAULT_FULL_POLICY;

    /**
     * The current effective policy. This is based on the current policy level's policy, with any
     * required adjustments.
     */
    @GuardedBy("mLock")
    private Policy mEffectivePolicy = OFF_POLICY;

    @IntDef(prefix = {"POLICY_LEVEL_"}, value = {
            POLICY_LEVEL_OFF,
            POLICY_LEVEL_ADAPTIVE,
@@ -230,6 +239,20 @@ public class BatterySaverPolicy extends ContentObserver {
    private final ContentResolver mContentResolver;
    private final BatterySavingStats mBatterySavingStats;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED:
                    setCarModeEnabled(true);
                    break;
                case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED:
                    setCarModeEnabled(false);
                    break;
            }
        }
    };

    @GuardedBy("mLock")
    private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>();

@@ -263,16 +286,25 @@ public class BatterySaverPolicy extends ContentObserver {

        final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class);

        acm.addAccessibilityStateChangeListener((enabled) -> {
        acm.addAccessibilityStateChangeListener((enabled) -> setAccessibilityEnabled(enabled));
        final boolean accessibilityEnabled = acm.isEnabled();
        synchronized (mLock) {
                mAccessibilityEnabled = enabled;
            }
            refreshSettings();
        });
        final boolean enabled = acm.isEnabled();
            mAccessibilityEnabled = accessibilityEnabled;
        }

        final IntentFilter filter = new IntentFilter(
                UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
        filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
        // The ENTER/EXIT_CAR_MODE_PRIORITIZED intents are sent to UserHandle.ALL, so no need to
        // register as all users here.
        mContext.registerReceiver(mBroadcastReceiver, filter);
        final boolean carModeEnabled =
                mContext.getSystemService(UiModeManager.class).getCurrentModeType()
                        == Configuration.UI_MODE_TYPE_CAR;
        synchronized (mLock) {
            mAccessibilityEnabled = enabled;
            mCarModeEnabled = carModeEnabled;
        }

        onChange(true, null);
    }

@@ -299,13 +331,34 @@ public class BatterySaverPolicy extends ContentObserver {
        PowerManager.invalidatePowerSaveModeCaches();
    }

    /**
     * Notifies listeners of a policy change on the handler thread only if the current policy level
     * is not {@link POLICY_LEVEL_OFF}.
     */
    private void maybeNotifyListenersOfPolicyChange() {
        final BatterySaverPolicyListener[] listeners;
        synchronized (mLock) {
            if (getPolicyLevelLocked() == POLICY_LEVEL_OFF) {
                // Current policy is OFF, so there's no change to notify listeners of.
                return;
            }
            // Don't call out to listeners with the lock held.
            listeners = mListeners.toArray(new BatterySaverPolicyListener[mListeners.size()]);
        }

        mHandler.post(() -> {
            for (BatterySaverPolicyListener listener : listeners) {
                listener.onBatterySaverPolicyChanged(this);
            }
        });
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        refreshSettings();
    }

    private void refreshSettings() {
        final BatterySaverPolicyListener[] listeners;
        synchronized (mLock) {
            // Load the non-device-specific setting.
            final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS);
@@ -334,16 +387,9 @@ public class BatterySaverPolicy extends ContentObserver {
                // Nothing of note changed.
                return;
            }

            listeners = mListeners.toArray(new BatterySaverPolicyListener[0]);
        }

        // Notify the listeners.
        mHandler.post(() -> {
            for (BatterySaverPolicyListener listener : listeners) {
                listener.onBatterySaverPolicyChanged(this);
            }
        });
        maybeNotifyListenersOfPolicyChange();
    }

    @GuardedBy("mLock")
@@ -404,31 +450,63 @@ public class BatterySaverPolicy extends ContentObserver {

    @GuardedBy("mLock")
    private void updatePolicyDependenciesLocked() {
        final Policy currPolicy = getCurrentPolicyLocked();
        // Update the effective vibration policy.
        mDisableVibrationEffective = currPolicy.disableVibration
                && !mAccessibilityEnabled; // Don't disable vibration when accessibility is on.
        final Policy rawPolicy = getCurrentRawPolicyLocked();

        final int locationMode;
        if (mCarModeEnabled
                && rawPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE
                && rawPolicy.locationMode != PowerManager.LOCATION_MODE_FOREGROUND_ONLY) {
            // If car projection is enabled, ensure that navigation works.
            locationMode = PowerManager.LOCATION_MODE_FOREGROUND_ONLY;
        } else {
            locationMode = rawPolicy.locationMode;
        }
        mEffectivePolicy = new Policy(
                rawPolicy.adjustBrightnessFactor,
                rawPolicy.advertiseIsEnabled,
                rawPolicy.deferFullBackup,
                rawPolicy.deferKeyValueBackup,
                rawPolicy.disableAnimation,
                rawPolicy.disableAod,
                rawPolicy.disableLaunchBoost,
                rawPolicy.disableOptionalSensors,
                rawPolicy.disableSoundTrigger,
                // Don't disable vibration when accessibility is on.
                rawPolicy.disableVibration && !mAccessibilityEnabled,
                rawPolicy.enableAdjustBrightness,
                rawPolicy.enableDataSaver,
                rawPolicy.enableFirewall,
                // Don't force night mode when car projection is enabled.
                rawPolicy.enableNightMode && !mCarModeEnabled,
                rawPolicy.enableQuickDoze,
                rawPolicy.filesForInteractive,
                rawPolicy.filesForNoninteractive,
                rawPolicy.forceAllAppsStandby,
                rawPolicy.forceBackgroundCheck,
                locationMode
        );


        final StringBuilder sb = new StringBuilder();

        if (currPolicy.forceAllAppsStandby) sb.append("A");
        if (currPolicy.forceBackgroundCheck) sb.append("B");
        if (mEffectivePolicy.forceAllAppsStandby) sb.append("A");
        if (mEffectivePolicy.forceBackgroundCheck) sb.append("B");

        if (mDisableVibrationEffective) sb.append("v");
        if (currPolicy.disableAnimation) sb.append("a");
        if (currPolicy.disableSoundTrigger) sb.append("s");
        if (currPolicy.deferFullBackup) sb.append("F");
        if (currPolicy.deferKeyValueBackup) sb.append("K");
        if (currPolicy.enableFirewall) sb.append("f");
        if (currPolicy.enableDataSaver) sb.append("d");
        if (currPolicy.enableAdjustBrightness) sb.append("b");
        if (mEffectivePolicy.disableVibration) sb.append("v");
        if (mEffectivePolicy.disableAnimation) sb.append("a");
        if (mEffectivePolicy.disableSoundTrigger) sb.append("s");
        if (mEffectivePolicy.deferFullBackup) sb.append("F");
        if (mEffectivePolicy.deferKeyValueBackup) sb.append("K");
        if (mEffectivePolicy.enableFirewall) sb.append("f");
        if (mEffectivePolicy.enableDataSaver) sb.append("d");
        if (mEffectivePolicy.enableAdjustBrightness) sb.append("b");

        if (currPolicy.disableLaunchBoost) sb.append("l");
        if (currPolicy.disableOptionalSensors) sb.append("S");
        if (currPolicy.disableAod) sb.append("o");
        if (currPolicy.enableQuickDoze) sb.append("q");
        if (mEffectivePolicy.disableLaunchBoost) sb.append("l");
        if (mEffectivePolicy.disableOptionalSensors) sb.append("S");
        if (mEffectivePolicy.disableAod) sb.append("o");
        if (mEffectivePolicy.enableQuickDoze) sb.append("q");

        sb.append(currPolicy.locationMode);
        sb.append(mEffectivePolicy.locationMode);

        mEventLogKeys = sb.toString();
    }
@@ -857,7 +935,7 @@ public class BatterySaverPolicy extends ContentObserver {
                    return builder.setBatterySaverEnabled(currPolicy.disableSoundTrigger)
                            .build();
                case ServiceType.VIBRATION:
                    return builder.setBatterySaverEnabled(mDisableVibrationEffective)
                    return builder.setBatterySaverEnabled(currPolicy.disableVibration)
                            .build();
                case ServiceType.FORCE_ALL_APPS_STANDBY:
                    return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby)
@@ -933,6 +1011,10 @@ public class BatterySaverPolicy extends ContentObserver {
    }

    private Policy getCurrentPolicyLocked() {
        return mEffectivePolicy;
    }

    private Policy getCurrentRawPolicyLocked() {
        switch (getPolicyLevelLocked()) {
            case POLICY_LEVEL_FULL:
                return mFullPolicy;
@@ -994,11 +1076,13 @@ public class BatterySaverPolicy extends ContentObserver {
            pw.println("    value: " + mAdaptiveDeviceSpecificSettings);

            pw.println("  mAccessibilityEnabled=" + mAccessibilityEnabled);
            pw.println("  mCarModeEnabled=" + mCarModeEnabled);
            pw.println("  mPolicyLevel=" + getPolicyLevelLocked());

            dumpPolicyLocked(pw, "  ", "full", mFullPolicy);
            dumpPolicyLocked(pw, "  ", "default adaptive", mDefaultAdaptivePolicy);
            dumpPolicyLocked(pw, "  ", "current adaptive", mAdaptivePolicy);
            dumpPolicyLocked(pw, "  ", "effective", mEffectivePolicy);
        }
    }

@@ -1009,11 +1093,7 @@ public class BatterySaverPolicy extends ContentObserver {
        pw.print(indent);
        pw.println("  " + KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled);
        pw.print(indent);
        pw.println("  " + KEY_VIBRATION_DISABLED + ":config=" + p.disableVibration);
        // mDisableVibrationEffective is based on the currently selected policy
        pw.print(indent);
        pw.println("  " + KEY_VIBRATION_DISABLED + ":effective=" + (p.disableVibration
                && !mAccessibilityEnabled));
        pw.println("  " + KEY_VIBRATION_DISABLED + "=" + p.disableVibration);
        pw.print(indent);
        pw.println("  " + KEY_ANIMATION_DISABLED + "=" + p.disableAnimation);
        pw.print(indent);
@@ -1070,10 +1150,24 @@ public class BatterySaverPolicy extends ContentObserver {
    }

    @VisibleForTesting
    public void setAccessibilityEnabledForTest(boolean enabled) {
    void setAccessibilityEnabled(boolean enabled) {
        synchronized (mLock) {
            if (mAccessibilityEnabled != enabled) {
                mAccessibilityEnabled = enabled;
                updatePolicyDependenciesLocked();
                maybeNotifyListenersOfPolicyChange();
            }
        }
    }

    @VisibleForTesting
    void setCarModeEnabled(boolean enabled) {
        synchronized (mLock) {
            if (mCarModeEnabled != enabled) {
                mCarModeEnabled = enabled;
                updatePolicyDependenciesLocked();
                maybeNotifyListenersOfPolicyChange();
            }
        }
    }

+54 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {

    @SmallTest
    public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() {
        mBatterySaverPolicy.setAccessibilityEnabledForTest(true);
        mBatterySaverPolicy.setAccessibilityEnabled(true);
        testServiceDefaultValue_Off(ServiceType.VIBRATION);
    }

@@ -339,4 +339,57 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
                Policy.fromSettings(BATTERY_SAVER_CONSTANTS, ""));
        verifyBatterySaverConstantsUpdated();
    }

    public void testCarModeChanges_Full() {
        mBatterySaverPolicy.updateConstantsLocked(
                "gps_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
                        + ",enable_night_mode=true", "");
        mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_FULL);
        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isEqualTo(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
        assertTrue(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);

        mBatterySaverPolicy.setCarModeEnabled(true);

        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isAnyOf(PowerManager.LOCATION_MODE_NO_CHANGE,
                        PowerManager.LOCATION_MODE_FOREGROUND_ONLY);
        assertFalse(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);

        mBatterySaverPolicy.setCarModeEnabled(false);

        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isEqualTo(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
        assertTrue(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);
    }

    public void testCarModeChanges_Adaptive() {
        mBatterySaverPolicy.setAdaptivePolicyLocked(
                Policy.fromSettings(
                        "gps_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
                                + ",enable_night_mode=true", ""));
        mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_ADAPTIVE);
        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isEqualTo(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
        assertTrue(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);

        mBatterySaverPolicy.setCarModeEnabled(true);

        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isAnyOf(PowerManager.LOCATION_MODE_NO_CHANGE,
                        PowerManager.LOCATION_MODE_FOREGROUND_ONLY);
        assertFalse(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);

        mBatterySaverPolicy.setCarModeEnabled(false);

        assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                .isEqualTo(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
        assertTrue(mBatterySaverPolicy.getBatterySaverPolicy(
                ServiceType.NIGHT_MODE).batterySaverEnabled);
    }
}