Loading src/com/android/launcher3/InstallShortcutReceiver.java +2 −2 Original line number Diff line number Diff line Loading @@ -163,8 +163,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver { if (info != null) { if (!info.isLauncherActivity()) { // Since its a custom shortcut, verify that it is safe to launch. if (!PackageManagerHelper.hasPermissionForActivity( context, info.launchIntent, null)) { if (!new PackageManagerHelper(context).hasPermissionForActivity( info.launchIntent, null)) { // Target cannot be launched, or requires some special permission to launch Log.e(TAG, "Ignoring malicious intent " + info.launchIntent.toUri(0)); return; Loading src/com/android/launcher3/Launcher.java +2 −2 Original line number Diff line number Diff line Loading @@ -1462,8 +1462,8 @@ public class Launcher extends BaseActivity if (info == null) { info = InstallShortcutReceiver.fromShortcutIntent(this, data); if (info == null || !PackageManagerHelper.hasPermissionForActivity( this, info.intent, args.getPendingIntent().getComponent().getPackageName())) { if (info == null || !new PackageManagerHelper(this).hasPermissionForActivity( info.intent, args.getPendingIntent().getComponent().getPackageName())) { // The app is trying to add a shortcut without sufficient permissions Log.e(TAG, "Ignoring malicious intent " + info.intent.toUri(0)); return; Loading src/com/android/launcher3/LauncherModel.java +5 −8 Original line number Diff line number Diff line Loading @@ -1097,12 +1097,11 @@ public class LauncherModel extends BroadcastReceiver if (LauncherAppState.PROFILE_STARTUP) { Trace.beginSection("Loading Workspace"); } final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; final Context context = mContext; final ContentResolver contentResolver = context.getContentResolver(); final PackageManager manager = context.getPackageManager(); final boolean isSafeMode = manager.isSafeMode(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); final boolean isSafeMode = pmHelper.isSafeMode(); final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context); final boolean isSdCardReady = Utilities.isBootCompleted(); Loading Loading @@ -1189,7 +1188,6 @@ public class LauncherModel extends BroadcastReceiver } ShortcutInfo info; String intentDescription; LauncherAppWidgetInfo appWidgetInfo; Intent intent; String targetPkg; Loading Loading @@ -1251,7 +1249,7 @@ public class LauncherModel extends BroadcastReceiver if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { // We allow auto install apps to have their intent // updated after an install. intent = manager.getLaunchIntentForPackage(targetPkg); intent = pmHelper.getAppLaunchIntent(targetPkg, c.user); if (intent != null) { c.restoreFlag = 0; c.updater().put( Loading Loading @@ -1292,8 +1290,7 @@ public class LauncherModel extends BroadcastReceiver c.markDeleted("Unrestored app removed: " + targetPkg); continue; } } else if (PackageManagerHelper.isAppOnSdcard( manager, targetPkg)) { } else if (pmHelper.isAppOnSdcard(targetPkg)) { // Package is present but not available. disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; // Add the icon on the workspace anyway. Loading Loading @@ -1353,7 +1350,7 @@ public class LauncherModel extends BroadcastReceiver info = c.loadSimpleShortcut(); // Shortcuts are only available on the primary profile if (PackageManagerHelper.isAppSuspended(manager, targetPkg)) { if (pmHelper.isAppSuspended(targetPkg)) { disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; } Loading src/com/android/launcher3/model/SdCardAvailableReceiver.java +2 −2 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); final PackageManager manager = context.getPackageManager(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); for (Entry<UserHandle, ArrayList<String>> entry : mPackages.entrySet()) { UserHandle user = entry.getKey(); Loading @@ -63,7 +63,7 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { for (String pkg : new HashSet<>(entry.getValue())) { if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { if (PackageManagerHelper.isAppOnSdcard(manager, pkg)) { if (pmHelper.isAppOnSdcard(pkg)) { packagesUnavailable.add(pkg); } else { packagesRemoved.add(pkg); Loading src/com/android/launcher3/util/PackageManagerHelper.java +37 −14 Original line number Diff line number Diff line Loading @@ -20,14 +20,20 @@ import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.UserHandle; import android.text.TextUtils; import com.android.launcher3.AppInfo; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; import java.util.List; /** * Utility methods using package manager Loading @@ -36,36 +42,55 @@ public class PackageManagerHelper { private static final int FLAG_SUSPENDED = 1<<30; private final Context mContext; private final PackageManager mPm; public PackageManagerHelper(Context context) { mContext = context; mPm = context.getPackageManager(); } /** * Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't * guarantee that the app is on SD card. */ public static boolean isAppOnSdcard(PackageManager pm, String packageName) { return isAppEnabled(pm, packageName, PackageManager.GET_UNINSTALLED_PACKAGES); public boolean isAppOnSdcard(String packageName) { return isAppEnabled(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); } public static boolean isAppEnabled(PackageManager pm, String packageName) { return isAppEnabled(pm, packageName, 0); public boolean isAppEnabled(String packageName) { return isAppEnabled(packageName, 0); } public static boolean isAppEnabled(PackageManager pm, String packageName, int flags) { public boolean isAppEnabled(String packageName, int flags) { try { ApplicationInfo info = pm.getApplicationInfo(packageName, flags); ApplicationInfo info = mPm.getApplicationInfo(packageName, flags); return info != null && info.enabled; } catch (PackageManager.NameNotFoundException e) { return false; } } public static boolean isAppSuspended(PackageManager pm, String packageName) { public boolean isAppSuspended(String packageName) { try { ApplicationInfo info = pm.getApplicationInfo(packageName, 0); ApplicationInfo info = mPm.getApplicationInfo(packageName, 0); return info != null && isAppSuspended(info); } catch (PackageManager.NameNotFoundException e) { return false; } } public boolean isSafeMode() { return mPm.isSafeMode(); } public Intent getAppLaunchIntent(String pkg, UserHandle user) { List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mContext) .getActivityList(pkg, user); return activities.isEmpty() ? null : AppInfo.makeLaunchIntent(mContext, activities.get(0), user); } public static boolean isAppSuspended(ApplicationInfo info) { // The value of FLAG_SUSPENDED was reused by a hidden constant // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N Loading @@ -82,10 +107,8 @@ public class PackageManagerHelper { * {@param intent}. If {@param srcPackage} is null, then the activity should not need * any permissions */ public static boolean hasPermissionForActivity(Context context, Intent intent, String srcPackage) { PackageManager pm = context.getPackageManager(); ResolveInfo target = pm.resolveActivity(intent, 0); public boolean hasPermissionForActivity(Intent intent, String srcPackage) { ResolveInfo target = mPm.resolveActivity(intent, 0); if (target == null) { // Not a valid target return false; Loading @@ -100,7 +123,7 @@ public class PackageManagerHelper { } // Source does not have sufficient permissions. if(pm.checkPermission(target.activityInfo.permission, srcPackage) != if(mPm.checkPermission(target.activityInfo.permission, srcPackage) != PackageManager.PERMISSION_GRANTED) { return false; } Loading @@ -120,7 +143,7 @@ public class PackageManagerHelper { // app-op is only enabled for apps running in compatibility mode, simply block such apps. try { return pm.getApplicationInfo(srcPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M; return mPm.getApplicationInfo(srcPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M; } catch (NameNotFoundException e) { } return false; Loading Loading
src/com/android/launcher3/InstallShortcutReceiver.java +2 −2 Original line number Diff line number Diff line Loading @@ -163,8 +163,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver { if (info != null) { if (!info.isLauncherActivity()) { // Since its a custom shortcut, verify that it is safe to launch. if (!PackageManagerHelper.hasPermissionForActivity( context, info.launchIntent, null)) { if (!new PackageManagerHelper(context).hasPermissionForActivity( info.launchIntent, null)) { // Target cannot be launched, or requires some special permission to launch Log.e(TAG, "Ignoring malicious intent " + info.launchIntent.toUri(0)); return; Loading
src/com/android/launcher3/Launcher.java +2 −2 Original line number Diff line number Diff line Loading @@ -1462,8 +1462,8 @@ public class Launcher extends BaseActivity if (info == null) { info = InstallShortcutReceiver.fromShortcutIntent(this, data); if (info == null || !PackageManagerHelper.hasPermissionForActivity( this, info.intent, args.getPendingIntent().getComponent().getPackageName())) { if (info == null || !new PackageManagerHelper(this).hasPermissionForActivity( info.intent, args.getPendingIntent().getComponent().getPackageName())) { // The app is trying to add a shortcut without sufficient permissions Log.e(TAG, "Ignoring malicious intent " + info.intent.toUri(0)); return; Loading
src/com/android/launcher3/LauncherModel.java +5 −8 Original line number Diff line number Diff line Loading @@ -1097,12 +1097,11 @@ public class LauncherModel extends BroadcastReceiver if (LauncherAppState.PROFILE_STARTUP) { Trace.beginSection("Loading Workspace"); } final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; final Context context = mContext; final ContentResolver contentResolver = context.getContentResolver(); final PackageManager manager = context.getPackageManager(); final boolean isSafeMode = manager.isSafeMode(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); final boolean isSafeMode = pmHelper.isSafeMode(); final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context); final boolean isSdCardReady = Utilities.isBootCompleted(); Loading Loading @@ -1189,7 +1188,6 @@ public class LauncherModel extends BroadcastReceiver } ShortcutInfo info; String intentDescription; LauncherAppWidgetInfo appWidgetInfo; Intent intent; String targetPkg; Loading Loading @@ -1251,7 +1249,7 @@ public class LauncherModel extends BroadcastReceiver if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { // We allow auto install apps to have their intent // updated after an install. intent = manager.getLaunchIntentForPackage(targetPkg); intent = pmHelper.getAppLaunchIntent(targetPkg, c.user); if (intent != null) { c.restoreFlag = 0; c.updater().put( Loading Loading @@ -1292,8 +1290,7 @@ public class LauncherModel extends BroadcastReceiver c.markDeleted("Unrestored app removed: " + targetPkg); continue; } } else if (PackageManagerHelper.isAppOnSdcard( manager, targetPkg)) { } else if (pmHelper.isAppOnSdcard(targetPkg)) { // Package is present but not available. disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; // Add the icon on the workspace anyway. Loading Loading @@ -1353,7 +1350,7 @@ public class LauncherModel extends BroadcastReceiver info = c.loadSimpleShortcut(); // Shortcuts are only available on the primary profile if (PackageManagerHelper.isAppSuspended(manager, targetPkg)) { if (pmHelper.isAppSuspended(targetPkg)) { disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; } Loading
src/com/android/launcher3/model/SdCardAvailableReceiver.java +2 −2 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); final PackageManager manager = context.getPackageManager(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); for (Entry<UserHandle, ArrayList<String>> entry : mPackages.entrySet()) { UserHandle user = entry.getKey(); Loading @@ -63,7 +63,7 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { for (String pkg : new HashSet<>(entry.getValue())) { if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { if (PackageManagerHelper.isAppOnSdcard(manager, pkg)) { if (pmHelper.isAppOnSdcard(pkg)) { packagesUnavailable.add(pkg); } else { packagesRemoved.add(pkg); Loading
src/com/android/launcher3/util/PackageManagerHelper.java +37 −14 Original line number Diff line number Diff line Loading @@ -20,14 +20,20 @@ import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.UserHandle; import android.text.TextUtils; import com.android.launcher3.AppInfo; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; import java.util.List; /** * Utility methods using package manager Loading @@ -36,36 +42,55 @@ public class PackageManagerHelper { private static final int FLAG_SUSPENDED = 1<<30; private final Context mContext; private final PackageManager mPm; public PackageManagerHelper(Context context) { mContext = context; mPm = context.getPackageManager(); } /** * Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't * guarantee that the app is on SD card. */ public static boolean isAppOnSdcard(PackageManager pm, String packageName) { return isAppEnabled(pm, packageName, PackageManager.GET_UNINSTALLED_PACKAGES); public boolean isAppOnSdcard(String packageName) { return isAppEnabled(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); } public static boolean isAppEnabled(PackageManager pm, String packageName) { return isAppEnabled(pm, packageName, 0); public boolean isAppEnabled(String packageName) { return isAppEnabled(packageName, 0); } public static boolean isAppEnabled(PackageManager pm, String packageName, int flags) { public boolean isAppEnabled(String packageName, int flags) { try { ApplicationInfo info = pm.getApplicationInfo(packageName, flags); ApplicationInfo info = mPm.getApplicationInfo(packageName, flags); return info != null && info.enabled; } catch (PackageManager.NameNotFoundException e) { return false; } } public static boolean isAppSuspended(PackageManager pm, String packageName) { public boolean isAppSuspended(String packageName) { try { ApplicationInfo info = pm.getApplicationInfo(packageName, 0); ApplicationInfo info = mPm.getApplicationInfo(packageName, 0); return info != null && isAppSuspended(info); } catch (PackageManager.NameNotFoundException e) { return false; } } public boolean isSafeMode() { return mPm.isSafeMode(); } public Intent getAppLaunchIntent(String pkg, UserHandle user) { List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mContext) .getActivityList(pkg, user); return activities.isEmpty() ? null : AppInfo.makeLaunchIntent(mContext, activities.get(0), user); } public static boolean isAppSuspended(ApplicationInfo info) { // The value of FLAG_SUSPENDED was reused by a hidden constant // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N Loading @@ -82,10 +107,8 @@ public class PackageManagerHelper { * {@param intent}. If {@param srcPackage} is null, then the activity should not need * any permissions */ public static boolean hasPermissionForActivity(Context context, Intent intent, String srcPackage) { PackageManager pm = context.getPackageManager(); ResolveInfo target = pm.resolveActivity(intent, 0); public boolean hasPermissionForActivity(Intent intent, String srcPackage) { ResolveInfo target = mPm.resolveActivity(intent, 0); if (target == null) { // Not a valid target return false; Loading @@ -100,7 +123,7 @@ public class PackageManagerHelper { } // Source does not have sufficient permissions. if(pm.checkPermission(target.activityInfo.permission, srcPackage) != if(mPm.checkPermission(target.activityInfo.permission, srcPackage) != PackageManager.PERMISSION_GRANTED) { return false; } Loading @@ -120,7 +143,7 @@ public class PackageManagerHelper { // app-op is only enabled for apps running in compatibility mode, simply block such apps. try { return pm.getApplicationInfo(srcPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M; return mPm.getApplicationInfo(srcPackage, 0).targetSdkVersion >= Build.VERSION_CODES.M; } catch (NameNotFoundException e) { } return false; Loading