131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.BroadcastReceiver; 2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 22f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chungimport android.content.SharedPreferences; 23c3a747ac245d6175a6838230d8b01c618555e062Winson Chungimport android.content.pm.ActivityInfo; 24c3a747ac245d6175a6838230d8b01c618555e062Winson Chungimport android.content.pm.PackageManager; 250b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyalimport android.content.pm.ResolveInfo; 2648c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurkaimport android.graphics.Bitmap; 2748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurkaimport android.graphics.BitmapFactory; 28dff0bfeb901e767ca9b57f9b8051c7fd077626e9Nilesh Agrawalimport android.text.TextUtils; 2948c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurkaimport android.util.Base64; 3048c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurkaimport android.util.Log; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 32e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyalimport com.android.launcher3.compat.LauncherActivityInfoCompat; 33e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyalimport com.android.launcher3.compat.LauncherAppsCompat; 34a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohenimport com.android.launcher3.compat.UserHandleCompat; 35e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyalimport com.android.launcher3.compat.UserManagerCompat; 36091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 37a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen 38e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyalimport org.json.JSONException; 3934c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurkaimport org.json.JSONObject; 4034c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurkaimport org.json.JSONStringer; 4134c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurkaimport org.json.JSONTokener; 4234c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka 43e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyalimport java.net.URISyntaxException; 44e428e292c27e650ab4de76b78728ba55019cd282Winson Chungimport java.util.ArrayList; 45f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chungimport java.util.HashSet; 46f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chungimport java.util.Iterator; 47f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chungimport java.util.Set; 48e428e292c27e650ab4de76b78728ba55019cd282Winson Chung 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class InstallShortcutReceiver extends BroadcastReceiver { 504e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert private static final String TAG = "InstallShortcutReceiver"; 514e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert private static final boolean DBG = false; 524e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert 532350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String ACTION_INSTALL_SHORTCUT = 5494d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung "com.android.launcher.action.INSTALL_SHORTCUT"; 55f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 562350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String LAUNCH_INTENT_KEY = "intent.launch"; 572350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String NAME_KEY = "name"; 582350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String ICON_KEY = "icon"; 592350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String ICON_RESOURCE_NAME_KEY = "iconResource"; 602350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage"; 61e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 62e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut"; 63e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static final String USER_HANDLE_KEY = "userHandle"; 64e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 6548c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka // The set of shortcuts that are pending install 662350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal private static final String APPS_PENDING_INSTALL = "apps_to_install"; 6748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka 68f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450; 69997a92348a6d6e061737399321393449c16cd4d8Winson Chung public static final int NEW_SHORTCUT_STAGGER_DELAY = 85; 70f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 71e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static final Object sLock = new Object(); 7248c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka 7348c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka private static void addToInstallQueue( 7448c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka SharedPreferences sharedPrefs, PendingInstallShortcutInfo info) { 7548c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka synchronized(sLock) { 76e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String encoded = info.encodeToString(); 77e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (encoded != null) { 78e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); 79e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (strings == null) { 80e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal strings = new HashSet<String>(1); 81e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } else { 82e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal strings = new HashSet<String>(strings); 8348c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 84e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal strings.add(encoded); 85d80439875557e8c94052e5b0f0327b656370b5fdSunny Goyal sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).apply(); 8648c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 8748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 8848c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 8948c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka 9097909124a2d8b89135a5885c52226191e30291b6Sunny Goyal public static void removeFromInstallQueue(Context context, HashSet<String> packageNames, 91e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal UserHandleCompat user) { 92df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung if (packageNames.isEmpty()) { 93df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung return; 94df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 95f725824fa2091cab44cf1bcbfe5b5b8d06475560Sunny Goyal SharedPreferences sp = Utilities.getPrefs(context); 96780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung synchronized(sLock) { 97e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Set<String> strings = sp.getStringSet(APPS_PENDING_INSTALL, null); 984e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert if (DBG) { 994e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert Log.d(TAG, "APPS_PENDING_INSTALL: " + strings 1004e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert + ", removing packages: " + packageNames); 1014e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert } 102780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung if (strings != null) { 103780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung Set<String> newStrings = new HashSet<String>(strings); 1044e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert Iterator<String> newStringsIter = newStrings.iterator(); 1054e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert while (newStringsIter.hasNext()) { 106e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String encoded = newStringsIter.next(); 107e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal PendingInstallShortcutInfo info = decode(encoded, context); 108e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (info == null || (packageNames.contains(info.getTargetPackage()) 109e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal && user.equals(info.user))) { 110e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal newStringsIter.remove(); 111780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung } 112780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung } 113d80439875557e8c94052e5b0f0327b656370b5fdSunny Goyal sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).apply(); 114780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung } 115780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung } 116780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung } 117780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung 11848c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka private static ArrayList<PendingInstallShortcutInfo> getAndClearInstallQueue( 119e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal SharedPreferences sharedPrefs, Context context) { 12048c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka synchronized(sLock) { 12148c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); 1224e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings); 12348c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka if (strings == null) { 12448c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka return new ArrayList<PendingInstallShortcutInfo>(); 12548c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 12648c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka ArrayList<PendingInstallShortcutInfo> infos = 12748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka new ArrayList<PendingInstallShortcutInfo>(); 128e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal for (String encoded : strings) { 129e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal PendingInstallShortcutInfo info = decode(encoded, context); 130e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (info != null) { 13148c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka infos.add(info); 13248c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 13348c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 134d80439875557e8c94052e5b0f0327b656370b5fdSunny Goyal sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, new HashSet<String>()).apply(); 13548c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka return infos; 13648c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 13748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka } 13848c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka 139f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung // Determines whether to defer installing shortcuts immediately until 140f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung // processAllPendingInstalls() is called. 141f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung private static boolean mUseInstallQueue = false; 142f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onReceive(Context context, Intent data) { 14451ed5b9bc05c6eb37dcb3fe38fa021f1044c0f88Romain Guy if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) { 14551ed5b9bc05c6eb37dcb3fe38fa021f1044c0f88Romain Guy return; 14651ed5b9bc05c6eb37dcb3fe38fa021f1044c0f88Romain Guy } 1477606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal PendingInstallShortcutInfo info = createPendingInfo(context, data); 1487606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal if (info != null) { 1497606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal queuePendingShortcutInfo(info, context); 1503290ec4cc220f97460b3b19f28adaf829ea971e1Sunny Goyal } 1517606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal } 1524e871a217b286775dc6c07feb6d9f1d7a7e914beBjorn Bringert 1537606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal /** 1547606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal * @return true is the extra is either null or is of type {@param type} 1557606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal */ 1567606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal private static boolean isValidExtraType(Intent intent, String key, Class type) { 1577606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal Object extra = intent.getParcelableExtra(key); 1587606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal return extra == null || type.isInstance(extra); 159e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 160dff0bfeb901e767ca9b57f9b8051c7fd077626e9Nilesh Agrawal 1617606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal /** 1627606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal * Verifies the intent and creates a {@link PendingInstallShortcutInfo} 1637606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal */ 1647606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal private static PendingInstallShortcutInfo createPendingInfo(Context context, Intent data) { 1657606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal if (!isValidExtraType(data, Intent.EXTRA_SHORTCUT_INTENT, Intent.class) || 1667606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal !(isValidExtraType(data, Intent.EXTRA_SHORTCUT_ICON_RESOURCE, 1677606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal Intent.ShortcutIconResource.class)) || 1687606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal !(isValidExtraType(data, Intent.EXTRA_SHORTCUT_ICON, Bitmap.class))) { 1697606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal 1707606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal if (DBG) Log.e(TAG, "Invalid install shortcut intent"); 1717606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal return null; 1727606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal } 1737606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal 1745c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context); 1755c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal if (info.launchIntent == null || info.label == null) { 1765c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal if (DBG) Log.e(TAG, "Invalid install shortcut intent"); 1775c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal return null; 1785c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal } 1797606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal 1807606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal return convertToLauncherActivityIfPossible(info); 1815c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal } 1825c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal 1837606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal public static ShortcutInfo fromShortcutIntent(Context context, Intent data) { 1847606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal PendingInstallShortcutInfo info = createPendingInfo(context, data); 1857606a412c5a7da2d8eff9bd9425c759f7028d888Sunny Goyal return info == null ? null : info.getShortcutInfo(); 186e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 18748c7a93eb7ef15ef551aee80c179b8e7e0d2399aMichael Jurka 188e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) { 189de0fb8fbf11caac382589ab464b50d528942273aWinson Chung // Queue the item up for adding if launcher has not loaded properly yet 190892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 191e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal boolean launcherNotLoaded = app.getModel().getCallback() == null; 192997a92348a6d6e061737399321393449c16cd4d8Winson Chung 193f725824fa2091cab44cf1bcbfe5b5b8d06475560Sunny Goyal addToInstallQueue(Utilities.getPrefs(context), info); 194997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (!mUseInstallQueue && !launcherNotLoaded) { 195997a92348a6d6e061737399321393449c16cd4d8Winson Chung flushInstallQueue(context); 196f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung } 197f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung } 198f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung 199f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung static void enableInstallQueue() { 200f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung mUseInstallQueue = true; 201f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung } 202f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung static void disableAndFlushInstallQueue(Context context) { 203f561bdf68dd304e1d7c3f7796621a4cc39ca15f2Winson Chung mUseInstallQueue = false; 204de0fb8fbf11caac382589ab464b50d528942273aWinson Chung flushInstallQueue(context); 205de0fb8fbf11caac382589ab464b50d528942273aWinson Chung } 206de0fb8fbf11caac382589ab464b50d528942273aWinson Chung static void flushInstallQueue(Context context) { 207f725824fa2091cab44cf1bcbfe5b5b8d06475560Sunny Goyal SharedPreferences sp = Utilities.getPrefs(context); 208e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp, context); 209997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (!installQueue.isEmpty()) { 210997a92348a6d6e061737399321393449c16cd4d8Winson Chung Iterator<PendingInstallShortcutInfo> iter = installQueue.iterator(); 211997a92348a6d6e061737399321393449c16cd4d8Winson Chung ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>(); 212997a92348a6d6e061737399321393449c16cd4d8Winson Chung while (iter.hasNext()) { 213997a92348a6d6e061737399321393449c16cd4d8Winson Chung final PendingInstallShortcutInfo pendingInfo = iter.next(); 214dff0bfeb901e767ca9b57f9b8051c7fd077626e9Nilesh Agrawal 215a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen // If the intent specifies a package, make sure the package exists 216e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String packageName = pendingInfo.getTargetPackage(); 217f2048779990bfd3c20b52149f5e8ab208bf2502aSunny Goyal if (!TextUtils.isEmpty(packageName)) { 218a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle(); 219a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen if (!LauncherModel.isValidPackage(context, packageName, myUserHandle)) { 220b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal if (DBG) Log.d(TAG, "Ignoring shortcut for absent package: " 221b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal + pendingInfo.launchIntent); 222a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen continue; 223a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 224a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 225a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen 226756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Generate a shortcut info to add into the model 227756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal addShortcuts.add(pendingInfo.getShortcutInfo()); 228f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung } 229f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 230997a92348a6d6e061737399321393449c16cd4d8Winson Chung // Add the new apps to the model and bind them 231997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (!addShortcuts.isEmpty()) { 232997a92348a6d6e061737399321393449c16cd4d8Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 23318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal app.getModel().addAndBindAddedWorkspaceItems(context, addShortcuts); 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 238dff0bfeb901e767ca9b57f9b8051c7fd077626e9Nilesh Agrawal /** 2392c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung * Ensures that we have a valid, non-null name. If the provided name is null, we will return 2402c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung * the application name instead. 2412c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung */ 242091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static CharSequence ensureValidName(Context context, Intent intent, CharSequence name) { 2432c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung if (name == null) { 2442c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung try { 2452c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung PackageManager pm = context.getPackageManager(); 2462c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung ActivityInfo info = pm.getActivityInfo(intent.getComponent(), 0); 24782b016cb56540fe26213e817dd0dd668099c8e20Winson Chung name = info.loadLabel(pm); 2482c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung } catch (PackageManager.NameNotFoundException nnfe) { 2492c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung return ""; 2502c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung } 2512c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung } 2522c1afde5cd60eb13f05aeae0c170e697493ef307Winson Chung return name; 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 254e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 255e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static class PendingInstallShortcutInfo { 256e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 257e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final LauncherActivityInfoCompat activityInfo; 258e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 259e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Intent data; 260e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Context mContext; 261e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Intent launchIntent; 262e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final String label; 263e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final UserHandleCompat user; 264e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 265e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal /** 266e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal * Initializes a PendingInstallShortcutInfo received from a different app. 267e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal */ 268e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public PendingInstallShortcutInfo(Intent data, Context context) { 269e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal this.data = data; 270e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal mContext = context; 271e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 272e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 273e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 274e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal user = UserHandleCompat.myUserHandle(); 275e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal activityInfo = null; 276e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 277e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 278e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal /** 279e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal * Initializes a PendingInstallShortcutInfo to represent a launcher target. 280e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal */ 281e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) { 282e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal this.data = null; 283e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal mContext = context; 284e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal activityInfo = info; 285e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal user = info.getUser(); 286e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 287e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent = AppInfo.makeLaunchIntent(context, info, user); 288e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal label = info.getLabel().toString(); 289e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 290e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 291e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public String encodeToString() { 292e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (activityInfo != null) { 293e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal try { 294e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // If it a launcher target, we only need component name, and user to 295e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // recreate this. 296e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return new JSONStringer() 297e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .object() 298e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0)) 299e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .key(APP_SHORTCUT_TYPE_KEY).value(true) 300e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext) 301e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .getSerialNumberForUser(user)) 302e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .endObject().toString(); 303e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } catch (JSONException e) { 304e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Log.d(TAG, "Exception when adding shortcut: " + e); 305e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return null; 306e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 307e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 308e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 309e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (launchIntent.getAction() == null) { 310e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent.setAction(Intent.ACTION_VIEW); 311e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) && 312e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent.getCategories() != null && 313e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 314e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent.addFlags( 315e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 316e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 317e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 318e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // This name is only used for comparisons and notifications, so fall back to activity 319e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // name if not supplied 320e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String name = ensureValidName(mContext, launchIntent, label).toString(); 321e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 322e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Intent.ShortcutIconResource iconResource = 323e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 324e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 325e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Only encode the parameters which are supported by the API. 326e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal try { 327e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal JSONStringer json = new JSONStringer() 328e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .object() 329e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0)) 330e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .key(NAME_KEY).value(name); 331e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (icon != null) { 3325b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal byte[] iconByteArray = Utilities.flattenBitmap(icon); 333e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal json = json.key(ICON_KEY).value( 334e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Base64.encodeToString( 335e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal iconByteArray, 0, iconByteArray.length, Base64.DEFAULT)); 336e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 337e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (iconResource != null) { 338e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal json = json.key(ICON_RESOURCE_NAME_KEY).value(iconResource.resourceName); 339e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY) 340e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .value(iconResource.packageName); 341e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 342e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return json.endObject().toString(); 343e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } catch (JSONException e) { 344e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Log.d(TAG, "Exception when adding shortcut: " + e); 345e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 346e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return null; 347e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 348e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 349e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public ShortcutInfo getShortcutInfo() { 350e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (activityInfo != null) { 35118bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal return ShortcutInfo.fromActivityInfo(activityInfo, mContext); 352e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } else { 353e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data); 354e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 355e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 356e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 357e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public String getTargetPackage() { 358e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String packageName = launchIntent.getPackage(); 359e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (packageName == null) { 360e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal packageName = launchIntent.getComponent() == null ? null : 361e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal launchIntent.getComponent().getPackageName(); 362e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 363e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return packageName; 364e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 3650b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal 366b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal public boolean isLauncherActivity() { 3670b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal return activityInfo != null; 3680b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal } 369e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 370e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 371e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static PendingInstallShortcutInfo decode(String encoded, Context context) { 372e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal try { 373e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal JSONObject object = (JSONObject) new JSONTokener(encoded).nextValue(); 374e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Intent launcherIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0); 375e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 376e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (object.optBoolean(APP_SHORTCUT_TYPE_KEY)) { 377e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // The is an internal launcher target shortcut. 378e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal UserHandleCompat user = UserManagerCompat.getInstance(context) 379e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .getUserForSerialNumber(object.getLong(USER_HANDLE_KEY)); 38006910a88445c46fb95c9ad5ff83793e37b6af692Sunny Goyal if (user == null) { 38106910a88445c46fb95c9ad5ff83793e37b6af692Sunny Goyal return null; 38206910a88445c46fb95c9ad5ff83793e37b6af692Sunny Goyal } 383e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 384e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context) 385e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .resolveActivity(launcherIntent, user); 386e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return info == null ? null : new PendingInstallShortcutInfo(info, context); 387e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 388e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 389e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Intent data = new Intent(); 390e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent); 391e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal data.putExtra(Intent.EXTRA_SHORTCUT_NAME, object.getString(NAME_KEY)); 392e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 393e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String iconBase64 = object.optString(ICON_KEY); 394e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY); 395e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String iconResourcePackageName = object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY); 396e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (iconBase64 != null && !iconBase64.isEmpty()) { 397e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT); 398e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length); 399e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal data.putExtra(Intent.EXTRA_SHORTCUT_ICON, b); 400e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } else if (iconResourceName != null && !iconResourceName.isEmpty()) { 401e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Intent.ShortcutIconResource iconResource = 402e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal new Intent.ShortcutIconResource(); 403e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal iconResource.resourceName = iconResourceName; 404e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal iconResource.packageName = iconResourcePackageName; 405e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); 406e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 407e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 408e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return new PendingInstallShortcutInfo(data, context); 409b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal } catch (JSONException | URISyntaxException e) { 410e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Log.d(TAG, "Exception reading shortcut to add: " + e); 411e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 412e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return null; 413e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 4140b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal 4150b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal /** 4160b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal * Tries to create a new PendingInstallShortcutInfo which represents the same target, 4170b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal * but is an app target and not a shortcut. 4180b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal * @return the newly created info or the original one. 4190b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal */ 4200b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal private static PendingInstallShortcutInfo convertToLauncherActivityIfPossible( 4210b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal PendingInstallShortcutInfo original) { 422b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal if (original.isLauncherActivity()) { 4230b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal // Already an activity target 4240b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal return original; 4250b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal } 4265c97f51fd9443e461a360ff7852aa223c05d667fSunny Goyal if (!Utilities.isLauncherAppTarget(original.launchIntent) 4270b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal || !original.user.equals(UserHandleCompat.myUserHandle())) { 4280b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal // We can only convert shortcuts which point to a main activity in the current user. 4290b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal return original; 4300b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal } 4310b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal 4320b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal PackageManager pm = original.mContext.getPackageManager(); 4330b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal ResolveInfo info = pm.resolveActivity(original.launchIntent, 0); 4340b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal 4350b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal if (info == null) { 4360b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal return original; 4370b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal } 4380b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal 4390b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal // Ignore any conflicts in the label name, as that can change based on locale. 4400b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal LauncherActivityInfoCompat launcherInfo = LauncherActivityInfoCompat 4410b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal .fromResolveInfo(info, original.mContext); 4420b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal return new PendingInstallShortcutInfo(launcherInfo, original.mContext); 4430b037789662d1c16627dc5b509d1ac55bc76971bSunny Goyal } 44431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 445