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