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.IntentFilter;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.PackageManager;
25 import android.hardware.usb.IUsbManager;
26 import android.os.RemoteException;
27 import android.os.SystemProperties;
28 import android.os.UserHandle;
29 import android.util.Log;
30 
31 import com.android.settingslib.R;
32 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 public class AppUtils {
38     private static final String TAG = "AppUtils";
39 
40     /**
41      * This should normally only be set in robolectric tests, to avoid getting a method not found
42      * exception when calling the isInstantApp method of the ApplicationInfo class, because
43      * robolectric does not yet have an implementation of it.
44      */
45     private static InstantAppDataProvider sInstantAppDataProvider = null;
46 
getLaunchByDefaultSummary(ApplicationsState.AppEntry appEntry, IUsbManager usbManager, PackageManager pm, Context context)47     public static CharSequence getLaunchByDefaultSummary(ApplicationsState.AppEntry appEntry,
48             IUsbManager usbManager, PackageManager pm, Context context) {
49         String packageName = appEntry.info.packageName;
50         boolean hasPreferred = hasPreferredActivities(pm, packageName)
51                 || hasUsbDefaults(usbManager, packageName);
52         int status = pm.getIntentVerificationStatusAsUser(packageName, UserHandle.myUserId());
53         // consider a visible current link-handling state to be any explicitly designated behavior
54         boolean hasDomainURLsPreference =
55                 status != PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
56         return context.getString(hasPreferred || hasDomainURLsPreference
57                 ? R.string.launch_defaults_some
58                 : R.string.launch_defaults_none);
59     }
60 
hasUsbDefaults(IUsbManager usbManager, String packageName)61     public static boolean hasUsbDefaults(IUsbManager usbManager, String packageName) {
62         try {
63             if (usbManager != null) {
64                 return usbManager.hasDefaults(packageName, UserHandle.myUserId());
65             }
66         } catch (RemoteException e) {
67             Log.e(TAG, "mUsbManager.hasDefaults", e);
68         }
69         return false;
70     }
71 
hasPreferredActivities(PackageManager pm, String packageName)72     public static boolean hasPreferredActivities(PackageManager pm, String packageName) {
73         // Get list of preferred activities
74         List<ComponentName> prefActList = new ArrayList<>();
75         // Intent list cannot be null. so pass empty list
76         List<IntentFilter> intentList = new ArrayList<>();
77         pm.getPreferredActivities(intentList, prefActList, packageName);
78         Log.d(TAG, "Have " + prefActList.size() + " number of activities in preferred list");
79         return prefActList.size() > 0;
80     }
81 
82     /**
83      * Returns a boolean indicating whether the given package should be considered an instant app
84      */
isInstant(ApplicationInfo info)85     public static boolean isInstant(ApplicationInfo info) {
86         if (sInstantAppDataProvider != null) {
87             if (sInstantAppDataProvider.isInstantApp(info)) {
88                 return true;
89             }
90         } else if (info.isInstantApp()) {
91             return true;
92         }
93 
94         // For debugging/testing, we support setting the following property to a comma-separated
95         // list of search terms (typically, but not necessarily, full package names) to match
96         // against the package names of the app.
97         String propVal = SystemProperties.get("settingsdebug.instant.packages");
98         if (propVal != null && !propVal.isEmpty() && info.packageName != null) {
99             String[] searchTerms = propVal.split(",");
100             if (searchTerms != null) {
101                 for (String term : searchTerms) {
102                     if (info.packageName.contains(term)) {
103                         return true;
104                     }
105                 }
106             }
107         }
108         return false;
109     }
110 
111     /** Returns the label for a given package. */
getApplicationLabel( PackageManager packageManager, String packageName)112     public static CharSequence getApplicationLabel(
113             PackageManager packageManager, String packageName) {
114         try {
115             final ApplicationInfo appInfo =
116                     packageManager.getApplicationInfo(
117                             packageName,
118                             PackageManager.MATCH_DISABLED_COMPONENTS
119                                     | PackageManager.MATCH_ANY_USER);
120             return appInfo.loadLabel(packageManager);
121         } catch (PackageManager.NameNotFoundException e) {
122             Log.w(TAG, "Unable to find info for package: " + packageName);
123         }
124         return null;
125     }
126 
127     /**
128      * Returns a boolean indicating whether the given package is a hidden system module
129      */
isHiddenSystemModule(Context context, String packageName)130     public static boolean isHiddenSystemModule(Context context, String packageName) {
131         return ApplicationsState.getInstance((Application) context.getApplicationContext())
132             .isHiddenModule(packageName);
133     }
134 
135     /**
136      * Returns a boolean indicating whether a given package is a system module.
137      */
isSystemModule(Context context, String packageName)138     public static boolean isSystemModule(Context context, String packageName) {
139         return ApplicationsState.getInstance((Application) context.getApplicationContext())
140                 .isSystemModule(packageName);
141     }
142 
143 }
144