1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.power.batterysaver; 17 18 import android.annotation.IntDef; 19 import android.app.UiModeManager; 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.database.ContentObserver; 23 import android.net.Uri; 24 import android.os.BatterySaverPolicyConfig; 25 import android.os.Handler; 26 import android.os.PowerManager; 27 import android.os.PowerManager.ServiceType; 28 import android.os.PowerSaveState; 29 import android.provider.DeviceConfig; 30 import android.provider.Settings; 31 import android.text.TextUtils; 32 import android.util.ArrayMap; 33 import android.util.IndentingPrintWriter; 34 import android.util.KeyValueListParser; 35 import android.util.Slog; 36 import android.view.accessibility.AccessibilityManager; 37 38 import com.android.internal.R; 39 import com.android.internal.annotations.GuardedBy; 40 import com.android.internal.annotations.VisibleForTesting; 41 import com.android.internal.os.BackgroundThread; 42 import com.android.internal.util.ConcurrentUtils; 43 import com.android.server.power.PowerManagerService; 44 45 import java.io.PrintWriter; 46 import java.lang.annotation.Retention; 47 import java.lang.annotation.RetentionPolicy; 48 import java.util.ArrayList; 49 import java.util.List; 50 import java.util.Map; 51 import java.util.Objects; 52 import java.util.Set; 53 54 /** 55 * Class to decide whether to turn on battery saver mode for specific services. 56 * 57 * IMPORTANT: This class shares the power manager lock, which is very low in the lock hierarchy. 58 * Do not call out with the lock held, such as AccessibilityManager. (Settings provider is okay.) 59 * 60 * Test: atest com.android.server.power.batterysaver.BatterySaverPolicyTest 61 */ 62 public class BatterySaverPolicy extends ContentObserver implements 63 DeviceConfig.OnPropertiesChangedListener { 64 private static final String TAG = "BatterySaverPolicy"; 65 66 static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE. 67 68 @VisibleForTesting 69 static final String KEY_LOCATION_MODE = "location_mode"; 70 @VisibleForTesting 71 static final String KEY_DISABLE_VIBRATION = "disable_vibration"; 72 @VisibleForTesting 73 static final String KEY_DISABLE_ANIMATION = "disable_animation"; 74 @VisibleForTesting 75 static final String KEY_SOUNDTRIGGER_MODE = "soundtrigger_mode"; 76 77 /** 78 * Turn on the network firewall when Battery Saver is turned on. 79 * If set to false, the firewall WILL NOT be turned on when Battery Saver is turned on. 80 * If set to true, the firewall WILL be turned on when Battery Saver is turned on. 81 */ 82 @VisibleForTesting 83 static final String KEY_ENABLE_FIREWALL = "enable_firewall"; 84 85 /** 86 * Turn on the special low power screen brightness dimming when Battery Saver is 87 * turned on. 88 * If set to false, the screen brightness dimming WILL NOT be turned on by Battery Saver. 89 * If set to true, the screen brightness WILL be turned on by Battery Saver. 90 */ 91 @VisibleForTesting 92 static final String KEY_ENABLE_BRIGHTNESS_ADJUSTMENT = "enable_brightness_adjustment"; 93 94 /** 95 * Turn on Data Saver when Battery Saver is turned on. 96 * If set to false, Data Saver WILL NOT be turned on when Battery Saver is turned on. 97 * If set to true, Data Saver WILL be turned on when Battery Saver is turned on. 98 */ 99 @VisibleForTesting 100 static final String KEY_ENABLE_DATASAVER = "enable_datasaver"; 101 102 /** 103 * {@code true} if the Policy should advertise to the rest of the system that battery saver 104 * is enabled. This advertising could cause other system components to change their 105 * behavior. This will not affect other policy flags and what they change. 106 */ 107 @VisibleForTesting 108 static final String KEY_ADVERTISE_IS_ENABLED = "advertise_is_enabled"; 109 110 @VisibleForTesting 111 static final String KEY_DISABLE_LAUNCH_BOOST = "disable_launch_boost"; 112 @VisibleForTesting 113 static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor"; 114 @VisibleForTesting 115 static final String KEY_DEFER_FULL_BACKUP = "defer_full_backup"; 116 @VisibleForTesting 117 static final String KEY_DEFER_KEYVALUE_BACKUP = "defer_keyvalue_backup"; 118 @VisibleForTesting 119 static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby"; 120 @VisibleForTesting 121 static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check"; 122 @VisibleForTesting 123 static final String KEY_DISABLE_OPTIONAL_SENSORS = "disable_optional_sensors"; 124 @VisibleForTesting 125 static final String KEY_DISABLE_AOD = "disable_aod"; 126 // Go into deep Doze as soon as the screen turns off. 127 @VisibleForTesting 128 static final String KEY_ENABLE_QUICK_DOZE = "enable_quick_doze"; 129 @VisibleForTesting 130 static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode"; 131 132 private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i"; 133 private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n"; 134 135 private static final String KEY_SUFFIX_ADAPTIVE = "_adaptive"; 136 137 @VisibleForTesting 138 static final Policy OFF_POLICY = new Policy( 139 1f, /* adjustBrightnessFactor */ 140 false, /* advertiseIsEnabled */ 141 new CpuFrequencies(), /* cpuFrequenciesForInteractive */ 142 new CpuFrequencies(), /* cpuFrequenciesForNoninteractive */ 143 false, /* deferFullBackup */ 144 false, /* deferKeyValueBackup */ 145 false, /* disableAnimation */ 146 false, /* disableAod */ 147 false, /* disableLaunchBoost */ 148 false, /* disableOptionalSensors */ 149 false, /* disableVibration */ 150 false, /* enableAdjustBrightness */ 151 false, /* enableDataSaver */ 152 false, /* enableFireWall */ 153 false, /* enableNightMode */ 154 false, /* enableQuickDoze */ 155 false, /* forceAllAppsStandby */ 156 false, /* forceBackgroundCheck */ 157 PowerManager.LOCATION_MODE_NO_CHANGE, /* locationMode */ 158 PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED /* soundTriggerMode */ 159 ); 160 161 private static final Policy DEFAULT_ADAPTIVE_POLICY = OFF_POLICY; 162 163 private static final Policy DEFAULT_FULL_POLICY = new Policy( 164 0.5f, /* adjustBrightnessFactor */ 165 true, /* advertiseIsEnabled */ 166 new CpuFrequencies(), /* cpuFrequenciesForInteractive */ 167 new CpuFrequencies(), /* cpuFrequenciesForNoninteractive */ 168 true, /* deferFullBackup */ 169 true, /* deferKeyValueBackup */ 170 false, /* disableAnimation */ 171 true, /* disableAod */ 172 true, /* disableLaunchBoost */ 173 true, /* disableOptionalSensors */ 174 true, /* disableVibration */ 175 false, /* enableAdjustBrightness */ 176 false, /* enableDataSaver */ 177 true, /* enableFirewall */ 178 true, /* enableNightMode */ 179 true, /* enableQuickDoze */ 180 true, /* forceAllAppsStandby */ 181 true, /* forceBackgroundCheck */ 182 PowerManager.LOCATION_MODE_FOREGROUND_ONLY, /* locationMode */ 183 PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY /* soundTriggerMode */ 184 ); 185 186 private final Object mLock; 187 private final Handler mHandler; 188 189 @GuardedBy("mLock") 190 private String mSettings; 191 192 @GuardedBy("mLock") 193 private String mDeviceSpecificSettings; 194 195 @GuardedBy("mLock") 196 private String mDeviceSpecificSettingsSource; // For dump() only. 197 198 @GuardedBy("mLock") 199 private DeviceConfig.Properties mLastDeviceConfigProperties; 200 201 /** 202 * A short string describing which battery saver is now enabled, which we dump in the eventlog. 203 */ 204 @GuardedBy("mLock") 205 private String mEventLogKeys; 206 207 /** 208 * Whether accessibility is currently enabled or not. 209 */ 210 @VisibleForTesting 211 final PolicyBoolean mAccessibilityEnabled = new PolicyBoolean("accessibility"); 212 213 /** Whether the phone has set automotive projection or not. */ 214 @VisibleForTesting 215 final PolicyBoolean mAutomotiveProjectionActive = new PolicyBoolean("automotiveProjection"); 216 217 /** The current default adaptive policy. */ 218 @GuardedBy("mLock") 219 private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY; 220 221 /** The policy that will be used for adaptive battery saver. */ 222 @GuardedBy("mLock") 223 private Policy mAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY; 224 225 /** The current default full policy. */ 226 @GuardedBy("mLock") 227 private Policy mDefaultFullPolicy = DEFAULT_FULL_POLICY; 228 229 /** The policy to be used for full battery saver. */ 230 @GuardedBy("mLock") 231 private Policy mFullPolicy = DEFAULT_FULL_POLICY; 232 233 /** 234 * The current effective policy. This is based on the current policy level's policy, with any 235 * required adjustments. 236 */ 237 @GuardedBy("mLock") 238 private Policy mEffectivePolicyRaw = OFF_POLICY; 239 240 @IntDef(prefix = {"POLICY_LEVEL_"}, value = { 241 POLICY_LEVEL_OFF, 242 POLICY_LEVEL_ADAPTIVE, 243 POLICY_LEVEL_FULL, 244 }) 245 @Retention(RetentionPolicy.SOURCE) 246 @interface PolicyLevel {} 247 248 static final int POLICY_LEVEL_OFF = 0; 249 static final int POLICY_LEVEL_ADAPTIVE = 1; 250 static final int POLICY_LEVEL_FULL = 2; 251 252 @GuardedBy("mLock") 253 private int mPolicyLevel = POLICY_LEVEL_OFF; 254 255 private final Context mContext; 256 private final ContentResolver mContentResolver; 257 private final BatterySavingStats mBatterySavingStats; 258 259 private final UiModeManager.OnProjectionStateChangedListener mOnProjectionStateChangedListener = 260 (t, pkgs) -> mAutomotiveProjectionActive.update(!pkgs.isEmpty()); 261 262 @GuardedBy("mLock") 263 private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>(); 264 265 public interface BatterySaverPolicyListener { onBatterySaverPolicyChanged(BatterySaverPolicy policy)266 void onBatterySaverPolicyChanged(BatterySaverPolicy policy); 267 } 268 BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats)269 public BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats) { 270 super(BackgroundThread.getHandler()); 271 mLock = lock; 272 mHandler = BackgroundThread.getHandler(); 273 mContext = context; 274 mContentResolver = context.getContentResolver(); 275 mBatterySavingStats = batterySavingStats; 276 } 277 278 /** 279 * Called by {@link PowerManagerService#systemReady}, *with no lock held.* 280 */ systemReady()281 public void systemReady() { 282 ConcurrentUtils.wtfIfLockHeld(TAG, mLock); 283 284 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 285 Settings.Global.BATTERY_SAVER_CONSTANTS), false, this); 286 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 287 Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this); 288 289 final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class); 290 291 acm.addAccessibilityStateChangeListener(enabled -> mAccessibilityEnabled.update(enabled)); 292 mAccessibilityEnabled.initialize(acm.isEnabled()); 293 294 UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class); 295 uiModeManager.addOnProjectionStateChangedListener(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, 296 mContext.getMainExecutor(), mOnProjectionStateChangedListener); 297 mAutomotiveProjectionActive.initialize( 298 uiModeManager.getActiveProjectionTypes() != UiModeManager.PROJECTION_TYPE_NONE); 299 300 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_SAVER, 301 mContext.getMainExecutor(), this); 302 mLastDeviceConfigProperties = 303 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER); 304 onChange(true, null); 305 } 306 307 @VisibleForTesting addListener(BatterySaverPolicyListener listener)308 public void addListener(BatterySaverPolicyListener listener) { 309 synchronized (mLock) { 310 // TODO: set this in the constructor instead 311 mListeners.add(listener); 312 } 313 } 314 315 @VisibleForTesting getGlobalSetting(String key)316 String getGlobalSetting(String key) { 317 return Settings.Global.getString(mContentResolver, key); 318 } 319 320 @VisibleForTesting getDeviceSpecificConfigResId()321 int getDeviceSpecificConfigResId() { 322 return R.string.config_batterySaverDeviceSpecificConfig; 323 } 324 325 @VisibleForTesting invalidatePowerSaveModeCaches()326 void invalidatePowerSaveModeCaches() { 327 PowerManager.invalidatePowerSaveModeCaches(); 328 } 329 330 /** 331 * Notifies listeners of a policy change on the handler thread only if the current policy level 332 * is not {@link #POLICY_LEVEL_OFF}. 333 */ maybeNotifyListenersOfPolicyChange()334 private void maybeNotifyListenersOfPolicyChange() { 335 final BatterySaverPolicyListener[] listeners; 336 synchronized (mLock) { 337 if (mPolicyLevel == POLICY_LEVEL_OFF) { 338 // Current policy is OFF, so there's no change to notify listeners of. 339 return; 340 } 341 // Don't call out to listeners with the lock held. 342 listeners = mListeners.toArray(new BatterySaverPolicyListener[mListeners.size()]); 343 } 344 345 mHandler.post(() -> { 346 for (BatterySaverPolicyListener listener : listeners) { 347 listener.onBatterySaverPolicyChanged(this); 348 } 349 }); 350 } 351 352 @Override onChange(boolean selfChange, Uri uri)353 public void onChange(boolean selfChange, Uri uri) { 354 refreshSettings(); 355 } 356 357 @Override onPropertiesChanged(DeviceConfig.Properties properties)358 public void onPropertiesChanged(DeviceConfig.Properties properties) { 359 // Need to get all of the flags atomically. 360 mLastDeviceConfigProperties = 361 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER); 362 Policy newAdaptivePolicy = null; 363 Policy newFullPolicy = null; 364 365 boolean changed = false; 366 367 synchronized (mLock) { 368 for (String name : properties.getKeyset()) { 369 if (name == null) { 370 continue; 371 } 372 if (name.endsWith(KEY_SUFFIX_ADAPTIVE)) { 373 if (newAdaptivePolicy == null) { 374 newAdaptivePolicy = Policy.fromSettings("", "", 375 mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE, 376 DEFAULT_ADAPTIVE_POLICY); 377 } 378 } else if (newFullPolicy == null) { 379 newFullPolicy = Policy.fromSettings(mSettings, mDeviceSpecificSettings, 380 mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY); 381 } 382 } 383 384 if (newFullPolicy != null) { 385 changed |= maybeUpdateDefaultFullPolicy(newFullPolicy); 386 } 387 388 if (newAdaptivePolicy != null && !mAdaptivePolicy.equals(newAdaptivePolicy)) { 389 mDefaultAdaptivePolicy = newAdaptivePolicy; 390 // This will override any config set by an external source. This should be fine 391 // for now. 392 // TODO(119261320): make sure it doesn't override what's set externally 393 mAdaptivePolicy = mDefaultAdaptivePolicy; 394 changed |= (mPolicyLevel == POLICY_LEVEL_ADAPTIVE); 395 } 396 397 updatePolicyDependenciesLocked(); 398 } 399 400 if (changed) { 401 maybeNotifyListenersOfPolicyChange(); 402 } 403 } 404 refreshSettings()405 private void refreshSettings() { 406 synchronized (mLock) { 407 // Load the non-device-specific setting. 408 final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS); 409 410 // Load the device specific setting. 411 // We first check the global setting, and if it's empty or the string "null" is set, 412 // use the default value from config.xml. 413 String deviceSpecificSetting = getGlobalSetting( 414 Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS); 415 mDeviceSpecificSettingsSource = 416 Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS; 417 418 if (TextUtils.isEmpty(deviceSpecificSetting) || "null".equals(deviceSpecificSetting)) { 419 deviceSpecificSetting = 420 mContext.getString(getDeviceSpecificConfigResId()); 421 mDeviceSpecificSettingsSource = "(overlay)"; 422 } 423 424 if (!updateConstantsLocked(setting, deviceSpecificSetting)) { 425 // Nothing of note changed. 426 return; 427 } 428 } 429 430 maybeNotifyListenersOfPolicyChange(); 431 } 432 433 @GuardedBy("mLock") 434 @VisibleForTesting 435 /** @return true if the currently active policy changed. */ updateConstantsLocked(String setting, String deviceSpecificSetting)436 boolean updateConstantsLocked(String setting, String deviceSpecificSetting) { 437 setting = TextUtils.emptyIfNull(setting); 438 deviceSpecificSetting = TextUtils.emptyIfNull(deviceSpecificSetting); 439 440 if (setting.equals(mSettings) 441 && deviceSpecificSetting.equals(mDeviceSpecificSettings)) { 442 return false; 443 } 444 445 mSettings = setting; 446 mDeviceSpecificSettings = deviceSpecificSetting; 447 448 if (DEBUG) { 449 Slog.i(TAG, "mSettings=" + mSettings); 450 Slog.i(TAG, "mDeviceSpecificSettings=" + mDeviceSpecificSettings); 451 } 452 453 boolean changed = maybeUpdateDefaultFullPolicy( 454 Policy.fromSettings(setting, deviceSpecificSetting, 455 mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY)); 456 457 mDefaultAdaptivePolicy = Policy.fromSettings("", "", 458 mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE, DEFAULT_ADAPTIVE_POLICY); 459 if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE 460 && !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) { 461 changed = true; 462 } 463 // This will override any config set by an external source. This should be fine for now. 464 // TODO: make sure it doesn't override what's set externally 465 mAdaptivePolicy = mDefaultAdaptivePolicy; 466 467 updatePolicyDependenciesLocked(); 468 469 return changed; 470 } 471 472 @GuardedBy("mLock") updatePolicyDependenciesLocked()473 private void updatePolicyDependenciesLocked() { 474 final Policy rawPolicy = getCurrentRawPolicyLocked(); 475 final int locationMode; 476 477 invalidatePowerSaveModeCaches(); 478 if (mAutomotiveProjectionActive.get() 479 && rawPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE 480 && rawPolicy.locationMode != PowerManager.LOCATION_MODE_FOREGROUND_ONLY) { 481 // If car projection is enabled, ensure that navigation works. 482 locationMode = PowerManager.LOCATION_MODE_FOREGROUND_ONLY; 483 } else { 484 locationMode = rawPolicy.locationMode; 485 } 486 487 mEffectivePolicyRaw = new Policy( 488 rawPolicy.adjustBrightnessFactor, 489 rawPolicy.advertiseIsEnabled, 490 rawPolicy.cpuFrequenciesForInteractive, 491 rawPolicy.cpuFrequenciesForNoninteractive, 492 rawPolicy.deferFullBackup, 493 rawPolicy.deferKeyValueBackup, 494 rawPolicy.disableAnimation, 495 rawPolicy.disableAod, 496 rawPolicy.disableLaunchBoost, 497 rawPolicy.disableOptionalSensors, 498 // Don't disable vibration when accessibility is on. 499 rawPolicy.disableVibration && !mAccessibilityEnabled.get(), 500 rawPolicy.enableAdjustBrightness, 501 rawPolicy.enableDataSaver, 502 rawPolicy.enableFirewall, 503 // Don't force night mode when car projection is enabled. 504 rawPolicy.enableNightMode && !mAutomotiveProjectionActive.get(), 505 rawPolicy.enableQuickDoze, 506 rawPolicy.forceAllAppsStandby, 507 rawPolicy.forceBackgroundCheck, 508 locationMode, 509 rawPolicy.soundTriggerMode 510 ); 511 512 513 final StringBuilder sb = new StringBuilder(); 514 515 if (mEffectivePolicyRaw.forceAllAppsStandby) sb.append("A"); 516 if (mEffectivePolicyRaw.forceBackgroundCheck) sb.append("B"); 517 518 if (mEffectivePolicyRaw.disableVibration) sb.append("v"); 519 if (mEffectivePolicyRaw.disableAnimation) sb.append("a"); 520 521 sb.append(mEffectivePolicyRaw.soundTriggerMode); 522 523 if (mEffectivePolicyRaw.deferFullBackup) sb.append("F"); 524 if (mEffectivePolicyRaw.deferKeyValueBackup) sb.append("K"); 525 if (mEffectivePolicyRaw.enableFirewall) sb.append("f"); 526 if (mEffectivePolicyRaw.enableDataSaver) sb.append("d"); 527 if (mEffectivePolicyRaw.enableAdjustBrightness) sb.append("b"); 528 529 if (mEffectivePolicyRaw.disableLaunchBoost) sb.append("l"); 530 if (mEffectivePolicyRaw.disableOptionalSensors) sb.append("S"); 531 if (mEffectivePolicyRaw.disableAod) sb.append("o"); 532 if (mEffectivePolicyRaw.enableQuickDoze) sb.append("q"); 533 534 sb.append(mEffectivePolicyRaw.locationMode); 535 536 mEventLogKeys = sb.toString(); 537 } 538 539 static class Policy { 540 /** 541 * This is the flag to decide the how much to adjust the screen brightness. This is 542 * the float value from 0 to 1 where 1 means don't change brightness. 543 * 544 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 545 * @see #KEY_ADJUST_BRIGHTNESS_FACTOR 546 */ 547 public final float adjustBrightnessFactor; 548 549 /** 550 * {@code true} if the Policy should advertise to the rest of the system that battery saver 551 * is enabled. This advertising could cause other system components to change their 552 * behavior. This will not affect other policy flags and what they change. 553 * 554 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 555 * @see #KEY_ADVERTISE_IS_ENABLED 556 */ 557 public final boolean advertiseIsEnabled; 558 559 /** 560 * {@code true} if full backup is deferred in battery saver mode. 561 * 562 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 563 * @see #KEY_DEFER_FULL_BACKUP 564 */ 565 public final boolean deferFullBackup; 566 567 /** 568 * {@code true} if key value backup is deferred in battery saver mode. 569 * 570 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 571 * @see #KEY_DEFER_KEYVALUE_BACKUP 572 */ 573 public final boolean deferKeyValueBackup; 574 575 /** 576 * {@code true} if animation is disabled in battery saver mode. 577 * 578 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 579 * @see #KEY_DISABLE_ANIMATION 580 */ 581 public final boolean disableAnimation; 582 583 /** 584 * {@code true} if AOD is disabled in battery saver mode. 585 */ 586 public final boolean disableAod; 587 588 /** 589 * {@code true} if launch boost should be disabled on battery saver. 590 */ 591 public final boolean disableLaunchBoost; 592 593 /** 594 * Whether to show non-essential sensors (e.g. edge sensors) or not. 595 */ 596 public final boolean disableOptionalSensors; 597 598 /** 599 * {@code true} if sound trigger is disabled in battery saver mode 600 * in battery saver mode. 601 * 602 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 603 * @see #KEY_SOUNDTRIGGER_MODE 604 */ 605 public final int soundTriggerMode; 606 607 /** 608 * {@code true} if vibration is disabled in battery saver mode. 609 * 610 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 611 * @see #KEY_DISABLE_VIBRATION 612 */ 613 public final boolean disableVibration; 614 615 /** 616 * {@code true} if low power mode brightness adjustment should be turned on in battery saver 617 * mode. 618 * 619 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 620 * @see #KEY_ENABLE_BRIGHTNESS_ADJUSTMENT 621 */ 622 public final boolean enableAdjustBrightness; 623 624 /** 625 * {@code true} if data saver should be turned on in battery saver mode. 626 * 627 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 628 * @see #KEY_ENABLE_DATASAVER 629 */ 630 public final boolean enableDataSaver; 631 632 /** 633 * {@code true} if network policy firewall should be turned on in battery saver mode. 634 * 635 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 636 * @see #KEY_ENABLE_FIREWALL 637 */ 638 public final boolean enableFirewall; 639 640 /** 641 * Whether to enable night mode or not. 642 */ 643 public final boolean enableNightMode; 644 645 /** 646 * Whether Quick Doze is enabled or not. 647 */ 648 public final boolean enableQuickDoze; 649 650 /** 651 * List of CPU frequencies that should be written when battery saver is activated 652 * and the device is interactive. 653 * 654 * We use this to change the max CPU frequencies. 655 */ 656 public final CpuFrequencies cpuFrequenciesForInteractive; 657 658 /** 659 * List of CPU frequencies that should be written when battery saver is activated 660 * and the device is non-interactive. 661 * 662 * We use this to change the max CPU frequencies. 663 */ 664 public final CpuFrequencies cpuFrequenciesForNoninteractive; 665 666 /** 667 * Whether to put all apps in the stand-by mode. 668 */ 669 public final boolean forceAllAppsStandby; 670 671 /** 672 * Whether to force background check. 673 */ 674 public final boolean forceBackgroundCheck; 675 676 /** 677 * This is the flag to decide the location mode in battery saver mode. This was 678 * previously called gpsMode. 679 * 680 * @see Settings.Global#BATTERY_SAVER_CONSTANTS 681 * @see #KEY_LOCATION_MODE 682 */ 683 public final int locationMode; 684 685 private final int mHashCode; 686 Policy( float adjustBrightnessFactor, boolean advertiseIsEnabled, CpuFrequencies cpuFrequenciesForInteractive, CpuFrequencies cpuFrequenciesForNoninteractive, boolean deferFullBackup, boolean deferKeyValueBackup, boolean disableAnimation, boolean disableAod, boolean disableLaunchBoost, boolean disableOptionalSensors, boolean disableVibration, boolean enableAdjustBrightness, boolean enableDataSaver, boolean enableFirewall, boolean enableNightMode, boolean enableQuickDoze, boolean forceAllAppsStandby, boolean forceBackgroundCheck, int locationMode, int soundTriggerMode)687 Policy( 688 float adjustBrightnessFactor, 689 boolean advertiseIsEnabled, 690 CpuFrequencies cpuFrequenciesForInteractive, 691 CpuFrequencies cpuFrequenciesForNoninteractive, 692 boolean deferFullBackup, 693 boolean deferKeyValueBackup, 694 boolean disableAnimation, 695 boolean disableAod, 696 boolean disableLaunchBoost, 697 boolean disableOptionalSensors, 698 boolean disableVibration, 699 boolean enableAdjustBrightness, 700 boolean enableDataSaver, 701 boolean enableFirewall, 702 boolean enableNightMode, 703 boolean enableQuickDoze, 704 boolean forceAllAppsStandby, 705 boolean forceBackgroundCheck, 706 int locationMode, 707 int soundTriggerMode) { 708 709 this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor)); 710 this.advertiseIsEnabled = advertiseIsEnabled; 711 this.cpuFrequenciesForInteractive = cpuFrequenciesForInteractive; 712 this.cpuFrequenciesForNoninteractive = cpuFrequenciesForNoninteractive; 713 this.deferFullBackup = deferFullBackup; 714 this.deferKeyValueBackup = deferKeyValueBackup; 715 this.disableAnimation = disableAnimation; 716 this.disableAod = disableAod; 717 this.disableLaunchBoost = disableLaunchBoost; 718 this.disableOptionalSensors = disableOptionalSensors; 719 this.disableVibration = disableVibration; 720 this.enableAdjustBrightness = enableAdjustBrightness; 721 this.enableDataSaver = enableDataSaver; 722 this.enableFirewall = enableFirewall; 723 this.enableNightMode = enableNightMode; 724 this.enableQuickDoze = enableQuickDoze; 725 this.forceAllAppsStandby = forceAllAppsStandby; 726 this.forceBackgroundCheck = forceBackgroundCheck; 727 728 if (locationMode < PowerManager.MIN_LOCATION_MODE 729 || PowerManager.MAX_LOCATION_MODE < locationMode) { 730 Slog.e(TAG, "Invalid location mode: " + locationMode); 731 this.locationMode = PowerManager.LOCATION_MODE_NO_CHANGE; 732 } else { 733 this.locationMode = locationMode; 734 } 735 736 if (soundTriggerMode < PowerManager.MIN_SOUND_TRIGGER_MODE 737 || soundTriggerMode > PowerManager.MAX_SOUND_TRIGGER_MODE) { 738 Slog.e(TAG, "Invalid SoundTrigger mode: " + soundTriggerMode); 739 this.soundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED; 740 } else { 741 this.soundTriggerMode = soundTriggerMode; 742 } 743 744 mHashCode = Objects.hash( 745 adjustBrightnessFactor, 746 advertiseIsEnabled, 747 cpuFrequenciesForInteractive, 748 cpuFrequenciesForNoninteractive, 749 deferFullBackup, 750 deferKeyValueBackup, 751 disableAnimation, 752 disableAod, 753 disableLaunchBoost, 754 disableOptionalSensors, 755 disableVibration, 756 enableAdjustBrightness, 757 enableDataSaver, 758 enableFirewall, 759 enableNightMode, 760 enableQuickDoze, 761 forceAllAppsStandby, 762 forceBackgroundCheck, 763 locationMode, 764 soundTriggerMode); 765 } 766 fromConfig(BatterySaverPolicyConfig config)767 static Policy fromConfig(BatterySaverPolicyConfig config) { 768 if (config == null) { 769 Slog.e(TAG, "Null config passed down to BatterySaverPolicy"); 770 return OFF_POLICY; 771 } 772 773 // Device-specific parameters. 774 Map<String, String> deviceSpecificSettings = config.getDeviceSpecificSettings(); 775 final String cpuFreqInteractive = 776 deviceSpecificSettings.getOrDefault(KEY_CPU_FREQ_INTERACTIVE, ""); 777 final String cpuFreqNoninteractive = 778 deviceSpecificSettings.getOrDefault(KEY_CPU_FREQ_NONINTERACTIVE, ""); 779 780 return new Policy( 781 config.getAdjustBrightnessFactor(), 782 config.getAdvertiseIsEnabled(), 783 (new CpuFrequencies()).parseString(cpuFreqInteractive), 784 (new CpuFrequencies()).parseString(cpuFreqNoninteractive), 785 config.getDeferFullBackup(), 786 config.getDeferKeyValueBackup(), 787 config.getDisableAnimation(), 788 config.getDisableAod(), 789 config.getDisableLaunchBoost(), 790 config.getDisableOptionalSensors(), 791 config.getDisableVibration(), 792 config.getEnableAdjustBrightness(), 793 config.getEnableDataSaver(), 794 config.getEnableFirewall(), 795 config.getEnableNightMode(), 796 config.getEnableQuickDoze(), 797 config.getForceAllAppsStandby(), 798 config.getForceBackgroundCheck(), 799 config.getLocationMode(), 800 config.getSoundTriggerMode() 801 ); 802 } 803 toConfig()804 BatterySaverPolicyConfig toConfig() { 805 return new BatterySaverPolicyConfig.Builder() 806 .addDeviceSpecificSetting(KEY_CPU_FREQ_INTERACTIVE, 807 cpuFrequenciesForInteractive.toString()) 808 .addDeviceSpecificSetting(KEY_CPU_FREQ_NONINTERACTIVE, 809 cpuFrequenciesForNoninteractive.toString()) 810 .setAdjustBrightnessFactor(adjustBrightnessFactor) 811 .setAdvertiseIsEnabled(advertiseIsEnabled) 812 .setDeferFullBackup(deferFullBackup) 813 .setDeferKeyValueBackup(deferKeyValueBackup) 814 .setDisableAnimation(disableAnimation) 815 .setDisableAod(disableAod) 816 .setDisableLaunchBoost(disableLaunchBoost) 817 .setDisableOptionalSensors(disableOptionalSensors) 818 .setDisableVibration(disableVibration) 819 .setEnableAdjustBrightness(enableAdjustBrightness) 820 .setEnableDataSaver(enableDataSaver) 821 .setEnableFirewall(enableFirewall) 822 .setEnableNightMode(enableNightMode) 823 .setEnableQuickDoze(enableQuickDoze) 824 .setForceAllAppsStandby(forceAllAppsStandby) 825 .setForceBackgroundCheck(forceBackgroundCheck) 826 .setLocationMode(locationMode) 827 .setSoundTriggerMode(soundTriggerMode) 828 .build(); 829 } 830 831 @VisibleForTesting fromSettings(String settings, String deviceSpecificSettings, DeviceConfig.Properties properties, String configSuffix)832 static Policy fromSettings(String settings, String deviceSpecificSettings, 833 DeviceConfig.Properties properties, String configSuffix) { 834 return fromSettings(settings, deviceSpecificSettings, properties, configSuffix, 835 OFF_POLICY); 836 } 837 fromSettings(String settings, String deviceSpecificSettings, DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy)838 private static Policy fromSettings(String settings, String deviceSpecificSettings, 839 DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy) { 840 final KeyValueListParser parser = new KeyValueListParser(','); 841 configSuffix = TextUtils.emptyIfNull(configSuffix); 842 843 // Device-specific parameters. 844 try { 845 parser.setString(deviceSpecificSettings == null ? "" : deviceSpecificSettings); 846 } catch (IllegalArgumentException e) { 847 Slog.wtf(TAG, "Bad device specific battery saver constants: " 848 + deviceSpecificSettings); 849 } 850 851 final String cpuFreqInteractive = parser.getString(KEY_CPU_FREQ_INTERACTIVE, ""); 852 final String cpuFreqNoninteractive = parser.getString(KEY_CPU_FREQ_NONINTERACTIVE, ""); 853 854 // Non-device-specific parameters. 855 try { 856 parser.setString(settings == null ? "" : settings); 857 } catch (IllegalArgumentException e) { 858 Slog.wtf(TAG, "Bad battery saver constants: " + settings); 859 } 860 861 // The Settings value overrides everything, since that will be set by the user. 862 // The DeviceConfig value takes second place, with the default as the last choice. 863 final float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR, 864 properties.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix, 865 defaultPolicy.adjustBrightnessFactor)); 866 final boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED, 867 properties.getBoolean(KEY_ADVERTISE_IS_ENABLED + configSuffix, 868 defaultPolicy.advertiseIsEnabled)); 869 final boolean deferFullBackup = parser.getBoolean(KEY_DEFER_FULL_BACKUP, 870 properties.getBoolean(KEY_DEFER_FULL_BACKUP + configSuffix, 871 defaultPolicy.deferFullBackup)); 872 final boolean deferKeyValueBackup = parser.getBoolean(KEY_DEFER_KEYVALUE_BACKUP, 873 properties.getBoolean(KEY_DEFER_KEYVALUE_BACKUP + configSuffix, 874 defaultPolicy.deferKeyValueBackup)); 875 final boolean disableAnimation = parser.getBoolean(KEY_DISABLE_ANIMATION, 876 properties.getBoolean(KEY_DISABLE_ANIMATION + configSuffix, 877 defaultPolicy.disableAnimation)); 878 final boolean disableAod = parser.getBoolean(KEY_DISABLE_AOD, 879 properties.getBoolean(KEY_DISABLE_AOD + configSuffix, 880 defaultPolicy.disableAod)); 881 final boolean disableLaunchBoost = parser.getBoolean(KEY_DISABLE_LAUNCH_BOOST, 882 properties.getBoolean(KEY_DISABLE_LAUNCH_BOOST + configSuffix, 883 defaultPolicy.disableLaunchBoost)); 884 final boolean disableOptionalSensors = parser.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS, 885 properties.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS + configSuffix, 886 defaultPolicy.disableOptionalSensors)); 887 final boolean disableVibrationConfig = parser.getBoolean(KEY_DISABLE_VIBRATION, 888 properties.getBoolean(KEY_DISABLE_VIBRATION + configSuffix, 889 defaultPolicy.disableVibration)); 890 final boolean enableBrightnessAdjustment = parser.getBoolean( 891 KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, 892 properties.getBoolean(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix, 893 defaultPolicy.enableAdjustBrightness)); 894 final boolean enableDataSaver = parser.getBoolean(KEY_ENABLE_DATASAVER, 895 properties.getBoolean(KEY_ENABLE_DATASAVER + configSuffix, 896 defaultPolicy.enableDataSaver)); 897 final boolean enableFirewall = parser.getBoolean(KEY_ENABLE_FIREWALL, 898 properties.getBoolean(KEY_ENABLE_FIREWALL + configSuffix, 899 defaultPolicy.enableFirewall)); 900 final boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE, 901 properties.getBoolean(KEY_ENABLE_NIGHT_MODE + configSuffix, 902 defaultPolicy.enableNightMode)); 903 final boolean enableQuickDoze = parser.getBoolean(KEY_ENABLE_QUICK_DOZE, 904 properties.getBoolean(KEY_ENABLE_QUICK_DOZE + configSuffix, 905 defaultPolicy.enableQuickDoze)); 906 final boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY, 907 properties.getBoolean(KEY_FORCE_ALL_APPS_STANDBY + configSuffix, 908 defaultPolicy.forceAllAppsStandby)); 909 final boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, 910 properties.getBoolean(KEY_FORCE_BACKGROUND_CHECK + configSuffix, 911 defaultPolicy.forceBackgroundCheck)); 912 final int locationMode = parser.getInt(KEY_LOCATION_MODE, 913 properties.getInt(KEY_LOCATION_MODE + configSuffix, 914 defaultPolicy.locationMode)); 915 final int soundTriggerMode = parser.getInt(KEY_SOUNDTRIGGER_MODE, 916 properties.getInt(KEY_SOUNDTRIGGER_MODE + configSuffix, 917 defaultPolicy.soundTriggerMode)); 918 return new Policy( 919 adjustBrightnessFactor, 920 advertiseIsEnabled, 921 (new CpuFrequencies()).parseString(cpuFreqInteractive), 922 (new CpuFrequencies()).parseString(cpuFreqNoninteractive), 923 deferFullBackup, 924 deferKeyValueBackup, 925 disableAnimation, 926 disableAod, 927 disableLaunchBoost, 928 disableOptionalSensors, 929 /* disableVibration */ 930 disableVibrationConfig, 931 enableBrightnessAdjustment, 932 enableDataSaver, 933 enableFirewall, 934 enableNightMode, 935 enableQuickDoze, 936 forceAllAppsStandby, 937 forceBackgroundCheck, 938 locationMode, 939 soundTriggerMode 940 ); 941 } 942 943 @Override equals(Object obj)944 public boolean equals(Object obj) { 945 if (this == obj) return true; 946 if (!(obj instanceof Policy)) return false; 947 Policy other = (Policy) obj; 948 return Float.compare(other.adjustBrightnessFactor, adjustBrightnessFactor) == 0 949 && advertiseIsEnabled == other.advertiseIsEnabled 950 && deferFullBackup == other.deferFullBackup 951 && deferKeyValueBackup == other.deferKeyValueBackup 952 && disableAnimation == other.disableAnimation 953 && disableAod == other.disableAod 954 && disableLaunchBoost == other.disableLaunchBoost 955 && disableOptionalSensors == other.disableOptionalSensors 956 && disableVibration == other.disableVibration 957 && enableAdjustBrightness == other.enableAdjustBrightness 958 && enableDataSaver == other.enableDataSaver 959 && enableFirewall == other.enableFirewall 960 && enableNightMode == other.enableNightMode 961 && enableQuickDoze == other.enableQuickDoze 962 && forceAllAppsStandby == other.forceAllAppsStandby 963 && forceBackgroundCheck == other.forceBackgroundCheck 964 && locationMode == other.locationMode 965 && soundTriggerMode == other.soundTriggerMode 966 && cpuFrequenciesForInteractive.equals(other.cpuFrequenciesForInteractive) 967 && cpuFrequenciesForNoninteractive.equals( 968 other.cpuFrequenciesForNoninteractive); 969 } 970 971 @Override hashCode()972 public int hashCode() { 973 return mHashCode; 974 } 975 } 976 977 /** 978 * Get the {@link PowerSaveState} based on the current policy level. 979 * The result will have {@link PowerSaveState#batterySaverEnabled} and some other 980 * parameters when necessary. 981 * 982 * @param type type of the service, one of {@link ServiceType} 983 * @return State data that contains battery saver data 984 */ getBatterySaverPolicy(@erviceType int type)985 public PowerSaveState getBatterySaverPolicy(@ServiceType int type) { 986 synchronized (mLock) { 987 final Policy currPolicy = getCurrentPolicyLocked(); 988 final PowerSaveState.Builder builder = new PowerSaveState.Builder() 989 .setGlobalBatterySaverEnabled(currPolicy.advertiseIsEnabled); 990 switch (type) { 991 case ServiceType.LOCATION: 992 boolean isEnabled = currPolicy.advertiseIsEnabled 993 || currPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE; 994 return builder.setBatterySaverEnabled(isEnabled) 995 .setLocationMode(currPolicy.locationMode) 996 .build(); 997 case ServiceType.ANIMATION: 998 return builder.setBatterySaverEnabled(currPolicy.disableAnimation) 999 .build(); 1000 case ServiceType.FULL_BACKUP: 1001 return builder.setBatterySaverEnabled(currPolicy.deferFullBackup) 1002 .build(); 1003 case ServiceType.KEYVALUE_BACKUP: 1004 return builder.setBatterySaverEnabled(currPolicy.deferKeyValueBackup) 1005 .build(); 1006 case ServiceType.NETWORK_FIREWALL: 1007 return builder.setBatterySaverEnabled(currPolicy.enableFirewall) 1008 .build(); 1009 case ServiceType.SCREEN_BRIGHTNESS: 1010 return builder.setBatterySaverEnabled(currPolicy.enableAdjustBrightness) 1011 .setBrightnessFactor(currPolicy.adjustBrightnessFactor) 1012 .build(); 1013 case ServiceType.DATA_SAVER: 1014 return builder.setBatterySaverEnabled(currPolicy.enableDataSaver) 1015 .build(); 1016 case ServiceType.SOUND: 1017 boolean soundTriggerBatterySaverEnabled = currPolicy.advertiseIsEnabled 1018 || currPolicy.soundTriggerMode 1019 != PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED; 1020 return builder.setBatterySaverEnabled(soundTriggerBatterySaverEnabled) 1021 .setSoundTriggerMode(currPolicy.soundTriggerMode) 1022 .build(); 1023 case ServiceType.VIBRATION: 1024 return builder.setBatterySaverEnabled(currPolicy.disableVibration) 1025 .build(); 1026 case ServiceType.FORCE_ALL_APPS_STANDBY: 1027 return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby) 1028 .build(); 1029 case ServiceType.FORCE_BACKGROUND_CHECK: 1030 return builder.setBatterySaverEnabled(currPolicy.forceBackgroundCheck) 1031 .build(); 1032 case ServiceType.NIGHT_MODE: 1033 return builder.setBatterySaverEnabled(currPolicy.enableNightMode) 1034 .build(); 1035 case ServiceType.OPTIONAL_SENSORS: 1036 return builder.setBatterySaverEnabled(currPolicy.disableOptionalSensors) 1037 .build(); 1038 case ServiceType.AOD: 1039 return builder.setBatterySaverEnabled(currPolicy.disableAod) 1040 .build(); 1041 case ServiceType.QUICK_DOZE: 1042 return builder.setBatterySaverEnabled(currPolicy.enableQuickDoze) 1043 .build(); 1044 default: 1045 return builder.setBatterySaverEnabled(currPolicy.advertiseIsEnabled) 1046 .build(); 1047 } 1048 } 1049 } 1050 1051 /** 1052 * Sets the current policy. 1053 * 1054 * @return true if the policy level was changed. 1055 */ setPolicyLevel(@olicyLevel int level)1056 boolean setPolicyLevel(@PolicyLevel int level) { 1057 synchronized (mLock) { 1058 if (mPolicyLevel == level) { 1059 return false; 1060 } 1061 // If we are leaving the full policy level, then any overrides to the full policy set 1062 // through #setFullPolicyLocked should be cleared. 1063 if (mPolicyLevel == POLICY_LEVEL_FULL) { 1064 mFullPolicy = mDefaultFullPolicy; 1065 } 1066 switch (level) { 1067 case POLICY_LEVEL_FULL: 1068 case POLICY_LEVEL_ADAPTIVE: 1069 case POLICY_LEVEL_OFF: 1070 mPolicyLevel = level; 1071 break; 1072 default: 1073 Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level); 1074 return false; 1075 } 1076 updatePolicyDependenciesLocked(); 1077 return true; 1078 } 1079 } 1080 1081 /** 1082 * Get the current policy for the provided policy level. 1083 */ getPolicyLocked(@olicyLevel int policyLevel)1084 Policy getPolicyLocked(@PolicyLevel int policyLevel) { 1085 switch (policyLevel) { 1086 case POLICY_LEVEL_OFF: 1087 return OFF_POLICY; 1088 case POLICY_LEVEL_ADAPTIVE: 1089 return mAdaptivePolicy; 1090 case POLICY_LEVEL_FULL: 1091 return mFullPolicy; 1092 } 1093 1094 throw new IllegalArgumentException( 1095 "getPolicyLocked: incorrect policy level provided - " + policyLevel); 1096 } 1097 1098 /** 1099 * Updates the default policy with the passed in policy. 1100 * If the full policy is not overridden with runtime settings, then the full policy will be 1101 * updated. 1102 * 1103 * @return True if the active policy requires an update, false if not. 1104 */ maybeUpdateDefaultFullPolicy(Policy p)1105 private boolean maybeUpdateDefaultFullPolicy(Policy p) { 1106 boolean fullPolicyChanged = false; 1107 if (!mDefaultFullPolicy.equals(p)) { 1108 // default policy can be overridden by #setFullPolicyLocked 1109 boolean isDefaultFullPolicyOverridden = !mDefaultFullPolicy.equals(mFullPolicy); 1110 if (!isDefaultFullPolicyOverridden) { 1111 mFullPolicy = p; 1112 fullPolicyChanged = (mPolicyLevel == POLICY_LEVEL_FULL); 1113 } 1114 mDefaultFullPolicy = p; 1115 } 1116 return fullPolicyChanged; 1117 } 1118 1119 /** @return true if the current policy changed and the policy level is FULL. */ setFullPolicyLocked(Policy p)1120 boolean setFullPolicyLocked(Policy p) { 1121 if (p == null) { 1122 Slog.wtf(TAG, "setFullPolicy given null policy"); 1123 return false; 1124 } 1125 if (mFullPolicy.equals(p)) { 1126 return false; 1127 } 1128 1129 mFullPolicy = p; 1130 if (mPolicyLevel == POLICY_LEVEL_FULL) { 1131 updatePolicyDependenciesLocked(); 1132 return true; 1133 } 1134 return false; 1135 } 1136 1137 /** @return true if the current policy changed and the policy level is ADAPTIVE. */ setAdaptivePolicyLocked(Policy p)1138 boolean setAdaptivePolicyLocked(Policy p) { 1139 if (p == null) { 1140 Slog.wtf(TAG, "setAdaptivePolicy given null policy"); 1141 return false; 1142 } 1143 if (mAdaptivePolicy.equals(p)) { 1144 return false; 1145 } 1146 1147 mAdaptivePolicy = p; 1148 if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE) { 1149 updatePolicyDependenciesLocked(); 1150 return true; 1151 } 1152 return false; 1153 } 1154 1155 /** @return true if the current policy changed and the policy level is ADAPTIVE. */ resetAdaptivePolicyLocked()1156 boolean resetAdaptivePolicyLocked() { 1157 return setAdaptivePolicyLocked(mDefaultAdaptivePolicy); 1158 } 1159 getCurrentPolicyLocked()1160 private Policy getCurrentPolicyLocked() { 1161 return mEffectivePolicyRaw; 1162 } 1163 getCurrentRawPolicyLocked()1164 private Policy getCurrentRawPolicyLocked() { 1165 switch (mPolicyLevel) { 1166 case POLICY_LEVEL_FULL: 1167 return mFullPolicy; 1168 case POLICY_LEVEL_ADAPTIVE: 1169 return mAdaptivePolicy; 1170 case POLICY_LEVEL_OFF: 1171 default: 1172 return OFF_POLICY; 1173 } 1174 } 1175 getGpsMode()1176 public int getGpsMode() { 1177 synchronized (mLock) { 1178 return getCurrentPolicyLocked().locationMode; 1179 } 1180 } 1181 getFileValues(boolean interactive)1182 public ArrayMap<String, String> getFileValues(boolean interactive) { 1183 synchronized (mLock) { 1184 return interactive 1185 ? getCurrentPolicyLocked().cpuFrequenciesForInteractive.toSysFileMap() 1186 : getCurrentPolicyLocked().cpuFrequenciesForNoninteractive.toSysFileMap(); 1187 } 1188 } 1189 isLaunchBoostDisabled()1190 public boolean isLaunchBoostDisabled() { 1191 synchronized (mLock) { 1192 return getCurrentPolicyLocked().disableLaunchBoost; 1193 } 1194 } 1195 shouldAdvertiseIsEnabled()1196 boolean shouldAdvertiseIsEnabled() { 1197 synchronized (mLock) { 1198 return getCurrentPolicyLocked().advertiseIsEnabled; 1199 } 1200 } 1201 toEventLogString()1202 public String toEventLogString() { 1203 synchronized (mLock) { 1204 return mEventLogKeys; 1205 } 1206 } 1207 dump(PrintWriter pw)1208 public void dump(PrintWriter pw) { 1209 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1210 1211 synchronized (mLock) { 1212 ipw.println(); 1213 mBatterySavingStats.dump(ipw); 1214 1215 ipw.println(); 1216 ipw.println("Battery saver policy (*NOTE* they only apply when battery saver is ON):"); 1217 ipw.increaseIndent(); 1218 ipw.println("Settings: " + Settings.Global.BATTERY_SAVER_CONSTANTS); 1219 ipw.increaseIndent(); 1220 ipw.println("value: " + mSettings); 1221 ipw.decreaseIndent(); 1222 ipw.println("Settings: " + mDeviceSpecificSettingsSource); 1223 ipw.increaseIndent(); 1224 ipw.println("value: " + mDeviceSpecificSettings); 1225 ipw.decreaseIndent(); 1226 ipw.println("DeviceConfig: " + DeviceConfig.NAMESPACE_BATTERY_SAVER); 1227 ipw.increaseIndent(); 1228 final Set<String> keys = mLastDeviceConfigProperties.getKeyset(); 1229 if (keys.size() == 0) { 1230 ipw.println("N/A"); 1231 } else { 1232 for (final String key : keys) { 1233 ipw.print(key); 1234 ipw.print(": "); 1235 ipw.println(mLastDeviceConfigProperties.getString(key, null)); 1236 } 1237 } 1238 ipw.decreaseIndent(); 1239 1240 ipw.println("mAccessibilityEnabled=" + mAccessibilityEnabled.get()); 1241 ipw.println("mAutomotiveProjectionActive=" + mAutomotiveProjectionActive.get()); 1242 ipw.println("mPolicyLevel=" + mPolicyLevel); 1243 1244 dumpPolicyLocked(ipw, "default full", mDefaultFullPolicy); 1245 dumpPolicyLocked(ipw, "current full", mFullPolicy); 1246 dumpPolicyLocked(ipw, "default adaptive", mDefaultAdaptivePolicy); 1247 dumpPolicyLocked(ipw, "current adaptive", mAdaptivePolicy); 1248 dumpPolicyLocked(ipw, "effective", mEffectivePolicyRaw); 1249 1250 ipw.decreaseIndent(); 1251 } 1252 } 1253 dumpPolicyLocked(IndentingPrintWriter pw, String label, Policy p)1254 private void dumpPolicyLocked(IndentingPrintWriter pw, String label, Policy p) { 1255 pw.println(); 1256 pw.println("Policy '" + label + "'"); 1257 pw.increaseIndent(); 1258 pw.println(KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled); 1259 pw.println(KEY_DISABLE_VIBRATION + "=" + p.disableVibration); 1260 pw.println(KEY_DISABLE_ANIMATION + "=" + p.disableAnimation); 1261 pw.println(KEY_DEFER_FULL_BACKUP + "=" + p.deferFullBackup); 1262 pw.println(KEY_DEFER_KEYVALUE_BACKUP + "=" + p.deferKeyValueBackup); 1263 pw.println(KEY_ENABLE_FIREWALL + "=" + p.enableFirewall); 1264 pw.println(KEY_ENABLE_DATASAVER + "=" + p.enableDataSaver); 1265 pw.println(KEY_DISABLE_LAUNCH_BOOST + "=" + p.disableLaunchBoost); 1266 pw.println(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + "=" + p.enableAdjustBrightness); 1267 pw.println(KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + p.adjustBrightnessFactor); 1268 pw.println(KEY_LOCATION_MODE + "=" + p.locationMode); 1269 pw.println(KEY_FORCE_ALL_APPS_STANDBY + "=" + p.forceAllAppsStandby); 1270 pw.println(KEY_FORCE_BACKGROUND_CHECK + "=" + p.forceBackgroundCheck); 1271 pw.println(KEY_DISABLE_OPTIONAL_SENSORS + "=" + p.disableOptionalSensors); 1272 pw.println(KEY_DISABLE_AOD + "=" + p.disableAod); 1273 pw.println(KEY_SOUNDTRIGGER_MODE + "=" + p.soundTriggerMode); 1274 pw.println(KEY_ENABLE_QUICK_DOZE + "=" + p.enableQuickDoze); 1275 pw.println(KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode); 1276 1277 pw.println("Interactive File values:"); 1278 pw.increaseIndent(); 1279 dumpMap(pw, p.cpuFrequenciesForInteractive.toSysFileMap()); 1280 pw.decreaseIndent(); 1281 pw.println(); 1282 1283 pw.println("Noninteractive File values:"); 1284 pw.increaseIndent(); 1285 dumpMap(pw, p.cpuFrequenciesForNoninteractive.toSysFileMap()); 1286 pw.decreaseIndent(); 1287 1288 // Decrease from indent right after "Policy" line 1289 pw.decreaseIndent(); 1290 } 1291 dumpMap(PrintWriter pw, ArrayMap<String, String> map)1292 private void dumpMap(PrintWriter pw, ArrayMap<String, String> map) { 1293 if (map == null || map.size() == 0) { 1294 pw.println("N/A"); 1295 return; 1296 } 1297 final int size = map.size(); 1298 for (int i = 0; i < size; i++) { 1299 pw.print(map.keyAt(i)); 1300 pw.print(": '"); 1301 pw.print(map.valueAt(i)); 1302 pw.println("'"); 1303 } 1304 } 1305 1306 /** 1307 * A boolean value which should trigger a policy update when it changes. 1308 */ 1309 @VisibleForTesting 1310 class PolicyBoolean { 1311 private final String mDebugName; 1312 @GuardedBy("mLock") 1313 private boolean mValue; 1314 PolicyBoolean(String debugName)1315 private PolicyBoolean(String debugName) { 1316 mDebugName = debugName; 1317 } 1318 1319 /** Sets the initial value without triggering a policy update. */ initialize(boolean initialValue)1320 private void initialize(boolean initialValue) { 1321 synchronized (mLock) { 1322 mValue = initialValue; 1323 } 1324 } 1325 get()1326 private boolean get() { 1327 synchronized (mLock) { 1328 return mValue; 1329 } 1330 } 1331 1332 /** Sets a value, which if different from the current value, triggers a policy update. */ 1333 @VisibleForTesting update(boolean newValue)1334 void update(boolean newValue) { 1335 synchronized (mLock) { 1336 if (mValue != newValue) { 1337 Slog.d(TAG, mDebugName + " changed to " + newValue + ", updating policy."); 1338 mValue = newValue; 1339 updatePolicyDependenciesLocked(); 1340 maybeNotifyListenersOfPolicyChange(); 1341 } 1342 } 1343 } 1344 } 1345 } 1346