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.compat; 18 19 import android.annotation.TargetApi; 20 import android.app.Activity; 21 import android.content.ActivityNotFoundException; 22 import android.content.ComponentName; 23 import android.content.Intent; 24 import android.content.IntentSender; 25 import android.content.pm.ActivityInfo; 26 import android.content.pm.LauncherActivityInfo; 27 import android.content.pm.LauncherApps; 28 import android.content.pm.PackageManager; 29 import android.graphics.drawable.Drawable; 30 import android.os.Process; 31 import android.os.UserHandle; 32 import android.util.Log; 33 import android.widget.Toast; 34 35 import com.android.launcher3.IconCache; 36 import com.android.launcher3.LauncherSettings; 37 import com.android.launcher3.R; 38 import com.android.launcher3.ShortcutInfo; 39 40 import java.lang.reflect.Method; 41 42 /** 43 * Wrapper class for representing a shortcut configure activity. 44 */ 45 public abstract class ShortcutConfigActivityInfo { 46 47 private static final String TAG = "SCActivityInfo"; 48 49 private final ComponentName mCn; 50 private final UserHandle mUser; 51 ShortcutConfigActivityInfo(ComponentName cn, UserHandle user)52 protected ShortcutConfigActivityInfo(ComponentName cn, UserHandle user) { 53 mCn = cn; 54 mUser = user; 55 } 56 getComponent()57 public ComponentName getComponent() { 58 return mCn; 59 } 60 getUser()61 public UserHandle getUser() { 62 return mUser; 63 } 64 getItemType()65 public int getItemType() { 66 return LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 67 } 68 getLabel()69 public abstract CharSequence getLabel(); 70 getFullResIcon(IconCache cache)71 public abstract Drawable getFullResIcon(IconCache cache); 72 73 /** 74 * Return a shortcut info, if it can be created directly on drop, without requiring any 75 * {@link #startConfigActivity(Activity, int)}. 76 */ createShortcutInfo()77 public ShortcutInfo createShortcutInfo() { 78 return null; 79 } 80 startConfigActivity(Activity activity, int requestCode)81 public boolean startConfigActivity(Activity activity, int requestCode) { 82 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT) 83 .setComponent(getComponent()); 84 try { 85 activity.startActivityForResult(intent, requestCode); 86 return true; 87 } catch (ActivityNotFoundException e) { 88 Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 89 } catch (SecurityException e) { 90 Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 91 Log.e(TAG, "Launcher does not have the permission to launch " + intent + 92 ". Make sure to create a MAIN intent-filter for the corresponding activity " + 93 "or use the exported attribute for this activity.", e); 94 } 95 return false; 96 } 97 98 /** 99 * Returns true if various properties ({@link #getLabel()}, {@link #getFullResIcon}) can 100 * be safely persisted. 101 */ isPersistable()102 public boolean isPersistable() { 103 return true; 104 } 105 106 static class ShortcutConfigActivityInfoVL extends ShortcutConfigActivityInfo { 107 108 private final ActivityInfo mInfo; 109 private final PackageManager mPm; 110 111 ShortcutConfigActivityInfoVL(ActivityInfo info, PackageManager pm)112 public ShortcutConfigActivityInfoVL(ActivityInfo info, PackageManager pm) { 113 super(new ComponentName(info.packageName, info.name), Process.myUserHandle()); 114 mInfo = info; 115 mPm = pm; 116 } 117 118 @Override getLabel()119 public CharSequence getLabel() { 120 return mInfo.loadLabel(mPm); 121 } 122 123 @Override getFullResIcon(IconCache cache)124 public Drawable getFullResIcon(IconCache cache) { 125 return cache.getFullResIcon(mInfo); 126 } 127 } 128 129 @TargetApi(26) 130 static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo { 131 132 private final LauncherActivityInfo mInfo; 133 ShortcutConfigActivityInfoVO(LauncherActivityInfo info)134 public ShortcutConfigActivityInfoVO(LauncherActivityInfo info) { 135 super(info.getComponentName(), info.getUser()); 136 mInfo = info; 137 } 138 139 @Override getLabel()140 public CharSequence getLabel() { 141 return mInfo.getLabel(); 142 } 143 144 @Override getFullResIcon(IconCache cache)145 public Drawable getFullResIcon(IconCache cache) { 146 return cache.getFullResIcon(mInfo); 147 } 148 149 @Override startConfigActivity(Activity activity, int requestCode)150 public boolean startConfigActivity(Activity activity, int requestCode) { 151 if (getUser().equals(Process.myUserHandle())) { 152 return super.startConfigActivity(activity, requestCode); 153 } 154 try { 155 Method m = LauncherApps.class.getDeclaredMethod( 156 "getShortcutConfigActivityIntent", LauncherActivityInfo.class); 157 IntentSender is = (IntentSender) m.invoke( 158 activity.getSystemService(LauncherApps.class), mInfo); 159 activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0); 160 return true; 161 } catch (Exception e) { 162 Log.e(TAG, "Error calling new API", e); 163 return false; 164 } 165 } 166 } 167 } 168