• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.tv.settings.library.about;
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.res.ColorStateList;
11 import android.content.res.TypedArray;
12 import android.graphics.Bitmap;
13 import android.graphics.Canvas;
14 import android.graphics.Color;
15 import android.graphics.ColorFilter;
16 import android.graphics.ColorMatrix;
17 import android.graphics.ColorMatrixColorFilter;
18 import android.graphics.drawable.Drawable;
19 import android.media.AudioManager;
20 import android.os.BatteryManager;
21 import android.telephony.AccessNetworkConstants;
22 import android.telephony.NetworkRegistrationInfo;
23 import android.telephony.ServiceState;
24 import android.telephony.TelephonyManager;
25 
26 import androidx.annotation.NonNull;
27 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
28 import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
29 
30 import java.text.NumberFormat;
31 
32 public class Utils {
33 
34     /** Formats a double from 0.0..100.0 with an option to round **/
formatPercentage(double percentage, boolean round)35     public static String formatPercentage(double percentage, boolean round) {
36         final int localPercentage = round ? Math.round((float) percentage) : (int) percentage;
37         return formatPercentage(localPercentage);
38     }
39 
40     /** Formats the ratio of amount/total as a percentage. */
formatPercentage(long amount, long total)41     public static String formatPercentage(long amount, long total) {
42         return formatPercentage(((double) amount) / total);
43     }
44 
45     /** Formats an integer from 0..100 as a percentage. */
formatPercentage(int percentage)46     public static String formatPercentage(int percentage) {
47         return formatPercentage(((double) percentage) / 100.0);
48     }
49 
50     /** Formats a double from 0.0..1.0 as a percentage. */
formatPercentage(double percentage)51     public static String formatPercentage(double percentage) {
52         return NumberFormat.getPercentInstance().format(percentage);
53     }
54 
getBatteryLevel(Intent batteryChangedIntent)55     public static int getBatteryLevel(Intent batteryChangedIntent) {
56         int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
57         int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
58         return (level * 100) / scale;
59     }
60 
getColorAccent(Context context)61     public static ColorStateList getColorAccent(Context context) {
62         return getColorAttr(context, android.R.attr.colorAccent);
63     }
64 
getColorError(Context context)65     public static ColorStateList getColorError(Context context) {
66         return getColorAttr(context, android.R.attr.colorError);
67     }
68 
69     @ColorInt
getColorAccentDefaultColor(Context context)70     public static int getColorAccentDefaultColor(Context context) {
71         return getColorAttrDefaultColor(context, android.R.attr.colorAccent);
72     }
73 
74     @ColorInt
getColorErrorDefaultColor(Context context)75     public static int getColorErrorDefaultColor(Context context) {
76         return getColorAttrDefaultColor(context, android.R.attr.colorError);
77     }
78 
79     @ColorInt
getColorStateListDefaultColor(Context context, int resId)80     public static int getColorStateListDefaultColor(Context context, int resId) {
81         final ColorStateList list =
82                 context.getResources().getColorStateList(resId, context.getTheme());
83         return list.getDefaultColor();
84     }
85 
86     /**
87      * This method computes disabled color from normal color
88      *
89      * @param context    the context
90      * @param inputColor normal color.
91      * @return disabled color.
92      */
93     @ColorInt
getDisabled(Context context, int inputColor)94     public static int getDisabled(Context context, int inputColor) {
95         return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
96     }
97 
98     @ColorInt
applyAlphaAttr(Context context, int attr, int inputColor)99     public static int applyAlphaAttr(Context context, int attr, int inputColor) {
100         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
101         float alpha = ta.getFloat(0, 0);
102         ta.recycle();
103         return applyAlpha(alpha, inputColor);
104     }
105 
106     @ColorInt
applyAlpha(float alpha, int inputColor)107     public static int applyAlpha(float alpha, int inputColor) {
108         alpha *= Color.alpha(inputColor);
109         return Color.argb((int) (alpha), Color.red(inputColor), Color.green(inputColor),
110                 Color.blue(inputColor));
111     }
112 
113     @ColorInt
getColorAttrDefaultColor(Context context, int attr)114     public static int getColorAttrDefaultColor(Context context, int attr) {
115         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
116         @ColorInt int colorAccent = ta.getColor(0, 0);
117         ta.recycle();
118         return colorAccent;
119     }
120 
getColorAttr(Context context, int attr)121     public static ColorStateList getColorAttr(Context context, int attr) {
122         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
123         ColorStateList stateList = null;
124         try {
125             stateList = ta.getColorStateList(0);
126         } finally {
127             ta.recycle();
128         }
129         return stateList;
130     }
131 
getThemeAttr(Context context, int attr)132     public static int getThemeAttr(Context context, int attr) {
133         return getThemeAttr(context, attr, 0);
134     }
135 
getThemeAttr(Context context, int attr, int defaultValue)136     public static int getThemeAttr(Context context, int attr, int defaultValue) {
137         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
138         int theme = ta.getResourceId(0, defaultValue);
139         ta.recycle();
140         return theme;
141     }
142 
getDrawable(Context context, int attr)143     public static Drawable getDrawable(Context context, int attr) {
144         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
145         Drawable drawable = ta.getDrawable(0);
146         ta.recycle();
147         return drawable;
148     }
149 
150     /**
151      * Create a color matrix suitable for a ColorMatrixColorFilter that modifies only the color but
152      * preserves the alpha for a given drawable
153      *
154      * @return a color matrix that uses the source alpha and given color
155      */
getAlphaInvariantColorMatrixForColor(@olorInt int color)156     public static ColorMatrix getAlphaInvariantColorMatrixForColor(@ColorInt int color) {
157         int r = Color.red(color);
158         int g = Color.green(color);
159         int b = Color.blue(color);
160 
161         ColorMatrix cm = new ColorMatrix(new float[]{
162                 0, 0, 0, 0, r,
163                 0, 0, 0, 0, g,
164                 0, 0, 0, 0, b,
165                 0, 0, 0, 1, 0});
166 
167         return cm;
168     }
169 
170     /**
171      * Create a ColorMatrixColorFilter to tint a drawable but retain its alpha characteristics
172      *
173      * @return a ColorMatrixColorFilter which changes the color of the output but is invariant on
174      * the source alpha
175      */
getAlphaInvariantColorFilterForColor(@olorInt int color)176     public static ColorFilter getAlphaInvariantColorFilterForColor(@ColorInt int color) {
177         return new ColorMatrixColorFilter(getAlphaInvariantColorMatrixForColor(color));
178     }
179 
180 
getFirstSignature(PackageInfo pkg)181     private static Signature getFirstSignature(PackageInfo pkg) {
182         if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
183             return pkg.signatures[0];
184         }
185         return null;
186     }
187 
getSystemSignature(PackageManager pm)188     private static Signature getSystemSignature(PackageManager pm) {
189         try {
190             final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
191             return getFirstSignature(sys);
192         } catch (NameNotFoundException e) {
193         }
194         return null;
195     }
196 
isWifiOnly(Context context)197     public static boolean isWifiOnly(Context context) {
198         return !context.getSystemService(TelephonyManager.class).isDataCapable();
199     }
200 
201 
202 
203     /**
204      * get that {@link AudioManager#getMode()} is in ringing/call/communication(VoIP) status.
205      */
isAudioModeOngoingCall(Context context)206     public static boolean isAudioModeOngoingCall(Context context) {
207         final AudioManager audioManager = context.getSystemService(AudioManager.class);
208         final int audioMode = audioManager.getMode();
209         return audioMode == AudioManager.MODE_RINGTONE
210                 || audioMode == AudioManager.MODE_IN_CALL
211                 || audioMode == AudioManager.MODE_IN_COMMUNICATION;
212     }
213 
214     /**
215      * Return the service state is in-service or not.
216      * To make behavior consistent with SystemUI and Settings/AboutPhone/SIM status UI
217      *
218      * @param serviceState Service state. {@link ServiceState}
219      */
isInService(ServiceState serviceState)220     public static boolean isInService(ServiceState serviceState) {
221         if (serviceState == null) {
222             return false;
223         }
224         int state = getCombinedServiceState(serviceState);
225         return state != ServiceState.STATE_POWER_OFF
226                 && state != ServiceState.STATE_OUT_OF_SERVICE
227                 && state != ServiceState.STATE_EMERGENCY_ONLY;
228     }
229 
230     /**
231      * Return the combined service state.
232      * To make behavior consistent with SystemUI and Settings/AboutPhone/SIM status UI
233      *
234      * @param serviceState Service state. {@link ServiceState}
235      */
getCombinedServiceState(ServiceState serviceState)236     public static int getCombinedServiceState(ServiceState serviceState) {
237         if (serviceState == null) {
238             return ServiceState.STATE_OUT_OF_SERVICE;
239         }
240 
241         // Consider the device to be in service if either voice or data
242         // service is available. Some SIM cards are marketed as data-only
243         // and do not support voice service, and on these SIM cards, we
244         // want to show signal bars for data service as well as the "no
245         // service" or "emergency calls only" text that indicates that voice
246         // is not available. Note that we ignore the IWLAN service state
247         // because that state indicates the use of VoWIFI and not cell service
248         final int state = serviceState.getState();
249         final int dataState = serviceState.getDataRegistrationState();
250 
251         if (state == ServiceState.STATE_OUT_OF_SERVICE
252                 || state == ServiceState.STATE_EMERGENCY_ONLY) {
253             if (dataState == ServiceState.STATE_IN_SERVICE && isNotInIwlan(serviceState)) {
254                 return ServiceState.STATE_IN_SERVICE;
255             }
256         }
257         return state;
258     }
259 
isNotInIwlan(ServiceState serviceState)260     private static boolean isNotInIwlan(ServiceState serviceState) {
261         final NetworkRegistrationInfo networkRegWlan = serviceState.getNetworkRegistrationInfo(
262                 NetworkRegistrationInfo.DOMAIN_PS,
263                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
264         if (networkRegWlan == null) {
265             return true;
266         }
267 
268         final boolean isInIwlan = (networkRegWlan.getRegistrationState()
269                 == NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
270                 || (networkRegWlan.getRegistrationState()
271                 == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
272         return !isInIwlan;
273     }
274 
275     /**
276      * Returns a bitmap with rounded corner.
277      *
278      * @param context      application context.
279      * @param source       bitmap to apply round corner.
280      * @param cornerRadius corner radius value.
281      */
convertCornerRadiusBitmap(@onNull Context context, @NonNull Bitmap source, @NonNull float cornerRadius)282     public static Bitmap convertCornerRadiusBitmap(@NonNull Context context,
283             @NonNull Bitmap source, @NonNull float cornerRadius) {
284         final Bitmap roundedBitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(),
285                 Bitmap.Config.ARGB_8888);
286         final RoundedBitmapDrawable drawable =
287                 RoundedBitmapDrawableFactory.create(context.getResources(), source);
288         drawable.setAntiAlias(true);
289         drawable.setCornerRadius(cornerRadius);
290         final Canvas canvas = new Canvas(roundedBitmap);
291         drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
292         drawable.draw(canvas);
293         return roundedBitmap;
294     }
295 }
296