handle shortcut restore for missing packages
Bug: 10778992 Change-Id: I8766b8d4dd9c0269d52a7ec3da58dd408bc5f09f
This commit is contained in:
@@ -842,6 +842,10 @@ public class LauncherBackupHelper implements BackupHelper {
|
||||
}
|
||||
values.put(Favorites.APPWIDGET_ID, favorite.appWidgetId);
|
||||
}
|
||||
|
||||
// Let LauncherModel know we've been here.
|
||||
values.put(LauncherSettings.Favorites.RESTORED, 1);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
@@ -1714,6 +1714,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
clearSBgDataStructures();
|
||||
|
||||
final ArrayList<Long> itemsToRemove = new ArrayList<Long>();
|
||||
final ArrayList<Long> restoredRows = new ArrayList<Long>();
|
||||
final Uri contentUri = LauncherSettings.Favorites.CONTENT_URI;
|
||||
if (DEBUG_LOADERS) Log.d(TAG, "loading model from " + contentUri);
|
||||
final Cursor c = contentResolver.query(contentUri, null, null, null, null);
|
||||
@@ -1754,6 +1755,8 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
(LauncherSettings.Favorites.SPANX);
|
||||
final int spanYIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.SPANY);
|
||||
final int restoredIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.RESTORED);
|
||||
//final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
|
||||
//final int displayModeIndex = c.getColumnIndexOrThrow(
|
||||
// LauncherSettings.Favorites.DISPLAY_MODE);
|
||||
@@ -1769,6 +1772,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
AtomicBoolean deleteOnInvalidPlacement = new AtomicBoolean(false);
|
||||
try {
|
||||
int itemType = c.getInt(itemTypeIndex);
|
||||
boolean restored = 0 != c.getInt(restoredIndex);
|
||||
|
||||
switch (itemType) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||
@@ -1779,24 +1783,44 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
intent = Intent.parseUri(intentDescription, 0);
|
||||
ComponentName cn = intent.getComponent();
|
||||
if (cn != null && !isValidPackageComponent(manager, cn)) {
|
||||
if (!mAppsCanBeOnRemoveableStorage) {
|
||||
// Log the invalid package, and remove it from the db
|
||||
Launcher.addDumpLog(TAG, "Invalid package removed: " + cn, true);
|
||||
itemsToRemove.add(id);
|
||||
if (restored) {
|
||||
// might be installed later
|
||||
Launcher.addDumpLog(TAG,
|
||||
"package not yet restored: " + cn, true);
|
||||
} else {
|
||||
// If apps can be on external storage, then we just
|
||||
// leave them for the user to remove (maybe add
|
||||
// visual treatment to it)
|
||||
Launcher.addDumpLog(TAG, "Invalid package found: " + cn, true);
|
||||
if (!mAppsCanBeOnRemoveableStorage) {
|
||||
// Log the invalid package, and remove it
|
||||
Launcher.addDumpLog(TAG,
|
||||
"Invalid package removed: " + cn, true);
|
||||
itemsToRemove.add(id);
|
||||
} else {
|
||||
// If apps can be on external storage, then we just
|
||||
// leave them for the user to remove (maybe add
|
||||
// visual treatment to it)
|
||||
Launcher.addDumpLog(TAG,
|
||||
"Invalid package found: " + cn, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
} else if (restored) {
|
||||
// no special handling necessary for this restored item
|
||||
restoredRows.add(id);
|
||||
restored = false;
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
Launcher.addDumpLog(TAG, "Invalid uri: " + intentDescription, true);
|
||||
Launcher.addDumpLog(TAG,
|
||||
"Invalid uri: " + intentDescription, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||
if (restored) {
|
||||
Launcher.addDumpLog(TAG,
|
||||
"constructing info for partially restored package",
|
||||
true);
|
||||
info = getRestoredItemInfo(c, titleIndex);
|
||||
intent = getRestoredItemIntent(c, context, intent);
|
||||
} else if (itemType ==
|
||||
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||
info = getShortcutInfo(manager, intent, context, c, iconIndex,
|
||||
titleIndex, mLabelCache);
|
||||
} else {
|
||||
@@ -1890,6 +1914,11 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
break;
|
||||
}
|
||||
|
||||
if (restored) {
|
||||
// no special handling required for restored folders
|
||||
restoredRows.add(id);
|
||||
}
|
||||
|
||||
sBgItemsIdMap.put(folderInfo.id, folderInfo);
|
||||
sBgFolders.put(folderInfo.id, folderInfo);
|
||||
break;
|
||||
@@ -1990,6 +2019,25 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
if (restoredRows.size() > 0) {
|
||||
ContentProviderClient updater = contentResolver.acquireContentProviderClient(
|
||||
LauncherSettings.Favorites.CONTENT_URI);
|
||||
// Update restored items that no longer require special handling
|
||||
try {
|
||||
StringBuilder selectionBuilder = new StringBuilder();
|
||||
selectionBuilder.append(LauncherSettings.Favorites._ID);
|
||||
selectionBuilder.append(" IN (");
|
||||
selectionBuilder.append(TextUtils.join(", ", restoredRows));
|
||||
selectionBuilder.append(")");
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(LauncherSettings.Favorites.RESTORED, 0);
|
||||
updater.update(LauncherSettings.Favorites.CONTENT_URI,
|
||||
values, selectionBuilder.toString(), null);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Could not update restored rows");
|
||||
}
|
||||
}
|
||||
|
||||
if (loadedOldDb) {
|
||||
long maxScreenId = 0;
|
||||
// If we're importing we use the old screen order.
|
||||
@@ -2736,6 +2784,40 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an ShortcutInfo object for a restored application or shortcut item that points
|
||||
* to a package that is not yet installed on the system.
|
||||
*/
|
||||
public ShortcutInfo getRestoredItemInfo(Cursor cursor, int titleIndex) {
|
||||
final ShortcutInfo info = new ShortcutInfo();
|
||||
info.usingFallbackIcon = true;
|
||||
info.setIcon(getFallbackIcon());
|
||||
if (cursor != null) {
|
||||
info.title = cursor.getString(titleIndex);
|
||||
} else {
|
||||
info.title = "";
|
||||
}
|
||||
info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an Intent object for a restored application or shortcut item that points
|
||||
* to the market page for the item.
|
||||
*/
|
||||
private Intent getRestoredItemIntent(Cursor c, Context context, Intent intent) {
|
||||
ComponentName componentName = intent.getComponent();
|
||||
Intent marketIntent = new Intent(Intent.ACTION_VIEW);
|
||||
Uri marketUri = new Uri.Builder()
|
||||
.scheme("market")
|
||||
.authority("details")
|
||||
.appendQueryParameter("id", componentName.getPackageName())
|
||||
.build();
|
||||
Log.d(TAG, "manufactured intent uri: " + marketUri.toString());
|
||||
marketIntent.setData(marketUri);
|
||||
return marketIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called from the code that adds shortcuts from the intent receiver. This
|
||||
* doesn't have a Cursor, but
|
||||
|
||||
@@ -68,7 +68,7 @@ public class LauncherProvider extends ContentProvider {
|
||||
|
||||
private static final String DATABASE_NAME = "launcher.db";
|
||||
|
||||
private static final int DATABASE_VERSION = 15;
|
||||
private static final int DATABASE_VERSION = 16;
|
||||
|
||||
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
|
||||
static final String AUTHORITY = ProviderConfig.AUTHORITY;
|
||||
@@ -409,7 +409,8 @@ public class LauncherProvider extends ContentProvider {
|
||||
"uri TEXT," +
|
||||
"displayMode INTEGER," +
|
||||
"appWidgetProvider TEXT," +
|
||||
"modified INTEGER NOT NULL DEFAULT 0" +
|
||||
"modified INTEGER NOT NULL DEFAULT 0," +
|
||||
"restored INTEGER NOT NULL DEFAULT 0" +
|
||||
");");
|
||||
addWorkspacesTable(db);
|
||||
|
||||
@@ -716,7 +717,6 @@ public class LauncherProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (version < 15) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
@@ -735,6 +735,23 @@ public class LauncherProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (version < 16) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
// Insert new column for holding restore status
|
||||
db.execSQL("ALTER TABLE favorites " +
|
||||
"ADD COLUMN restored INTEGER NOT NULL DEFAULT 0;");
|
||||
db.setTransactionSuccessful();
|
||||
version = 16;
|
||||
} catch (SQLException ex) {
|
||||
// Old version remains, which means we wipe old data
|
||||
Log.e(TAG, ex.getMessage(), ex);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
if (version != DATABASE_VERSION) {
|
||||
Log.w(TAG, "Destroying all old data.");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
|
||||
|
||||
@@ -275,5 +275,11 @@ class LauncherSettings {
|
||||
* @see android.provider.LiveFolders#DISPLAY_MODE_LIST
|
||||
*/
|
||||
static final String DISPLAY_MODE = "displayMode";
|
||||
|
||||
/**
|
||||
* Boolean indicating that his item was restored and not yet successfully bound.
|
||||
* <P>Type: INTEGER</P>
|
||||
*/
|
||||
static final String RESTORED = "restored";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user