Loading AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.launcher3"> <uses-sdk android:targetSdkVersion="19" android:minSdkVersion="16"/> <permission android:name="com.android.launcher3.permission.PRELOAD_WORKSPACE" Loading src/com/android/launcher3/Launcher.java +20 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,8 @@ public class Launcher extends Activity static final boolean DEBUG_RESUME_TIME = false; static final boolean DEBUG_DUMP_LOG = false; static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run private static final int REQUEST_CREATE_SHORTCUT = 1; private static final int REQUEST_CREATE_APPWIDGET = 5; private static final int REQUEST_PICK_APPLICATION = 6; Loading Loading @@ -1571,6 +1573,15 @@ public class Launcher extends Activity } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(); } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) { mModel.resetLoadedState(false, true); mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE); } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) { mModel.resetLoadedState(false, true); mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS); } } }; Loading @@ -1583,6 +1594,10 @@ public class Launcher extends Activity final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); if (ENABLE_DEBUG_INTENTS) { filter.addAction(DebugIntents.DELETE_DATABASE); filter.addAction(DebugIntents.MIGRATE_DATABASE); } registerReceiver(mReceiver, filter); FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView()); mAttached = true; Loading Loading @@ -4704,3 +4719,8 @@ interface LauncherTransitionable { void onLauncherTransitionStep(Launcher l, float t); void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace); } interface DebugIntents { static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE"; static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE"; } src/com/android/launcher3/LauncherModel.java +27 −5 Original line number Diff line number Diff line Loading @@ -75,6 +75,10 @@ public class LauncherModel extends BroadcastReceiver { // false = strew non-workspace apps across the workspace on upgrade public static final boolean UPGRADE_USE_MORE_APPS_FOLDER = false; public static final int LOADER_FLAG_NONE = 0; public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0; public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1; private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons private static final long INVALID_SCREEN_ID = -1L; private final boolean mAppsCanBeOnRemoveableStorage; Loading Loading @@ -1193,6 +1197,10 @@ public class LauncherModel extends BroadcastReceiver { } public void startLoader(boolean isLaunching, int synchronousBindPage) { startLoader(isLaunching, synchronousBindPage, LOADER_FLAG_NONE); } public void startLoader(boolean isLaunching, int synchronousBindPage, int loadFlags) { synchronized (mLock) { if (DEBUG_LOADERS) { Log.d(TAG, "startLoader isLaunching=" + isLaunching); Loading @@ -1207,7 +1215,7 @@ public class LauncherModel extends BroadcastReceiver { // If there is already one running, tell it to stop. // also, don't downgrade isLaunching if we're already running isLaunching = isLaunching || stopLoaderLocked(); mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching); mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching, loadFlags); if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE && mAllAppsLoaded && mWorkspaceLoaded) { mLoaderTask.runBindSynchronousPage(synchronousBindPage); Loading Loading @@ -1298,13 +1306,15 @@ public class LauncherModel extends BroadcastReceiver { private boolean mIsLoadingAndBindingWorkspace; private boolean mStopped; private boolean mLoadAndBindStepFinished; private int mFlags; private HashMap<Object, CharSequence> mLabelCache; LoaderTask(Context context, boolean isLaunching) { LoaderTask(Context context, boolean isLaunching, int flags) { mContext = context; mIsLaunching = isLaunching; mLabelCache = new HashMap<Object, CharSequence>(); mFlags = flags; } boolean isLaunching() { Loading Loading @@ -1651,7 +1661,7 @@ public class LauncherModel extends BroadcastReceiver { } } /** Returns whether this is an upgradge path */ /** Returns whether this is an upgrade path */ private boolean loadWorkspace() { // Log to disk Launcher.addDumpLog(TAG, "11683562 - loadWorkspace()", true); Loading @@ -1669,8 +1679,20 @@ public class LauncherModel extends BroadcastReceiver { int countX = (int) grid.numColumns; int countY = (int) grid.numRows; // Make sure the default workspace is loaded, if needed if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) { Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true); LauncherAppState.getLauncherProvider().deleteDatabase(); } if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) { // append the user's Launcher2 shortcuts Launcher.addDumpLog(TAG, "loadWorkspace: migrating from launcher2", true); LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts(); } else { // Make sure the default workspace is loaded Launcher.addDumpLog(TAG, "loadWorkspace: loading default favorites", false); LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(0); } // Check if we need to do any upgrade-path logic // (Includes having just imported default favorites) Loading src/com/android/launcher3/LauncherProvider.java +223 −1 Original line number Diff line number Diff line Loading @@ -55,9 +55,11 @@ import com.android.launcher3.config.ProviderConfig; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; public class LauncherProvider extends ContentProvider { Loading @@ -72,7 +74,7 @@ public class LauncherProvider extends ContentProvider { static final String AUTHORITY = ProviderConfig.AUTHORITY; // Should we attempt to load anything from the com.android.launcher2 provider? static final boolean IMPORT_LAUNCHER2_DATABASE = true; static final boolean IMPORT_LAUNCHER2_DATABASE = false; static final String TABLE_FAVORITES = "favorites"; static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens"; Loading Loading @@ -133,6 +135,9 @@ public class LauncherProvider extends ContentProvider { private static long dbInsertAndCheck(DatabaseHelper helper, SQLiteDatabase db, String table, String nullColumnHack, ContentValues values) { if (values == null) { throw new RuntimeException("Error: attempting to insert null values"); } if (!values.containsKey(LauncherSettings.Favorites._ID)) { throw new RuntimeException("Error: attempting to add item without specifying an id"); } Loading Loading @@ -287,6 +292,11 @@ public class LauncherProvider extends ContentProvider { } } public void migrateLauncher2Shortcuts() { mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(), LauncherSettings.Favorites.OLD_CONTENT_URI); } private static int getDefaultWorkspaceResourceId() { if (LauncherAppState.isDisableAllApps()) { return R.xml.default_workspace_no_all_apps; Loading @@ -306,6 +316,15 @@ public class LauncherProvider extends ContentProvider { return !isTablet && IMPORT_LAUNCHER2_DATABASE; } public void deleteDatabase() { // Are you sure? (y/n) final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); final String dbFile = db.getPath(); mOpenHelper.close(); SQLiteDatabase.deleteDatabase(new File(dbFile)); mOpenHelper = new DatabaseHelper(getContext()); } private static class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG_FAVORITES = "favorites"; private static final String TAG_FAVORITE = "favorite"; Loading Loading @@ -1431,6 +1450,209 @@ public class LauncherProvider extends ContentProvider { } return id; } public void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) { final ContentResolver resolver = mContext.getContentResolver(); Cursor c = null; int count = 0; int curScreen = 0; try { c = resolver.query(uri, null, null, null, "title ASC"); } catch (Exception e) { // Ignore } // We already have a favorites database in the old provider if (c != null) { try { if (c.getCount() > 0) { final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT); final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE); final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE); final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE); int i = 0; int curX = 0; int curY = 0; final LauncherAppState app = LauncherAppState.getInstance(); final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); final int width = (int) grid.numColumns; final int height = (int) grid.numRows; final int hotseatWidth = (int) grid.numHotseatIcons; final HashSet<String> seenIntents = new HashSet<String>(c.getCount()); final ContentValues[] rows = new ContentValues[c.getCount()]; while (c.moveToNext()) { final int itemType = c.getInt(itemTypeIndex); if (itemType != Favorites.ITEM_TYPE_APPLICATION && itemType != Favorites.ITEM_TYPE_SHORTCUT && itemType != Favorites.ITEM_TYPE_FOLDER) { continue; } final int cellX = c.getInt(cellXIndex); final int cellY = c.getInt(cellYIndex); final int screen = c.getInt(screenIndex); int container = c.getInt(containerIndex); final String intentStr = c.getString(intentIndex); Launcher.addDumpLog(TAG, "migrating \"" + c.getString(titleIndex) + "\": " + intentStr, true); if (itemType != Favorites.ITEM_TYPE_FOLDER) { if (TextUtils.isEmpty(intentStr)) { // no intent? no icon Launcher.addDumpLog(TAG, "skipping empty intent", true); continue; } else { try { // Canonicalize final Intent intent = Intent.parseUri(intentStr, 0); // the Play Store sets the package parameter, but Launcher // does not, so we clear that out to keep them the same intent.setPackage(null); final String key = intent.toUri(0); if (seenIntents.contains(key)) { Launcher.addDumpLog(TAG, "skipping duplicate", true); continue; } else { seenIntents.add(key); } } catch (URISyntaxException e) { // bogus intent? Launcher.addDumpLog(TAG, "skipping invalid intent uri", true); continue; } } } ContentValues values = new ContentValues(c.getColumnCount()); values.put(LauncherSettings.Favorites._ID, c.getInt(idIndex)); values.put(LauncherSettings.Favorites.INTENT, intentStr); values.put(LauncherSettings.Favorites.TITLE, c.getString(titleIndex)); values.put(LauncherSettings.Favorites.ICON_TYPE, c.getInt(iconTypeIndex)); values.put(LauncherSettings.Favorites.ICON, c.getBlob(iconIndex)); values.put(LauncherSettings.Favorites.ICON_PACKAGE, c.getString(iconPackageIndex)); values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex)); values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType); values.put(LauncherSettings.Favorites.APPWIDGET_ID, -1); values.put(LauncherSettings.Favorites.URI, c.getString(uriIndex)); values.put(LauncherSettings.Favorites.DISPLAY_MODE, c.getInt(displayModeIndex)); if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT && screen >= hotseatWidth) { // no room for you in the hotseat? it's off to the desktop with you container = Favorites.CONTAINER_DESKTOP; } if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { // In a folder or in the hotseat, preserve position values.put(LauncherSettings.Favorites.SCREEN, screen); values.put(LauncherSettings.Favorites.CELLX, cellX); values.put(LauncherSettings.Favorites.CELLY, cellY); } else { values.put(LauncherSettings.Favorites.SCREEN, curScreen); values.put(LauncherSettings.Favorites.CELLX, curX); values.put(LauncherSettings.Favorites.CELLY, curY); curX = (curX + 1) % width; if (curX == 0) { curY = (curY + 1); } // Leave the last row of icons blank on screen 0 if (curScreen == 0 && curY == height - 1 || curY == height) { curScreen = (int) generateNewScreenId(); curY = 0; } } values.put(LauncherSettings.Favorites.CONTAINER, container); rows[i++] = values; } if (i > 0) { db.beginTransaction(); try { final int N = rows.length; for (i = 0; i < N; i++) { if (rows[i] == null) continue; if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, rows[i]) < 0) { return; } else { count++; } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } db.beginTransaction(); try { for (i=0; i<=curScreen; i++) { final ContentValues values = new ContentValues(); values.put(LauncherSettings.WorkspaceScreens._ID, i); values.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); if (dbInsertAndCheck(this, db, TABLE_WORKSPACE_SCREENS, null, values) < 0) { return; } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } } finally { c.close(); } } Launcher.addDumpLog(TAG, "migrated " + count + " icons from Launcher2 into " + (curScreen+1) + " screens", true); // ensure that new screens are created to hold these icons setFlagJustLoadedOldDb(); // Update max IDs; very important since we just grabbed IDs from another database mMaxItemId = initializeMaxItemId(db); mMaxScreenId = initializeMaxScreenId(db); if (LOGD) Log.d(TAG, "mMaxItemId: " + mMaxItemId + " mMaxScreenId: " + mMaxScreenId); } } /** Loading Loading
AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.launcher3"> <uses-sdk android:targetSdkVersion="19" android:minSdkVersion="16"/> <permission android:name="com.android.launcher3.permission.PRELOAD_WORKSPACE" Loading
src/com/android/launcher3/Launcher.java +20 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,8 @@ public class Launcher extends Activity static final boolean DEBUG_RESUME_TIME = false; static final boolean DEBUG_DUMP_LOG = false; static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run private static final int REQUEST_CREATE_SHORTCUT = 1; private static final int REQUEST_CREATE_APPWIDGET = 5; private static final int REQUEST_PICK_APPLICATION = 6; Loading Loading @@ -1571,6 +1573,15 @@ public class Launcher extends Activity } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(); } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) { mModel.resetLoadedState(false, true); mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE); } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) { mModel.resetLoadedState(false, true); mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS); } } }; Loading @@ -1583,6 +1594,10 @@ public class Launcher extends Activity final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); if (ENABLE_DEBUG_INTENTS) { filter.addAction(DebugIntents.DELETE_DATABASE); filter.addAction(DebugIntents.MIGRATE_DATABASE); } registerReceiver(mReceiver, filter); FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView()); mAttached = true; Loading Loading @@ -4704,3 +4719,8 @@ interface LauncherTransitionable { void onLauncherTransitionStep(Launcher l, float t); void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace); } interface DebugIntents { static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE"; static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE"; }
src/com/android/launcher3/LauncherModel.java +27 −5 Original line number Diff line number Diff line Loading @@ -75,6 +75,10 @@ public class LauncherModel extends BroadcastReceiver { // false = strew non-workspace apps across the workspace on upgrade public static final boolean UPGRADE_USE_MORE_APPS_FOLDER = false; public static final int LOADER_FLAG_NONE = 0; public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0; public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1; private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons private static final long INVALID_SCREEN_ID = -1L; private final boolean mAppsCanBeOnRemoveableStorage; Loading Loading @@ -1193,6 +1197,10 @@ public class LauncherModel extends BroadcastReceiver { } public void startLoader(boolean isLaunching, int synchronousBindPage) { startLoader(isLaunching, synchronousBindPage, LOADER_FLAG_NONE); } public void startLoader(boolean isLaunching, int synchronousBindPage, int loadFlags) { synchronized (mLock) { if (DEBUG_LOADERS) { Log.d(TAG, "startLoader isLaunching=" + isLaunching); Loading @@ -1207,7 +1215,7 @@ public class LauncherModel extends BroadcastReceiver { // If there is already one running, tell it to stop. // also, don't downgrade isLaunching if we're already running isLaunching = isLaunching || stopLoaderLocked(); mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching); mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching, loadFlags); if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE && mAllAppsLoaded && mWorkspaceLoaded) { mLoaderTask.runBindSynchronousPage(synchronousBindPage); Loading Loading @@ -1298,13 +1306,15 @@ public class LauncherModel extends BroadcastReceiver { private boolean mIsLoadingAndBindingWorkspace; private boolean mStopped; private boolean mLoadAndBindStepFinished; private int mFlags; private HashMap<Object, CharSequence> mLabelCache; LoaderTask(Context context, boolean isLaunching) { LoaderTask(Context context, boolean isLaunching, int flags) { mContext = context; mIsLaunching = isLaunching; mLabelCache = new HashMap<Object, CharSequence>(); mFlags = flags; } boolean isLaunching() { Loading Loading @@ -1651,7 +1661,7 @@ public class LauncherModel extends BroadcastReceiver { } } /** Returns whether this is an upgradge path */ /** Returns whether this is an upgrade path */ private boolean loadWorkspace() { // Log to disk Launcher.addDumpLog(TAG, "11683562 - loadWorkspace()", true); Loading @@ -1669,8 +1679,20 @@ public class LauncherModel extends BroadcastReceiver { int countX = (int) grid.numColumns; int countY = (int) grid.numRows; // Make sure the default workspace is loaded, if needed if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) { Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true); LauncherAppState.getLauncherProvider().deleteDatabase(); } if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) { // append the user's Launcher2 shortcuts Launcher.addDumpLog(TAG, "loadWorkspace: migrating from launcher2", true); LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts(); } else { // Make sure the default workspace is loaded Launcher.addDumpLog(TAG, "loadWorkspace: loading default favorites", false); LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(0); } // Check if we need to do any upgrade-path logic // (Includes having just imported default favorites) Loading
src/com/android/launcher3/LauncherProvider.java +223 −1 Original line number Diff line number Diff line Loading @@ -55,9 +55,11 @@ import com.android.launcher3.config.ProviderConfig; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; public class LauncherProvider extends ContentProvider { Loading @@ -72,7 +74,7 @@ public class LauncherProvider extends ContentProvider { static final String AUTHORITY = ProviderConfig.AUTHORITY; // Should we attempt to load anything from the com.android.launcher2 provider? static final boolean IMPORT_LAUNCHER2_DATABASE = true; static final boolean IMPORT_LAUNCHER2_DATABASE = false; static final String TABLE_FAVORITES = "favorites"; static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens"; Loading Loading @@ -133,6 +135,9 @@ public class LauncherProvider extends ContentProvider { private static long dbInsertAndCheck(DatabaseHelper helper, SQLiteDatabase db, String table, String nullColumnHack, ContentValues values) { if (values == null) { throw new RuntimeException("Error: attempting to insert null values"); } if (!values.containsKey(LauncherSettings.Favorites._ID)) { throw new RuntimeException("Error: attempting to add item without specifying an id"); } Loading Loading @@ -287,6 +292,11 @@ public class LauncherProvider extends ContentProvider { } } public void migrateLauncher2Shortcuts() { mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(), LauncherSettings.Favorites.OLD_CONTENT_URI); } private static int getDefaultWorkspaceResourceId() { if (LauncherAppState.isDisableAllApps()) { return R.xml.default_workspace_no_all_apps; Loading @@ -306,6 +316,15 @@ public class LauncherProvider extends ContentProvider { return !isTablet && IMPORT_LAUNCHER2_DATABASE; } public void deleteDatabase() { // Are you sure? (y/n) final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); final String dbFile = db.getPath(); mOpenHelper.close(); SQLiteDatabase.deleteDatabase(new File(dbFile)); mOpenHelper = new DatabaseHelper(getContext()); } private static class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG_FAVORITES = "favorites"; private static final String TAG_FAVORITE = "favorite"; Loading Loading @@ -1431,6 +1450,209 @@ public class LauncherProvider extends ContentProvider { } return id; } public void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) { final ContentResolver resolver = mContext.getContentResolver(); Cursor c = null; int count = 0; int curScreen = 0; try { c = resolver.query(uri, null, null, null, "title ASC"); } catch (Exception e) { // Ignore } // We already have a favorites database in the old provider if (c != null) { try { if (c.getCount() > 0) { final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT); final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE); final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE); final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE); int i = 0; int curX = 0; int curY = 0; final LauncherAppState app = LauncherAppState.getInstance(); final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); final int width = (int) grid.numColumns; final int height = (int) grid.numRows; final int hotseatWidth = (int) grid.numHotseatIcons; final HashSet<String> seenIntents = new HashSet<String>(c.getCount()); final ContentValues[] rows = new ContentValues[c.getCount()]; while (c.moveToNext()) { final int itemType = c.getInt(itemTypeIndex); if (itemType != Favorites.ITEM_TYPE_APPLICATION && itemType != Favorites.ITEM_TYPE_SHORTCUT && itemType != Favorites.ITEM_TYPE_FOLDER) { continue; } final int cellX = c.getInt(cellXIndex); final int cellY = c.getInt(cellYIndex); final int screen = c.getInt(screenIndex); int container = c.getInt(containerIndex); final String intentStr = c.getString(intentIndex); Launcher.addDumpLog(TAG, "migrating \"" + c.getString(titleIndex) + "\": " + intentStr, true); if (itemType != Favorites.ITEM_TYPE_FOLDER) { if (TextUtils.isEmpty(intentStr)) { // no intent? no icon Launcher.addDumpLog(TAG, "skipping empty intent", true); continue; } else { try { // Canonicalize final Intent intent = Intent.parseUri(intentStr, 0); // the Play Store sets the package parameter, but Launcher // does not, so we clear that out to keep them the same intent.setPackage(null); final String key = intent.toUri(0); if (seenIntents.contains(key)) { Launcher.addDumpLog(TAG, "skipping duplicate", true); continue; } else { seenIntents.add(key); } } catch (URISyntaxException e) { // bogus intent? Launcher.addDumpLog(TAG, "skipping invalid intent uri", true); continue; } } } ContentValues values = new ContentValues(c.getColumnCount()); values.put(LauncherSettings.Favorites._ID, c.getInt(idIndex)); values.put(LauncherSettings.Favorites.INTENT, intentStr); values.put(LauncherSettings.Favorites.TITLE, c.getString(titleIndex)); values.put(LauncherSettings.Favorites.ICON_TYPE, c.getInt(iconTypeIndex)); values.put(LauncherSettings.Favorites.ICON, c.getBlob(iconIndex)); values.put(LauncherSettings.Favorites.ICON_PACKAGE, c.getString(iconPackageIndex)); values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex)); values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType); values.put(LauncherSettings.Favorites.APPWIDGET_ID, -1); values.put(LauncherSettings.Favorites.URI, c.getString(uriIndex)); values.put(LauncherSettings.Favorites.DISPLAY_MODE, c.getInt(displayModeIndex)); if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT && screen >= hotseatWidth) { // no room for you in the hotseat? it's off to the desktop with you container = Favorites.CONTAINER_DESKTOP; } if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { // In a folder or in the hotseat, preserve position values.put(LauncherSettings.Favorites.SCREEN, screen); values.put(LauncherSettings.Favorites.CELLX, cellX); values.put(LauncherSettings.Favorites.CELLY, cellY); } else { values.put(LauncherSettings.Favorites.SCREEN, curScreen); values.put(LauncherSettings.Favorites.CELLX, curX); values.put(LauncherSettings.Favorites.CELLY, curY); curX = (curX + 1) % width; if (curX == 0) { curY = (curY + 1); } // Leave the last row of icons blank on screen 0 if (curScreen == 0 && curY == height - 1 || curY == height) { curScreen = (int) generateNewScreenId(); curY = 0; } } values.put(LauncherSettings.Favorites.CONTAINER, container); rows[i++] = values; } if (i > 0) { db.beginTransaction(); try { final int N = rows.length; for (i = 0; i < N; i++) { if (rows[i] == null) continue; if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, rows[i]) < 0) { return; } else { count++; } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } db.beginTransaction(); try { for (i=0; i<=curScreen; i++) { final ContentValues values = new ContentValues(); values.put(LauncherSettings.WorkspaceScreens._ID, i); values.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); if (dbInsertAndCheck(this, db, TABLE_WORKSPACE_SCREENS, null, values) < 0) { return; } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } } finally { c.close(); } } Launcher.addDumpLog(TAG, "migrated " + count + " icons from Launcher2 into " + (curScreen+1) + " screens", true); // ensure that new screens are created to hold these icons setFlagJustLoadedOldDb(); // Update max IDs; very important since we just grabbed IDs from another database mMaxItemId = initializeMaxItemId(db); mMaxScreenId = initializeMaxScreenId(db); if (LOGD) Log.d(TAG, "mMaxItemId: " + mMaxItemId + " mMaxScreenId: " + mMaxScreenId); } } /** Loading