• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.settingslib.applications;
18 
19 import android.app.Application;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageInfo;
26 import android.content.pm.PackageManager;
27 import android.content.pm.ResolveInfo;
28 import android.hardware.usb.IUsbManager;
29 import android.net.Uri;
30 import android.os.Environment;
31 import android.os.RemoteException;
32 import android.os.SystemProperties;
33 import android.os.UserHandle;
34 import android.text.TextUtils;
35 import android.util.Log;
36 
37 import com.android.settingslib.R;
38 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 public class AppUtils {
44     private static final String TAG = "AppUtils";
45 
46     /**
47      * This should normally only be set in robolectric tests, to avoid getting a method not found
48      * exception when calling the isInstantApp method of the ApplicationInfo class, because
49      * robolectric does not yet have an implementation of it.
50      */
51     private static InstantAppDataProvider sInstantAppDataProvider = null;
52 
53     private static final Intent sBrowserIntent;
54 
55     static {
56         sBrowserIntent = new Intent()
57                 .setAction(Intent.ACTION_VIEW)
58                 .addCategory(Intent.CATEGORY_BROWSABLE)
59                 .setData(Uri.parse("http:"));
60     }
61 
getLaunchByDefaultSummary(ApplicationsState.AppEntry appEntry, IUsbManager usbManager, PackageManager pm, Context context)62     public static CharSequence getLaunchByDefaultSummary(ApplicationsState.AppEntry appEntry,
63             IUsbManager usbManager, PackageManager pm, Context context) {
64         String packageName = appEntry.info.packageName;
65         boolean hasPreferred = hasPreferredActivities(pm, packageName)
66                 || hasUsbDefaults(usbManager, packageName);
67         int status = pm.getIntentVerificationStatusAsUser(packageName, UserHandle.myUserId());
68         // consider a visible current link-handling state to be any explicitly designated behavior
69         boolean hasDomainURLsPreference =
70                 status != PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
71         return context.getString(hasPreferred || hasDomainURLsPreference
72                 ? R.string.launch_defaults_some
73                 : R.string.launch_defaults_none);
74     }
75 
hasUsbDefaults(IUsbManager usbManager, String packageName)76     public static boolean hasUsbDefaults(IUsbManager usbManager, String packageName) {
77         try {
78             if (usbManager != null) {
79                 return usbManager.hasDefaults(packageName, UserHandle.myUserId());
80             }
81         } catch (RemoteException e) {
82             Log.e(TAG, "mUsbManager.hasDefaults", e);
83         }
84         return false;
85     }
86 
hasPreferredActivities(PackageManager pm, String packageName)87     public static boolean hasPreferredActivities(PackageManager pm, String packageName) {
88         // Get list of preferred activities
89         List<ComponentName> prefActList = new ArrayList<>();
90         // Intent list cannot be null. so pass empty list
91         List<IntentFilter> intentList = new ArrayList<>();
92         pm.getPreferredActivities(intentList, prefActList, packageName);
93         Log.d(TAG, "Have " + prefActList.size() + " number of activities in preferred list");
94         return prefActList.size() > 0;
95     }
96 
97     /**
98      * Returns a boolean indicating whether the given package should be considered an instant app
99      */
isInstant(ApplicationInfo info)100     public static boolean isInstant(ApplicationInfo info) {
101         if (sInstantAppDataProvider != null) {
102             if (sInstantAppDataProvider.isInstantApp(info)) {
103                 return true;
104             }
105         } else if (info.isInstantApp()) {
106             return true;
107         }
108 
109         // For debugging/testing, we support setting the following property to a comma-separated
110         // list of search terms (typically, but not necessarily, full package names) to match
111         // against the package names of the app.
112         String propVal = SystemProperties.get("settingsdebug.instant.packages");
113         if (propVal != null && !propVal.isEmpty() && info.packageName != null) {
114             String[] searchTerms = propVal.split(",");
115             if (searchTerms != null) {
116                 for (String term : searchTerms) {
117                     if (info.packageName.contains(term)) {
118                         return true;
119                     }
120                 }
121             }
122         }
123         return false;
124     }
125 
126     /** Returns the label for a given package. */
getApplicationLabel( PackageManager packageManager, String packageName)127     public static CharSequence getApplicationLabel(
128             PackageManager packageManager, String packageName) {
129         return com.android.settingslib.utils.applications.AppUtils
130                 .getApplicationLabel(packageManager, packageName);
131     }
132 
133     /**
134      * Returns a boolean indicating whether the given package is a hidden system module
135      */
isHiddenSystemModule(Context context, String packageName)136     public static boolean isHiddenSystemModule(Context context, String packageName) {
137         return ApplicationsState.getInstance((Application) context.getApplicationContext())
138                 .isHiddenModule(packageName);
139     }
140 
141     /**
142      * Returns a boolean indicating whether a given package is a system module.
143      */
isSystemModule(Context context, String packageName)144     public static boolean isSystemModule(Context context, String packageName) {
145         return ApplicationsState.getInstance((Application) context.getApplicationContext())
146                 .isSystemModule(packageName);
147     }
148 
149     /**
150      * Returns a boolean indicating whether a given package is a mainline module.
151      */
isMainlineModule(PackageManager pm, String packageName)152     public static boolean isMainlineModule(PackageManager pm, String packageName) {
153         // Check if the package is listed among the system modules.
154         try {
155             pm.getModuleInfo(packageName, 0 /* flags */);
156             return true;
157         } catch (PackageManager.NameNotFoundException e) {
158             //pass
159         }
160 
161         try {
162             final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
163             // Check if the package is contained in an APEX. There is no public API to properly
164             // check whether a given APK package comes from an APEX registered as module.
165             // Therefore we conservatively assume that any package scanned from an /apex path is
166             // a system package.
167             return pkg.applicationInfo.sourceDir.startsWith(
168                     Environment.getApexDirectory().getAbsolutePath());
169         } catch (PackageManager.NameNotFoundException e) {
170             return false;
171         }
172     }
173 
174     /**
175      * Returns a content description of an app name which distinguishes a personal app from a
176      * work app for accessibility purpose.
177      * If the app is in a work profile, then add a "work" prefix to the app name.
178      */
getAppContentDescription(Context context, String packageName, int userId)179     public static String getAppContentDescription(Context context, String packageName,
180             int userId) {
181         return com.android.settingslib.utils.applications.AppUtils.getAppContentDescription(context,
182                 packageName, userId);
183     }
184 
185     /**
186      * Returns a boolean indicating whether a given package is a browser app.
187      *
188      * An app is a "browser" if it has an activity resolution that wound up
189      * marked with the 'handleAllWebDataURI' flag.
190      */
isBrowserApp(Context context, String packageName, int userId)191     public static boolean isBrowserApp(Context context, String packageName, int userId) {
192         sBrowserIntent.setPackage(packageName);
193         final List<ResolveInfo> list = context.getPackageManager().queryIntentActivitiesAsUser(
194                 sBrowserIntent, PackageManager.MATCH_ALL, userId);
195         for (ResolveInfo info : list) {
196             if (info.activityInfo != null && info.handleAllWebDataURI) {
197                 return true;
198             }
199         }
200         return false;
201     }
202 
203     /**
204      * Returns a boolean indicating whether a given package is a default browser.
205      *
206      * @param packageName a given package.
207      * @return true if the given package is default browser.
208      */
isDefaultBrowser(Context context, String packageName)209     public static boolean isDefaultBrowser(Context context, String packageName) {
210         final String defaultBrowserPackage =
211                 context.getPackageManager().getDefaultBrowserPackageNameAsUser(
212                         UserHandle.myUserId());
213         return TextUtils.equals(packageName, defaultBrowserPackage);
214     }
215 }
216