diff --git a/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml b/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml index 1622742a52..2a0188ae2b 100644 --- a/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml +++ b/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml @@ -20,6 +20,7 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 50bbe51a5b..70d44cee40 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -505,11 +505,11 @@ public class Launcher extends Activity } /** - * To be overridden by subclasses to create the custom content and call + * To be overridden by subclasses to populate the custom content container and call * {@link #addToCustomContentPage}. This will only be invoked if * {@link #hasCustomContentToLeft()} is {@code true}. */ - protected void addCustomContentToLeft() { + protected void populateCustomContentContainer() { } /** @@ -539,8 +539,8 @@ public class Launcher extends Activity if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) { // Create the custom content page and call the subclass to populate it. - mWorkspace.createCustomContentPage(); - addCustomContentToLeft(); + mWorkspace.createCustomContentContainer(); + populateCustomContentContainer(); } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) { mWorkspace.removeCustomContentPage(); } @@ -1033,12 +1033,6 @@ public class Launcher extends Activity } } - protected void onFinishBindingItems() { - if (mWorkspace != null && hasCustomContentToLeft() && mWorkspace.hasCustomContent()) { - addCustomContentToLeft(); - } - } - QSBScroller mQsbScroller = new QSBScroller() { int scrollY = 0; @@ -2373,7 +2367,7 @@ public class Launcher extends Activity final String shortcutClass = intent.getComponent().getClassName(); if (shortcutClass.equals(WidgetAdder.class.getName())) { - showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true); + onClickAddWidgetButton(); return; } else if (shortcutClass.equals(MemoryDumpActivity.class.getName())) { MemoryDumpActivity.startDump(this); @@ -2466,6 +2460,14 @@ public class Launcher extends Activity showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false); } + /** + * Event handler for the (Add) Widgets button that appears after a long press + * on the home screen. + */ + protected void onClickAddWidgetButton() { + showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true); + } + public void onTouchDownAllAppsButton(View v) { // Provide the same haptic feedback that the system offers for virtual keys. v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); @@ -2522,7 +2524,8 @@ public class Launcher extends Activity String packageName = componentName.getPackageName(); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", packageName, null)); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | + Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); startActivitySafely(null, intent, "startApplicationDetailsActivity"); } @@ -2877,7 +2880,7 @@ public class Launcher extends Activity mWorkspaceBackgroundDrawable : null); } - void updateWallpaperVisibility(boolean visible) { + protected void changeWallpaperVisiblity(boolean visible) { int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0; int curflags = getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; @@ -3787,9 +3790,9 @@ public class Launcher extends Activity // Create the custom content page (this call updates mDefaultScreen which calls // setCurrentPage() so ensure that all pages are added before calling this). - // The actual content of the custom page will be added during onFinishBindingItems(). - if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) { - mWorkspace.createCustomContentPage(); + if (hasCustomContentToLeft()) { + mWorkspace.createCustomContentContainer(); + populateCustomContentContainer(); } } @@ -4071,13 +4074,6 @@ public class Launcher extends Activity mWorkspace.getUniqueComponents(true, null); mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null); } - - mWorkspace.post(new Runnable() { - @Override - public void run() { - onFinishBindingItems(); - } - }); } public boolean isAllAppsButtonRank(int rank) { diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java index 57cdfb94aa..74eefcaec8 100644 --- a/src/com/android/launcher3/LauncherBackupHelper.java +++ b/src/com/android/launcher3/LauncherBackupHelper.java @@ -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; } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 2102a1faca..6839bb3e53 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1714,6 +1714,7 @@ public class LauncherModel extends BroadcastReceiver { clearSBgDataStructures(); final ArrayList itemsToRemove = new ArrayList(); + final ArrayList restoredRows = new ArrayList(); 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 diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 52bcf98e7c..cec9167f39 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -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); diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java index 988e5efca9..f4ee3007d3 100644 --- a/src/com/android/launcher3/LauncherSettings.java +++ b/src/com/android/launcher3/LauncherSettings.java @@ -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. + *

Type: INTEGER

+ */ + static final String RESTORED = "restored"; } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 359fd86401..751b4c67a1 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -209,6 +209,10 @@ public class Workspace extends SmoothPagedView private boolean mWorkspaceFadeInAdjacentScreens; WallpaperOffsetInterpolator mWallpaperOffset; + private boolean mWallpaperIsLiveWallpaper; + private int mNumPagesForWallpaperParallax; + private float mLastSetWallpaperOffsetSteps = 0; + private Runnable mDelayedResizeRunnable; private Runnable mDelayedSnapToPageRunnable; private Point mDisplaySize = new Point(); @@ -421,7 +425,7 @@ public class Workspace extends SmoothPagedView setClipChildren(false); setClipToPadding(false); setChildrenDrawnWithCacheEnabled(true); - + setMinScale(mOverviewModeShrinkFactor); setupLayoutTransition(); @@ -562,7 +566,7 @@ public class Workspace extends SmoothPagedView return screenId; } - public void createCustomContentPage() { + public void createCustomContentContainer() { CellLayout customScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null); customScreen.disableBackground(); @@ -1347,7 +1351,14 @@ public class Workspace extends SmoothPagedView // Don't use up all the wallpaper parallax until you have at least // MIN_PARALLAX_PAGE_SPAN pages int numScrollingPages = getNumScreensExcludingEmptyAndCustom(); - int parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages - 1); + int parallaxPageSpan; + if (mWallpaperIsLiveWallpaper) { + parallaxPageSpan = numScrollingPages - 1; + } else { + parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages - 1); + } + mNumPagesForWallpaperParallax = parallaxPageSpan; + // On RTL devices, push the wallpaper offset to the right if we don't have enough // pages (ie if numScrollingPages < MIN_PARALLAX_PAGE_SPAN) int padding = isLayoutRtl() ? parallaxPageSpan - numScrollingPages + 1 : 0; @@ -1391,7 +1402,11 @@ public class Workspace extends SmoothPagedView private void setWallpaperOffsetSteps() { // Set wallpaper offset steps (1 / (number of screens - 1)) - mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f); + float xOffset = 1.0f / mNumPagesForWallpaperParallax; + if (xOffset != mLastSetWallpaperOffsetSteps) { + mWallpaperManager.setWallpaperOffsetSteps(xOffset, 1.0f); + mLastSetWallpaperOffsetSteps = xOffset; + } } public void setFinalX(float x) { @@ -1700,6 +1715,10 @@ public class Workspace extends SmoothPagedView if (LauncherAppState.getInstance().hasWallpaperChangedSinceLastCheck()) { setWallpaperDimension(); } + mWallpaperIsLiveWallpaper = mWallpaperManager.getWallpaperInfo() != null; + // Force the wallpaper offset steps to be set again, because another app might have changed + // them + mLastSetWallpaperOffsetSteps = 0f; } @Override