Home | History | Annotate | Download | only in settingslib
      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.BitmapFactory;
     16 import android.graphics.Color;
     17 import android.graphics.drawable.Drawable;
     18 import android.graphics.drawable.LayerDrawable;
     19 import android.net.ConnectivityManager;
     20 import android.net.NetworkBadging;
     21 import android.os.BatteryManager;
     22 import android.os.UserManager;
     23 import android.print.PrintManager;
     24 import android.view.View;
     25 
     26 import com.android.internal.util.UserIcons;
     27 import com.android.settingslib.drawable.UserIconDrawable;
     28 
     29 import java.text.NumberFormat;
     30 
     31 public class Utils {
     32     private static Signature[] sSystemSignature;
     33     private static String sPermissionControllerPackageName;
     34     private static String sServicesSystemSharedLibPackageName;
     35     private static String sSharedSystemSharedLibPackageName;
     36 
     37     public static final int[] WIFI_PIE_FOR_BADGING = {
     38           com.android.internal.R.drawable.ic_signal_wifi_badged_0_bars,
     39           com.android.internal.R.drawable.ic_signal_wifi_badged_1_bar,
     40           com.android.internal.R.drawable.ic_signal_wifi_badged_2_bars,
     41           com.android.internal.R.drawable.ic_signal_wifi_badged_3_bars,
     42           com.android.internal.R.drawable.ic_signal_wifi_badged_4_bars
     43     };
     44 
     45     /**
     46      * Return string resource that best describes combination of tethering
     47      * options available on this device.
     48      */
     49     public static int getTetheringLabel(ConnectivityManager cm) {
     50         String[] usbRegexs = cm.getTetherableUsbRegexs();
     51         String[] wifiRegexs = cm.getTetherableWifiRegexs();
     52         String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
     53 
     54         boolean usbAvailable = usbRegexs.length != 0;
     55         boolean wifiAvailable = wifiRegexs.length != 0;
     56         boolean bluetoothAvailable = bluetoothRegexs.length != 0;
     57 
     58         if (wifiAvailable && usbAvailable && bluetoothAvailable) {
     59             return R.string.tether_settings_title_all;
     60         } else if (wifiAvailable && usbAvailable) {
     61             return R.string.tether_settings_title_all;
     62         } else if (wifiAvailable && bluetoothAvailable) {
     63             return R.string.tether_settings_title_all;
     64         } else if (wifiAvailable) {
     65             return R.string.tether_settings_title_wifi;
     66         } else if (usbAvailable && bluetoothAvailable) {
     67             return R.string.tether_settings_title_usb_bluetooth;
     68         } else if (usbAvailable) {
     69             return R.string.tether_settings_title_usb;
     70         } else {
     71             return R.string.tether_settings_title_bluetooth;
     72         }
     73     }
     74 
     75     /**
     76      * Returns a label for the user, in the form of "User: user name" or "Work profile".
     77      */
     78     public static String getUserLabel(Context context, UserInfo info) {
     79         String name = info != null ? info.name : null;
     80         if (info.isManagedProfile()) {
     81             // We use predefined values for managed profiles
     82             return context.getString(R.string.managed_user_title);
     83         } else if (info.isGuest()) {
     84             name = context.getString(R.string.user_guest);
     85         }
     86         if (name == null && info != null) {
     87             name = Integer.toString(info.id);
     88         } else if (info == null) {
     89             name = context.getString(R.string.unknown);
     90         }
     91         return context.getResources().getString(R.string.running_process_item_user_label, name);
     92     }
     93 
     94     /**
     95      * Returns a circular icon for a user.
     96      */
     97     public static UserIconDrawable getUserIcon(Context context, UserManager um, UserInfo user) {
     98         final int iconSize = UserIconDrawable.getSizeForList(context);
     99         if (user.isManagedProfile()) {
    100             // We use predefined values for managed profiles
    101             Bitmap b = BitmapFactory.decodeResource(context.getResources(),
    102                     com.android.internal.R.drawable.ic_corp_icon);
    103             return new UserIconDrawable(iconSize).setIcon(b).bake();
    104         }
    105         if (user.iconPath != null) {
    106             Bitmap icon = um.getUserIcon(user.id);
    107             if (icon != null) {
    108                 return new UserIconDrawable(iconSize).setIcon(icon).bake();
    109             }
    110         }
    111         return new UserIconDrawable(iconSize).setIconDrawable(
    112                 UserIcons.getDefaultUserIcon(user.id, /* light= */ false)).bake();
    113     }
    114 
    115     /** Formats a double from 0.0..100.0 with an option to round **/
    116     public static String formatPercentage(double percentage, boolean round) {
    117         final int localPercentage = round ? Math.round((float) percentage) : (int) percentage;
    118         return formatPercentage(localPercentage);
    119     }
    120 
    121     /** Formats the ratio of amount/total as a percentage. */
    122     public static String formatPercentage(long amount, long total) {
    123         return formatPercentage(((double) amount) / total);
    124     }
    125 
    126     /** Formats an integer from 0..100 as a percentage. */
    127     public static String formatPercentage(int percentage) {
    128         return formatPercentage(((double) percentage) / 100.0);
    129     }
    130 
    131     /** Formats a double from 0.0..1.0 as a percentage. */
    132     private static String formatPercentage(double percentage) {
    133         return NumberFormat.getPercentInstance().format(percentage);
    134     }
    135 
    136     public static int getBatteryLevel(Intent batteryChangedIntent) {
    137         int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
    138         int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
    139         return (level * 100) / scale;
    140     }
    141 
    142     public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) {
    143         int status = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_STATUS,
    144                 BatteryManager.BATTERY_STATUS_UNKNOWN);
    145         String statusString;
    146         if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
    147             statusString = res.getString(R.string.battery_info_status_charging);
    148         } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
    149             statusString = res.getString(R.string.battery_info_status_discharging);
    150         } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
    151             statusString = res.getString(R.string.battery_info_status_not_charging);
    152         } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
    153             statusString = res.getString(R.string.battery_info_status_full);
    154         } else {
    155             statusString = res.getString(R.string.battery_info_status_unknown);
    156         }
    157 
    158         return statusString;
    159     }
    160 
    161     @ColorInt
    162     public static int getColorAccent(Context context) {
    163         return getColorAttr(context, android.R.attr.colorAccent);
    164     }
    165 
    166     @ColorInt
    167     public static int getColorError(Context context) {
    168         return getColorAttr(context, android.R.attr.colorError);
    169     }
    170 
    171     @ColorInt
    172     public static int getDefaultColor(Context context, int resId) {
    173         final ColorStateList list =
    174                 context.getResources().getColorStateList(resId, context.getTheme());
    175 
    176         return list.getDefaultColor();
    177     }
    178 
    179     @ColorInt
    180     public static int getDisabled(Context context, int inputColor) {
    181         return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
    182     }
    183 
    184     @ColorInt
    185     public static int applyAlphaAttr(Context context, int attr, int inputColor) {
    186         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    187         float alpha = ta.getFloat(0, 0);
    188         ta.recycle();
    189         return applyAlpha(alpha, inputColor);
    190     }
    191 
    192     @ColorInt
    193     public static int applyAlpha(float alpha, int inputColor) {
    194         alpha *= Color.alpha(inputColor);
    195         return Color.argb((int) (alpha), Color.red(inputColor), Color.green(inputColor),
    196                 Color.blue(inputColor));
    197     }
    198 
    199     @ColorInt
    200     public static int getColorAttr(Context context, int attr) {
    201         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    202         @ColorInt int colorAccent = ta.getColor(0, 0);
    203         ta.recycle();
    204         return colorAccent;
    205     }
    206 
    207     public static int getThemeAttr(Context context, int attr) {
    208         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    209         int theme = ta.getResourceId(0, 0);
    210         ta.recycle();
    211         return theme;
    212     }
    213 
    214     public static Drawable getDrawable(Context context, int attr) {
    215         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    216         Drawable drawable = ta.getDrawable(0);
    217         ta.recycle();
    218         return drawable;
    219     }
    220 
    221     /**
    222      * Determine whether a package is a "system package", in which case certain things (like
    223      * disabling notifications or disabling the package altogether) should be disallowed.
    224      */
    225     public static boolean isSystemPackage(Resources resources, PackageManager pm, PackageInfo pkg) {
    226         if (sSystemSignature == null) {
    227             sSystemSignature = new Signature[]{ getSystemSignature(pm) };
    228         }
    229         if (sPermissionControllerPackageName == null) {
    230             sPermissionControllerPackageName = pm.getPermissionControllerPackageName();
    231         }
    232         if (sServicesSystemSharedLibPackageName == null) {
    233             sServicesSystemSharedLibPackageName = pm.getServicesSystemSharedLibraryPackageName();
    234         }
    235         if (sSharedSystemSharedLibPackageName == null) {
    236             sSharedSystemSharedLibPackageName = pm.getSharedSystemSharedLibraryPackageName();
    237         }
    238         return (sSystemSignature[0] != null
    239                         && sSystemSignature[0].equals(getFirstSignature(pkg)))
    240                 || pkg.packageName.equals(sPermissionControllerPackageName)
    241                 || pkg.packageName.equals(sServicesSystemSharedLibPackageName)
    242                 || pkg.packageName.equals(sSharedSystemSharedLibPackageName)
    243                 || pkg.packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME)
    244                 || isDeviceProvisioningPackage(resources, pkg.packageName);
    245     }
    246 
    247     private static Signature getFirstSignature(PackageInfo pkg) {
    248         if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
    249             return pkg.signatures[0];
    250         }
    251         return null;
    252     }
    253 
    254     private static Signature getSystemSignature(PackageManager pm) {
    255         try {
    256             final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
    257             return getFirstSignature(sys);
    258         } catch (NameNotFoundException e) {
    259         }
    260         return null;
    261     }
    262 
    263     /**
    264      * Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
    265      * returns {@code false}.
    266      */
    267     public static boolean isDeviceProvisioningPackage(Resources resources, String packageName) {
    268         String deviceProvisioningPackage = resources.getString(
    269                 com.android.internal.R.string.config_deviceProvisioningPackage);
    270         return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName);
    271     }
    272 
    273     /**
    274      * Returns a badged Wifi icon drawable.
    275      *
    276      * <p>The first layer contains the Wifi pie and the second layer contains the badge. Callers
    277      * should set the drawable to the appropriate size and tint color.
    278      *
    279      * @param context The caller's context (must have access to internal resources)
    280      * @param level The number of bars to show (0-4)
    281      * @param badge The badge enum {@see android.net.ScoredNetwork}
    282      *
    283      * @throws IllegalArgumentException if an invalid badge enum is given
    284      *
    285      * @deprecated TODO(sghuman): Finalize the form of this method and then move it to a new
    286      *         location.
    287      */
    288     public static LayerDrawable getBadgedWifiIcon(Context context, int level, int badge) {
    289         return new LayerDrawable(
    290                 new Drawable[] {
    291                         context.getDrawable(WIFI_PIE_FOR_BADGING[level]),
    292                         context.getDrawable(getWifiBadgeResource(badge))
    293                 });
    294     }
    295 
    296     /**
    297      * Returns the resource id for the given badge or {@link View.NO_ID} if no badge is to be shown.
    298      *
    299      * @throws IllegalArgumentException if the given badge value is not supported.
    300      */
    301     public static int getWifiBadgeResource(int badge) {
    302         switch (badge) {
    303             case NetworkBadging.BADGING_NONE:
    304                 return View.NO_ID;
    305             case NetworkBadging.BADGING_SD:
    306                 return com.android.internal.R.drawable.ic_signal_wifi_badged_sd;
    307             case NetworkBadging.BADGING_HD:
    308                 return com.android.internal.R.drawable.ic_signal_wifi_badged_hd;
    309             case NetworkBadging.BADGING_4K:
    310                 return com.android.internal.R.drawable.ic_signal_wifi_badged_4k;
    311             default:
    312                 throw new IllegalArgumentException(
    313                     "No badge resource found for badge value: " + badge);
    314         }
    315     }
    316 }
    317