2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.launcher3.util;
19 import android.app.AppOpsManager;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.LauncherActivityInfo;
24 import android.content.pm.PackageManager;
25 import android.content.pm.PackageManager.NameNotFoundException;
26 import android.content.pm.ResolveInfo;
27 import android.net.Uri;
28 import android.os.Build;
29 import android.os.UserHandle;
30 import android.text.TextUtils;
32 import com.android.launcher3.AppInfo;
33 import com.android.launcher3.Utilities;
34 import com.android.launcher3.compat.LauncherAppsCompat;
36 import java.util.List;
39 * Utility methods using package manager
41 public class PackageManagerHelper {
43 private static final int FLAG_SUSPENDED = 1<<30;
45 private final Context mContext;
46 private final PackageManager mPm;
48 public PackageManagerHelper(Context context) {
50 mPm = context.getPackageManager();
54 * Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't
55 * guarantee that the app is on SD card.
57 public boolean isAppOnSdcard(String packageName) {
58 return isAppEnabled(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
61 public boolean isAppEnabled(String packageName) {
62 return isAppEnabled(packageName, 0);
65 public boolean isAppEnabled(String packageName, int flags) {
67 ApplicationInfo info = mPm.getApplicationInfo(packageName, flags);
68 return info != null && info.enabled;
69 } catch (PackageManager.NameNotFoundException e) {
74 public boolean isAppSuspended(String packageName) {
76 ApplicationInfo info = mPm.getApplicationInfo(packageName, 0);
77 return info != null && isAppSuspended(info);
78 } catch (PackageManager.NameNotFoundException e) {
83 public boolean isSafeMode() {
84 return mPm.isSafeMode();
87 public Intent getAppLaunchIntent(String pkg, UserHandle user) {
88 List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mContext)
89 .getActivityList(pkg, user);
90 return activities.isEmpty() ? null :
91 AppInfo.makeLaunchIntent(mContext, activities.get(0), user);
94 public static boolean isAppSuspended(ApplicationInfo info) {
95 // The value of FLAG_SUSPENDED was reused by a hidden constant
96 // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N
98 if (Utilities.ATLEAST_NOUGAT) {
99 return (info.flags & FLAG_SUSPENDED) != 0;
106 * Returns true if {@param srcPackage} has the permission required to start the activity from
107 * {@param intent}. If {@param srcPackage} is null, then the activity should not need
110 public boolean hasPermissionForActivity(Intent intent, String srcPackage) {
111 ResolveInfo target = mPm.resolveActivity(intent, 0);
112 if (target == null) {
113 // Not a valid target
116 if (TextUtils.isEmpty(target.activityInfo.permission)) {
117 // No permission is needed
120 if (TextUtils.isEmpty(srcPackage)) {
121 // The activity requires some permission but there is no source.
125 // Source does not have sufficient permissions.
126 if(mPm.checkPermission(target.activityInfo.permission, srcPackage) !=
127 PackageManager.PERMISSION_GRANTED) {
131 if (!Utilities.ATLEAST_MARSHMALLOW) {
132 // These checks are sufficient for below M devices.
136 // On M and above also check AppOpsManager for compatibility mode permissions.
137 if (TextUtils.isEmpty(AppOpsManager.permissionToOp(target.activityInfo.permission))) {
138 // There is no app-op for this permission, which could have been disabled.
142 // There is no direct way to check if the app-op is allowed for a particular app. Since
143 // app-op is only enabled for apps running in compatibility mode, simply block such apps.
146 return mPm.getApplicationInfo(srcPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M;
147 } catch (NameNotFoundException e) { }
152 public static Intent getMarketIntent(String packageName) {
153 return new Intent(Intent.ACTION_VIEW)
154 .setData(new Uri.Builder()
156 .authority("details")
157 .appendQueryParameter("id", packageName)