handle shortcut restore for missing packages

Bug: 10778992
Change-Id: I8766b8d4dd9c0269d52a7ec3da58dd408bc5f09f
This commit is contained in:
Chris Wren
2014-01-16 18:13:56 -05:00
parent 947ef4e7ab
commit f4d081107f
4 changed files with 123 additions and 14 deletions
@@ -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;
}
+93 -11
View File
@@ -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";
}
}