From 16f3ea870aac47292cd6cbe1a4b4343173097aa9 Mon Sep 17 00:00:00 2001 From: Nilesh Agrawal Date: Thu, 9 Jan 2014 17:14:01 -0800 Subject: [PATCH 1/8] Allow DISABLE_ALL_APPS to be set using a system property. - Moving the property to LauncherAppState - The property is only read on dogfood builds. The property can be set using setprop or /data/local.prop Change-Id: I14c7354efb12edb93f97e81687a6f920cc634e9a --- res/values/config.xml | 3 ++ .../launcher3/AppsCustomizePagedView.java | 14 ++++---- src/com/android/launcher3/BuildInfo.java | 32 +++++++++++++++++++ .../android/launcher3/DeleteDropTarget.java | 10 +++--- src/com/android/launcher3/DeviceProfile.java | 2 +- src/com/android/launcher3/DynamicGrid.java | 2 +- src/com/android/launcher3/Folder.java | 4 +-- src/com/android/launcher3/Hotseat.java | 8 ++--- .../launcher3/InstallShortcutReceiver.java | 2 +- src/com/android/launcher3/Launcher.java | 13 ++++---- .../android/launcher3/LauncherAppState.java | 10 +++++- src/com/android/launcher3/LauncherModel.java | 4 +-- .../android/launcher3/LauncherProvider.java | 2 +- 13 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 src/com/android/launcher3/BuildInfo.java diff --git a/res/values/config.xml b/res/values/config.xml index 2a08216624..b512ffe67b 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -94,4 +94,7 @@ filter the activities shown in the launcher. Can be empty. --> + + diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index 2865bc5d5c..37cdb9e137 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -199,8 +199,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen private AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f); private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4); - public static boolean DISABLE_ALL_APPS = false; - // Previews & outlines ArrayList mRunningTasks; private static final int sPageSleepDelay = 200; @@ -427,7 +425,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (!isDataReady()) { - if ((DISABLE_ALL_APPS || !mApps.isEmpty()) && !mWidgets.isEmpty()) { + if ((LauncherAppState.isDisableAllApps() || !mApps.isEmpty()) && !mWidgets.isEmpty()) { setDataIsReady(); setMeasuredDimension(width, height); onDataReady(width, height); @@ -1558,7 +1556,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } public void setApps(ArrayList list) { - if (!DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { mApps = list; Collections.sort(mApps, LauncherModel.getAppNameComparator()); updatePageCountsAndInvalidateData(); @@ -1576,7 +1574,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } } public void addApps(ArrayList list) { - if (!DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { addAppsWithoutInvalidate(list); updatePageCountsAndInvalidateData(); } @@ -1604,7 +1602,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } } public void removeApps(ArrayList appInfos) { - if (!DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { removeAppsWithoutInvalidate(appInfos); updatePageCountsAndInvalidateData(); } @@ -1613,7 +1611,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // We remove and re-add the updated applications list because it's properties may have // changed (ie. the title), and this will ensure that the items will be in their proper // place in the list. - if (!DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { removeAppsWithoutInvalidate(list); addAppsWithoutInvalidate(list); updatePageCountsAndInvalidateData(); @@ -1727,4 +1725,4 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen return String.format(getContext().getString(stringId), page + 1, count); } -} +} \ No newline at end of file diff --git a/src/com/android/launcher3/BuildInfo.java b/src/com/android/launcher3/BuildInfo.java new file mode 100644 index 0000000000..b49ee0d9b8 --- /dev/null +++ b/src/com/android/launcher3/BuildInfo.java @@ -0,0 +1,32 @@ +package com.android.launcher3; + +import android.text.TextUtils; +import android.util.Log; + +public class BuildInfo { + private static final boolean DBG = false; + private static final String TAG = "BuildInfo"; + + public boolean isDogfoodBuild() { + return false; + } + + public static BuildInfo loadByName(String className) { + if (TextUtils.isEmpty(className)) return new BuildInfo(); + + if (DBG) Log.d(TAG, "Loading BuildInfo: " + className); + try { + Class cls = Class.forName(className); + return (BuildInfo) cls.newInstance(); + } catch (ClassNotFoundException e) { + Log.e(TAG, "Bad BuildInfo class", e); + } catch (InstantiationException e) { + Log.e(TAG, "Bad BuildInfo class", e); + } catch (IllegalAccessException e) { + Log.e(TAG, "Bad BuildInfo class", e); + } catch (ClassCastException e) { + Log.e(TAG, "Bad BuildInfo class", e); + } + return new BuildInfo(); + } +} diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index c76425a5ed..75d906bc20 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -146,12 +146,12 @@ public class DeleteDropTarget extends ButtonDropTarget { return true; } - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && + if (!LauncherAppState.isDisableAllApps() && item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { return true; } - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && + if (!LauncherAppState.isDisableAllApps() && item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && item instanceof AppInfo) { AppInfo appInfo = (AppInfo) info; @@ -160,7 +160,7 @@ public class DeleteDropTarget extends ButtonDropTarget { if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && item instanceof ShortcutInfo) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { ShortcutInfo shortcutInfo = (ShortcutInfo) info; return (shortcutInfo.flags & AppInfo.DOWNLOADED_FLAG) != 0; } else { @@ -174,7 +174,7 @@ public class DeleteDropTarget extends ButtonDropTarget { @Override public void onDragStart(DragSource source, Object info, int dragAction) { boolean isVisible = true; - boolean useUninstallLabel = !AppsCustomizePagedView.DISABLE_ALL_APPS && + boolean useUninstallLabel = !LauncherAppState.isDisableAllApps() && isAllAppsApplication(source, info); boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget(); @@ -264,7 +264,7 @@ public class DeleteDropTarget extends ButtonDropTarget { } private boolean isUninstallFromWorkspace(DragObject d) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS && isWorkspaceOrFolderApplication(d)) { + if (LauncherAppState.isDisableAllApps() && isWorkspaceOrFolderApplication(d)) { ShortcutInfo shortcut = (ShortcutInfo) d.dragInfo; // Only allow manifest shortcuts to initiate an un-install. return !InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 67b0933c9a..a236b84db8 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -126,7 +126,7 @@ public class DeviceProfile { DeviceProfile(String n, float w, float h, float r, float c, float is, float its, float hs, float his) { // Ensure that we have an odd number of hotseat items (since we need to place all apps) - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && hs % 2 == 0) { + if (!LauncherAppState.isDisableAllApps() && hs % 2 == 0) { throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces"); } diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java index 22928ccf3a..3aced1faea 100644 --- a/src/com/android/launcher3/DynamicGrid.java +++ b/src/com/android/launcher3/DynamicGrid.java @@ -56,7 +56,7 @@ public class DynamicGrid { DisplayMetrics dm = resources.getDisplayMetrics(); ArrayList deviceProfiles = new ArrayList(); - boolean hasAA = !AppsCustomizePagedView.DISABLE_ALL_APPS; + boolean hasAA = !LauncherAppState.isDisableAllApps(); DEFAULT_ICON_SIZE_PX = pxFromDp(DEFAULT_ICON_SIZE_DP, dm); // Our phone profiles include the bar sizes in each orientation deviceProfiles.add(new DeviceProfile("Super Short Stubby", diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index 758ee5baba..a98d121a6c 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -146,7 +146,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList Resources res = getResources(); mMaxCountX = (int) grid.numColumns; // Allow scrolling folders when DISABLE_ALL_APPS is true. - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { mMaxCountY = mMaxNumItems = Integer.MAX_VALUE; } else { mMaxCountY = (int) grid.numRows; @@ -1018,7 +1018,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(getContentAreaHeight(), MeasureSpec.EXACTLY); - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { // Don't cap the height of the content to allow scrolling. mContent.setFixedSize(getContentAreaWidth(), mContent.getDesiredHeight()); } else { diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 094e188c77..59d60e3812 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -95,7 +95,7 @@ public class Hotseat extends FrameLayout { return hasVerticalHotseat() ? (mContent.getCountY() - (rank + 1)) : 0; } public boolean isAllAppsButtonRank(int rank) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { return false; } else { return rank == mAllAppsButtonRank; @@ -142,7 +142,7 @@ public class Hotseat extends FrameLayout { void resetLayout() { mContent.removeAllViewsInLayout(); - if (!AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { // Add the Apps button Context context = getContext(); @@ -189,7 +189,7 @@ public class Hotseat extends FrameLayout { void addAllAppsFolder(IconCache iconCache, ArrayList allApps, ArrayList onWorkspace, Launcher launcher, Workspace workspace) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { FolderInfo fi = new FolderInfo(); fi.cellX = getCellXFromOrder(mAllAppsButtonRank); @@ -219,7 +219,7 @@ public class Hotseat extends FrameLayout { } void addAppsToAllAppsFolder(ArrayList apps) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { View v = mContent.getChildAt(getCellXFromOrder(mAllAppsButtonRank), getCellYFromOrder(mAllAppsButtonRank)); FolderIcon fi = null; diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 1ff94720ba..7ab4e0477c 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -272,7 +272,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { final Intent intent = pendingInfo.launchIntent; final String name = pendingInfo.name; - if (AppsCustomizePagedView.DISABLE_ALL_APPS && !isValidShortcutLaunchIntent(intent)) { + if (LauncherAppState.isDisableAllApps() && !isValidShortcutLaunchIntent(intent)) { if (DBG) Log.d(TAG, "Ignoring shortcut with launchIntent:" + intent); continue; } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index c05769cfa2..8ef28de711 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -155,6 +155,7 @@ public class Launcher extends Activity // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS] static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate"; static final String DUMP_STATE_PROPERTY = "launcher_dump_state"; + static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps"; // The Intent extra that defines whether to ignore the launch animation static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION = @@ -365,7 +366,7 @@ public class Launcher extends Activity private Stats mStats; - private static boolean isPropertyEnabled(String propertyName) { + static boolean isPropertyEnabled(String propertyName) { return Log.isLoggable(propertyName, Log.VERBOSE); } @@ -2906,7 +2907,7 @@ public class Launcher extends Activity // Shrink workspaces away if going to AppsCustomize from workspace Animator workspaceAnim = mWorkspace.getChangeStateAnimation(Workspace.State.SMALL, animated); - if (!AppsCustomizePagedView.DISABLE_ALL_APPS + if (!LauncherAppState.isDisableAllApps() || contentType == AppsCustomizePagedView.ContentType.Widgets) { // Set the content type for the all apps/widgets space mAppsCustomizeTabHost.setContentTypeImmediate(contentType); @@ -3777,7 +3778,7 @@ public class Launcher extends Activity // Remove the extra empty screen mWorkspace.removeExtraEmptyScreen(false, null); - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && + if (!LauncherAppState.isDisableAllApps() && addedApps != null && mAppsCustomizeContent != null) { mAppsCustomizeContent.addApps(addedApps); } @@ -4044,7 +4045,7 @@ public class Launcher extends Activity * Implementation of the method from LauncherModel.Callbacks. */ public void bindAllApplications(final ArrayList apps) { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { if (mIntentsOnWorkspaceFromUpgradePath != null) { if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) { getHotseat().addAllAppsFolder(mIconCache, apps, @@ -4084,7 +4085,7 @@ public class Launcher extends Activity mWorkspace.updateShortcuts(apps); } - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && + if (!LauncherAppState.isDisableAllApps() && mAppsCustomizeContent != null) { mAppsCustomizeContent.updateApps(apps); } @@ -4121,7 +4122,7 @@ public class Launcher extends Activity mDragController.onAppsRemoved(packageNames, appInfos); // Update AllApps - if (!AppsCustomizePagedView.DISABLE_ALL_APPS && + if (!LauncherAppState.isDisableAllApps() && mAppsCustomizeContent != null) { mAppsCustomizeContent.removeApps(appInfos); } diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 84a1d04118..5e41fcad05 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -30,9 +30,10 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks { private static final String TAG = "LauncherAppState"; private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs"; + private final AppFilter mAppFilter; + private final BuildInfo mBuildInfo; private LauncherModel mModel; private IconCache mIconCache; - private AppFilter mAppFilter; private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb; private boolean mIsScreenLarge; private float mScreenDensity; @@ -87,6 +88,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks { mIconCache = new IconCache(sContext); mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class)); + mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class)); mModel = new LauncherModel(this, mIconCache, mAppFilter); // Register intent receivers @@ -230,4 +232,10 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks { public void onAvailableSizeChanged(DeviceProfile grid) { Utilities.setIconSize(grid.iconSizePx); } + + public static boolean isDisableAllApps() { + // Returns false on non-dogfood builds. + return getInstance().mBuildInfo.isDogfoodBuild() && + Launcher.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY); + } } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index b2cfb2456a..0c716a1f08 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1466,7 +1466,7 @@ public class LauncherModel extends BroadcastReceiver { sBgDbIconCache.clear(); } - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { // Ensure that all the applications that are in the system are // represented on the home screen. if (!UPGRADE_USE_MORE_APPS_FOLDER || !isUpgrade) { @@ -2564,7 +2564,7 @@ public class LauncherModel extends BroadcastReceiver { if (added != null) { // Ensure that we add all the workspace applications to the db Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; - if (!AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (!LauncherAppState.isDisableAllApps()) { addAndBindAddedApps(context, new ArrayList(), cb, added); } else { final ArrayList addedInfos = new ArrayList(added); diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 28efd01487..1fb58cc991 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -288,7 +288,7 @@ public class LauncherProvider extends ContentProvider { } private static int getDefaultWorkspaceResourceId() { - if (AppsCustomizePagedView.DISABLE_ALL_APPS) { + if (LauncherAppState.isDisableAllApps()) { return R.xml.default_workspace_no_all_apps; } else { return R.xml.default_workspace; From 0eb687fdc431e7eae4e8f2f4d5dd3a6e48779008 Mon Sep 17 00:00:00 2001 From: Dan Sandler Date: Fri, 10 Jan 2014 13:24:55 -0500 Subject: [PATCH 2/8] Quick patch for b/12446428. Bug: 12446428 Change-Id: I5b9472e55a8919f5640c6e97fede9b5637819be0 --- src/com/android/launcher3/Folder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index 758ee5baba..a9a161ab80 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -1107,7 +1107,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList if (getItemCount() <= 1) { // Remove the folder LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); - cellLayout.removeView(mFolderIcon); + if (cellLayout != null) { + // b/12446428 -- sometimes the cell layout has already gone away? + cellLayout.removeView(mFolderIcon); + } if (mFolderIcon instanceof DropTarget) { mDragController.removeDropTarget((DropTarget) mFolderIcon); } From d502404a44fb7c4ea739622d7f8bdd2a764d97a1 Mon Sep 17 00:00:00 2001 From: Dan Sandler Date: Thu, 9 Jan 2014 15:01:33 -0500 Subject: [PATCH 3/8] 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 --- AndroidManifest.xml | 1 + src/com/android/launcher3/Launcher.java | 20 ++ src/com/android/launcher3/LauncherModel.java | 32 ++- .../android/launcher3/LauncherProvider.java | 224 +++++++++++++++++- 4 files changed, 271 insertions(+), 6 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4e27e6f27c..36fa4c190a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -20,6 +20,7 @@ + 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 seenIntents = new HashSet(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); + } } /** From a694524047fda0a51dede4eefb1201a598d2d3a7 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 8 Jan 2014 14:04:34 -0800 Subject: [PATCH 4/8] Adding migration Clings. (Bug 11973614) - Refactoring Launcher cling code out to LauncherClings. Change-Id: Iff4f84f5b8bfeb69b1be0b4802022c3eb20b6f2c --- proguard.flags | 3 + res/layout-port/launcher.xml | 10 + res/layout-port/migration_cling.xml | 93 ++++ res/layout-port/migration_workspace_cling.xml | 70 +++ res/values/strings.xml | 8 + .../launcher3/AppsCustomizeTabHost.java | 2 +- src/com/android/launcher3/Cling.java | 79 +++- src/com/android/launcher3/DeviceProfile.java | 8 + src/com/android/launcher3/DragLayer.java | 3 +- src/com/android/launcher3/Folder.java | 4 +- src/com/android/launcher3/Launcher.java | 419 ++++------------- src/com/android/launcher3/LauncherClings.java | 444 ++++++++++++++++++ src/com/android/launcher3/LauncherModel.java | 13 +- src/com/android/launcher3/Workspace.java | 4 +- 14 files changed, 812 insertions(+), 348 deletions(-) create mode 100644 res/layout-port/migration_cling.xml create mode 100644 res/layout-port/migration_workspace_cling.xml create mode 100644 src/com/android/launcher3/LauncherClings.java diff --git a/proguard.flags b/proguard.flags index 9b59b217ec..a922e919d2 100644 --- a/proguard.flags +++ b/proguard.flags @@ -8,6 +8,9 @@ public void onClickAllAppsButton(android.view.View); public void onClickAppMarketButton(android.view.View); public void dismissFirstRunCling(android.view.View); + public void dismissMigrationClingCopyApps(android.view.View); + public void dismissMigrationClingUseDefault(android.view.View); + public void dismissMigrationWorkspaceCling(android.view.View); public void dismissWorkspaceCling(android.view.View); public void dismissAllAppsCling(android.view.View); } diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index 2b3cf81a48..74005348cf 100644 --- a/res/layout-port/launcher.xml +++ b/res/layout-port/launcher.xml @@ -73,6 +73,16 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" /> + + + + + + + + + + + + + + + + + +