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.UserInfo; 10 import android.content.pm.Signature; 11 import android.content.res.Resources; 12 import android.content.res.TypedArray; 13 import android.graphics.Bitmap; 14 import android.graphics.BitmapFactory; 15 import android.graphics.drawable.Drawable; 16 import android.net.ConnectivityManager; 17 import android.os.BatteryManager; 18 import android.os.UserManager; 19 import android.print.PrintManager; 20 import com.android.internal.util.UserIcons; 21 import com.android.settingslib.drawable.UserIconDrawable; 22 23 import java.text.NumberFormat; 24 25 public class Utils { 26 private static Signature[] sSystemSignature; 27 private static String sPermissionControllerPackageName; 28 private static String sServicesSystemSharedLibPackageName; 29 private static String sSharedSystemSharedLibPackageName; 30 31 /** 32 * Return string resource that best describes combination of tethering 33 * options available on this device. 34 */ 35 public static int getTetheringLabel(ConnectivityManager cm) { 36 String[] usbRegexs = cm.getTetherableUsbRegexs(); 37 String[] wifiRegexs = cm.getTetherableWifiRegexs(); 38 String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs(); 39 40 boolean usbAvailable = usbRegexs.length != 0; 41 boolean wifiAvailable = wifiRegexs.length != 0; 42 boolean bluetoothAvailable = bluetoothRegexs.length != 0; 43 44 if (wifiAvailable && usbAvailable && bluetoothAvailable) { 45 return R.string.tether_settings_title_all; 46 } else if (wifiAvailable && usbAvailable) { 47 return R.string.tether_settings_title_all; 48 } else if (wifiAvailable && bluetoothAvailable) { 49 return R.string.tether_settings_title_all; 50 } else if (wifiAvailable) { 51 return R.string.tether_settings_title_wifi; 52 } else if (usbAvailable && bluetoothAvailable) { 53 return R.string.tether_settings_title_usb_bluetooth; 54 } else if (usbAvailable) { 55 return R.string.tether_settings_title_usb; 56 } else { 57 return R.string.tether_settings_title_bluetooth; 58 } 59 } 60 61 /** 62 * Returns a label for the user, in the form of "User: user name" or "Work profile". 63 */ 64 public static String getUserLabel(Context context, UserInfo info) { 65 String name = info != null ? info.name : null; 66 if (info.isManagedProfile()) { 67 // We use predefined values for managed profiles 68 return context.getString(R.string.managed_user_title); 69 } else if (info.isGuest()) { 70 name = context.getString(R.string.user_guest); 71 } 72 if (name == null && info != null) { 73 name = Integer.toString(info.id); 74 } else if (info == null) { 75 name = context.getString(R.string.unknown); 76 } 77 return context.getResources().getString(R.string.running_process_item_user_label, name); 78 } 79 80 /** 81 * Returns a circular icon for a user. 82 */ 83 public static UserIconDrawable getUserIcon(Context context, UserManager um, UserInfo user) { 84 final int iconSize = UserIconDrawable.getSizeForList(context); 85 if (user.isManagedProfile()) { 86 // We use predefined values for managed profiles 87 Bitmap b = BitmapFactory.decodeResource(context.getResources(), 88 com.android.internal.R.drawable.ic_corp_icon); 89 return new UserIconDrawable(iconSize).setIcon(b).bake(); 90 } 91 if (user.iconPath != null) { 92 Bitmap icon = um.getUserIcon(user.id); 93 if (icon != null) { 94 return new UserIconDrawable(iconSize).setIcon(icon).bake(); 95 } 96 } 97 return new UserIconDrawable(iconSize).setIconDrawable( 98 UserIcons.getDefaultUserIcon(user.id, /* light= */ false)).bake(); 99 } 100 101 /** Formats the ratio of amount/total as a percentage. */ 102 public static String formatPercentage(long amount, long total) { 103 return formatPercentage(((double) amount) / total); 104 } 105 106 /** Formats an integer from 0..100 as a percentage. */ 107 public static String formatPercentage(int percentage) { 108 return formatPercentage(((double) percentage) / 100.0); 109 } 110 111 /** Formats a double from 0.0..1.0 as a percentage. */ 112 private static String formatPercentage(double percentage) { 113 return NumberFormat.getPercentInstance().format(percentage); 114 } 115 116 public static int getBatteryLevel(Intent batteryChangedIntent) { 117 int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); 118 int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); 119 return (level * 100) / scale; 120 } 121 122 public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) { 123 return Utils.getBatteryStatus(res, batteryChangedIntent, false); 124 } 125 126 public static String getBatteryStatus(Resources res, Intent batteryChangedIntent, 127 boolean shortString) { 128 int plugType = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); 129 int status = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_STATUS, 130 BatteryManager.BATTERY_STATUS_UNKNOWN); 131 String statusString; 132 if (status == BatteryManager.BATTERY_STATUS_CHARGING) { 133 int resId; 134 if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { 135 resId = shortString ? R.string.battery_info_status_charging_ac_short 136 : R.string.battery_info_status_charging_ac; 137 } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { 138 resId = shortString ? R.string.battery_info_status_charging_usb_short 139 : R.string.battery_info_status_charging_usb; 140 } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { 141 resId = shortString ? R.string.battery_info_status_charging_wireless_short 142 : R.string.battery_info_status_charging_wireless; 143 } else { 144 resId = R.string.battery_info_status_charging; 145 } 146 statusString = res.getString(resId); 147 } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { 148 statusString = res.getString(R.string.battery_info_status_discharging); 149 } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { 150 statusString = res.getString(R.string.battery_info_status_not_charging); 151 } else if (status == BatteryManager.BATTERY_STATUS_FULL) { 152 statusString = res.getString(R.string.battery_info_status_full); 153 } else { 154 statusString = res.getString(R.string.battery_info_status_unknown); 155 } 156 157 return statusString; 158 } 159 160 @ColorInt 161 public static int getColorAccent(Context context) { 162 TypedArray ta = context.obtainStyledAttributes(new int[]{android.R.attr.colorAccent}); 163 @ColorInt int colorAccent = ta.getColor(0, 0); 164 ta.recycle(); 165 return colorAccent; 166 } 167 168 /** 169 * Determine whether a package is a "system package", in which case certain things (like 170 * disabling notifications or disabling the package altogether) should be disallowed. 171 */ 172 public static boolean isSystemPackage(Resources resources, PackageManager pm, PackageInfo pkg) { 173 if (sSystemSignature == null) { 174 sSystemSignature = new Signature[]{ getSystemSignature(pm) }; 175 } 176 if (sPermissionControllerPackageName == null) { 177 sPermissionControllerPackageName = pm.getPermissionControllerPackageName(); 178 } 179 if (sServicesSystemSharedLibPackageName == null) { 180 sServicesSystemSharedLibPackageName = pm.getServicesSystemSharedLibraryPackageName(); 181 } 182 if (sSharedSystemSharedLibPackageName == null) { 183 sSharedSystemSharedLibPackageName = pm.getSharedSystemSharedLibraryPackageName(); 184 } 185 return (sSystemSignature[0] != null 186 && sSystemSignature[0].equals(getFirstSignature(pkg))) 187 || pkg.packageName.equals(sPermissionControllerPackageName) 188 || pkg.packageName.equals(sServicesSystemSharedLibPackageName) 189 || pkg.packageName.equals(sSharedSystemSharedLibPackageName) 190 || pkg.packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME) 191 || isDeviceProvisioningPackage(resources, pkg.packageName); 192 } 193 194 private static Signature getFirstSignature(PackageInfo pkg) { 195 if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) { 196 return pkg.signatures[0]; 197 } 198 return null; 199 } 200 201 private static Signature getSystemSignature(PackageManager pm) { 202 try { 203 final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES); 204 return getFirstSignature(sys); 205 } catch (NameNotFoundException e) { 206 } 207 return null; 208 } 209 210 /** 211 * Returns {@code true} if the supplied package is the device provisioning app. Otherwise, 212 * returns {@code false}. 213 */ 214 public static boolean isDeviceProvisioningPackage(Resources resources, String packageName) { 215 String deviceProvisioningPackage = resources.getString( 216 com.android.internal.R.string.config_deviceProvisioningPackage); 217 return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName); 218 } 219 } 220