summaryrefslogtreecommitdiff
path: root/packages/SettingsLib/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SettingsLib/src')
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/SignalIcon.java211
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/RecentAppOpsAccess.java (renamed from packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java)96
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java16
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java140
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java24
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java36
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiRestrictionsCache.java131
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java2
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) {