diff options
Diffstat (limited to 'packages/SettingsLib/src')
18 files changed, 434 insertions, 305 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java index 2b357c57b306..1e8cb9fc4622 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java @@ -38,6 +38,7 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.text.style.ImageSpan; +import android.util.Log; import android.view.MenuItem; import android.widget.TextView; @@ -54,6 +55,7 @@ import java.util.List; public class RestrictedLockUtilsInternal extends RestrictedLockUtils { private static final String LOG_TAG = "RestrictedLockUtils"; + private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); /** * @return drawables for displaying with settings that are locked by a device admin. @@ -92,14 +94,25 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils { } final UserManager um = UserManager.get(context); + final UserHandle userHandle = UserHandle.of(userId); final List<UserManager.EnforcingUser> enforcingUsers = - um.getUserRestrictionSources(userRestriction, UserHandle.of(userId)); + um.getUserRestrictionSources(userRestriction, userHandle); if (enforcingUsers.isEmpty()) { // Restriction is not enforced. return null; - } else if (enforcingUsers.size() > 1) { - return EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction); + } + final int size = enforcingUsers.size(); + if (size > 1) { + final EnforcedAdmin enforcedAdmin = EnforcedAdmin + .createDefaultEnforcedAdminWithRestriction(userRestriction); + enforcedAdmin.user = userHandle; + if (DEBUG) { + Log.d(LOG_TAG, "Multiple (" + size + ") enforcing users for restriction '" + + userRestriction + "' on user " + userHandle + "; returning default admin " + + "(" + enforcedAdmin + ")"); + } + return enforcedAdmin; } final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource(); diff --git a/packages/SettingsLib/src/com/android/settingslib/SignalIcon.java b/packages/SettingsLib/src/com/android/settingslib/SignalIcon.java index 1f311086a1fb..280e40726c03 100644 --- a/packages/SettingsLib/src/com/android/settingslib/SignalIcon.java +++ b/packages/SettingsLib/src/com/android/settingslib/SignalIcon.java @@ -15,11 +15,8 @@ */ package com.android.settingslib; -import java.text.SimpleDateFormat; -import java.util.Objects; - /** - * Icons and states for SysUI and Settings. + * Icons for SysUI and Settings. */ public class SignalIcon { @@ -40,9 +37,17 @@ public class SignalIcon { // For logging. public final String name; - public IconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc, - int sbNullState, int qsNullState, int sbDiscState, int qsDiscState, - int discContentDesc) { + public IconGroup( + String name, + int[][] sbIcons, + int[][] qsIcons, + int[] contentDesc, + int sbNullState, + int qsNullState, + int sbDiscState, + int qsDiscState, + int discContentDesc + ) { this.name = name; this.sbIcons = sbIcons; this.qsIcons = qsIcons; @@ -61,184 +66,36 @@ public class SignalIcon { } /** - * Holds states for SysUI. - */ - public static class State { - // No locale as it's only used for logging purposes - private static SimpleDateFormat sSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); - public boolean connected; - public boolean enabled; - public boolean activityIn; - public boolean activityOut; - public int level; - public IconGroup iconGroup; - public int inetCondition; - public int rssi; // Only for logging. - - // Not used for comparison, just used for logging. - public long time; - - /** - * Generates a copy of the source state. - */ - public void copyFrom(State state) { - connected = state.connected; - enabled = state.enabled; - level = state.level; - iconGroup = state.iconGroup; - inetCondition = state.inetCondition; - activityIn = state.activityIn; - activityOut = state.activityOut; - rssi = state.rssi; - time = state.time; - } - - @Override - public String toString() { - if (time != 0) { - StringBuilder builder = new StringBuilder(); - toString(builder); - return builder.toString(); - } else { - return "Empty " + getClass().getSimpleName(); - } - } - - protected void toString(StringBuilder builder) { - builder.append("connected=").append(connected).append(',') - .append("enabled=").append(enabled).append(',') - .append("level=").append(level).append(',') - .append("inetCondition=").append(inetCondition).append(',') - .append("iconGroup=").append(iconGroup).append(',') - .append("activityIn=").append(activityIn).append(',') - .append("activityOut=").append(activityOut).append(',') - .append("rssi=").append(rssi).append(',') - .append("lastModified=").append(sSDF.format(time)); - } - - @Override - public boolean equals(Object o) { - if (!o.getClass().equals(getClass())) { - return false; - } - State other = (State) o; - return other.connected == connected - && other.enabled == enabled - && other.level == level - && other.inetCondition == inetCondition - && other.iconGroup == iconGroup - && other.activityIn == activityIn - && other.activityOut == activityOut - && other.rssi == rssi; - } - } - - /** * Holds icons for a given MobileState. */ public static class MobileIconGroup extends IconGroup { public final int dataContentDescription; // mContentDescriptionDataType public final int dataType; - public final boolean isWide; - public final int qsDataType; - public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc, - int sbNullState, int qsNullState, int sbDiscState, int qsDiscState, - int discContentDesc, int dataContentDesc, int dataType, boolean isWide) { - super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState, - qsDiscState, discContentDesc); + public MobileIconGroup( + String name, + int[][] sbIcons, + int[][] qsIcons, + int[] contentDesc, + int sbNullState, + int qsNullState, + int sbDiscState, + int qsDiscState, + int discContentDesc, + int dataContentDesc, + int dataType + ) { + super(name, + sbIcons, + qsIcons, + contentDesc, + sbNullState, + qsNullState, + sbDiscState, + qsDiscState, + discContentDesc); this.dataContentDescription = dataContentDesc; this.dataType = dataType; - this.isWide = isWide; - this.qsDataType = dataType; // TODO: remove this field - } - } - - /** - * Holds mobile states for SysUI. - */ - public static class MobileState extends State { - public String networkName; - public String networkNameData; - public boolean dataSim; - public boolean dataConnected; - public boolean isEmergency; - public boolean airplaneMode; - public boolean carrierNetworkChangeMode; - public boolean isDefault; - public boolean userSetup; - public boolean roaming; - public boolean defaultDataOff; // Tracks the on/off state of the defaultDataSubscription - public boolean imsRegistered; - public boolean voiceCapable; - public boolean videoCapable; - public boolean mobileDataEnabled; - public boolean roamingDataEnabled; - - @Override - public void copyFrom(State s) { - super.copyFrom(s); - MobileState state = (MobileState) s; - dataSim = state.dataSim; - networkName = state.networkName; - networkNameData = state.networkNameData; - dataConnected = state.dataConnected; - isDefault = state.isDefault; - isEmergency = state.isEmergency; - airplaneMode = state.airplaneMode; - carrierNetworkChangeMode = state.carrierNetworkChangeMode; - userSetup = state.userSetup; - roaming = state.roaming; - defaultDataOff = state.defaultDataOff; - imsRegistered = state.imsRegistered; - voiceCapable = state.voiceCapable; - videoCapable = state.videoCapable; - mobileDataEnabled = state.mobileDataEnabled; - roamingDataEnabled = state.roamingDataEnabled; - } - - @Override - protected void toString(StringBuilder builder) { - super.toString(builder); - builder.append(','); - builder.append("dataSim=").append(dataSim).append(','); - builder.append("networkName=").append(networkName).append(','); - builder.append("networkNameData=").append(networkNameData).append(','); - builder.append("dataConnected=").append(dataConnected).append(','); - builder.append("roaming=").append(roaming).append(','); - builder.append("isDefault=").append(isDefault).append(','); - builder.append("isEmergency=").append(isEmergency).append(','); - builder.append("airplaneMode=").append(airplaneMode).append(','); - builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode) - .append(','); - builder.append("userSetup=").append(userSetup).append(','); - builder.append("defaultDataOff=").append(defaultDataOff); - builder.append("imsRegistered=").append(imsRegistered).append(','); - builder.append("voiceCapable=").append(voiceCapable).append(','); - builder.append("videoCapable=").append(videoCapable).append(','); - builder.append("mobileDataEnabled=").append(mobileDataEnabled).append(','); - builder.append("roamingDataEnabled=").append(roamingDataEnabled); - } - - @Override - public boolean equals(Object o) { - return super.equals(o) - && Objects.equals(((MobileState) o).networkName, networkName) - && Objects.equals(((MobileState) o).networkNameData, networkNameData) - && ((MobileState) o).dataSim == dataSim - && ((MobileState) o).dataConnected == dataConnected - && ((MobileState) o).isEmergency == isEmergency - && ((MobileState) o).airplaneMode == airplaneMode - && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode - && ((MobileState) o).userSetup == userSetup - && ((MobileState) o).isDefault == isDefault - && ((MobileState) o).roaming == roaming - && ((MobileState) o).defaultDataOff == defaultDataOff - && ((MobileState) o).imsRegistered == imsRegistered - && ((MobileState) o).voiceCapable == voiceCapable - && ((MobileState) o).videoCapable == videoCapable - && ((MobileState) o).mobileDataEnabled == mobileDataEnabled - && ((MobileState) o).roamingDataEnabled == roamingDataEnabled; } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/applications/RecentAppOpsAccess.java index 877dd2dfa26e..2e7cfcb13d8c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/RecentAppOpsAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,8 @@ * limitations under the License. */ -package com.android.settingslib.location; +package com.android.settingslib.applications; + import android.app.AppOpsManager; import android.content.Context; @@ -39,14 +40,24 @@ import java.util.Comparator; import java.util.List; /** - * Retrieves the information of applications which accessed location recently. + * Retrieval of app ops information for the specified ops. */ -public class RecentLocationAccesses { - private static final String TAG = RecentLocationAccesses.class.getSimpleName(); +public class RecentAppOpsAccess { @VisibleForTesting - static final String ANDROID_SYSTEM_PACKAGE_NAME = "android"; + static final int[] LOCATION_OPS = new int[]{ + AppOpsManager.OP_FINE_LOCATION, + AppOpsManager.OP_COARSE_LOCATION, + }; + private static final int[] MICROPHONE_OPS = new int[]{ + AppOpsManager.OP_RECORD_AUDIO, + }; + - // Keep last 24 hours of location app information. + private static final String TAG = RecentAppOpsAccess.class.getSimpleName(); + @VisibleForTesting + public static final String ANDROID_SYSTEM_PACKAGE_NAME = "android"; + + // Keep last 24 hours of access app information. private static final long RECENT_TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS; /** The flags for querying ops that are trusted for showing in the UI. */ @@ -54,47 +65,55 @@ public class RecentLocationAccesses { | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY | AppOpsManager.OP_FLAG_TRUSTED_PROXIED; - @VisibleForTesting - static final int[] LOCATION_OPS = new int[]{ - AppOpsManager.OP_FINE_LOCATION, - AppOpsManager.OP_COARSE_LOCATION, - }; - private final PackageManager mPackageManager; private final Context mContext; + private final int[] mOps; private final IconDrawableFactory mDrawableFactory; private final Clock mClock; - public RecentLocationAccesses(Context context) { - this(context, Clock.systemDefaultZone()); + public RecentAppOpsAccess(Context context, int[] ops) { + this(context, Clock.systemDefaultZone(), ops); } @VisibleForTesting - RecentLocationAccesses(Context context, Clock clock) { + RecentAppOpsAccess(Context context, Clock clock, int[] ops) { mContext = context; mPackageManager = context.getPackageManager(); + mOps = ops; mDrawableFactory = IconDrawableFactory.newInstance(context); mClock = clock; } /** - * Fills a list of applications which queried location recently within specified time. - * Apps are sorted by recency. Apps with more recent location accesses are in the front. + * Creates an instance of {@link RecentAppOpsAccess} for location (coarse and fine) access. + */ + public static RecentAppOpsAccess createForLocation(Context context) { + return new RecentAppOpsAccess(context, LOCATION_OPS); + } + + /** + * Creates an instance of {@link RecentAppOpsAccess} for microphone access. + */ + public static RecentAppOpsAccess createForMicrophone(Context context) { + return new RecentAppOpsAccess(context, MICROPHONE_OPS); + } + + /** + * Fills a list of applications which queried for access recently within specified time. + * Apps are sorted by recency. Apps with more recent accesses are in the front. */ @VisibleForTesting - List<Access> getAppList(boolean showSystemApps) { - // Retrieve a location usage list from AppOps - PackageManager pm = mContext.getPackageManager(); - AppOpsManager aoManager = - (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); - List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(LOCATION_OPS); + public List<Access> getAppList(boolean showSystemApps) { + // Retrieve a access usage list from AppOps + AppOpsManager aoManager = mContext.getSystemService(AppOpsManager.class); + List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(mOps); final int appOpsCount = appOps != null ? appOps.size() : 0; // Process the AppOps list and generate a preference list. ArrayList<Access> accesses = new ArrayList<>(appOpsCount); final long now = mClock.millis(); - final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + final UserManager um = mContext.getSystemService(UserManager.class); final List<UserHandle> profiles = um.getUserProfiles(); for (int i = 0; i < appOpsCount; ++i) { @@ -111,9 +130,10 @@ public class RecentLocationAccesses { // Don't show apps that do not have user sensitive location permissions boolean showApp = true; if (!showSystemApps) { - for (int op : LOCATION_OPS) { + for (int op : mOps) { final String permission = AppOpsManager.opToPermission(op); - final int permissionFlags = pm.getPermissionFlags(permission, packageName, + final int permissionFlags = mPackageManager.getPermissionFlags(permission, + packageName, user); if (PermissionChecker.checkPermissionForPreflight(mContext, permission, PermissionChecker.PID_UNKNOWN, uid, packageName) @@ -144,12 +164,11 @@ public class RecentLocationAccesses { return accesses; } - /** - * Gets a list of apps that accessed location recently, sorting by recency. + * Gets a list of apps that accessed the app op recently, sorting by recency. * * @param showSystemApps whether includes system apps in the list. - * @return the list of apps that recently accessed location. + * @return the list of apps that recently accessed the app op. */ public List<Access> getAppListSorted(boolean showSystemApps) { List<Access> accesses = getAppList(showSystemApps); @@ -174,18 +193,18 @@ public class RecentLocationAccesses { AppOpsManager.PackageOps ops) { String packageName = ops.getPackageName(); List<AppOpsManager.OpEntry> entries = ops.getOps(); - long locationAccessFinishTime = 0L; - // Earliest time for a location access to end and still be shown in list. - long recentLocationCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS; + long accessFinishTime = 0L; + // Earliest time for a access to end and still be shown in list. + long recentAccessCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS; // Compute the most recent access time from all op entries. for (AppOpsManager.OpEntry entry : entries) { long lastAccessTime = entry.getLastAccessTime(TRUSTED_STATE_FLAGS); - if (lastAccessTime > locationAccessFinishTime) { - locationAccessFinishTime = lastAccessTime; + if (lastAccessTime > accessFinishTime) { + accessFinishTime = lastAccessTime; } } // Bail out if the entry is out of date. - if (locationAccessFinishTime < recentLocationCutoffTime) { + if (accessFinishTime < recentAccessCutoffTime) { return null; } @@ -213,13 +232,16 @@ public class RecentLocationAccesses { badgedAppLabel = null; } access = new Access(packageName, userHandle, icon, appLabel, badgedAppLabel, - locationAccessFinishTime); + accessFinishTime); } catch (NameNotFoundException e) { Log.w(TAG, "package name not found for " + packageName + ", userId " + userId); } return access; } + /** + * Information about when an app last accessed a particular app op. + */ public static class Access { public final String packageName; public final UserHandle userHandle; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index f3dcc1bc677a..90642768109e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -113,6 +113,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsA2dpProfileConnectedFail = false; private boolean mIsHeadsetProfileConnectedFail = false; private boolean mIsHearingAidProfileConnectedFail = false; + private boolean mUnpairing = false; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; @VisibleForTesting @@ -473,6 +474,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } if (dev != null) { + mUnpairing = true; final boolean successful = dev.removeBond(); if (successful) { releaseLruCache(); @@ -1433,4 +1435,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public int getmType() { return mType; } + + boolean getUnpairing() { + return mUnpairing; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java index 20ece69d7281..818f5ca33ebf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java @@ -180,6 +180,9 @@ public class HearingAidDeviceManager { break; case BluetoothProfile.STATE_DISCONNECTED: mainDevice = findMainDevice(cachedDevice); + if (cachedDevice.getUnpairing()) { + return true; + } if (mainDevice != null) { // When main device exists, receiving sub device disconnection // To update main device UI diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index a1fba4a018e2..dc109cac37b2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -16,7 +16,8 @@ package com.android.settingslib.bluetooth; -import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_ALL; +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO; +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; @@ -29,6 +30,7 @@ import android.content.Context; import android.util.Log; import com.android.settingslib.R; +import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.List; @@ -162,9 +164,12 @@ public class HearingAidProfile implements LocalBluetoothProfile { if (mBluetoothAdapter == null) { return false; } + int profiles = Utils.isAudioModeOngoingCall(mContext) + ? ACTIVE_DEVICE_PHONE_CALL + : ACTIVE_DEVICE_AUDIO; return device == null - ? mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_ALL) - : mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_ALL); + ? mBluetoothAdapter.removeActiveDevice(profiles) + : mBluetoothAdapter.setActiveDevice(device, profiles); } public List<BluetoothDevice> getActiveDevices() { diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java index 6cb60d1aaf0e..7390b6aaaaed 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java @@ -97,6 +97,9 @@ public class MetricsFeatureProvider { /** * Logs a simple action without page id or attribution + * + * @param category the target page + * @param taggedData the data for {@link EventLogWriter} */ public void action(Context context, int category, Pair<Integer, Object>... taggedData) { for (LogWriter writer : mLoggerWriters) { diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java index 274696bfec0e..468aa05052ad 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java @@ -183,6 +183,20 @@ public class UserIconDrawable extends Drawable implements Drawable.Callback { return setBadge(badge); } + /** + * Sets the managed badge to this user icon if the device has a device owner. + */ + public UserIconDrawable setBadgeIfManagedDevice(Context context) { + Drawable badge = null; + boolean deviceOwnerExists = context.getSystemService(DevicePolicyManager.class) + .getDeviceOwnerComponentOnAnyUser() != null; + if (deviceOwnerExists) { + badge = getDrawableForDisplayDensity( + context, com.android.internal.R.drawable.ic_corp_badge_case); + } + return setBadge(badge); + } + public void setBadgeRadius(float radius) { mBadgeRadius = radius; onBoundsChange(getBounds()); diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java index b3205d7563b2..b56ae3864fb7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java @@ -109,6 +109,15 @@ public class BatteryStatus { } /** + * Determine whether the device is plugged in wireless. + * + * @return true if the device is plugged in wireless + */ + public boolean isPluggedInWireless() { + return plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS; + } + + /** * Whether or not the device is charged. Note that some devices never return 100% for * battery level, so this allows either battery level or status to determine if the * battery is charged. diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java index c501b3aab4d4..2e8f36834584 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java @@ -110,6 +110,18 @@ public class PowerAllowlistBackend { } /** + * Check if target package is in allow list except idle app + */ + public boolean isAllowlistedExceptIdle(String pkg) { + try { + return mDeviceIdleService.isPowerSaveWhitelistExceptIdleApp(pkg); + } catch (RemoteException e) { + Log.w(TAG, "Unable to reach IDeviceIdleController", e); + return true; + } + } + + /** * * @param pkgs a list of packageName * @return true when one of package is in allow list diff --git a/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java b/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java index 1ba701818cbe..8f9232ef9ef8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java @@ -318,23 +318,11 @@ public class SettingsInjector { @Override public boolean onPreferenceClick(Preference preference) { - // Activity to start if they click on the preference. Must start in new task to ensure - // that "android.settings.LOCATION_SOURCE_SETTINGS" brings user back to - // Settings > Location. + // Activity to start if they click on the preference. Intent settingIntent = new Intent(); settingIntent.setClassName(mInfo.packageName, mInfo.settingsActivity); + // No flags set to ensure the activity is launched within the same settings task. logPreferenceClick(settingIntent); - // Sometimes the user may navigate back to "Settings" and launch another different - // injected setting after one injected setting has been launched. - // - // FLAG_ACTIVITY_CLEAR_TOP allows multiple Activities to stack on each other. When - // "back" button is clicked, the user will navigate through all the injected settings - // launched before. Such behavior could be quite confusing sometimes. - // - // In order to avoid such confusion, we use FLAG_ACTIVITY_CLEAR_TASK, which always clear - // up all existing injected settings and make sure that "back" button always brings the - // user back to "Settings" directly. - settingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mContext.startActivityAsUser(settingIntent, mInfo.mUserHandle); return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index 22001c9c925a..c40b7b7d88af 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -479,9 +479,9 @@ public class LocalMediaManager implements BluetoothCallback { @Override public void onDeviceListAdded(List<MediaDevice> devices) { synchronized (mMediaDevicesLock) { + Collections.sort(devices, COMPARATOR); mMediaDevices.clear(); mMediaDevices.addAll(devices); - Collections.sort(devices, COMPARATOR); // Add disconnected bluetooth devices only when phone output device is available. for (MediaDevice device : devices) { final int type = device.getDeviceType(); diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java index fab915d3d08e..29bbe46c4f5e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java +++ b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java @@ -114,6 +114,8 @@ public class MobileMappings { TelephonyIcons.UNKNOWN); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EDGE), TelephonyIcons.E); + networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_GPRS), + TelephonyIcons.G); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_CDMA), TelephonyIcons.ONE_X); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_1xRTT), @@ -123,6 +125,8 @@ public class MobileMappings { TelephonyIcons.THREE_G); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EDGE), TelephonyIcons.THREE_G); + networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_GPRS), + TelephonyIcons.THREE_G); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_CDMA), TelephonyIcons.THREE_G); networkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_1xRTT), diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java index 0129e0dddadd..bb675bb10ccf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java +++ b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java @@ -55,178 +55,194 @@ public class TelephonyIcons { null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.carrier_network_change_mode, - 0, - false); + 0 + ); public static final MobileIconGroup THREE_G = new MobileIconGroup( "3G", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_3g, - TelephonyIcons.ICON_3G, - true); + TelephonyIcons.ICON_3G + ); public static final MobileIconGroup WFC = new MobileIconGroup( "WFC", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], - 0, 0, false); + 0, + 0); public static final MobileIconGroup UNKNOWN = new MobileIconGroup( "Unknown", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], - 0, 0, false); + 0, + 0); public static final MobileIconGroup E = new MobileIconGroup( "E", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_edge, - TelephonyIcons.ICON_E, - false); + TelephonyIcons.ICON_E + ); public static final MobileIconGroup ONE_X = new MobileIconGroup( "1X", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_cdma, - TelephonyIcons.ICON_1X, - true); + TelephonyIcons.ICON_1X + ); public static final MobileIconGroup G = new MobileIconGroup( "G", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_gprs, - TelephonyIcons.ICON_G, - false); + TelephonyIcons.ICON_G + ); public static final MobileIconGroup H = new MobileIconGroup( "H", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_3_5g, - TelephonyIcons.ICON_H, - false); + TelephonyIcons.ICON_H + ); public static final MobileIconGroup H_PLUS = new MobileIconGroup( "H+", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_3_5g_plus, - TelephonyIcons.ICON_H_PLUS, - false); + TelephonyIcons.ICON_H_PLUS + ); public static final MobileIconGroup FOUR_G = new MobileIconGroup( "4G", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_4g, - TelephonyIcons.ICON_4G, - true); + TelephonyIcons.ICON_4G + ); public static final MobileIconGroup FOUR_G_PLUS = new MobileIconGroup( "4G+", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_4g_plus, - TelephonyIcons.ICON_4G_PLUS, - true); + TelephonyIcons.ICON_4G_PLUS + ); public static final MobileIconGroup LTE = new MobileIconGroup( "LTE", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_lte, - TelephonyIcons.ICON_LTE, - true); + TelephonyIcons.ICON_LTE + ); public static final MobileIconGroup LTE_PLUS = new MobileIconGroup( "LTE+", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_lte_plus, - TelephonyIcons.ICON_LTE_PLUS, - true); + TelephonyIcons.ICON_LTE_PLUS + ); public static final MobileIconGroup LTE_CA_5G_E = new MobileIconGroup( "5Ge", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5ge_html, - TelephonyIcons.ICON_5G_E, - true); + TelephonyIcons.ICON_5G_E + ); public static final MobileIconGroup NR_5G = new MobileIconGroup( "5G", @@ -239,8 +255,8 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g, - TelephonyIcons.ICON_5G, - true); + TelephonyIcons.ICON_5G + ); public static final MobileIconGroup NR_5G_PLUS = new MobileIconGroup( "5G_PLUS", @@ -253,34 +269,36 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g_plus, - TelephonyIcons.ICON_5G_PLUS, - true); + TelephonyIcons.ICON_5G_PLUS + ); public static final MobileIconGroup DATA_DISABLED = new MobileIconGroup( "DataDisabled", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.cell_data_off_content_description, - 0, - false); + 0 + ); public static final MobileIconGroup NOT_DEFAULT_DATA = new MobileIconGroup( "NotDefaultData", null, null, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, - 0, 0, + 0, + 0, 0, 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.not_default_data_content_description, - 0, - false); + 0 + ); public static final MobileIconGroup CARRIER_MERGED_WIFI = new MobileIconGroup( "CWF", @@ -293,8 +311,8 @@ public class TelephonyIcons { /* qsDiscState= */ 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_carrier_wifi, - TelephonyIcons.ICON_CWF, - /* isWide= */ true); + TelephonyIcons.ICON_CWF + ); // When adding a new MobileIconGround, check if the dataContentDescription has to be filtered // in QSCarrier#hasValidTypeContentDescription @@ -309,8 +327,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g, - TelephonyIcons.ICON_5G, - false); + TelephonyIcons.ICON_5G); public static final MobileIconGroup FIVE_G_BASIC = new MobileIconGroup( "5GBasic", @@ -322,8 +339,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g_basic, - TelephonyIcons.ICON_5G_BASIC, - false); + TelephonyIcons.ICON_5G_BASIC); public static final MobileIconGroup FIVE_G_UWB = new MobileIconGroup( "5GUWB", @@ -335,8 +351,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g_uwb, - TelephonyIcons.ICON_5G_UWB, - false); + TelephonyIcons.ICON_5G_UWB); public static final MobileIconGroup FIVE_G_SA = new MobileIconGroup( "5GSA", @@ -348,8 +363,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], R.string.data_connection_5g_sa, - TelephonyIcons.ICON_5G_SA, - false); + TelephonyIcons.ICON_5G_SA); public static final MobileIconGroup VOWIFI = new MobileIconGroup( "VoWIFI", @@ -361,8 +375,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], 0, - TelephonyIcons.ICON_VOWIFI, - false); + TelephonyIcons.ICON_VOWIFI); public static final MobileIconGroup VOWIFI_CALLING = new MobileIconGroup( "VoWIFICall", @@ -374,8 +387,7 @@ public class TelephonyIcons { 0, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], 0, - TelephonyIcons.ICON_VOWIFI_CALLING, - false); + TelephonyIcons.ICON_VOWIFI_CALLING); /** Mapping icon name(lower case) to the icon object. */ public static final Map<String, MobileIconGroup> ICON_NAME_TO_ICON; diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java index a210e90a3cfc..dee68948a16e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java @@ -19,7 +19,6 @@ package com.android.settingslib.notification; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.AlertDialog; -import android.app.Dialog; import android.app.NotificationManager; import android.content.Context; import android.content.DialogInterface; @@ -85,6 +84,8 @@ public class EnableZenModeDialog { @VisibleForTesting protected Context mContext; + private final int mThemeResId; + private final boolean mCancelIsNeutral; @VisibleForTesting protected TextView mZenAlarmWarning; @VisibleForTesting @@ -97,10 +98,20 @@ public class EnableZenModeDialog { protected LayoutInflater mLayoutInflater; public EnableZenModeDialog(Context context) { + this(context, 0); + } + + public EnableZenModeDialog(Context context, int themeResId) { + this(context, themeResId, false /* cancelIsNeutral */); + } + + public EnableZenModeDialog(Context context, int themeResId, boolean cancelIsNeutral) { mContext = context; + mThemeResId = themeResId; + mCancelIsNeutral = cancelIsNeutral; } - public Dialog createDialog() { + public AlertDialog createDialog() { mNotificationManager = (NotificationManager) mContext. getSystemService(Context.NOTIFICATION_SERVICE); mForeverId = Condition.newId(mContext).appendPath("forever").build(); @@ -108,9 +119,8 @@ public class EnableZenModeDialog { mUserId = mContext.getUserId(); mAttached = false; - final AlertDialog.Builder builder = new AlertDialog.Builder(mContext) + final AlertDialog.Builder builder = new AlertDialog.Builder(mContext, mThemeResId) .setTitle(R.string.zen_mode_settings_turn_on_dialog_title) - .setNegativeButton(R.string.cancel, null) .setPositiveButton(R.string.zen_mode_enable_dialog_turn_on, new DialogInterface.OnClickListener() { @Override @@ -140,6 +150,12 @@ public class EnableZenModeDialog { } }); + if (mCancelIsNeutral) { + builder.setNeutralButton(R.string.cancel, null); + } else { + builder.setNegativeButton(R.string.cancel, null); + } + View contentView = getContentView(); bindConditions(forever()); builder.setView(contentView); diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java index b65637f4c45f..5ee919bfe538 100644 --- a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java @@ -19,6 +19,7 @@ package com.android.settingslib.utils; import android.content.Context; import android.icu.text.MeasureFormat; import android.icu.text.MeasureFormat.FormatWidth; +import android.icu.text.MessageFormat; import android.icu.text.RelativeDateTimeFormatter; import android.icu.text.RelativeDateTimeFormatter.RelativeUnit; import android.icu.util.Measure; @@ -31,7 +32,9 @@ import android.text.style.TtsSpan; import com.android.settingslib.R; import java.util.ArrayList; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; /** Utility class for generally useful string methods **/ public class StringUtil { @@ -183,4 +186,37 @@ public class StringUtil { return formatRelativeTime(context, millis, withSeconds, RelativeDateTimeFormatter.Style.LONG); } + + /** + * Get ICU plural string without additional arguments + * + * @param context Context used to get the string + * @param count The number used to get the correct string for the current language's plural + * rules. + * @param resId Resource id of the string + * + * @return Formatted plural string + */ + public static String getIcuPluralsString(Context context, int count, int resId) { + MessageFormat msgFormat = new MessageFormat(context.getResources().getString(resId), + Locale.getDefault()); + Map<String, Object> arguments = new HashMap<>(); + arguments.put("count", count); + return msgFormat.format(arguments); + } + + /** + * Get ICU plural string with additional arguments + * + * @param context Context used to get the string + * @param args String arguments + * @param resId Resource id of the string + * + * @return Formatted plural string + */ + public static String getIcuPluralsString(Context context, Map<String, Object> args, int resId) { + MessageFormat msgFormat = new MessageFormat(context.getResources().getString(resId), + Locale.getDefault()); + return msgFormat.format(args); + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiRestrictionsCache.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiRestrictionsCache.java new file mode 100644 index 000000000000..7ffae4094add --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiRestrictionsCache.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.wifi; + +import static android.os.UserManager.DISALLOW_CONFIG_WIFI; + +import android.annotation.NonNull; +import android.content.Context; +import android.os.Bundle; +import android.os.UserManager; +import android.util.SparseArray; + +import androidx.annotation.VisibleForTesting; + +import java.util.HashMap; +import java.util.Map; + +/** + * This is a singleton class for Wi-Fi restrictions caching. + */ +public class WifiRestrictionsCache { + private static final String TAG = "WifiResCache"; + + /** + * Manages mapping between user ID and corresponding singleton {@link WifiRestrictionsCache} + * object. + */ + @VisibleForTesting + protected static final SparseArray<WifiRestrictionsCache> sInstances = new SparseArray<>(); + + @VisibleForTesting + protected UserManager mUserManager; + @VisibleForTesting + protected Bundle mUserRestrictions; + @VisibleForTesting + protected final Map<String, Boolean> mRestrictions = new HashMap<>(); + + /** + * @return an instance of {@link WifiRestrictionsCache} object. + */ + @NonNull + public static WifiRestrictionsCache getInstance(@NonNull Context context) { + final int requestUserId = context.getUserId(); + WifiRestrictionsCache cache; + synchronized (sInstances) { + // We have same user context as request. + if (sInstances.indexOfKey(requestUserId) >= 0) { + return sInstances.get(requestUserId); + } + // Request by a new user context. + cache = new WifiRestrictionsCache(context); + sInstances.put(context.getUserId(), cache); + } + return cache; + } + + /** + * Removes all the instances. + */ + public static void clearInstance() { + synchronized (sInstances) { + for (int i = 0; i < sInstances.size(); i++) { + int key = sInstances.keyAt(i); + WifiRestrictionsCache cache = sInstances.get(key); + cache.clearRestrictions(); + sInstances.remove(key); + } + sInstances.clear(); + } + } + + /** + * Constructor to create a singleton class for Wi-Fi restrictions cache. + * + * @param context The Context this is associated with. + */ + protected WifiRestrictionsCache(@NonNull Context context) { + mUserManager = context.getSystemService(UserManager.class); + if (mUserManager != null) { + mUserRestrictions = mUserManager.getUserRestrictions(); + } + } + + /** + * @return the boolean value of the restrictions + */ + public Boolean getRestriction(String key) { + if (mUserRestrictions == null) { + return false; + } + Boolean restriction; + synchronized (mRestrictions) { + if (mRestrictions.containsKey(key)) { + return mRestrictions.get(key); + } + restriction = mUserRestrictions.getBoolean(key); + mRestrictions.put(key, restriction); + } + return restriction; + } + + /** + * Removes all the restrictions. + */ + public void clearRestrictions() { + synchronized (mRestrictions) { + mRestrictions.clear(); + } + } + + /** + * @return Whether the user is allowed to config Wi-Fi. + */ + public Boolean isConfigWifiAllowed() { + return !getRestriction(DISALLOW_CONFIG_WIFI); + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index 0ddad5f7d7cd..e999e0d8b757 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -268,8 +268,6 @@ public class WifiStatusTracker { private void updateWifiState() { state = mWifiManager.getWifiState(); enabled = state == WifiManager.WIFI_STATE_ENABLED; - isCarrierMerged = false; - subId = 0; } private void updateRssi(int newRssi) { |