• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.companiondevicemanager;
18 
19 import android.annotation.NonNull;
20 import android.annotation.StringRes;
21 import android.content.Context;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManager.ApplicationInfoFlags;
25 import android.content.res.Configuration;
26 import android.graphics.drawable.Drawable;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Looper;
30 import android.os.Parcel;
31 import android.os.ResultReceiver;
32 import android.text.Html;
33 import android.text.Spanned;
34 
35 /**
36  * Utilities.
37  */
38 class Utils {
39     private static final String COMPANION_DEVICE_ACTIVITY_VENDOR_ICON =
40             "android.companion.vendor_icon";
41     private static final String COMPANION_DEVICE_ACTIVITY_VENDOR_NAME =
42             "android.companion.vendor_name";
43 
44     /**
45      * Convert an instance of a "locally-defined" ResultReceiver to an instance of
46      * {@link android.os.ResultReceiver} itself, which the receiving process will be able to
47      * unmarshall.
48      */
prepareResultReceiverForIpc(T resultReceiver)49     static <T extends ResultReceiver> ResultReceiver prepareResultReceiverForIpc(T resultReceiver) {
50         final Parcel parcel = Parcel.obtain();
51         resultReceiver.writeToParcel(parcel, 0);
52         parcel.setDataPosition(0);
53 
54         final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel);
55         parcel.recycle();
56 
57         return ipcFriendly;
58     }
59 
getApplicationLabel( @onNull Context context, @NonNull String packageName, int userId)60     static @NonNull CharSequence getApplicationLabel(
61             @NonNull Context context, @NonNull String packageName, int userId)
62             throws PackageManager.NameNotFoundException {
63         final PackageManager packageManager = context.getPackageManager();
64 
65         final ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
66                 packageName, PackageManager.ApplicationInfoFlags.of(0), userId);
67 
68         return packageManager.getApplicationLabel(appInfo);
69     }
70 
getApplicationIcon(@onNull Context context, @NonNull String packageName)71     static @NonNull Drawable getApplicationIcon(@NonNull Context context,
72             @NonNull String packageName) throws PackageManager.NameNotFoundException {
73         final PackageManager packageManager = context.getPackageManager();
74         return packageManager.getApplicationIcon(packageName);
75     }
76 
getHtmlFromResources( @onNull Context context, @StringRes int resId, CharSequence... formatArgs)77     static Spanned getHtmlFromResources(
78             @NonNull Context context, @StringRes int resId, CharSequence... formatArgs) {
79         final String[] escapedArgs = new String[formatArgs.length];
80         for (int i = 0; i < escapedArgs.length; i++) {
81             escapedArgs[i] = Html.escapeHtml(formatArgs[i]);
82         }
83         final String plain = context.getString(resId, (Object[]) escapedArgs);
84         return Html.fromHtml(plain, 0);
85     }
86 
getVendorHeaderIcon(@onNull Context context, @NonNull String packageName, int userId)87     static @NonNull Drawable getVendorHeaderIcon(@NonNull Context context,
88             @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
89         final ApplicationInfo appInfo = getApplicationInfo(context, packageName, userId);
90         final Bundle bundle = appInfo.metaData;
91         int resId = bundle == null ? 0 : bundle.getInt(COMPANION_DEVICE_ACTIVITY_VENDOR_ICON, 0);
92 
93         if (bundle == null || resId == 0) {
94             return getApplicationIcon(context, packageName);
95         }
96 
97         return context.createPackageContext(packageName, /* flags= */ 0).getDrawable(resId);
98     }
99 
getVendorHeaderName(@onNull Context context, @NonNull String packageName, int userId)100     static CharSequence getVendorHeaderName(@NonNull Context context,
101             @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
102         final ApplicationInfo appInfo = getApplicationInfo(context, packageName, userId);
103         final Bundle bundle = appInfo.metaData;
104 
105         if (bundle == null) {
106             return "";
107         }
108 
109         return appInfo.metaData.getCharSequence(COMPANION_DEVICE_ACTIVITY_VENDOR_NAME, "");
110     }
111 
hasVendorIcon(@onNull Context context, @NonNull String packageName, int userId)112     static boolean hasVendorIcon(@NonNull Context context,
113             @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
114         final ApplicationInfo appInfo = getApplicationInfo(context, packageName, userId);
115         final Bundle bundle = appInfo.metaData;
116 
117         if (bundle == null) {
118             return false;
119         } else {
120             return bundle.getInt(COMPANION_DEVICE_ACTIVITY_VENDOR_ICON) != 0;
121         }
122     }
123 
isDarkTheme(@onNull Context context)124     private static boolean isDarkTheme(@NonNull Context context) {
125         int nightModeFlags = context.getResources().getConfiguration().uiMode
126                 & Configuration.UI_MODE_NIGHT_MASK;
127         return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
128     }
129 
130     // Get image color for the corresponding theme.
getImageColor(@onNull Context context)131     static int getImageColor(@NonNull Context context) {
132         if (isDarkTheme(context)) {
133             return android.R.color.system_accent1_200;
134         } else {
135             return android.R.color.system_accent1_600;
136         }
137     }
138     /**
139      * Getting ApplicationInfo from meta-data.
140      */
getApplicationInfo(@onNull Context context, @NonNull String packageName, int userId)141     private static @NonNull ApplicationInfo getApplicationInfo(@NonNull Context context,
142             @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
143         final PackageManager packageManager = context.getPackageManager();
144         final ApplicationInfoFlags flags = ApplicationInfoFlags.of(PackageManager.GET_META_DATA);
145         final ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
146                 packageName, flags, userId);
147 
148         return appInfo;
149     }
150 
getIcon(@onNull Context context, int resId)151     static @NonNull Drawable getIcon(@NonNull Context context, int resId) {
152         Drawable icon = context.getResources().getDrawable(resId, null);
153         return icon;
154     }
155 
runOnMainThread(Runnable runnable)156     static void runOnMainThread(Runnable runnable) {
157         if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
158             runnable.run();
159         } else {
160             Handler.getMain().post(runnable);
161         }
162     }
163 
Utils()164     private Utils() {
165     }
166 }
167