1 package org.robolectric.shadows; 2 3 import android.content.Intent; 4 import android.content.IntentSender; 5 import android.content.IntentSender.SendIntentException; 6 import android.content.pm.ShortcutInfo; 7 import android.content.pm.ShortcutManager; 8 import android.os.Build; 9 import com.google.common.collect.ImmutableList; 10 import java.util.ArrayList; 11 import java.util.HashMap; 12 import java.util.List; 13 import java.util.Map; 14 import org.robolectric.RuntimeEnvironment; 15 import org.robolectric.annotation.Implementation; 16 import org.robolectric.annotation.Implements; 17 18 /** */ 19 @Implements(value = ShortcutManager.class, minSdk = Build.VERSION_CODES.N_MR1) 20 public class ShadowShortcutManager { 21 22 private static final int MAX_ICON_DIMENSION = 128; 23 private static final int MAX_NUM_SHORTCUTS_PER_ACTIVITY = 16; 24 25 private final Map<String, ShortcutInfo> dynamicShortcuts = new HashMap<>(); 26 private final Map<String, ShortcutInfo> activePinnedShortcuts = new HashMap<>(); 27 private final Map<String, ShortcutInfo> disabledPinnedShortcuts = new HashMap<>(); 28 29 private boolean isRequestPinShortcutSupported = true; 30 31 @Implementation 32 public boolean addDynamicShortcuts(List<ShortcutInfo> shortcutInfoList) { 33 for (ShortcutInfo shortcutInfo : shortcutInfoList) { 34 if (activePinnedShortcuts.containsKey(shortcutInfo.getId())) { 35 ShortcutInfo previousShortcut = activePinnedShortcuts.get(shortcutInfo.getId()); 36 if (!previousShortcut.isImmutable()) { 37 activePinnedShortcuts.put(shortcutInfo.getId(), shortcutInfo); 38 } 39 } else if (disabledPinnedShortcuts.containsKey(shortcutInfo.getId())) { 40 ShortcutInfo previousShortcut = disabledPinnedShortcuts.get(shortcutInfo.getId()); 41 if (!previousShortcut.isImmutable()) { 42 disabledPinnedShortcuts.put(shortcutInfo.getId(), shortcutInfo); 43 } 44 } else if (dynamicShortcuts.containsKey(shortcutInfo.getId())) { 45 ShortcutInfo previousShortcut = dynamicShortcuts.get(shortcutInfo.getId()); 46 if (!previousShortcut.isImmutable()) { 47 dynamicShortcuts.put(shortcutInfo.getId(), shortcutInfo); 48 } 49 } else { 50 dynamicShortcuts.put(shortcutInfo.getId(), shortcutInfo); 51 } 52 } 53 return true; 54 } 55 56 @Implementation(minSdk = Build.VERSION_CODES.O) 57 public Intent createShortcutResultIntent(ShortcutInfo shortcut) { 58 if (disabledPinnedShortcuts.containsKey(shortcut.getId())) { 59 throw new IllegalArgumentException(); 60 } 61 return new Intent(); 62 } 63 64 @Implementation 65 public void disableShortcuts(List<String> shortcutIds) { 66 disableShortcuts(shortcutIds, "Shortcut is disabled."); 67 } 68 69 @Implementation 70 public void disableShortcuts(List<String> shortcutIds, CharSequence unused) { 71 for (String shortcutId : shortcutIds) { 72 ShortcutInfo shortcut = activePinnedShortcuts.remove(shortcutId); 73 if (shortcut != null) { 74 disabledPinnedShortcuts.put(shortcutId, shortcut); 75 } 76 } 77 } 78 79 @Implementation 80 public void enableShortcuts(List<String> shortcutIds) { 81 for (String shortcutId : shortcutIds) { 82 ShortcutInfo shortcut = disabledPinnedShortcuts.remove(shortcutId); 83 if (shortcut != null) { 84 activePinnedShortcuts.put(shortcutId, shortcut); 85 } 86 } 87 } 88 89 @Implementation 90 public List<ShortcutInfo> getDynamicShortcuts() { 91 return ImmutableList.copyOf(dynamicShortcuts.values()); 92 } 93 94 @Implementation 95 public int getIconMaxHeight() { 96 return MAX_ICON_DIMENSION; 97 } 98 99 @Implementation 100 public int getIconMaxWidth() { 101 return MAX_ICON_DIMENSION; 102 } 103 104 @Implementation 105 public List<ShortcutInfo> getManifestShortcuts() { 106 return ImmutableList.of(); 107 } 108 109 @Implementation 110 public int getMaxShortcutCountPerActivity() { 111 return MAX_NUM_SHORTCUTS_PER_ACTIVITY; 112 } 113 114 @Implementation 115 public List<ShortcutInfo> getPinnedShortcuts() { 116 ImmutableList.Builder<ShortcutInfo> pinnedShortcuts = ImmutableList.builder(); 117 pinnedShortcuts.addAll(activePinnedShortcuts.values()); 118 pinnedShortcuts.addAll(disabledPinnedShortcuts.values()); 119 return pinnedShortcuts.build(); 120 } 121 122 @Implementation 123 public boolean isRateLimitingActive() { 124 return false; 125 } 126 127 @Implementation(minSdk = Build.VERSION_CODES.O) 128 public boolean isRequestPinShortcutSupported() { 129 return isRequestPinShortcutSupported; 130 } 131 132 public void setIsRequestPinShortcutSupported(boolean isRequestPinShortcutSupported) { 133 this.isRequestPinShortcutSupported = isRequestPinShortcutSupported; 134 } 135 136 @Implementation 137 public void removeAllDynamicShortcuts() { 138 dynamicShortcuts.clear(); 139 } 140 141 @Implementation 142 public void removeDynamicShortcuts(List<String> shortcutIds) { 143 for (String shortcutId : shortcutIds) { 144 dynamicShortcuts.remove(shortcutId); 145 } 146 } 147 148 @Implementation 149 public void reportShortcutUsed(String shortcutId) {} 150 151 @Implementation(minSdk = Build.VERSION_CODES.O) 152 public boolean requestPinShortcut(ShortcutInfo shortcut, IntentSender resultIntent) { 153 if (disabledPinnedShortcuts.containsKey(shortcut.getId())) { 154 throw new IllegalArgumentException( 155 "Shortcut with ID [" + shortcut.getId() + "] already exists and is disabled."); 156 } 157 if (dynamicShortcuts.containsKey(shortcut.getId())) { 158 activePinnedShortcuts.put(shortcut.getId(), dynamicShortcuts.remove(shortcut.getId())); 159 } else { 160 activePinnedShortcuts.put(shortcut.getId(), shortcut); 161 } 162 if (resultIntent != null) { 163 try { 164 resultIntent.sendIntent(RuntimeEnvironment.application, 0, null, null, null); 165 } catch (SendIntentException e) { 166 throw new IllegalStateException(); 167 } 168 } 169 return true; 170 } 171 172 @Implementation 173 public boolean setDynamicShortcuts(List<ShortcutInfo> shortcutInfoList) { 174 dynamicShortcuts.clear(); 175 return addDynamicShortcuts(shortcutInfoList); 176 } 177 178 @Implementation 179 public boolean updateShortcuts(List<ShortcutInfo> shortcutInfoList) { 180 List<ShortcutInfo> existingShortcutsToUpdate = new ArrayList<>(); 181 for (ShortcutInfo shortcutInfo : shortcutInfoList) { 182 if (dynamicShortcuts.containsKey(shortcutInfo.getId()) 183 || activePinnedShortcuts.containsKey(shortcutInfo.getId()) 184 || disabledPinnedShortcuts.containsKey(shortcutInfo.getId())) { 185 existingShortcutsToUpdate.add(shortcutInfo); 186 } 187 } 188 return addDynamicShortcuts(existingShortcutsToUpdate); 189 } 190 } 191