1 /* 2 * Copyright (C) 2019 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.systemui; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.ActivityInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 25 import java.util.List; 26 27 /** 28 * Contains useful methods for querying properties of an Activity Intent. 29 */ 30 public class ActivityIntentHelper { 31 32 private final Context mContext; 33 ActivityIntentHelper(Context context)34 public ActivityIntentHelper(Context context) { 35 mContext = context; 36 } 37 38 /** 39 * Determines if sending the given intent would result in starting an Intent resolver activity, 40 * instead of resolving to a specific component. 41 * 42 * @param intent the intent 43 * @param currentUserId the id for the user to resolve as 44 * @return true if the intent would launch a resolver activity 45 */ wouldLaunchResolverActivity(Intent intent, int currentUserId)46 public boolean wouldLaunchResolverActivity(Intent intent, int currentUserId) { 47 ActivityInfo targetActivityInfo = getTargetActivityInfo(intent, currentUserId, 48 false /* onlyDirectBootAware */); 49 return targetActivityInfo == null; 50 } 51 52 /** 53 * Returns info about the target Activity of a given intent, or null if the intent does not 54 * resolve to a specific component meeting the requirements. 55 * 56 * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must 57 * be direct boot aware when in direct boot mode if false, all packages are considered 58 * a match even if they are not aware. 59 * @return the target activity info of the intent it resolves to a specific package or 60 * {@code null} if it resolved to the resolver activity 61 */ getTargetActivityInfo(Intent intent, int currentUserId, boolean onlyDirectBootAware)62 public ActivityInfo getTargetActivityInfo(Intent intent, int currentUserId, 63 boolean onlyDirectBootAware) { 64 PackageManager packageManager = mContext.getPackageManager(); 65 int flags = PackageManager.MATCH_DEFAULT_ONLY; 66 if (!onlyDirectBootAware) { 67 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE 68 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 69 } 70 final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( 71 intent, flags, currentUserId); 72 if (appList.size() == 0) { 73 return null; 74 } 75 ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, 76 flags | PackageManager.GET_META_DATA, currentUserId); 77 if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) { 78 return null; 79 } else { 80 return resolved.activityInfo; 81 } 82 } 83 84 /** 85 * Determines if the given intent resolves to an Activity which is allowed to appear above 86 * the lock screen. 87 * 88 * @param intent the intent to resolve 89 * @return true if the launched Activity would appear above the lock screen 90 */ wouldShowOverLockscreen(Intent intent, int currentUserId)91 public boolean wouldShowOverLockscreen(Intent intent, int currentUserId) { 92 ActivityInfo targetActivityInfo = getTargetActivityInfo(intent, 93 currentUserId, false /* onlyDirectBootAware */); 94 return targetActivityInfo != null 95 && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED 96 | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0; 97 } 98 99 /** 100 * Determines if sending the given intent would result in starting an Intent resolver activity, 101 * instead of resolving to a specific component. 102 * 103 * @param resolved the resolveInfo for the intent as returned by resolveActivityAsUser 104 * @param appList a list of resolveInfo as returned by queryIntentActivitiesAsUser 105 * @return true if the intent would launch a resolver activity 106 */ wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList)107 public boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) { 108 // If the list contains the above resolved activity, then it can't be 109 // ResolverActivity itself. 110 for (int i = 0; i < appList.size(); i++) { 111 ResolveInfo tmp = appList.get(i); 112 if (tmp.activityInfo.name.equals(resolved.activityInfo.name) 113 && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { 114 return false; 115 } 116 } 117 return true; 118 } 119 } 120