if (version < 3) {
// upgrade 1,2 -> 3 added appWidgetId column
db.beginTransaction();
try {
// Insert new column for holding appWidgetIds
db.execSQL("ALTER TABLE favorites " +"ADD COLUMN appWidgetId INTEGER NOT NULL DEFAULT -1;");
db.setTransactionSuccessful();
version = 3;
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(TAG, ex.getMessage(), ex);
} finally {
db.endTransaction();
}
// Convert existing widgets only if table upgrade was successfulif (version == 3) {
convertWidgets(db);
}
}
/**
* Upgrade existing clock and photo frame widgets into their new widget equivalents.
*/privatevoidconvertWidgets(SQLiteDatabase db) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
finalint[] bindSources = newint[] {
Favorites.ITEM_TYPE_WIDGET_CLOCK, Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME, Favorites.ITEM_TYPE_WIDGET_SEARCH,
};
final String selectWhere = buildOrWhereString(Favorites.ITEM_TYPE,bindSources);
Cursor c = null;
db.beginTransaction();
try {
// Select and iterate through each matching widget
c = db.query(TABLE_FAVORITES, new String[] { Favorites._ID, Favorites.ITEM_TYPE },
selectWhere, null, null, null, null);
if (LOGD) Log.d(TAG, "found upgrade cursor count=" + c.getCount());
final ContentValues values = new ContentValues();
while (c != null && c.moveToNext()) {
long favoriteId = c.getLong(0);
int favoriteType = c.getInt(1);
// Allocate and update database with new appWidgetIdtry {
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
if (LOGD) {
Log.d(TAG, "allocated appWidgetId=" + appWidgetId
+ " for favoriteId=" + favoriteId);
}
values.clear(); values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPWIDGET); values.put(Favorites.APPWIDGET_ID, appWidgetId);
// Original widgets might not have valid spans when upgradingif (favoriteType == Favorites.ITEM_TYPE_WIDGET_SEARCH) { values.put(LauncherSettings.Favorites.SPANX, 4);
values.put(LauncherSettings.Favorites.SPANY, 1);
} else { values.put(LauncherSettings.Favorites.SPANX, 2); values.put(LauncherSettings.Favorites.SPANY, 2);
}
String updateWhere = Favorites._ID + "=" + favoriteId;
db.update(TABLE_FAVORITES, values, updateWhere, null);
if (favoriteType == Favorites.ITEM_TYPE_WIDGET_CLOCK) {
// TODO: check return value
appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
new ComponentName("com.android.alarmclock",
"com.android.alarmclock.AnalogAppWidgetProvider"));
} elseif (favoriteType == Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
// TODO: check return value appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,new ComponentName("com.android.camera", "com.android.camera.PhotoAppWidgetProvider"));
} elseif (favoriteType == Favorites.ITEM_TYPE_WIDGET_SEARCH) {
// TODO: check return value
appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
getSearchWidgetProvider());
}
} catch (RuntimeException ex) {
Log.e(TAG, "Problem allocating appWidgetId", ex);
}
}
db.setTransactionSuccessful();
} catch (SQLException ex) {
Log.w(TAG, "Problem while allocating appWidgetIds for existing widgets", ex);
} finally {
db.endTransaction();
if (c != null) {
c.close();
}
}
}
privatebooleanupdateContactsShortcuts(SQLiteDatabase db) {
final String selectWhere = buildOrWhereString(Favorites.ITEM_TYPE,
newint[] { Favorites.ITEM_TYPE_SHORTCUT });
Cursor c = null;
final String actionQuickContact = "com.android.contacts.action.QUICK_CONTACT";
db.beginTransaction();
try {
// Select and iterate through each matching widget
c = db.query(TABLE_FAVORITES,
new String[] { Favorites._ID, Favorites.INTENT },
selectWhere, null, null, null, null);
if (c == null) returnfalse;
if (LOGD) Log.d(TAG, "found upgrade cursor count=" + c.getCount());
finalint idIndex = c.getColumnIndex(Favorites._ID);
finalint intentIndex = c.getColumnIndex(Favorites.INTENT);
while (c.moveToNext()) {
long favoriteId = c.getLong(idIndex);
final String intentUri = c.getString(intentIndex);
if (intentUri != null) {
try {
final Intent intent = Intent.parseUri(intentUri, 0);
android.util.Log.d("Home", intent.toString());
final Uri uri = intent.getData();
if (uri != null) {
final String data = uri.toString();
if ((Intent.ACTION_VIEW.equals(intent.getAction()) ||
actionQuickContact.equals(intent.getAction())) &&
(data.startsWith("content://contacts/people/") ||
data.startsWith("content://com.android.contacts/" +
"contacts/lookup/"))) {
final Intent newIntent = new Intent(actionQuickContact);
// When starting from the launcher, start in a new, cleared task// CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we// clear the whole thing preemptively here since// QuickContactActivity will finish itself when launching other// detail activities.
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
newIntent.putExtra(
Launcher.INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION, true);
newIntent.setData(uri);
// Determine the type and also put that in the shortcut// (that can speed up launch a bit)
newIntent.setDataAndType(uri, newIntent.resolveType(mContext));
final ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites.INTENT,
newIntent.toUri(0));
String updateWhere = Favorites._ID + "=" + favoriteId;
db.update(TABLE_FAVORITES, values, updateWhere, null);
}
}
} catch (RuntimeException ex) {
Log.e(TAG, "Problem upgrading shortcut", ex);
} catch (URISyntaxException e) {
Log.e(TAG, "Problem upgrading shortcut", e);
}
}
}
db.setTransactionSuccessful();
} catch (SQLException ex) {
Log.w(TAG, "Problem while upgrading contacts", ex);
returnfalse;
} finally {
db.endTransaction();
if (c != null) {
c.close();
}
}
returntrue;
}
privatevoidnormalizeIcons(SQLiteDatabase db) {
Log.d(TAG, "normalizing icons");
db.beginTransaction();
Cursor c = null;
SQLiteStatement update = null;
try {
boolean logged = false;
update = db.compileStatement("UPDATE favorites "
+ "SET icon=? WHERE _id=?");
c = db.rawQuery("SELECT _id, icon FROM favorites WHERE iconType=" +
Favorites.ICON_TYPE_BITMAP, null);
finalint idIndex = c.getColumnIndexOrThrow(Favorites._ID);
finalint iconIndex = c.getColumnIndexOrThrow(Favorites.ICON);
while (c.moveToNext()) {
long id = c.getLong(idIndex);
byte[] data = c.getBlob(iconIndex);
try {
Bitmap bitmap = Utilities.resampleIconBitmap(
BitmapFactory.decodeByteArray(data, 0, data.length),
mContext);
if (bitmap != null) {
update.bindLong(1, id);
data = ItemInfo.flattenBitmap(bitmap);
if (data != null) {
update.bindBlob(2, data);
update.execute();
}
bitmap.recycle();
}
} catch (Exception e) {
if (!logged) {
Log.e(TAG, "Failed normalizing icon " + id, e);
} else {
Log.e(TAG, "Also failed normalizing icon " + id);
}
logged = true;
}
}
db.setTransactionSuccessful();
} catch (SQLException ex) {
Log.w(TAG, "Problem while allocating appWidgetIds for existing widgets", ex);
} finally {
db.endTransaction();
if (update != null) {
update.close();
}
if (c != null) {
c.close();
}
}
}
/**
* Loads the default set of favorite packages from an xml file.
*
* @param db The database to write the values into
* @param filterContainerId The specific container id of items to load
*/privateintloadFavorites(SQLiteDatabase db, int workspaceResourceId) {
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ContentValues values = new ContentValues();
PackageManager packageManager = mContext.getPackageManager();
int allAppsButtonRank =
mContext.getResources().getInteger(R.integer.hotseat_all_apps_index);
int i = 0;
try {
XmlResourceParser parser = mContext.getResources().getXml(workspaceResourceId);
AttributeSet attrs = Xml.asAttributeSet(parser);
beginDocument(parser, TAG_FAVORITES);
finalint depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
boolean added = false;
final String name = parser.getName();
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);
long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
if (a.hasValue(R.styleable.Favorite_container)) {
container = Long.valueOf(a.getString(R.styleable.Favorite_container));
}
String screen = a.getString(R.styleable.Favorite_screen);
String x = a.getString(R.styleable.Favorite_x);
String y = a.getString(R.styleable.Favorite_y);
// If we are adding to the hotseat, the screen is used as the position in the// hotseat. This screen can't be at position 0 because AllApps is in the// zeroth position.if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
&& Integer.valueOf(screen) == allAppsButtonRank) {
thrownew RuntimeException("Invalid screen position for hotseat item");
}
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER, container);
values.put(LauncherSettings.Favorites.SCREEN, screen);
values.put(LauncherSettings.Favorites.CELLX, x);
values.put(LauncherSettings.Favorites.CELLY, y);
if (TAG_FAVORITE.equals(name)) {
long id = addAppShortcut(db, values, a, packageManager, intent);
added = id >= 0;
} elseif (TAG_SEARCH.equals(name)) {
added = addSearchWidget(db, values);
} elseif (TAG_CLOCK.equals(name)) {
added = addClockWidget(db, values);
} elseif (TAG_APPWIDGET.equals(name)) {
added = addAppWidget(parser, attrs, type, db, values, a, packageManager);
} elseif (TAG_SHORTCUT.equals(name)) {
long id = addUriShortcut(db, values, a);
added = id >= 0;
} elseif (TAG_FOLDER.equals(name)) {
String title;
int titleResId = a.getResourceId(R.styleable.Favorite_title, -1);
if (titleResId != -1) {
title = mContext.getResources().getString(titleResId);
} else {
title = mContext.getResources().getString(R.string.folder_name);
}
values.put(LauncherSettings.Favorites.TITLE, title);
long folderId = addFolder(db, values);
added = folderId >= 0;
ArrayList<Long> folderItems = new ArrayList<Long>();
int folderDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > folderDepth) {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String folder_item_name = parser.getName();
TypedArray ar = mContext.obtainStyledAttributes(attrs,
R.styleable.Favorite);
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER, folderId);
if (TAG_FAVORITE.equals(folder_item_name) && folderId >= 0) {
long id =
addAppShortcut(db, values, ar, packageManager, intent);
if (id >= 0) {
folderItems.add(id);
}
} elseif (TAG_SHORTCUT.equals(folder_item_name) && folderId >= 0) {
long id = addUriShortcut(db, values, ar);
if (id >= 0) {
folderItems.add(id);
}
} else {
thrownew RuntimeException("Folders can " +
"contain only shortcuts");
}
ar.recycle();
}
// We can only have folders with >= 2 items, so we need to remove the// folder and clean up if less than 2 items were included, or some// failed to add, and less than 2 were actually addedif (folderItems.size() < 2 && folderId >= 0) {
// We just delete the folder and any items that made it
deleteId(db, folderId);
if (folderItems.size() > 0) {
deleteId(db, folderItems.get(0));
}
added = false;
}
}
if (added) i++;
a.recycle();
}
} catch (XmlPullParserException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
} catch (IOException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
} catch (RuntimeException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
}
return i;
}