Merge "Allow location when Car mode is active." into rvc-dev

This commit is contained in:
Kweku Adams
2020-02-25 21:52:27 +00:00
committed by Android (Google) Code Review
2 changed files with 200 additions and 53 deletions

View File

@@ -16,8 +16,13 @@
package com.android.server.power.batterysaver; package com.android.server.power.batterysaver;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.net.Uri; import android.net.Uri;
import android.os.BatterySaverPolicyConfig; import android.os.BatterySaverPolicyConfig;
@@ -182,19 +187,16 @@ public class BatterySaverPolicy extends ContentObserver {
@GuardedBy("mLock") @GuardedBy("mLock")
private String mEventLogKeys; 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. * Whether accessibility is currently enabled or not.
*/ */
@GuardedBy("mLock") @GuardedBy("mLock")
private boolean mAccessibilityEnabled; private boolean mAccessibilityEnabled;
/** Whether the phone is projecting in car mode or not. */
@GuardedBy("mLock")
private boolean mCarModeEnabled;
/** The current default adaptive policy. */ /** The current default adaptive policy. */
@GuardedBy("mLock") @GuardedBy("mLock")
private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY; private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;
@@ -207,6 +209,13 @@ public class BatterySaverPolicy extends ContentObserver {
@GuardedBy("mLock") @GuardedBy("mLock")
private Policy mFullPolicy = DEFAULT_FULL_POLICY; 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 = { @IntDef(prefix = {"POLICY_LEVEL_"}, value = {
POLICY_LEVEL_OFF, POLICY_LEVEL_OFF,
POLICY_LEVEL_ADAPTIVE, POLICY_LEVEL_ADAPTIVE,
@@ -230,6 +239,20 @@ public class BatterySaverPolicy extends ContentObserver {
private final ContentResolver mContentResolver; private final ContentResolver mContentResolver;
private final BatterySavingStats mBatterySavingStats; 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") @GuardedBy("mLock")
private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>(); private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>();
@@ -263,16 +286,25 @@ public class BatterySaverPolicy extends ContentObserver {
final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class); final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class);
acm.addAccessibilityStateChangeListener((enabled) -> { acm.addAccessibilityStateChangeListener((enabled) -> setAccessibilityEnabled(enabled));
final boolean accessibilityEnabled = acm.isEnabled();
synchronized (mLock) { synchronized (mLock) {
mAccessibilityEnabled = enabled; mAccessibilityEnabled = accessibilityEnabled;
} }
refreshSettings();
}); final IntentFilter filter = new IntentFilter(
final boolean enabled = acm.isEnabled(); 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) { synchronized (mLock) {
mAccessibilityEnabled = enabled; mCarModeEnabled = carModeEnabled;
} }
onChange(true, null); onChange(true, null);
} }
@@ -299,13 +331,34 @@ public class BatterySaverPolicy extends ContentObserver {
PowerManager.invalidatePowerSaveModeCaches(); 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 @Override
public void onChange(boolean selfChange, Uri uri) { public void onChange(boolean selfChange, Uri uri) {
refreshSettings(); refreshSettings();
} }
private void refreshSettings() { private void refreshSettings() {
final BatterySaverPolicyListener[] listeners;
synchronized (mLock) { synchronized (mLock) {
// Load the non-device-specific setting. // Load the non-device-specific setting.
final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS); final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS);
@@ -334,16 +387,9 @@ public class BatterySaverPolicy extends ContentObserver {
// Nothing of note changed. // Nothing of note changed.
return; return;
} }
listeners = mListeners.toArray(new BatterySaverPolicyListener[0]);
} }
// Notify the listeners. maybeNotifyListenersOfPolicyChange();
mHandler.post(() -> {
for (BatterySaverPolicyListener listener : listeners) {
listener.onBatterySaverPolicyChanged(this);
}
});
} }
@GuardedBy("mLock") @GuardedBy("mLock")
@@ -404,31 +450,63 @@ public class BatterySaverPolicy extends ContentObserver {
@GuardedBy("mLock") @GuardedBy("mLock")
private void updatePolicyDependenciesLocked() { private void updatePolicyDependenciesLocked() {
final Policy currPolicy = getCurrentPolicyLocked(); final Policy rawPolicy = getCurrentRawPolicyLocked();
// Update the effective vibration policy.
mDisableVibrationEffective = currPolicy.disableVibration final int locationMode;
&& !mAccessibilityEnabled; // Don't disable vibration when accessibility is on. 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(); final StringBuilder sb = new StringBuilder();
if (currPolicy.forceAllAppsStandby) sb.append("A"); if (mEffectivePolicy.forceAllAppsStandby) sb.append("A");
if (currPolicy.forceBackgroundCheck) sb.append("B"); if (mEffectivePolicy.forceBackgroundCheck) sb.append("B");
if (mDisableVibrationEffective) sb.append("v"); if (mEffectivePolicy.disableVibration) sb.append("v");
if (currPolicy.disableAnimation) sb.append("a"); if (mEffectivePolicy.disableAnimation) sb.append("a");
if (currPolicy.disableSoundTrigger) sb.append("s"); if (mEffectivePolicy.disableSoundTrigger) sb.append("s");
if (currPolicy.deferFullBackup) sb.append("F"); if (mEffectivePolicy.deferFullBackup) sb.append("F");
if (currPolicy.deferKeyValueBackup) sb.append("K"); if (mEffectivePolicy.deferKeyValueBackup) sb.append("K");
if (currPolicy.enableFirewall) sb.append("f"); if (mEffectivePolicy.enableFirewall) sb.append("f");
if (currPolicy.enableDataSaver) sb.append("d"); if (mEffectivePolicy.enableDataSaver) sb.append("d");
if (currPolicy.enableAdjustBrightness) sb.append("b"); if (mEffectivePolicy.enableAdjustBrightness) sb.append("b");
if (currPolicy.disableLaunchBoost) sb.append("l"); if (mEffectivePolicy.disableLaunchBoost) sb.append("l");
if (currPolicy.disableOptionalSensors) sb.append("S"); if (mEffectivePolicy.disableOptionalSensors) sb.append("S");
if (currPolicy.disableAod) sb.append("o"); if (mEffectivePolicy.disableAod) sb.append("o");
if (currPolicy.enableQuickDoze) sb.append("q"); if (mEffectivePolicy.enableQuickDoze) sb.append("q");
sb.append(currPolicy.locationMode); sb.append(mEffectivePolicy.locationMode);
mEventLogKeys = sb.toString(); mEventLogKeys = sb.toString();
} }
@@ -857,7 +935,7 @@ public class BatterySaverPolicy extends ContentObserver {
return builder.setBatterySaverEnabled(currPolicy.disableSoundTrigger) return builder.setBatterySaverEnabled(currPolicy.disableSoundTrigger)
.build(); .build();
case ServiceType.VIBRATION: case ServiceType.VIBRATION:
return builder.setBatterySaverEnabled(mDisableVibrationEffective) return builder.setBatterySaverEnabled(currPolicy.disableVibration)
.build(); .build();
case ServiceType.FORCE_ALL_APPS_STANDBY: case ServiceType.FORCE_ALL_APPS_STANDBY:
return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby) return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby)
@@ -933,6 +1011,10 @@ public class BatterySaverPolicy extends ContentObserver {
} }
private Policy getCurrentPolicyLocked() { private Policy getCurrentPolicyLocked() {
return mEffectivePolicy;
}
private Policy getCurrentRawPolicyLocked() {
switch (getPolicyLevelLocked()) { switch (getPolicyLevelLocked()) {
case POLICY_LEVEL_FULL: case POLICY_LEVEL_FULL:
return mFullPolicy; return mFullPolicy;
@@ -994,11 +1076,13 @@ public class BatterySaverPolicy extends ContentObserver {
pw.println(" value: " + mAdaptiveDeviceSpecificSettings); pw.println(" value: " + mAdaptiveDeviceSpecificSettings);
pw.println(" mAccessibilityEnabled=" + mAccessibilityEnabled); pw.println(" mAccessibilityEnabled=" + mAccessibilityEnabled);
pw.println(" mCarModeEnabled=" + mCarModeEnabled);
pw.println(" mPolicyLevel=" + getPolicyLevelLocked()); pw.println(" mPolicyLevel=" + getPolicyLevelLocked());
dumpPolicyLocked(pw, " ", "full", mFullPolicy); dumpPolicyLocked(pw, " ", "full", mFullPolicy);
dumpPolicyLocked(pw, " ", "default adaptive", mDefaultAdaptivePolicy); dumpPolicyLocked(pw, " ", "default adaptive", mDefaultAdaptivePolicy);
dumpPolicyLocked(pw, " ", "current adaptive", mAdaptivePolicy); dumpPolicyLocked(pw, " ", "current adaptive", mAdaptivePolicy);
dumpPolicyLocked(pw, " ", "effective", mEffectivePolicy);
} }
} }
@@ -1009,11 +1093,7 @@ public class BatterySaverPolicy extends ContentObserver {
pw.print(indent); pw.print(indent);
pw.println(" " + KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled); pw.println(" " + KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled);
pw.print(indent); pw.print(indent);
pw.println(" " + KEY_VIBRATION_DISABLED + ":config=" + p.disableVibration); pw.println(" " + KEY_VIBRATION_DISABLED + "=" + p.disableVibration);
// mDisableVibrationEffective is based on the currently selected policy
pw.print(indent);
pw.println(" " + KEY_VIBRATION_DISABLED + ":effective=" + (p.disableVibration
&& !mAccessibilityEnabled));
pw.print(indent); pw.print(indent);
pw.println(" " + KEY_ANIMATION_DISABLED + "=" + p.disableAnimation); pw.println(" " + KEY_ANIMATION_DISABLED + "=" + p.disableAnimation);
pw.print(indent); pw.print(indent);
@@ -1070,10 +1150,24 @@ public class BatterySaverPolicy extends ContentObserver {
} }
@VisibleForTesting @VisibleForTesting
public void setAccessibilityEnabledForTest(boolean enabled) { void setAccessibilityEnabled(boolean enabled) {
synchronized (mLock) { synchronized (mLock) {
if (mAccessibilityEnabled != enabled) {
mAccessibilityEnabled = enabled; mAccessibilityEnabled = enabled;
updatePolicyDependenciesLocked(); updatePolicyDependenciesLocked();
maybeNotifyListenersOfPolicyChange();
}
}
}
@VisibleForTesting
void setCarModeEnabled(boolean enabled) {
synchronized (mLock) {
if (mCarModeEnabled != enabled) {
mCarModeEnabled = enabled;
updatePolicyDependenciesLocked();
maybeNotifyListenersOfPolicyChange();
}
} }
} }

View File

@@ -117,7 +117,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
@SmallTest @SmallTest
public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() { public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() {
mBatterySaverPolicy.setAccessibilityEnabledForTest(true); mBatterySaverPolicy.setAccessibilityEnabled(true);
testServiceDefaultValue_Off(ServiceType.VIBRATION); testServiceDefaultValue_Off(ServiceType.VIBRATION);
} }
@@ -339,4 +339,57 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
Policy.fromSettings(BATTERY_SAVER_CONSTANTS, "")); Policy.fromSettings(BATTERY_SAVER_CONSTANTS, ""));
verifyBatterySaverConstantsUpdated(); 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);
}
} }