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

Commit 8e2641b2 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Allow location when Car mode is active."

parents d9dea525 8da3edbb
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);
    }
}