1 /* 2 * Copyright (C) 2017 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.launcher3.pm; 18 19 import static com.android.launcher3.Utilities.allowBGLaunch; 20 21 import android.annotation.TargetApi; 22 import android.app.Activity; 23 import android.app.ActivityOptions; 24 import android.content.ActivityNotFoundException; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentSender; 29 import android.content.pm.LauncherActivityInfo; 30 import android.content.pm.LauncherApps; 31 import android.content.pm.PackageManager; 32 import android.graphics.drawable.Drawable; 33 import android.os.Build; 34 import android.os.Process; 35 import android.os.UserHandle; 36 import android.util.Log; 37 import android.widget.Toast; 38 39 import androidx.annotation.Nullable; 40 41 import com.android.launcher3.LauncherSettings; 42 import com.android.launcher3.R; 43 import com.android.launcher3.icons.ComponentWithLabelAndIcon; 44 import com.android.launcher3.icons.IconCache; 45 import com.android.launcher3.model.data.WorkspaceItemInfo; 46 import com.android.launcher3.util.PackageUserKey; 47 48 import java.util.ArrayList; 49 import java.util.Collections; 50 import java.util.List; 51 52 /** 53 * Wrapper class for representing a shortcut configure activity. 54 */ 55 public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAndIcon { 56 57 private static final String TAG = "SCActivityInfo"; 58 59 private final ComponentName mCn; 60 private final UserHandle mUser; 61 ShortcutConfigActivityInfo(ComponentName cn, UserHandle user)62 protected ShortcutConfigActivityInfo(ComponentName cn, UserHandle user) { 63 mCn = cn; 64 mUser = user; 65 } 66 67 @Override getComponent()68 public ComponentName getComponent() { 69 return mCn; 70 } 71 72 @Override getUser()73 public UserHandle getUser() { 74 return mUser; 75 } 76 getItemType()77 public int getItemType() { 78 return LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; 79 } 80 81 @Override getFullResIcon(IconCache cache)82 public abstract Drawable getFullResIcon(IconCache cache); 83 84 /** 85 * Return a WorkspaceItemInfo, if it can be created directly on drop, without requiring any 86 * {@link #startConfigActivity(Activity, int)}. 87 */ createWorkspaceItemInfo()88 public WorkspaceItemInfo createWorkspaceItemInfo() { 89 return null; 90 } 91 startConfigActivity(Activity activity, int requestCode)92 public boolean startConfigActivity(Activity activity, int requestCode) { 93 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT) 94 .setComponent(getComponent()); 95 try { 96 activity.startActivityForResult(intent, requestCode); 97 return true; 98 } catch (ActivityNotFoundException e) { 99 Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 100 } catch (SecurityException e) { 101 Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 102 Log.e(TAG, "Launcher does not have the permission to launch " + intent 103 + ". Make sure to create a MAIN intent-filter for the corresponding activity " 104 + "or use the exported attribute for this activity.", e); 105 } 106 return false; 107 } 108 109 /** 110 * Returns true if various properties ({@link #getLabel(PackageManager)}, 111 * {@link #getFullResIcon}) can be safely persisted. 112 */ isPersistable()113 public boolean isPersistable() { 114 return true; 115 } 116 117 @TargetApi(26) 118 public static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo { 119 120 private final LauncherActivityInfo mInfo; 121 ShortcutConfigActivityInfoVO(LauncherActivityInfo info)122 public ShortcutConfigActivityInfoVO(LauncherActivityInfo info) { 123 super(info.getComponentName(), info.getUser()); 124 mInfo = info; 125 } 126 127 @Override getLabel(PackageManager pm)128 public CharSequence getLabel(PackageManager pm) { 129 return mInfo.getLabel(); 130 } 131 132 @Override getFullResIcon(IconCache cache)133 public Drawable getFullResIcon(IconCache cache) { 134 return cache.getFullResIcon(mInfo); 135 } 136 137 @Override startConfigActivity(Activity activity, int requestCode)138 public boolean startConfigActivity(Activity activity, int requestCode) { 139 if (getUser().equals(Process.myUserHandle())) { 140 return super.startConfigActivity(activity, requestCode); 141 } 142 IntentSender is = activity.getSystemService(LauncherApps.class) 143 .getShortcutConfigActivityIntent(mInfo); 144 ActivityOptions options = allowBGLaunch(ActivityOptions.makeBasic()); 145 try { 146 activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0, 147 options.toBundle()); 148 return true; 149 } catch (IntentSender.SendIntentException e) { 150 Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 151 return false; 152 } 153 } 154 } 155 queryList( Context context, @Nullable PackageUserKey packageUser)156 public static List<ShortcutConfigActivityInfo> queryList( 157 Context context, @Nullable PackageUserKey packageUser) { 158 List<ShortcutConfigActivityInfo> result = new ArrayList<>(); 159 final List<UserHandle> users; 160 final String packageName; 161 if (packageUser == null) { 162 users = UserCache.INSTANCE.get(context).getUserProfiles(); 163 packageName = null; 164 } else { 165 users = Collections.singletonList(packageUser.mUser); 166 packageName = packageUser.mPackageName; 167 } 168 LauncherApps launcherApps = context.getSystemService(LauncherApps.class); 169 for (UserHandle user : users) { 170 for (LauncherActivityInfo activityInfo : 171 launcherApps.getShortcutConfigActivityList(packageName, user)) { 172 if (activityInfo.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) { 173 result.add(new ShortcutConfigActivityInfoVO(activityInfo)); 174 } 175 } 176 } 177 return result; 178 } 179 } 180