diff options
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); } |