Fixing loadWorkspace
> Adding checks on legacy shortcuts > Checking restore status based on package and not componentName Bug: 34123342 Change-Id: I442699e4ebb34ae66aa25c512bfcdc1b4fd5ae2a
This commit is contained in:
parent
ab45ec0c23
commit
81e4491450
|
@ -1144,8 +1144,6 @@ public class LauncherModel extends BroadcastReceiver
|
|||
HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
|
||||
|
||||
try {
|
||||
final int intentIndex = c.getColumnIndexOrThrow
|
||||
(LauncherSettings.Favorites.INTENT);
|
||||
final int appWidgetIdIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.APPWIDGET_ID);
|
||||
final int appWidgetProviderIndex = c.getColumnIndexOrThrow(
|
||||
|
@ -1192,7 +1190,7 @@ public class LauncherModel extends BroadcastReceiver
|
|||
String intentDescription;
|
||||
LauncherAppWidgetInfo appWidgetInfo;
|
||||
Intent intent;
|
||||
String targetPackage;
|
||||
String targetPkg;
|
||||
|
||||
while (!mStopped && c.moveToNext()) {
|
||||
try {
|
||||
|
@ -1204,116 +1202,126 @@ public class LauncherModel extends BroadcastReceiver
|
|||
|
||||
boolean allowMissingTarget = false;
|
||||
switch (c.itemType) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: {
|
||||
if (!Process.myUserHandle().equals(c.user)) {
|
||||
c.markDeleted("Legacy shortcuts are only allowed for default user");
|
||||
continue;
|
||||
}
|
||||
// Follow through.
|
||||
}
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
||||
intentDescription = c.getString(intentIndex);
|
||||
int disabledState = 0;
|
||||
targetPackage = null;
|
||||
intent = c.parseIntent();
|
||||
if (intent == null) {
|
||||
c.markDeleted("Invalid or null intent");
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
intent = Intent.parseUri(intentDescription, 0);
|
||||
ComponentName cn = intent.getComponent();
|
||||
if (cn != null && cn.getPackageName() != null) {
|
||||
boolean validPkg = launcherApps.isPackageEnabledForProfile(
|
||||
cn.getPackageName(), c.user);
|
||||
boolean validComponent = validPkg &&
|
||||
launcherApps.isActivityEnabledForProfile(cn, c.user);
|
||||
if (validPkg) {
|
||||
targetPackage = cn.getPackageName();
|
||||
}
|
||||
int disabledState = quietMode.get(c.serialNumber) ?
|
||||
ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0;
|
||||
ComponentName cn = intent.getComponent();
|
||||
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
|
||||
|
||||
if (validComponent) {
|
||||
// no special handling necessary for this item
|
||||
c.markRestored();
|
||||
if (quietMode.get(c.serialNumber)) {
|
||||
disabledState = ShortcutInfo.FLAG_DISABLED_QUIET_USER;
|
||||
}
|
||||
} else if (validPkg) {
|
||||
intent = null;
|
||||
if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
|
||||
// We allow auto install apps to have their intent
|
||||
// updated after an install.
|
||||
intent = manager.getLaunchIntentForPackage(
|
||||
cn.getPackageName());
|
||||
if (intent != null) {
|
||||
c.updater().put(
|
||||
LauncherSettings.Favorites.INTENT,
|
||||
intent.toUri(0)).commit();
|
||||
}
|
||||
}
|
||||
if (!Process.myUserHandle().equals(c.user)) {
|
||||
if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||
c.markDeleted("Legacy shortcuts are only allowed for default user");
|
||||
continue;
|
||||
} else if (c.restoreFlag != 0) {
|
||||
// Don't restore items for other profiles.
|
||||
c.markDeleted("Restore from managed profile not supported");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(targetPkg) &&
|
||||
c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||
c.markDeleted("Only legacy shortcuts can have null package");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (intent == null) {
|
||||
// The app is installed but the component is no
|
||||
// longer available.
|
||||
c.markDeleted("Invalid component removed: " + cn);
|
||||
continue;
|
||||
} else {
|
||||
// no special handling necessary for this item
|
||||
c.markRestored();
|
||||
}
|
||||
} else if (c.restoreFlag != 0) {
|
||||
// Package is not yet available but might be
|
||||
// installed later.
|
||||
FileLog.d(TAG, "package not yet restored: " + cn);
|
||||
// If there is no target package, its an implicit intent
|
||||
// (legacy shortcut) which is always valid
|
||||
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
|
||||
launcherApps.isPackageEnabledForProfile(targetPkg, c.user);
|
||||
|
||||
if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
|
||||
// Restore has started once.
|
||||
} else if (installingPkgs.containsKey(cn.getPackageName())) {
|
||||
// App restore has started. Update the flag
|
||||
c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
|
||||
if (cn != null && validTarget) {
|
||||
// If the apk is present and the shortcut points to a specific
|
||||
// component.
|
||||
|
||||
// If the component is already present
|
||||
if (launcherApps.isActivityEnabledForProfile(cn, c.user)) {
|
||||
// no special handling necessary for this item
|
||||
c.markRestored();
|
||||
} else {
|
||||
if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
|
||||
// We allow auto install apps to have their intent
|
||||
// updated after an install.
|
||||
intent = manager.getLaunchIntentForPackage(targetPkg);
|
||||
if (intent != null) {
|
||||
c.restoreFlag = 0;
|
||||
c.updater().put(
|
||||
LauncherSettings.Favorites.RESTORED,
|
||||
c.restoreFlag).commit();
|
||||
LauncherSettings.Favorites.INTENT,
|
||||
intent.toUri(0)).commit();
|
||||
cn = intent.getComponent();
|
||||
} else {
|
||||
c.markDeleted("Unrestored package removed: " + cn);
|
||||
c.markDeleted("Unable to find a launch target");
|
||||
continue;
|
||||
}
|
||||
} else if (PackageManagerHelper.isAppOnSdcard(
|
||||
manager, cn.getPackageName())) {
|
||||
// Package is present but not available.
|
||||
allowMissingTarget = true;
|
||||
disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
|
||||
} else if (!isSdCardReady) {
|
||||
// SdCard is not ready yet. Package might get available,
|
||||
// once it is ready.
|
||||
Log.d(TAG, "Invalid package: " + cn + " (check again later)");
|
||||
pendingPackages.addToList(c.user, cn.getPackageName());
|
||||
allowMissingTarget = true;
|
||||
// Add the icon on the workspace anyway.
|
||||
|
||||
} else {
|
||||
// Do not wait for external media load anymore.
|
||||
// Log the invalid package, and remove it
|
||||
c.markDeleted("Invalid package removed: " + cn);
|
||||
// The app is installed but the component is no
|
||||
// longer available.
|
||||
c.markDeleted("Invalid component removed: " + cn);
|
||||
continue;
|
||||
}
|
||||
} else if (cn == null) {
|
||||
// For shortcuts with no component, keep them as they are
|
||||
c.markRestored();
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
c.markDeleted("Invalid uri: " + intentDescription);
|
||||
continue;
|
||||
}
|
||||
// else if cn == null => can't infer much, leave it
|
||||
// else if !validPkg => could be restored icon or missing sd-card
|
||||
|
||||
if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
|
||||
// Points to a valid app (superset of cn != null) but the apk
|
||||
// is not available.
|
||||
|
||||
if (c.restoreFlag != 0) {
|
||||
// Package is not yet available but might be
|
||||
// installed later.
|
||||
FileLog.d(TAG, "package not yet restored: " + targetPkg);
|
||||
|
||||
if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
|
||||
// Restore has started once.
|
||||
} else if (installingPkgs.containsKey(targetPkg)) {
|
||||
// App restore has started. Update the flag
|
||||
c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
|
||||
c.updater().commit();
|
||||
} else {
|
||||
c.markDeleted("Unrestored app removed: " + targetPkg);
|
||||
continue;
|
||||
}
|
||||
} else if (PackageManagerHelper.isAppOnSdcard(
|
||||
manager, targetPkg)) {
|
||||
// Package is present but not available.
|
||||
disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
|
||||
// Add the icon on the workspace anyway.
|
||||
allowMissingTarget = true;
|
||||
} else if (!isSdCardReady) {
|
||||
// SdCard is not ready yet. Package might get available,
|
||||
// once it is ready.
|
||||
Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
|
||||
pendingPackages.addToList(c.user, targetPkg);
|
||||
// Add the icon on the workspace anyway.
|
||||
allowMissingTarget = true;
|
||||
} else {
|
||||
// Do not wait for external media load anymore.
|
||||
c.markDeleted("Invalid package removed: " + targetPkg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (validTarget) {
|
||||
// The shortcut points to a valid target (either no target
|
||||
// or something which is ready to be used)
|
||||
c.markRestored();
|
||||
}
|
||||
|
||||
boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
|
||||
c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
|
||||
|
||||
if (c.restoreFlag != 0) {
|
||||
if (c.user.equals(Process.myUserHandle())) {
|
||||
info = c.getRestoredItemInfo(intent);
|
||||
} else {
|
||||
// Don't restore items for other profiles.
|
||||
c.markDeleted("Restore from managed profile not supported");
|
||||
continue;
|
||||
}
|
||||
// Already verified above that user is same as default user
|
||||
info = c.getRestoredItemInfo(intent);
|
||||
} else if (c.itemType ==
|
||||
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||
info = c.getAppShortcutInfo(
|
||||
|
@ -1343,7 +1351,7 @@ public class LauncherModel extends BroadcastReceiver
|
|||
info = c.loadSimpleShortcut();
|
||||
|
||||
// Shortcuts are only available on the primary profile
|
||||
if (PackageManagerHelper.isAppSuspended(manager, targetPackage)) {
|
||||
if (PackageManagerHelper.isAppSuspended(manager, targetPkg)) {
|
||||
disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
|
||||
}
|
||||
|
||||
|
@ -1375,15 +1383,12 @@ public class LauncherModel extends BroadcastReceiver
|
|||
info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
|
||||
}
|
||||
|
||||
if (c.restoreFlag != 0) {
|
||||
ComponentName cn = info.getTargetComponent();
|
||||
if (cn != null) {
|
||||
Integer progress = installingPkgs.get(cn.getPackageName());
|
||||
if (progress != null) {
|
||||
info.setInstallProgress(progress);
|
||||
} else {
|
||||
info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
|
||||
}
|
||||
if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
|
||||
Integer progress = installingPkgs.get(targetPkg);
|
||||
if (progress != null) {
|
||||
info.setInstallProgress(progress);
|
||||
} else {
|
||||
info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1489,11 +1494,7 @@ public class LauncherModel extends BroadcastReceiver
|
|||
}
|
||||
if (appWidgetInfo.hasRestoreFlag(
|
||||
LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
|
||||
intentDescription = c.getString(intentIndex);
|
||||
if (!TextUtils.isEmpty(intentDescription)) {
|
||||
appWidgetInfo.bindOptions =
|
||||
Intent.parseUri(intentDescription, 0);
|
||||
}
|
||||
appWidgetInfo.bindOptions = c.parseIntent();
|
||||
}
|
||||
|
||||
c.applyCommonProperties(appWidgetInfo);
|
||||
|
|
|
@ -37,7 +37,7 @@ public class LauncherSettings {
|
|||
public static final String MODIFIED = "modified";
|
||||
}
|
||||
|
||||
static interface BaseLauncherColumns extends ChangeLogColumns {
|
||||
static public interface BaseLauncherColumns extends ChangeLogColumns {
|
||||
/**
|
||||
* Descriptive name of the gesture that can be displayed to the user.
|
||||
* <P>Type: TEXT</P>
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.android.launcher3.util.GridOccupancy;
|
|||
import com.android.launcher3.util.LongArrayMap;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -84,6 +85,7 @@ public class LoaderCursor extends CursorWrapper {
|
|||
private final int cellYIndex;
|
||||
private final int profileIdIndex;
|
||||
private final int restoredIndex;
|
||||
private final int intentIndex;
|
||||
|
||||
// Properties loaded per iteration
|
||||
public long serialNumber;
|
||||
|
@ -114,6 +116,7 @@ public class LoaderCursor extends CursorWrapper {
|
|||
cellYIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
|
||||
profileIdIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.PROFILE_ID);
|
||||
restoredIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.RESTORED);
|
||||
intentIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,6 +134,17 @@ public class LoaderCursor extends CursorWrapper {
|
|||
return result;
|
||||
}
|
||||
|
||||
public Intent parseIntent() {
|
||||
String intentDescription = getString(intentIndex);
|
||||
try {
|
||||
return TextUtils.isEmpty(intentDescription) ?
|
||||
null : Intent.parseUri(intentDescription, 0);
|
||||
} catch (URISyntaxException e) {
|
||||
Log.e(TAG, "Error parsing Intent");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ShortcutInfo loadSimpleShortcut() {
|
||||
final ShortcutInfo info = new ShortcutInfo();
|
||||
// Non-app shortcuts are only supported for current user.
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.runner.RunWith;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.android.launcher3.LauncherSettings.BaseLauncherColumns.INTENT;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CELLX;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CELLY;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER;
|
||||
|
@ -73,7 +74,7 @@ public class LoaderCursorTest {
|
|||
mCursor = new MatrixCursor(new String[] {
|
||||
ICON, ICON_PACKAGE, ICON_RESOURCE, TITLE,
|
||||
_ID, CONTAINER, ITEM_TYPE, PROFILE_ID,
|
||||
SCREEN, CELLX, CELLY, RESTORED
|
||||
SCREEN, CELLX, CELLY, RESTORED, INTENT
|
||||
});
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
|
|
Loading…
Reference in New Issue