New launcher2 icon migration algorithm.

The user will be able to request "icon migration", which is
not a direct mapping of the old workspace, but rather
follows this heuristic for bringing the user's favorite
icons (by dint of their existence on the workspace) into
Launcher3:

Workspace shortcuts are placed in lexicographic order on the workspace
starting at screen 0 (leaving the bottom row of screen 0 empty to make
sure there's room to move things around). Folders are preserved and
their contents sorted. Duplicate icons (that is, shortcuts
with the same intent, pursuant to some cleanups) are removed.

Hotseat icons are migrated in their original place, unless their new
location is not accommodated by the hotseat (i.e. the L3 hotseat is
too small on this device), in which case they're treated like any
other shortcut and tossed into the workspace.

To test, turn on Launcher.ENABLE_DEBUG_INTENTS and then:

$ adb shell am broadcast -a com.android.launcher3.action.DELETE_DATABASE
$ adb shell am broadcast -a com.android.launcher3.action.MIGRATE_DATABASE

Bug: 12416411
Change-Id: Ia5c56f36c11455867ea20a39f70210f595020a87
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c05769c..ceb31b0 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -130,6 +130,8 @@
     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;
@@ -1551,6 +1553,15 @@
             } 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);
             }
         }
     };
@@ -1563,6 +1574,10 @@
         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;
@@ -4667,3 +4682,8 @@
     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";
+}
\ No newline at end of file