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