• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.settingslib;
2 
3 import android.annotation.ColorInt;
4 import android.content.Context;
5 import android.content.Intent;
6 import android.content.pm.PackageInfo;
7 import android.content.pm.PackageManager;
8 import android.content.pm.PackageManager.NameNotFoundException;
9 import android.content.pm.Signature;
10 import android.content.pm.UserInfo;
11 import android.content.res.ColorStateList;
12 import android.content.res.Resources;
13 import android.content.res.TypedArray;
14 import android.graphics.Bitmap;
15 import android.graphics.Color;
16 import android.graphics.drawable.Drawable;
17 import android.location.LocationManager;
18 import android.media.AudioManager;
19 import android.net.ConnectivityManager;
20 import android.os.BatteryManager;
21 import android.os.SystemProperties;
22 import android.os.UserHandle;
23 import android.os.UserManager;
24 import android.print.PrintManager;
25 import android.provider.Settings;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.internal.util.UserIcons;
29 import com.android.settingslib.drawable.UserIconDrawable;
30 import com.android.settingslib.wrapper.LocationManagerWrapper;
31 import java.text.NumberFormat;
32 
33 public class Utils {
34 
35     private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
36     private static final String NEW_MODE_KEY = "NEW_MODE";
37     @VisibleForTesting
38     static final String STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY =
39             "ro.storage_manager.show_opt_in";
40 
41     private static Signature[] sSystemSignature;
42     private static String sPermissionControllerPackageName;
43     private static String sServicesSystemSharedLibPackageName;
44     private static String sSharedSystemSharedLibPackageName;
45 
46     static final int[] WIFI_PIE = {
47             com.android.internal.R.drawable.ic_wifi_signal_0,
48             com.android.internal.R.drawable.ic_wifi_signal_1,
49             com.android.internal.R.drawable.ic_wifi_signal_2,
50             com.android.internal.R.drawable.ic_wifi_signal_3,
51             com.android.internal.R.drawable.ic_wifi_signal_4
52     };
53 
updateLocationEnabled(Context context, boolean enabled, int userId, int source)54     public static void updateLocationEnabled(Context context, boolean enabled, int userId,
55             int source) {
56         Settings.Secure.putIntForUser(
57                 context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source,
58                 userId);
59         Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION);
60 
61         final int oldMode = Settings.Secure.getIntForUser(context.getContentResolver(),
62                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userId);
63         final int newMode = enabled
64                 ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
65                 : Settings.Secure.LOCATION_MODE_OFF;
66         intent.putExtra(CURRENT_MODE_KEY, oldMode);
67         intent.putExtra(NEW_MODE_KEY, newMode);
68         context.sendBroadcastAsUser(
69                 intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
70         LocationManager locationManager =
71                 (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
72         LocationManagerWrapper wrapper = new LocationManagerWrapper(locationManager);
73         wrapper.setLocationEnabledForUser(enabled, UserHandle.of(userId));
74     }
75 
updateLocationMode(Context context, int oldMode, int newMode, int userId, int source)76     public static boolean updateLocationMode(Context context, int oldMode, int newMode, int userId,
77             int source) {
78         Settings.Secure.putIntForUser(
79                 context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source,
80                 userId);
81         Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION);
82         intent.putExtra(CURRENT_MODE_KEY, oldMode);
83         intent.putExtra(NEW_MODE_KEY, newMode);
84         context.sendBroadcastAsUser(
85                 intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
86         return Settings.Secure.putIntForUser(
87                 context.getContentResolver(), Settings.Secure.LOCATION_MODE, newMode, userId);
88     }
89 
90     /**
91      * Return string resource that best describes combination of tethering
92      * options available on this device.
93      */
getTetheringLabel(ConnectivityManager cm)94     public static int getTetheringLabel(ConnectivityManager cm) {
95         String[] usbRegexs = cm.getTetherableUsbRegexs();
96         String[] wifiRegexs = cm.getTetherableWifiRegexs();
97         String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
98 
99         boolean usbAvailable = usbRegexs.length != 0;
100         boolean wifiAvailable = wifiRegexs.length != 0;
101         boolean bluetoothAvailable = bluetoothRegexs.length != 0;
102 
103         if (wifiAvailable && usbAvailable && bluetoothAvailable) {
104             return R.string.tether_settings_title_all;
105         } else if (wifiAvailable && usbAvailable) {
106             return R.string.tether_settings_title_all;
107         } else if (wifiAvailable && bluetoothAvailable) {
108             return R.string.tether_settings_title_all;
109         } else if (wifiAvailable) {
110             return R.string.tether_settings_title_wifi;
111         } else if (usbAvailable && bluetoothAvailable) {
112             return R.string.tether_settings_title_usb_bluetooth;
113         } else if (usbAvailable) {
114             return R.string.tether_settings_title_usb;
115         } else {
116             return R.string.tether_settings_title_bluetooth;
117         }
118     }
119 
120     /**
121      * Returns a label for the user, in the form of "User: user name" or "Work profile".
122      */
getUserLabel(Context context, UserInfo info)123     public static String getUserLabel(Context context, UserInfo info) {
124         String name = info != null ? info.name : null;
125         if (info.isManagedProfile()) {
126             // We use predefined values for managed profiles
127             return context.getString(R.string.managed_user_title);
128         } else if (info.isGuest()) {
129             name = context.getString(R.string.user_guest);
130         }
131         if (name == null && info != null) {
132             name = Integer.toString(info.id);
133         } else if (info == null) {
134             name = context.getString(R.string.unknown);
135         }
136         return context.getResources().getString(R.string.running_process_item_user_label, name);
137     }
138 
139     /**
140      * Returns a circular icon for a user.
141      */
getUserIcon(Context context, UserManager um, UserInfo user)142     public static Drawable getUserIcon(Context context, UserManager um, UserInfo user) {
143         final int iconSize = UserIconDrawable.getSizeForList(context);
144         if (user.isManagedProfile()) {
145             Drawable drawable =  UserIconDrawable.getManagedUserDrawable(context);
146             drawable.setBounds(0, 0, iconSize, iconSize);
147             return drawable;
148         }
149         if (user.iconPath != null) {
150             Bitmap icon = um.getUserIcon(user.id);
151             if (icon != null) {
152                 return new UserIconDrawable(iconSize).setIcon(icon).bake();
153             }
154         }
155         return new UserIconDrawable(iconSize).setIconDrawable(
156                 UserIcons.getDefaultUserIcon(context.getResources(), user.id, /* light= */ false))
157                 .bake();
158     }
159 
160     /** Formats a double from 0.0..100.0 with an option to round **/
formatPercentage(double percentage, boolean round)161     public static String formatPercentage(double percentage, boolean round) {
162         final int localPercentage = round ? Math.round((float) percentage) : (int) percentage;
163         return formatPercentage(localPercentage);
164     }
165 
166     /** Formats the ratio of amount/total as a percentage. */
formatPercentage(long amount, long total)167     public static String formatPercentage(long amount, long total) {
168         return formatPercentage(((double) amount) / total);
169     }
170 
171     /** Formats an integer from 0..100 as a percentage. */
formatPercentage(int percentage)172     public static String formatPercentage(int percentage) {
173         return formatPercentage(((double) percentage) / 100.0);
174     }
175 
176     /** Formats a double from 0.0..1.0 as a percentage. */
formatPercentage(double percentage)177     public static String formatPercentage(double percentage) {
178         return NumberFormat.getPercentInstance().format(percentage);
179     }
180 
getBatteryLevel(Intent batteryChangedIntent)181     public static int getBatteryLevel(Intent batteryChangedIntent) {
182         int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
183         int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
184         return (level * 100) / scale;
185     }
186 
getBatteryStatus(Resources res, Intent batteryChangedIntent)187     public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) {
188         int status = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_STATUS,
189                 BatteryManager.BATTERY_STATUS_UNKNOWN);
190         String statusString;
191         if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
192             statusString = res.getString(R.string.battery_info_status_charging);
193         } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
194             statusString = res.getString(R.string.battery_info_status_discharging);
195         } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
196             statusString = res.getString(R.string.battery_info_status_not_charging);
197         } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
198             statusString = res.getString(R.string.battery_info_status_full);
199         } else {
200             statusString = res.getString(R.string.battery_info_status_unknown);
201         }
202 
203         return statusString;
204     }
205 
206     @ColorInt
getColorAccent(Context context)207     public static int getColorAccent(Context context) {
208         return getColorAttr(context, android.R.attr.colorAccent);
209     }
210 
211     @ColorInt
getColorError(Context context)212     public static int getColorError(Context context) {
213         return getColorAttr(context, android.R.attr.colorError);
214     }
215 
216     @ColorInt
getDefaultColor(Context context, int resId)217     public static int getDefaultColor(Context context, int resId) {
218         final ColorStateList list =
219                 context.getResources().getColorStateList(resId, context.getTheme());
220 
221         return list.getDefaultColor();
222     }
223 
224     @ColorInt
getDisabled(Context context, int inputColor)225     public static int getDisabled(Context context, int inputColor) {
226         return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
227     }
228 
229     @ColorInt
applyAlphaAttr(Context context, int attr, int inputColor)230     public static int applyAlphaAttr(Context context, int attr, int inputColor) {
231         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
232         float alpha = ta.getFloat(0, 0);
233         ta.recycle();
234         return applyAlpha(alpha, inputColor);
235     }
236 
237     @ColorInt
applyAlpha(float alpha, int inputColor)238     public static int applyAlpha(float alpha, int inputColor) {
239         alpha *= Color.alpha(inputColor);
240         return Color.argb((int) (alpha), Color.red(inputColor), Color.green(inputColor),
241                 Color.blue(inputColor));
242     }
243 
244     @ColorInt
getColorAttr(Context context, int attr)245     public static int getColorAttr(Context context, int attr) {
246         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
247         @ColorInt int colorAccent = ta.getColor(0, 0);
248         ta.recycle();
249         return colorAccent;
250     }
251 
getThemeAttr(Context context, int attr)252     public static int getThemeAttr(Context context, int attr) {
253         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
254         int theme = ta.getResourceId(0, 0);
255         ta.recycle();
256         return theme;
257     }
258 
getDrawable(Context context, int attr)259     public static Drawable getDrawable(Context context, int attr) {
260         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
261         Drawable drawable = ta.getDrawable(0);
262         ta.recycle();
263         return drawable;
264     }
265 
266     /**
267      * Determine whether a package is a "system package", in which case certain things (like
268      * disabling notifications or disabling the package altogether) should be disallowed.
269      */
isSystemPackage(Resources resources, PackageManager pm, PackageInfo pkg)270     public static boolean isSystemPackage(Resources resources, PackageManager pm, PackageInfo pkg) {
271         if (sSystemSignature == null) {
272             sSystemSignature = new Signature[]{getSystemSignature(pm)};
273         }
274         if (sPermissionControllerPackageName == null) {
275             sPermissionControllerPackageName = pm.getPermissionControllerPackageName();
276         }
277         if (sServicesSystemSharedLibPackageName == null) {
278             sServicesSystemSharedLibPackageName = pm.getServicesSystemSharedLibraryPackageName();
279         }
280         if (sSharedSystemSharedLibPackageName == null) {
281             sSharedSystemSharedLibPackageName = pm.getSharedSystemSharedLibraryPackageName();
282         }
283         return (sSystemSignature[0] != null
284                 && sSystemSignature[0].equals(getFirstSignature(pkg)))
285                 || pkg.packageName.equals(sPermissionControllerPackageName)
286                 || pkg.packageName.equals(sServicesSystemSharedLibPackageName)
287                 || pkg.packageName.equals(sSharedSystemSharedLibPackageName)
288                 || pkg.packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME)
289                 || isDeviceProvisioningPackage(resources, pkg.packageName);
290     }
291 
getFirstSignature(PackageInfo pkg)292     private static Signature getFirstSignature(PackageInfo pkg) {
293         if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
294             return pkg.signatures[0];
295         }
296         return null;
297     }
298 
getSystemSignature(PackageManager pm)299     private static Signature getSystemSignature(PackageManager pm) {
300         try {
301             final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
302             return getFirstSignature(sys);
303         } catch (NameNotFoundException e) {
304         }
305         return null;
306     }
307 
308     /**
309      * Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
310      * returns {@code false}.
311      */
isDeviceProvisioningPackage(Resources resources, String packageName)312     public static boolean isDeviceProvisioningPackage(Resources resources, String packageName) {
313         String deviceProvisioningPackage = resources.getString(
314                 com.android.internal.R.string.config_deviceProvisioningPackage);
315         return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName);
316     }
317 
318     /**
319      * Returns the Wifi icon resource for a given RSSI level.
320      *
321      * @param level The number of bars to show (0-4)
322      * @throws IllegalArgumentException if an invalid RSSI level is given.
323      */
getWifiIconResource(int level)324     public static int getWifiIconResource(int level) {
325         if (level < 0 || level >= WIFI_PIE.length) {
326             throw new IllegalArgumentException("No Wifi icon found for level: " + level);
327         }
328         return WIFI_PIE[level];
329     }
330 
getDefaultStorageManagerDaysToRetain(Resources resources)331     public static int getDefaultStorageManagerDaysToRetain(Resources resources) {
332         int defaultDays = Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_DEFAULT;
333         try {
334             defaultDays =
335                     resources.getInteger(
336                             com.android
337                                     .internal
338                                     .R
339                                     .integer
340                                     .config_storageManagerDaystoRetainDefault);
341         } catch (Resources.NotFoundException e) {
342             // We are likely in a test environment.
343         }
344         return defaultDays;
345     }
346 
isWifiOnly(Context context)347     public static boolean isWifiOnly(Context context) {
348         return !context.getSystemService(ConnectivityManager.class)
349                 .isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
350     }
351 
352     /** Returns if the automatic storage management feature is turned on or not. **/
isStorageManagerEnabled(Context context)353     public static boolean isStorageManagerEnabled(Context context) {
354         boolean isDefaultOn;
355         try {
356             // Turn off by default if the opt-in was shown.
357             isDefaultOn = !SystemProperties.getBoolean(STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY, true);
358         } catch (Resources.NotFoundException e) {
359             isDefaultOn = false;
360         }
361         return Settings.Secure.getInt(context.getContentResolver(),
362                 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
363                 isDefaultOn ? 1 : 0)
364                 != 0;
365     }
366 
367     /**
368      * get that {@link AudioManager#getMode()} is in ringing/call/communication(VoIP) status.
369      */
isAudioModeOngoingCall(Context context)370     public static boolean isAudioModeOngoingCall(Context context) {
371         final AudioManager audioManager = context.getSystemService(AudioManager.class);
372         final int audioMode = audioManager.getMode();
373         return audioMode == AudioManager.MODE_RINGTONE
374                 || audioMode == AudioManager.MODE_IN_CALL
375                 || audioMode == AudioManager.MODE_IN_COMMUNICATION;
376     }
377 }
378