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