summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/PowerManager.java69
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java1
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java325
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java41
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java150
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java5
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java67
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java11
13 files changed, 475 insertions, 213 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2fff595d7150..45e777c7d01b 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -44,70 +44,10 @@ import java.util.concurrent.Executor;
* <p>
* <b>Device battery life will be significantly affected by the use of this API.</b>
* Do not acquire {@link WakeLock}s unless you really need them, use the minimum levels
- * possible, and be sure to release them as soon as possible.
- * </p><p>
- * The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}.
- * This will create a {@link PowerManager.WakeLock} object. You can then use methods
- * on the wake lock object to control the power state of the device.
- * </p><p>
- * In practice it's quite simple:
- * {@samplecode
- * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- * PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
- * wl.acquire();
- * ..screen will stay on during this section..
- * wl.release();
- * }
- * </p><p>
- * The following wake lock levels are defined, with varying effects on system power.
- * <i>These levels are mutually exclusive - you may only specify one of them.</i>
+ * possible, and be sure to release them as soon as possible. In most cases,
+ * you'll want to use
+ * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead.
*
- * <table>
- * <tr><th>Flag Value</th>
- * <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr>
- *
- * <tr><td>{@link #PARTIAL_WAKE_LOCK}</td>
- * <td>On*</td> <td>Off</td> <td>Off</td>
- * </tr>
- *
- * <tr><td>{@link #SCREEN_DIM_WAKE_LOCK}</td>
- * <td>On</td> <td>Dim</td> <td>Off</td>
- * </tr>
- *
- * <tr><td>{@link #SCREEN_BRIGHT_WAKE_LOCK}</td>
- * <td>On</td> <td>Bright</td> <td>Off</td>
- * </tr>
- *
- * <tr><td>{@link #FULL_WAKE_LOCK}</td>
- * <td>On</td> <td>Bright</td> <td>Bright</td>
- * </tr>
- * </table>
- * </p><p>
- * *<i>If you hold a partial wake lock, the CPU will continue to run, regardless of any
- * display timeouts or the state of the screen and even after the user presses the power button.
- * In all other wake locks, the CPU will run, but the user can still put the device to sleep
- * using the power button.</i>
- * </p><p>
- * In addition, you can add two more flags, which affect behavior of the screen only.
- * <i>These flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i></p>
- *
- * <table>
- * <tr><th>Flag Value</th> <th>Description</th></tr>
- *
- * <tr><td>{@link #ACQUIRE_CAUSES_WAKEUP}</td>
- * <td>Normal wake locks don't actually turn on the illumination. Instead, they cause
- * the illumination to remain on once it turns on (e.g. from user activity). This flag
- * will force the screen and/or keyboard to turn on immediately, when the WakeLock is
- * acquired. A typical use would be for notifications which are important for the user to
- * see immediately.</td>
- * </tr>
- *
- * <tr><td>{@link #ON_AFTER_RELEASE}</td>
- * <td>If this flag is set, the user activity timer will be reset when the WakeLock is
- * released, causing the illumination to remain on a bit longer. This can be used to
- * reduce flicker if you are cycling between wake lock conditions.</td>
- * </tr>
- * </table>
* <p>
* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
* permission in an {@code <uses-permission>} element of the application's manifest.
@@ -914,7 +854,8 @@ public final class PowerManager {
* {@link #FULL_WAKE_LOCK}, {@link #SCREEN_DIM_WAKE_LOCK}
* and {@link #SCREEN_BRIGHT_WAKE_LOCK}. Exactly one wake lock level must be
* specified as part of the {@code levelAndFlags} parameter.
- * </p><p>
+ * </p>
+ * <p>
* The wake lock flags are: {@link #ACQUIRE_CAUSES_WAKEUP}
* and {@link #ON_AFTER_RELEASE}. Multiple flags can be combined as part of the
* {@code levelAndFlags} parameters.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ce3f403c230d..1ee6120aa66b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16131,7 +16131,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* by the most recent call to {@link #measure(int, int)}. This result is a bit mask
* as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
* This should be used during measurement and layout calculations only. Use
- * {@link #getHeight()} to see how wide a view is after layout.
+ * {@link #getHeight()} to see how high a view is after layout.
*
* @return The measured height of this view as a bit mask.
*/
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 457308498398..3113004a406d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1868,6 +1868,7 @@ public class BatteryStatsImpl extends BatteryStats {
mCount = computeCurrentCountLocked();
mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0;
mUnpluggedReportedCount = mCurrentReportedCount = 0;
+ mTrackingReportedValues = false;
}
public void setUpdateVersion(int version) {
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index b7b02a3d61f1..874d99edc02a 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -732,6 +732,7 @@ public class SettingsBackupTest {
Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.TAP_GESTURE,
+ Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable
Settings.Secure.FACE_UNLOCK_RE_ENROLL);
@Test
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 6b1ceae4bed8..1d9e4ae890eb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -176,6 +176,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
static final String KEY_CARRIER_AP_EAP_TYPE = "key_carrier_ap_eap_type";
static final String KEY_CARRIER_NAME = "key_carrier_name";
static final String KEY_EAPTYPE = "eap_psktype";
+ static final String KEY_IS_PSK_SAE_TRANSITION_MODE = "key_is_psk_sae_transition_mode";
+ static final String KEY_IS_OWE_TRANSITION_MODE = "key_is_owe_transition_mode";
static final AtomicInteger sLastId = new AtomicInteger(0);
/*
@@ -190,15 +192,12 @@ public class AccessPoint implements Comparable<AccessPoint> {
public static final int SECURITY_OWE = 4;
public static final int SECURITY_SAE = 5;
public static final int SECURITY_EAP_SUITE_B = 6;
- public static final int SECURITY_PSK_SAE_TRANSITION = 7;
- public static final int SECURITY_OWE_TRANSITION = 8;
- public static final int SECURITY_MAX_VAL = 9; // Has to be the last
+ public static final int SECURITY_MAX_VAL = 7; // Has to be the last
private static final int PSK_UNKNOWN = 0;
private static final int PSK_WPA = 1;
private static final int PSK_WPA2 = 2;
private static final int PSK_WPA_WPA2 = 3;
- private static final int PSK_SAE = 4;
private static final int EAP_UNKNOWN = 0;
private static final int EAP_WPA = 1; // WPA-EAP
@@ -259,6 +258,9 @@ public class AccessPoint implements Comparable<AccessPoint> {
private String mOsuFailure;
private boolean mOsuProvisioningComplete = false;
+ private boolean mIsPskSaeTransitionMode = false;
+ private boolean mIsOweTransitionMode = false;
+
/**
* The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP.
*/
@@ -322,6 +324,13 @@ public class AccessPoint implements Comparable<AccessPoint> {
if (savedState.containsKey(KEY_CARRIER_NAME)) {
mCarrierName = savedState.getString(KEY_CARRIER_NAME);
}
+ if (savedState.containsKey(KEY_IS_PSK_SAE_TRANSITION_MODE)) {
+ mIsPskSaeTransitionMode = savedState.getBoolean(KEY_IS_PSK_SAE_TRANSITION_MODE);
+ }
+ if (savedState.containsKey(KEY_IS_OWE_TRANSITION_MODE)) {
+ mIsOweTransitionMode = savedState.getBoolean(KEY_IS_OWE_TRANSITION_MODE);
+ }
+
update(mConfig, mInfo, mNetworkInfo);
// Calculate required fields
@@ -647,8 +656,15 @@ public class AccessPoint implements Comparable<AccessPoint> {
return oldMetering == mIsScoredNetworkMetered;
}
- public static String getKey(ScanResult result) {
- return getKey(result.SSID, result.BSSID, getSecurity(result));
+ /**
+ * Generates an AccessPoint key for a given scan result
+ *
+ * @param context
+ * @param result Scan result
+ * @return AccessPoint key
+ */
+ public static String getKey(Context context, ScanResult result) {
+ return getKey(result.SSID, result.BSSID, getSecurity(context, result));
}
/**
@@ -706,7 +722,42 @@ public class AccessPoint implements Comparable<AccessPoint> {
* Determines if the other AccessPoint represents the same network as this AccessPoint
*/
public boolean matches(AccessPoint other) {
- return getKey().equals(other.getKey());
+ if (isPasspoint() || isPasspointConfig() || isOsuProvider()) {
+ return getKey().equals(other.getKey());
+ }
+
+ if (!isSameSsidOrBssid(other)) {
+ return false;
+ }
+
+ final int otherApSecurity = other.getSecurity();
+ if (mIsPskSaeTransitionMode) {
+ if (otherApSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) {
+ return true;
+ } else if (otherApSecurity == SECURITY_PSK) {
+ return true;
+ }
+ } else {
+ if ((security == SECURITY_SAE || security == SECURITY_PSK)
+ && other.isPskSaeTransitionMode()) {
+ return true;
+ }
+ }
+
+ if (mIsOweTransitionMode) {
+ if (otherApSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {
+ return true;
+ } else if (otherApSecurity == SECURITY_NONE) {
+ return true;
+ }
+ } else {
+ if ((security == SECURITY_OWE || security == SECURITY_NONE)
+ && other.isOweTransitionMode()) {
+ return true;
+ }
+ }
+
+ return security == other.getSecurity();
}
public boolean matches(WifiConfiguration config) {
@@ -720,18 +771,77 @@ public class AccessPoint implements Comparable<AccessPoint> {
}
final int configSecurity = getSecurity(config);
- final WifiManager wifiManager = getWifiManager();
- switch (security) {
- case SECURITY_PSK_SAE_TRANSITION:
- return configSecurity == SECURITY_PSK
- || (wifiManager.isWpa3SaeSupported() && configSecurity == SECURITY_SAE);
- case SECURITY_OWE_TRANSITION:
- return configSecurity == SECURITY_NONE
- || (wifiManager.isEnhancedOpenSupported()
- && configSecurity == SECURITY_OWE);
- default:
- return security == configSecurity;
+ if (mIsPskSaeTransitionMode) {
+ if (configSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) {
+ return true;
+ } else if (configSecurity == SECURITY_PSK) {
+ return true;
+ }
+ }
+
+ if (mIsOweTransitionMode) {
+ if (configSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {
+ return true;
+ } else if (configSecurity == SECURITY_NONE) {
+ return true;
+ }
+ }
+
+ return security == getSecurity(config);
+ }
+
+ private boolean matches(WifiConfiguration config, WifiInfo wifiInfo) {
+ if (config == null || wifiInfo == null) {
+ return false;
+ }
+ if (!config.isPasspoint() && !isSameSsidOrBssid(wifiInfo)) {
+ return false;
+ }
+ return matches(config);
+ }
+
+ @VisibleForTesting
+ boolean matches(ScanResult scanResult) {
+ if (scanResult == null) {
+ return false;
+ }
+ if (isPasspoint() || isOsuProvider()) {
+ throw new IllegalStateException("Should not matches a Passpoint by ScanResult");
+ }
+
+ if (!isSameSsidOrBssid(scanResult)) {
+ return false;
+ }
+
+ if (mIsPskSaeTransitionMode) {
+ if (scanResult.capabilities.contains("SAE")
+ && getWifiManager().isWpa3SaeSupported()) {
+ return true;
+ } else if (scanResult.capabilities.contains("PSK")) {
+ return true;
+ }
+ } else {
+ if ((security == SECURITY_SAE || security == SECURITY_PSK)
+ && AccessPoint.isPskSaeTransitionMode(scanResult)) {
+ return true;
+ }
+ }
+
+ if (mIsOweTransitionMode) {
+ final int scanResultSccurity = getSecurity(mContext, scanResult);
+ if (scanResultSccurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {
+ return true;
+ } else if (scanResultSccurity == SECURITY_NONE) {
+ return true;
+ }
+ } else {
+ if ((security == SECURITY_OWE || security == SECURITY_NONE)
+ && AccessPoint.isOweTransitionMode(scanResult)) {
+ return true;
+ }
}
+
+ return security == getSecurity(mContext, scanResult);
}
public WifiConfiguration getConfig() {
@@ -818,14 +928,17 @@ public class AccessPoint implements Comparable<AccessPoint> {
if (bestResult != null) {
ssid = bestResult.SSID;
bssid = bestResult.BSSID;
- security = getSecurity(bestResult);
- if (security == SECURITY_PSK || security == SECURITY_SAE
- || security == SECURITY_PSK_SAE_TRANSITION) {
+ security = getSecurity(mContext, bestResult);
+ if (security == SECURITY_PSK || security == SECURITY_SAE) {
pskType = getPskType(bestResult);
}
if (security == SECURITY_EAP) {
mEapType = getEapType(bestResult);
}
+
+ mIsPskSaeTransitionMode = AccessPoint.isPskSaeTransitionMode(bestResult);
+ mIsOweTransitionMode = AccessPoint.isOweTransitionMode(bestResult);
+
mIsCarrierAp = bestResult.isCarrierAp;
mCarrierApEapType = bestResult.carrierApEapType;
mCarrierName = bestResult.carrierName;
@@ -858,6 +971,12 @@ public class AccessPoint implements Comparable<AccessPoint> {
return concise ? context.getString(R.string.wifi_security_short_eap) :
context.getString(R.string.wifi_security_eap);
}
+
+ if (mIsPskSaeTransitionMode) {
+ return concise ? context.getString(R.string.wifi_security_short_psk_sae) :
+ context.getString(R.string.wifi_security_psk_sae);
+ }
+
switch(security) {
case SECURITY_EAP:
switch (mEapType) {
@@ -897,20 +1016,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
return concise ? context.getString(R.string.wifi_security_short_wep) :
context.getString(R.string.wifi_security_wep);
case SECURITY_SAE:
- case SECURITY_PSK_SAE_TRANSITION:
- if (pskType == PSK_SAE) {
- return concise ? context.getString(R.string.wifi_security_short_psk_sae) :
- context.getString(R.string.wifi_security_psk_sae);
- } else {
- return concise ? context.getString(R.string.wifi_security_short_sae) :
- context.getString(R.string.wifi_security_sae);
- }
- case SECURITY_OWE_TRANSITION:
- if (mConfig != null && getSecurity(mConfig) == SECURITY_OWE) {
- return concise ? context.getString(R.string.wifi_security_short_owe) :
- context.getString(R.string.wifi_security_owe);
- }
- return concise ? "" : context.getString(R.string.wifi_security_none);
+ return concise ? context.getString(R.string.wifi_security_short_sae) :
+ context.getString(R.string.wifi_security_sae);
case SECURITY_OWE:
return concise ? context.getString(R.string.wifi_security_short_owe) :
context.getString(R.string.wifi_security_owe);
@@ -1194,7 +1301,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
if (networkId != WifiConfiguration.INVALID_NETWORK_ID) {
return networkId == info.getNetworkId();
} else if (config != null) {
- return isKeyEqual(getKey(config));
+ return matches(config, info);
} else {
// Might be an ephemeral connection with no WifiConfiguration. Try matching on SSID.
// (Note that we only do this if the WifiConfiguration explicitly equals INVALID).
@@ -1220,8 +1327,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
* Can only be called for unsecured networks.
*/
public void generateOpenNetworkConfig() {
- if ((security != SECURITY_NONE) && (security != SECURITY_OWE)
- && (security != SECURITY_OWE_TRANSITION)) {
+ if ((security != SECURITY_NONE) && (security != SECURITY_OWE)) {
throw new IllegalStateException();
}
if (mConfig != null)
@@ -1264,43 +1370,14 @@ public class AccessPoint implements Comparable<AccessPoint> {
savedState.putBoolean(KEY_IS_CARRIER_AP, mIsCarrierAp);
savedState.putInt(KEY_CARRIER_AP_EAP_TYPE, mCarrierApEapType);
savedState.putString(KEY_CARRIER_NAME, mCarrierName);
+ savedState.putBoolean(KEY_IS_PSK_SAE_TRANSITION_MODE, mIsPskSaeTransitionMode);
+ savedState.putBoolean(KEY_IS_OWE_TRANSITION_MODE, mIsOweTransitionMode);
}
public void setListener(AccessPointListener listener) {
mAccessPointListener = listener;
}
- private static final String sPskSuffix = "," + String.valueOf(SECURITY_PSK);
- private static final String sSaeSuffix = "," + String.valueOf(SECURITY_SAE);
- private static final String sPskSaeSuffix = "," + String.valueOf(SECURITY_PSK_SAE_TRANSITION);
- private static final String sOweSuffix = "," + String.valueOf(SECURITY_OWE);
- private static final String sOpenSuffix = "," + String.valueOf(SECURITY_NONE);
- private static final String sOweTransSuffix = "," + String.valueOf(SECURITY_OWE_TRANSITION);
-
- private boolean isKeyEqual(String compareTo) {
- if (mKey == null) {
- return false;
- }
-
- if (compareTo.endsWith(sPskSuffix) || compareTo.endsWith(sSaeSuffix)) {
- if (mKey.endsWith(sPskSaeSuffix)) {
- // Special handling for PSK-SAE transition mode. If the AP has advertised both,
- // we compare the key with both PSK and SAE for a match.
- return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')),
- compareTo.substring(0, compareTo.lastIndexOf(',')));
- }
- }
- if (compareTo.endsWith(sOpenSuffix) || compareTo.endsWith(sOweSuffix)) {
- if (mKey.endsWith(sOweTransSuffix)) {
- // Special handling for OWE/Open networks. If AP advertises OWE in transition mode
- // and we have an Open network saved, allow this connection to be established.
- return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')),
- compareTo.substring(0, compareTo.lastIndexOf(',')));
- }
- }
- return mKey.equals(compareTo);
- }
-
/**
* Sets {@link #mScanResults} to the given collection and updates info based on the best RSSI
* scan result.
@@ -1317,11 +1394,10 @@ public class AccessPoint implements Comparable<AccessPoint> {
// Passpoint networks are not bound to a specific SSID/BSSID, so skip this for passpoint.
if (mKey != null && !isPasspoint() && !isOsuProvider()) {
for (ScanResult result : scanResults) {
- String scanResultKey = AccessPoint.getKey(result);
- if (!isKeyEqual(scanResultKey)) {
+ if (!matches(result)) {
Log.d(TAG, String.format(
- "ScanResult %s\nkey of %s did not match current AP key %s",
- result, scanResultKey, mKey));
+ "ScanResult %s\nkey of %s did not match current AP key %s",
+ result, getKey(mContext, result), mKey));
return;
}
}
@@ -1594,11 +1670,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
private static int getPskType(ScanResult result) {
boolean wpa = result.capabilities.contains("WPA-PSK");
boolean wpa2 = result.capabilities.contains("RSN-PSK");
- boolean wpa3TransitionMode = result.capabilities.contains("PSK+SAE");
boolean wpa3 = result.capabilities.contains("RSN-SAE");
- if (wpa3TransitionMode) {
- return PSK_SAE;
- } else if (wpa2 && wpa) {
+ if (wpa2 && wpa) {
return PSK_WPA_WPA2;
} else if (wpa2) {
return PSK_WPA2;
@@ -1625,22 +1698,37 @@ public class AccessPoint implements Comparable<AccessPoint> {
return EAP_UNKNOWN;
}
- private static int getSecurity(ScanResult result) {
- if (result.capabilities.contains("WEP")) {
+ private static int getSecurity(Context context, ScanResult result) {
+ final boolean isWep = result.capabilities.contains("WEP");
+ final boolean isSae = result.capabilities.contains("SAE");
+ final boolean isPsk = result.capabilities.contains("PSK");
+ final boolean isEapSuiteB192 = result.capabilities.contains("EAP_SUITE_B_192");
+ final boolean isEap = result.capabilities.contains("EAP");
+ final boolean isOwe = result.capabilities.contains("OWE");
+ final boolean isOweTransition = result.capabilities.contains("OWE_TRANSITION");
+
+ if (isSae && isPsk) {
+ final WifiManager wifiManager = (WifiManager)
+ context.getSystemService(Context.WIFI_SERVICE);
+ return wifiManager.isWpa3SaeSupported() ? SECURITY_SAE : SECURITY_PSK;
+ }
+ if (isOweTransition) {
+ final WifiManager wifiManager = (WifiManager)
+ context.getSystemService(Context.WIFI_SERVICE);
+ return wifiManager.isEnhancedOpenSupported() ? SECURITY_OWE : SECURITY_NONE;
+ }
+
+ if (isWep) {
return SECURITY_WEP;
- } else if (result.capabilities.contains("PSK+SAE")) {
- return SECURITY_PSK_SAE_TRANSITION;
- } else if (result.capabilities.contains("SAE")) {
+ } else if (isSae) {
return SECURITY_SAE;
- } else if (result.capabilities.contains("PSK")) {
+ } else if (isPsk) {
return SECURITY_PSK;
- } else if (result.capabilities.contains("EAP_SUITE_B_192")) {
+ } else if (isEapSuiteB192) {
return SECURITY_EAP_SUITE_B;
- } else if (result.capabilities.contains("EAP")) {
+ } else if (isEap) {
return SECURITY_EAP;
- } else if (result.capabilities.contains("OWE_TRANSITION")) {
- return SECURITY_OWE_TRANSITION;
- } else if (result.capabilities.contains("OWE")) {
+ } else if (isOwe) {
return SECURITY_OWE;
}
return SECURITY_NONE;
@@ -1686,10 +1774,6 @@ public class AccessPoint implements Comparable<AccessPoint> {
return "SUITE_B";
} else if (security == SECURITY_OWE) {
return "OWE";
- } else if (security == SECURITY_PSK_SAE_TRANSITION) {
- return "PSK+SAE";
- } else if (security == SECURITY_OWE_TRANSITION) {
- return "OWE_TRANSITION";
}
return "NONE";
}
@@ -1859,4 +1943,61 @@ public class AccessPoint implements Comparable<AccessPoint> {
}
}
}
+
+ public boolean isPskSaeTransitionMode() {
+ return mIsPskSaeTransitionMode;
+ }
+
+ public boolean isOweTransitionMode() {
+ return mIsOweTransitionMode;
+ }
+
+ private static boolean isPskSaeTransitionMode(ScanResult scanResult) {
+ return scanResult.capabilities.contains("PSK")
+ && scanResult.capabilities.contains("SAE");
+ }
+
+ private static boolean isOweTransitionMode(ScanResult scanResult) {
+ return scanResult.capabilities.contains("OWE_TRANSITION");
+ }
+
+ private boolean isSameSsidOrBssid(ScanResult scanResult) {
+ if (scanResult == null) {
+ return false;
+ }
+
+ if (TextUtils.equals(ssid, scanResult.SSID)) {
+ return true;
+ } else if (scanResult.BSSID != null && TextUtils.equals(bssid, scanResult.BSSID)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isSameSsidOrBssid(WifiInfo wifiInfo) {
+ if (wifiInfo == null) {
+ return false;
+ }
+
+ if (TextUtils.equals(ssid, removeDoubleQuotes(wifiInfo.getSSID()))) {
+ return true;
+ } else if (wifiInfo.getBSSID() != null && TextUtils.equals(bssid, wifiInfo.getBSSID())) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isSameSsidOrBssid(AccessPoint accessPoint) {
+ if (accessPoint == null) {
+ return false;
+ }
+
+ if (TextUtils.equals(ssid, accessPoint.getSsid())) {
+ return true;
+ } else if (accessPoint.getBssid() != null
+ && TextUtils.equals(bssid, accessPoint.getBssid())) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index dae546497aba..6269a717b333 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -201,8 +201,7 @@ public class AccessPointPreference extends Preference {
return;
}
if ((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE)
- && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE)
- && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE_TRANSITION)) {
+ && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) {
mFrictionSld.setState(STATE_SECURED);
} else if (mAccessPoint.isMetered()) {
mFrictionSld.setState(STATE_METERED);
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 3e359d216234..f1c5f46a30e8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -70,8 +70,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
/**
* Tracks saved or available wifi networks and their state.
@@ -475,7 +477,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
continue;
}
- String apKey = AccessPoint.getKey(result);
+ String apKey = AccessPoint.getKey(mContext, result);
List<ScanResult> resultList;
if (scanResultsByApKey.containsKey(apKey)) {
resultList = scanResultsByApKey.get(apKey);
@@ -548,14 +550,6 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
private void updateAccessPoints(final List<ScanResult> newScanResults,
List<WifiConfiguration> configs) {
- // Map configs and scan results necessary to make AccessPoints
- final Map<String, WifiConfiguration> configsByKey = new ArrayMap(configs.size());
- if (configs != null) {
- for (WifiConfiguration config : configs) {
- configsByKey.put(AccessPoint.getKey(config), config);
- }
- }
-
WifiConfiguration connectionConfig = null;
if (mLastInfo != null) {
connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(), configs);
@@ -587,7 +581,26 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
getCachedOrCreate(entry.getValue(), cachedAccessPoints);
// Update the matching config if there is one, to populate saved network info
- accessPoint.update(configsByKey.get(entry.getKey()));
+ final List<WifiConfiguration> matchedConfigs = configs.stream()
+ .filter(config -> accessPoint.matches(config))
+ .collect(Collectors.toList());
+
+ final int matchedConfigCount = matchedConfigs.size();
+ if (matchedConfigCount == 0) {
+ accessPoint.update(null);
+ } else if (matchedConfigCount == 1) {
+ accessPoint.update(matchedConfigs.get(0));
+ } else {
+ // We may have 2 matched configured WifiCongiguration if the AccessPoint is
+ // of PSK/SAE transition mode or open/OWE transition mode.
+ Optional<WifiConfiguration> preferredConfig = matchedConfigs.stream()
+ .filter(config -> isSaeOrOwe(config)).findFirst();
+ if (preferredConfig.isPresent()) {
+ accessPoint.update(preferredConfig.get());
+ } else {
+ accessPoint.update(matchedConfigs.get(0));
+ }
+ }
accessPoints.add(accessPoint);
}
@@ -653,6 +666,11 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
conditionallyNotifyListeners();
}
+ private static boolean isSaeOrOwe(WifiConfiguration config) {
+ final int security = AccessPoint.getSecurity(config);
+ return security == AccessPoint.SECURITY_SAE || security == AccessPoint.SECURITY_OWE;
+ }
+
@VisibleForTesting
List<AccessPoint> updatePasspointAccessPoints(
List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans,
@@ -701,7 +719,8 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
private AccessPoint getCachedOrCreate(
List<ScanResult> scanResults,
List<AccessPoint> cache) {
- AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(scanResults.get(0)));
+ AccessPoint accessPoint = getCachedByKey(cache,
+ AccessPoint.getKey(mContext, scanResults.get(0)));
if (accessPoint == null) {
accessPoint = new AccessPoint(mContext, scanResults);
} else {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index af4704c3618e..77473f52f4be 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -39,6 +39,7 @@ import android.net.ScoredNetwork;
import android.net.WifiKey;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -1272,7 +1273,7 @@ public class AccessPointTest {
@Test
public void testGetKey_matchesKeysCorrectly() {
AccessPoint ap = new AccessPoint(mContext, mScanResults);
- assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mScanResults.get(0)));
+ assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mContext, mScanResults.get(0)));
WifiConfiguration spyConfig = spy(new WifiConfiguration());
when(spyConfig.isPasspoint()).thenReturn(true);
@@ -1294,6 +1295,44 @@ public class AccessPointTest {
}
/**
+ * Test that getKey returns a key of SAE type for a PSK/SAE transition mode ScanResult.
+ */
+ @Test
+ public void testGetKey_supportSaeTransitionMode_shouldGetSaeKey() {
+ ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI);
+ scanResult.capabilities =
+ "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]";
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
+ when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+ StringBuilder key = new StringBuilder();
+ key.append(AccessPoint.KEY_PREFIX_AP);
+ key.append(TEST_SSID);
+ key.append(',');
+ key.append(AccessPoint.SECURITY_SAE);
+
+ assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString());
+ }
+
+ /**
+ * Test that getKey returns a key of PSK type for a PSK/SAE transition mode ScanResult.
+ */
+ @Test
+ public void testGetKey_notSupportSaeTransitionMode_shouldGetPskKey() {
+ ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI);
+ scanResult.capabilities =
+ "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]";
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false);
+ when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+ StringBuilder key = new StringBuilder();
+ key.append(AccessPoint.KEY_PREFIX_AP);
+ key.append(TEST_SSID);
+ key.append(',');
+ key.append(AccessPoint.SECURITY_PSK);
+
+ assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString());
+ }
+
+ /**
* Verifies that the Passpoint AccessPoint constructor creates AccessPoints whose isPasspoint()
* returns true.
*/
@@ -1522,4 +1561,113 @@ public class AccessPointTest {
verify(mMockConnectListener).onFailure(anyInt());
}
+
+ /**
+ * Verifies that matches(AccessPoint other) matches a PSK/SAE transition mode AP to a PSK or a
+ * SAE AP.
+ */
+ @Test
+ public void testMatches1_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() {
+ when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
+ AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+
+ // Transition mode AP matches a SAE AP.
+ AccessPoint saeAccessPoint = new TestAccessPointBuilder(mContext)
+ .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID))
+ .setSecurity(AccessPoint.SECURITY_SAE)
+ .build();
+ assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isTrue();
+
+ // Transition mode AP matches a PSK AP.
+ AccessPoint pskAccessPoint = new TestAccessPointBuilder(mContext)
+ .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID))
+ .setSecurity(AccessPoint.SECURITY_PSK)
+ .build();
+
+ assertThat(pskSaeTransitionModeAp.matches(pskAccessPoint)).isTrue();
+
+ // Transition mode AP does not match a SAE AP if the device does not support SAE.
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false);
+ pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+ saeAccessPoint = new TestAccessPointBuilder(mContext)
+ .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID))
+ .setSecurity(AccessPoint.SECURITY_SAE)
+ .build();
+
+ assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isFalse();
+ }
+
+ /**
+ * Verifies that matches(WifiConfiguration config) matches a PSK/SAE transition mode AP to a PSK
+ * or a SAE WifiConfiguration.
+ */
+ @Test
+ public void testMatches2_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() {
+ when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
+ AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+
+ // Transition mode AP matches a SAE WifiConfiguration.
+ WifiConfiguration saeConfig = new WifiConfiguration();
+ saeConfig.SSID = TEST_SSID;
+ saeConfig.allowedKeyManagement.set(KeyMgmt.SAE);
+
+ assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isTrue();
+
+ // Transition mode AP matches a PSK WifiConfiguration.
+ WifiConfiguration pskConfig = new WifiConfiguration();
+ pskConfig.SSID = TEST_SSID;
+ pskConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+
+ assertThat(pskSaeTransitionModeAp.matches(pskConfig)).isTrue();
+
+ // Transition mode AP does not matches a SAE WifiConfiguration if the device does not
+ // support SAE.
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false);
+ pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+
+ assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isFalse();
+ }
+
+ /**
+ * Verifies that matches(ScanResult scanResult) matches a PSK/SAE transition mode AP to a PSK
+ * or a SAE ScanResult.
+ */
+ @Test
+ public void testMatches3_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() {
+ when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
+ AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+
+ // Transition mode AP matches a SAE ScanResult.
+ ScanResult saeScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID),
+ TEST_BSSID, DEFAULT_RSSI);
+ saeScanResult.capabilities = "[SAE-CCMP][ESS][WPS]";
+
+ assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isTrue();
+
+ // Transition mode AP matches a PSK ScanResult.
+ ScanResult pskScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID),
+ TEST_BSSID, DEFAULT_RSSI);
+ pskScanResult.capabilities = "[RSN-PSK-CCMP][ESS][WPS]";
+
+ assertThat(pskSaeTransitionModeAp.matches(pskScanResult)).isTrue();
+
+ // Transition mode AP does not matches a SAE ScanResult if the device does not support SAE.
+ when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false);
+ pskSaeTransitionModeAp = getPskSaeTransitionModeAp();
+
+ assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isFalse();
+ }
+
+ private AccessPoint getPskSaeTransitionModeAp() {
+ ScanResult scanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID),
+ TEST_BSSID, DEFAULT_RSSI);
+ scanResult.capabilities =
+ "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]";
+ return new TestAccessPointBuilder(mMockContext)
+ .setScanResults(new ArrayList<ScanResult>(Arrays.asList(scanResult)))
+ .build();
+ }
}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index be1623b18826..72c0ba858b61 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -892,8 +892,8 @@
<string name="quick_settings_secondary_label_until">Until <xliff:g id="time" example="7 am">%s</xliff:g></string>
<!-- QuickSettings: Label for the toggle to activate dark theme (A.K.A Dark Mode). [CHAR LIMIT=20] -->
<string name="quick_settings_ui_mode_night_label">Dark theme</string>
- <!-- QuickSettings: Label for the dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
- <string name="quick_settings_ui_mode_night_label_battery_saver">Dark theme\nBattery saver</string>
+ <!-- QuickSettings: Secondary text for the dark theme tile when enabled by battery saver. [CHAR LIMIT=20] -->
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver">Battery Saver</string>
<!-- QuickSettings: Secondary text for when the Dark Mode will be enabled at sunset. [CHAR LIMIT=20] -->
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset">On at sunset</string>
<!-- QuickSettings: Secondary text for when the Dark Mode will be on until sunrise. [CHAR LIMIT=20] -->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index 54fbaf361745..107958f49b91 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -91,7 +91,10 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
boolean nightMode = (mContext.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
- if (isAuto && !powerSave) {
+ if (powerSave) {
+ state.secondaryLabel = mContext.getResources().getString(
+ R.string.quick_settings_dark_mode_secondary_label_battery_saver);
+ } else if (isAuto) {
state.secondaryLabel = mContext.getResources().getString(nightMode
? R.string.quick_settings_dark_mode_secondary_label_until_sunrise
: R.string.quick_settings_dark_mode_secondary_label_on_at_sunset);
@@ -99,9 +102,7 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
state.secondaryLabel = null;
}
state.value = nightMode;
- state.label = mContext.getString(powerSave
- ? R.string.quick_settings_ui_mode_night_label_battery_saver
- : R.string.quick_settings_ui_mode_night_label);
+ state.label = mContext.getString(R.string.quick_settings_ui_mode_night_label);
state.icon = mIcon;
state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
? state.label
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a589ca588fa7..c6dee5e9bdf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -694,6 +694,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mFalsingManager = Dependency.get(FalsingManager.class);
+ mWallpaperSupported =
+ mContext.getSystemService(WallpaperManager.class).isWallpaperSupported();
// Connect in to the status bar manager service
mCommandQueue = getComponent(CommandQueue.class);
@@ -708,9 +710,6 @@ public class StatusBar extends SystemUI implements DemoMode,
createAndAddWindows(result);
- mWallpaperSupported =
- mContext.getSystemService(WallpaperManager.class).isWallpaperSupported();
-
if (mWallpaperSupported) {
// Make sure we always have the most current wallpaper info.
IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index ff9129956a3b..a62bb74730f8 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -773,9 +773,9 @@ public class BatterySaverStateMachine {
// Handle triggering the notification to show/hide when appropriate
if (intReason == BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON) {
- runOnBgThread(this::triggerDynamicModeNotification);
+ triggerDynamicModeNotification();
} else if (!enable) {
- runOnBgThread(this::hideDynamicModeNotification);
+ hideDynamicModeNotification();
}
if (DEBUG) {
@@ -787,33 +787,42 @@ public class BatterySaverStateMachine {
@VisibleForTesting
void triggerDynamicModeNotification() {
- NotificationManager manager = mContext.getSystemService(NotificationManager.class);
- ensureNotificationChannelExists(manager, DYNAMIC_MODE_NOTIF_CHANNEL_ID,
- R.string.dynamic_mode_notification_channel_name);
-
- manager.notifyAsUser(TAG, DYNAMIC_MODE_NOTIFICATION_ID,
- buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID,
- mContext.getResources().getString(R.string.dynamic_mode_notification_title),
- R.string.dynamic_mode_notification_summary,
- Intent.ACTION_POWER_USAGE_SUMMARY),
- UserHandle.ALL);
+ // The current lock is the PowerManager lock, which sits very low in the service lock
+ // hierarchy. We shouldn't call out to NotificationManager with the PowerManager lock.
+ runOnBgThread(() -> {
+ NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ ensureNotificationChannelExists(manager, DYNAMIC_MODE_NOTIF_CHANNEL_ID,
+ R.string.dynamic_mode_notification_channel_name);
+
+ manager.notifyAsUser(TAG, DYNAMIC_MODE_NOTIFICATION_ID,
+ buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID,
+ mContext.getResources().getString(
+ R.string.dynamic_mode_notification_title),
+ R.string.dynamic_mode_notification_summary,
+ Intent.ACTION_POWER_USAGE_SUMMARY),
+ UserHandle.ALL);
+ });
}
@VisibleForTesting
void triggerStickyDisabledNotification() {
- NotificationManager manager = mContext.getSystemService(NotificationManager.class);
- ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
- R.string.battery_saver_notification_channel_name);
-
- final String percentage = NumberFormat.getPercentInstance()
- .format((double) mBatteryLevel / 100.0);
- manager.notifyAsUser(TAG, STICKY_AUTO_DISABLED_NOTIFICATION_ID,
- buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID,
- mContext.getResources().getString(
- R.string.battery_saver_charged_notification_title, percentage),
- R.string.battery_saver_off_notification_summary,
- Settings.ACTION_BATTERY_SAVER_SETTINGS),
- UserHandle.ALL);
+ // The current lock is the PowerManager lock, which sits very low in the service lock
+ // hierarchy. We shouldn't call out to NotificationManager with the PowerManager lock.
+ runOnBgThread(() -> {
+ NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
+ R.string.battery_saver_notification_channel_name);
+
+ final String percentage = NumberFormat.getPercentInstance()
+ .format((double) mBatteryLevel / 100.0);
+ manager.notifyAsUser(TAG, STICKY_AUTO_DISABLED_NOTIFICATION_ID,
+ buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID,
+ mContext.getResources().getString(
+ R.string.battery_saver_charged_notification_title, percentage),
+ R.string.battery_saver_off_notification_summary,
+ Settings.ACTION_BATTERY_SAVER_SETTINGS),
+ UserHandle.ALL);
+ });
}
private void ensureNotificationChannelExists(NotificationManager manager,
@@ -854,8 +863,12 @@ public class BatterySaverStateMachine {
}
private void hideNotification(int notificationId) {
- NotificationManager manager = mContext.getSystemService(NotificationManager.class);
- manager.cancel(notificationId);
+ // The current lock is the PowerManager lock, which sits very low in the service lock
+ // hierarchy. We shouldn't call out to NotificationManager with the PowerManager lock.
+ runOnBgThread(() -> {
+ NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ manager.cancelAsUser(TAG, notificationId, UserHandle.ALL);
+ });
}
private void setStickyActive(boolean active) {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 11c0e4abdb35..9fc1949183f8 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -136,17 +136,16 @@ class UserUsageStatsService {
}
// During system reboot, add a DEVICE_SHUTDOWN event to the end of event list, the timestamp
- // is last time UsageStatsDatabase is persisted to disk.
+ // is last time UsageStatsDatabase is persisted to disk or the last event's time whichever
+ // is higher (because the file system timestamp is round down to integral seconds).
// Also add a DEVICE_STARTUP event with current system timestamp.
final IntervalStats currentDailyStats = mCurrentStats[INTERVAL_DAILY];
if (currentDailyStats != null) {
- // File system timestamp only has precision of 1 second, add 1000ms to make up
- // for the loss of round up.
- final Event shutdownEvent =
- new Event(DEVICE_SHUTDOWN, currentDailyStats.lastTimeSaved + 1000);
+ final Event shutdownEvent = new Event(DEVICE_SHUTDOWN,
+ Math.max(currentDailyStats.lastTimeSaved, currentDailyStats.endTime));
shutdownEvent.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
currentDailyStats.addEvent(shutdownEvent);
- final Event startupEvent = new Event(DEVICE_STARTUP, currentTimeMillis);
+ final Event startupEvent = new Event(DEVICE_STARTUP, System.currentTimeMillis());
startupEvent.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
currentDailyStats.addEvent(startupEvent);
}