diff options
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/launcher3/CellLayout.java | 8 | ||||
-rw-r--r-- | src/com/android/launcher3/DeviceProfile.java | 22 | ||||
-rw-r--r-- | src/com/android/launcher3/IconCache.java | 43 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 11 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherBackupAgentHelper.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherBackupHelper.java | 53 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 17 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherProvider.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherStateTransitionAnimation.java | 129 | ||||
-rw-r--r-- | src/com/android/launcher3/model/WidgetsModel.java | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/util/UiThreadCircularReveal.java | 6 | ||||
-rw-r--r-- | src/com/android/launcher3/widget/PendingAddWidgetInfo.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/widget/WidgetsListAdapter.java | 13 |
13 files changed, 174 insertions, 153 deletions
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 2cde3d53d..809688712 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -2690,8 +2690,12 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { * @param result An array of length 2 in which to store the result (may be null). */ public static int[] rectToCell(Launcher launcher, int width, int height, int[] result) { - DeviceProfile grid = launcher.getDeviceProfile(); - Rect padding = grid.getWorkspacePadding(Utilities.isRtl(launcher.getResources())); + return rectToCell(launcher.getDeviceProfile(), launcher, width, height, result); + } + + public static int[] rectToCell(DeviceProfile grid, Context context, int width, int height, + int[] result) { + Rect padding = grid.getWorkspacePadding(Utilities.isRtl(context.getResources())); // Always assume we're working with the smallest span to make sure we // reserve enough space in both orientations. diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 1c0743cbc..6e90fc291 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -263,7 +263,7 @@ public class DeviceProfile { if (isTablet) { // Pad the left and right of the workspace to ensure consistent spacing // between all icons - int width = isLandscape ? Math.max(widthPx, heightPx) : Math.min(widthPx, heightPx); + int width = getCurrentWidth(); // XXX: If the icon size changes across orientations, we will have to take // that into account here too. int gap = (int) ((width - 2 * edgeMarginPx - @@ -299,12 +299,8 @@ public class DeviceProfile { // Pad the left and right of the workspace to ensure consistent spacing // between all icons float gapScale = 1f + (dragViewScale - 1f) / 2f; - int width = isLandscape - ? Math.max(widthPx, heightPx) - : Math.min(widthPx, heightPx); - int height = isLandscape - ? Math.max(widthPx, heightPx) - : Math.min(widthPx, heightPx); + int width = getCurrentWidth(); + int height = getCurrentHeight(); int paddingTop = searchBarBounds.bottom; int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx; int availableWidth = Math.max(0, width - (int) ((inv.numColumns * cellWidthPx) + @@ -508,4 +504,16 @@ public class DeviceProfile { } } } + + private int getCurrentWidth() { + return isLandscape + ? Math.max(widthPx, heightPx) + : Math.min(widthPx, heightPx); + } + + private int getCurrentHeight() { + return isLandscape + ? Math.min(widthPx, heightPx) + : Math.max(widthPx, heightPx); + } } diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index b9ac2a47a..ea1c0fd3e 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -466,7 +466,7 @@ public class IconCache { } LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user); - CacheEntry entry = cacheLocked(component, launcherActInfo, user, true, true); + CacheEntry entry = cacheLocked(component, launcherActInfo, user, true, false /* useLowRes */); return entry.icon; } @@ -540,7 +540,7 @@ public class IconCache { mCache.put(cacheKey, entry); // Check the DB first. - if (!getEntryFromDB(componentName, user, entry, useLowResIcon)) { + if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { if (info != null) { entry.icon = Utilities.createIconBitmap(info.getBadgedIcon(mIconDpi), mContext); } else { @@ -579,7 +579,14 @@ public class IconCache { Bitmap icon, CharSequence title) { removeFromMemCacheLocked(packageName, user); - CacheEntry entry = getEntryForPackageLocked(packageName, user, false); + ComponentKey cacheKey = getPackageKey(packageName, user); + CacheEntry entry = mCache.get(cacheKey); + + // For icon caching, do not go through DB. Just update the in-memory entry. + if (entry == null) { + entry = new CacheEntry(); + mCache.put(cacheKey, entry); + } if (!TextUtils.isEmpty(title)) { entry.title = title; } @@ -588,15 +595,18 @@ public class IconCache { } } + private static ComponentKey getPackageKey(String packageName, UserHandleCompat user) { + ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME); + return new ComponentKey(cn, user); + } + /** * Gets an entry for the package, which can be used as a fallback entry for various components. * This method is not thread safe, it must be called from a synchronized method. - * */ private CacheEntry getEntryForPackageLocked(String packageName, UserHandleCompat user, boolean useLowResIcon) { - ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME); - ComponentKey cacheKey = new ComponentKey(cn, user); + ComponentKey cacheKey = getPackageKey(packageName, user); CacheEntry entry = mCache.get(cacheKey); if (entry == null || (entry.isLowResIcon && !useLowResIcon)) { @@ -604,7 +614,7 @@ public class IconCache { boolean entryUpdated = true; // Check the DB first. - if (!getEntryFromDB(cn, user, entry, useLowResIcon)) { + if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { try { PackageInfo info = mPackageManager.getPackageInfo(packageName, 0); ApplicationInfo appInfo = info.applicationInfo; @@ -622,7 +632,8 @@ public class IconCache { // package updates. ContentValues values = newContentValues(entry.icon, entry.title.toString(), mPackageBgColor); - addIconToDB(values, cn, info, mUserManager.getSerialNumberForUser(user)); + addIconToDB(values, cacheKey.componentName, info, + mUserManager.getSerialNumberForUser(user)); } catch (NameNotFoundException e) { if (DEBUG) Log.d(TAG, "Application not installed " + packageName); @@ -649,7 +660,7 @@ public class IconCache { * @param dpi the native density of the icon */ public void preloadIcon(ComponentName componentName, Bitmap icon, int dpi, String label, - long userSerial) { + long userSerial, InvariantDeviceProfile idp) { // TODO rescale to the correct native DPI try { PackageManager packageManager = mContext.getPackageManager(); @@ -660,21 +671,22 @@ public class IconCache { // pass } - ContentValues values = newContentValues(icon, label, Color.TRANSPARENT); + ContentValues values = newContentValues( + Bitmap.createScaledBitmap(icon, idp.iconBitmapSize, idp.iconBitmapSize, true), + label, Color.TRANSPARENT); values.put(IconDB.COLUMN_COMPONENT, componentName.flattenToString()); values.put(IconDB.COLUMN_USER, userSerial); mIconDb.getWritableDatabase().insertWithOnConflict(IconDB.TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE); } - private boolean getEntryFromDB(ComponentName component, UserHandleCompat user, - CacheEntry entry, boolean lowRes) { + private boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { Cursor c = mIconDb.getReadableDatabase().query(IconDB.TABLE_NAME, new String[] {lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON, IconDB.COLUMN_LABEL}, IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?", - new String[] {component.flattenToString(), - Long.toString(mUserManager.getSerialNumberForUser(user))}, + new String[] {cacheKey.componentName.flattenToString(), + Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))}, null, null, null); try { if (c.moveToNext()) { @@ -685,7 +697,8 @@ public class IconCache { entry.title = ""; entry.contentDescription = ""; } else { - entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); + entry.contentDescription = mUserManager.getBadgedLabelForUser( + entry.title, cacheKey.user); } return true; } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 339d5a3f7..6648b6e74 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -263,6 +263,7 @@ public class Launcher extends Activity private ViewGroup mOverviewPanel; private View mAllAppsButton; + private View mWidgetsButton; private SearchDropTargetBar mSearchDropTargetBar; @@ -1370,8 +1371,8 @@ public class Launcher extends Activity } mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel); - View widgetButton = findViewById(R.id.widget_button); - widgetButton.setOnClickListener(new OnClickListener() { + mWidgetsButton = findViewById(R.id.widget_button); + mWidgetsButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (!mWorkspace.isSwitchingState()) { @@ -1379,7 +1380,7 @@ public class Launcher extends Activity } } }); - widgetButton.setOnTouchListener(getHapticFeedbackTouchListener()); + mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener()); View wallpaperButton = findViewById(R.id.wallpaper_button); wallpaperButton.setOnClickListener(new OnClickListener() { @@ -1465,6 +1466,10 @@ public class Launcher extends Activity return mAllAppsButton; } + public View getWidgetsButton() { + return mWidgetsButton; + } + /** * Creates a view representing a shortcut. * diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java index e607a0faf..a92a889f9 100644 --- a/src/com/android/launcher3/LauncherBackupAgentHelper.java +++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java @@ -92,7 +92,7 @@ public class LauncherBackupAgentHelper extends BackupAgentHelper { LauncherClings.synchonouslyMarkFirstRunClingDismissed(this); // TODO: Update the backup set to include rank. - if (mHelper.restoredBackupVersion <= 2) { + if (mHelper.restoredBackupVersion <= 3) { LauncherAppState.getLauncherProvider().updateFolderItemsRank(); LauncherAppState.getLauncherProvider().convertShortcutsToLauncherActivities(); } diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java index f2097366a..38a4bdeb4 100644 --- a/src/com/android/launcher3/LauncherBackupHelper.java +++ b/src/com/android/launcher3/LauncherBackupHelper.java @@ -75,7 +75,7 @@ public class LauncherBackupHelper implements BackupHelper { private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE; private static final boolean DEBUG = LauncherBackupAgentHelper.DEBUG; - private static final int BACKUP_VERSION = 2; + private static final int BACKUP_VERSION = 3; private static final int MAX_JOURNAL_SIZE = 1000000; // Journal key is such that it is always smaller than any dynamically generated @@ -148,10 +148,15 @@ public class LauncherBackupHelper implements BackupHelper { private IconCache mIconCache; private DeviceProfieData mDeviceProfileData; + private InvariantDeviceProfile mIdp; boolean restoreSuccessful; int restoredBackupVersion = 1; + // When migrating from a device which different hotseat configuration, the icons are shifted + // to center along the new all-apps icon. + private int mHotseatShift = 0; + public LauncherBackupHelper(Context context) { mContext = context; mExistingKeys = new HashSet<String>(); @@ -178,6 +183,7 @@ public class LauncherBackupHelper implements BackupHelper { mExistingKeys.add(keyToBackupKey(key)); } } + restoredBackupVersion = journal.backupVersion; } /** @@ -206,7 +212,8 @@ public class LauncherBackupHelper implements BackupHelper { if (mDeviceProfileData == null) { LauncherAppState app = LauncherAppState.getInstance(); - mDeviceProfileData = initDeviceProfileData(app.getInvariantDeviceProfile()); + mIdp = app.getInvariantDeviceProfile(); + mDeviceProfileData = initDeviceProfileData(mIdp); mIconCache = app.getIconCache(); } @@ -282,10 +289,15 @@ public class LauncherBackupHelper implements BackupHelper { boolean isHotsetCompatible = false; if (currentProfile.allappsRank >= oldProfile.hotseatCount) { isHotsetCompatible = true; + mHotseatShift = 0; } - if ((currentProfile.hotseatCount >= oldProfile.hotseatCount) && - (currentProfile.allappsRank == oldProfile.allappsRank)) { + + if ((currentProfile.allappsRank >= oldProfile.allappsRank) + && ((currentProfile.hotseatCount - currentProfile.allappsRank) >= + (oldProfile.hotseatCount - oldProfile.allappsRank))) { + // There is enough space on both sides of the hotseat. isHotsetCompatible = true; + mHotseatShift = currentProfile.allappsRank - oldProfile.allappsRank; } return isHotsetCompatible && (currentProfile.desktopCols >= oldProfile.desktopCols) @@ -308,9 +320,9 @@ public class LauncherBackupHelper implements BackupHelper { if (mDeviceProfileData == null) { // This call does not happen on a looper thread. So LauncherAppState // can't be created . Instead initialize required dependencies directly. - InvariantDeviceProfile profile = new InvariantDeviceProfile(mContext); - mDeviceProfileData = initDeviceProfileData(profile); - mIconCache = new IconCache(mContext, profile); + mIdp = new InvariantDeviceProfile(mContext); + mDeviceProfileData = initDeviceProfileData(mIdp); + mIconCache = new IconCache(mContext, mIdp); } int dataSize = data.size(); @@ -335,7 +347,6 @@ public class LauncherBackupHelper implements BackupHelper { MessageNano.mergeFrom(journal, readCheckedBytes(mBuffer, dataSize)); applyJournal(journal); restoreSuccessful = isBackupCompatible(journal); - restoredBackupVersion = journal.backupVersion; return; } @@ -599,10 +610,11 @@ public class LauncherBackupHelper implements BackupHelper { Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length); if (icon == null) { Log.w(TAG, "failed to unpack icon for " + key.name); + } else { + if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name); + mIconCache.preloadIcon(ComponentName.unflattenFromString(key.name), icon, res.dpi, + "" /* label */, mUserSerial, mIdp); } - if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name); - mIconCache.preloadIcon(ComponentName.unflattenFromString(key.name), icon, res.dpi, - "" /* label */, mUserSerial); } /** @@ -636,7 +648,7 @@ public class LauncherBackupHelper implements BackupHelper { } else { Log.w(TAG, "empty intent on appwidget: " + id); } - if (mExistingKeys.contains(backupKey)) { + if (mExistingKeys.contains(backupKey) && restoredBackupVersion >= BACKUP_VERSION) { if (DEBUG) Log.d(TAG, "already saved widget " + backupKey); // remember that we already backed this up previously @@ -683,7 +695,7 @@ public class LauncherBackupHelper implements BackupHelper { Log.w(TAG, "failed to unpack widget icon for " + key.name); } else { mIconCache.preloadIcon(ComponentName.unflattenFromString(widget.provider), - icon, widget.icon.dpi, widget.label, mUserSerial); + icon, widget.icon.dpi, widget.label, mUserSerial, mIdp); } } @@ -845,6 +857,11 @@ public class LauncherBackupHelper implements BackupHelper { throws IOException { Favorite favorite = unpackProto(new Favorite(), buffer, dataSize); + // If it is a hotseat item, move it accordingly. + if (favorite.container == Favorites.CONTAINER_HOTSEAT) { + favorite.screen += mHotseatShift; + } + ContentValues values = new ContentValues(); values.put(Favorites._ID, favorite.id); values.put(Favorites.SCREEN, favorite.screen); @@ -969,6 +986,16 @@ public class LauncherBackupHelper implements BackupHelper { widget.icon.data = Utilities.flattenBitmap(icon); widget.icon.dpi = dpi; } + + // Calculate the spans corresponding to any one of the orientations as it should not change + // based on orientation. + int[] minSpans = CellLayout.rectToCell( + mIdp.portraitProfile, mContext, info.minResizeWidth, info.minResizeHeight, null); + widget.minSpanX = (info.resizeMode & LauncherAppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0 + ? minSpans[0] : -1; + widget.minSpanY = (info.resizeMode & LauncherAppWidgetProviderInfo.RESIZE_VERTICAL) != 0 + ? minSpans[1] : -1; + return widget; } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 7414a2204..0b67310fa 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1999,7 +1999,7 @@ public class LauncherModel extends BroadcastReceiver "constructing info for partially restored package", true); info = getRestoredItemInfo(c, titleIndex, intent, - promiseType, cursorIconInfo, context); + promiseType, itemType, cursorIconInfo, context); intent = getRestoredItemIntent(c, context, intent); } else { // Don't restore items for other profiles. @@ -2163,7 +2163,11 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, provider.provider); - int status = restoreStatus; + // The provider is available. So the widget is either + // available or not available. We do not need to track + // any future restore updates. + int status = restoreStatus & + ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; if (!wasProviderReady) { // If provider was not previously ready, update the // status and UI flag. @@ -2209,6 +2213,7 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo.cellY = c.getInt(cellYIndex); appWidgetInfo.spanX = c.getInt(spanXIndex); appWidgetInfo.spanY = c.getInt(spanYIndex); + appWidgetInfo.user = user; if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { @@ -3154,7 +3159,9 @@ public class LauncherModel extends BroadcastReceiver if (mUser.equals(widgetInfo.user) && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) && packageSet.contains(widgetInfo.providerName.getPackageName())) { - widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY; + widgetInfo.restoreStatus &= + ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY & + ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; widgets.add(widgetInfo); updateItemInDatabase(context, widgetInfo); } @@ -3380,7 +3387,7 @@ public class LauncherModel extends BroadcastReceiver * to a package that is not yet installed on the system. */ public ShortcutInfo getRestoredItemInfo(Cursor c, int titleIndex, Intent intent, - int promiseType, CursorIconInfo iconInfo, Context context) { + int promiseType, int itemType, CursorIconInfo iconInfo, Context context) { final ShortcutInfo info = new ShortcutInfo(); info.user = UserHandleCompat.myUserHandle(); @@ -3406,7 +3413,7 @@ public class LauncherModel extends BroadcastReceiver } info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); - info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; + info.itemType = itemType; info.promisedIntent = intent; info.status = promiseType; return info; diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index ee72aea81..cc5e18bc1 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -772,7 +772,7 @@ public class LauncherProvider extends ContentProvider { long id = c.getLong(idIndex); updateStmt.bindLong(1, id); - updateStmt.execute(); + updateStmt.executeUpdateDelete(); } db.setTransactionSuccessful(); } catch (SQLException ex) { diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index 0ea9d8bd0..d69b7432d 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -90,21 +90,14 @@ public class LauncherStateTransitionAnimation { * Private callbacks made during transition setup. */ static abstract class PrivateTransitionCallbacks { - void onRevealViewVisible(View revealView, View contentView, View allAppsButtonView) {} float getMaterialRevealViewFinalAlpha(View revealView) { return 0; } - float getMaterialRevealViewFinalXDrift(View revealView) { - return 0; - } - float getMaterialRevealViewFinalYDrift(View revealView) { - return 0; - } float getMaterialRevealViewStartFinalRadius() { return 0; } AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, - View allAppsButtonView) { + View buttonView) { return null; } void onTransitionComplete() {} @@ -135,30 +128,13 @@ public class LauncherStateTransitionAnimation { public void startAnimationToAllApps(final boolean animated, final boolean startSearchAfterTransition) { final AllAppsContainerView toView = mLauncher.getAppsView(); + final View buttonView = mLauncher.getAllAppsButton(); PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { - private int[] mAllAppsToPanelDelta; - - @Override - public void onRevealViewVisible(View revealView, View contentView, - View allAppsButtonView) { - // Get the y delta between the center of the page and the center of the all apps - // button - mAllAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, - allAppsButtonView, null); - } @Override public float getMaterialRevealViewFinalAlpha(View revealView) { return 1f; } @Override - public float getMaterialRevealViewFinalXDrift(View revealView) { - return mAllAppsToPanelDelta[0]; - } - @Override - public float getMaterialRevealViewFinalYDrift(View revealView) { - return mAllAppsToPanelDelta[1]; - } - @Override public float getMaterialRevealViewStartFinalRadius() { int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; return allAppsButtonSize / 2; @@ -183,9 +159,9 @@ public class LauncherStateTransitionAnimation { } }; // Only animate the search bar if animating from spring loaded mode back to all apps - startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, toView, toView.getContentView(), - toView.getRevealView(), toView.getSearchBarView(), animated, - true /* hideSearchBar */, cb); + startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, buttonView, toView, + toView.getContentView(), toView.getRevealView(), toView.getSearchBarView(), + animated, true /* hideSearchBar */, cb); } /** @@ -193,22 +169,15 @@ public class LauncherStateTransitionAnimation { */ public void startAnimationToWidgets(final boolean animated) { final WidgetsContainerView toView = mLauncher.getWidgetsView(); - final Resources res = mLauncher.getResources(); + final View buttonView = mLauncher.getWidgetsButton(); + PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { @Override - public void onRevealViewVisible(View revealView, View contentView, - View allAppsButtonView) { - } - @Override public float getMaterialRevealViewFinalAlpha(View revealView) { return 0.3f; } - @Override - public float getMaterialRevealViewFinalYDrift(View revealView) { - return revealView.getMeasuredHeight() / 2; - } }; - startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, toView, + startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, toView.getContentView(), toView.getRevealView(), null, animated, true /* hideSearchBar */, cb); } @@ -238,23 +207,22 @@ public class LauncherStateTransitionAnimation { * Creates and starts a new animation to a particular overlay view. */ @SuppressLint("NewApi") - private void startAnimationToOverlay(final Workspace.State toWorkspaceState, final View toView, - final View contentView, final View revealView, final View overlaySearchBarView, - final boolean animated, final boolean hideSearchBar, - final PrivateTransitionCallbacks pCb) { + private void startAnimationToOverlay(final Workspace.State toWorkspaceState, + final View buttonView, final View toView, final View contentView, final View revealView, + final View overlaySearchBarView, final boolean animated, final boolean hideSearchBar, + final PrivateTransitionCallbacks pCb) { final Resources res = mLauncher.getResources(); final boolean material = Utilities.isLmpOrAbove(); final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); - final View allAppsButtonView = mLauncher.getAllAppsButton(); final View fromView = mLauncher.getWorkspace(); final HashMap<View, Integer> layerViews = new HashMap<>(); // If for some reason our views aren't initialized, don't animate - boolean initialized = allAppsButtonView != null; + boolean initialized = buttonView != null; // Cancel the current animation cancelAnimation(); @@ -275,16 +243,17 @@ public class LauncherStateTransitionAnimation { revealView.setAlpha(0f); revealView.setTranslationY(0f); revealView.setTranslationX(0f); - pCb.onRevealViewVisible(revealView, contentView, allAppsButtonView); // Calculate the final animation values final float revealViewToAlpha; final float revealViewToXDrift; final float revealViewToYDrift; if (material) { + int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, + buttonView, null); revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView); - revealViewToYDrift = pCb.getMaterialRevealViewFinalYDrift(revealView); - revealViewToXDrift = pCb.getMaterialRevealViewFinalXDrift(revealView); + revealViewToYDrift = buttonViewToPanelDelta[1]; + revealViewToXDrift = buttonViewToPanelDelta[0]; } else { revealViewToAlpha = 0f; revealViewToYDrift = 2 * height / 3; @@ -337,10 +306,9 @@ public class LauncherStateTransitionAnimation { mStateAnimation.play(itemsAlpha); if (material) { - // Animate the all apps button float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( - revealView, allAppsButtonView); + revealView, buttonView); Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, height / 2, startRadius, revealRadius); reveal.setDuration(revealDuration); @@ -453,22 +421,6 @@ public class LauncherStateTransitionAnimation { int[] mAllAppsToPanelDelta; @Override - public void onRevealViewVisible(View revealView, View contentView, - View allAppsButtonView) { - // Get the y delta between the center of the page and the center of the all apps - // button - mAllAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, - allAppsButtonView, null); - } - @Override - public float getMaterialRevealViewFinalXDrift(View revealView) { - return mAllAppsToPanelDelta[0]; - } - @Override - public float getMaterialRevealViewFinalYDrift(View revealView) { - return mAllAppsToPanelDelta[1]; - } - @Override float getMaterialRevealViewFinalAlpha(View revealView) { // No alpha anim from all apps return 1f; @@ -499,9 +451,10 @@ public class LauncherStateTransitionAnimation { } }; // Only animate the search bar if animating to spring loaded mode from all apps - startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, appsView, - appsView.getContentView(), appsView.getRevealView(), appsView.getSearchBarView(), - animated, onCompleteRunnable, cb); + startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, + mLauncher.getAllAppsButton(), appsView, appsView.getContentView(), + appsView.getRevealView(), appsView.getSearchBarView(), animated, + onCompleteRunnable, cb); } /** @@ -510,23 +463,14 @@ public class LauncherStateTransitionAnimation { private void startAnimationToWorkspaceFromWidgets(final Workspace.State toWorkspaceState, final int toWorkspacePage, final boolean animated, final Runnable onCompleteRunnable) { final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); - final Resources res = mLauncher.getResources(); PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { @Override - public void onRevealViewVisible(View revealView, View contentView, - View allAppsButtonView) { - } - @Override - public float getMaterialRevealViewFinalYDrift(View revealView) { - return revealView.getMeasuredHeight() / 2; - } - @Override float getMaterialRevealViewFinalAlpha(View revealView) { - return 0.4f; + return 0.3f; } @Override public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( - final View revealView, final View allAppsButtonView) { + final View revealView, final View widgetsButtonView) { return new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { // Hide the reveal view @@ -535,31 +479,31 @@ public class LauncherStateTransitionAnimation { }; } }; - startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, widgetsView, - widgetsView.getContentView(), widgetsView.getRevealView(), null, animated, - onCompleteRunnable, cb); + startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, + mLauncher.getWidgetsButton(), widgetsView, widgetsView.getContentView(), + widgetsView.getRevealView(), null, animated, onCompleteRunnable, cb); } /** * Creates and starts a new animation to the workspace. */ private void startAnimationToWorkspaceFromOverlay(final Workspace.State toWorkspaceState, - final int toWorkspacePage, final View fromView, final View contentView, - final View revealView, final View overlaySearchBarView, final boolean animated, - final Runnable onCompleteRunnable, final PrivateTransitionCallbacks pCb) { + final int toWorkspacePage, final View buttonView, final View fromView, + final View contentView, final View revealView, final View overlaySearchBarView, + final boolean animated, final Runnable onCompleteRunnable, + final PrivateTransitionCallbacks pCb) { final Resources res = mLauncher.getResources(); final boolean material = Utilities.isLmpOrAbove(); final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); - final View allAppsButtonView = mLauncher.getAllAppsButton(); final View toView = mLauncher.getWorkspace(); final HashMap<View, Integer> layerViews = new HashMap<>(); // If for some reason our views aren't initialized, don't animate - boolean initialized = allAppsButtonView != null; + boolean initialized = buttonView != null; // Cancel the current animation cancelAnimation(); @@ -589,14 +533,15 @@ public class LauncherStateTransitionAnimation { revealView.setAlpha(1f); revealView.setTranslationY(0); layerViews.put(revealView, BUILD_AND_SET_LAYER); - pCb.onRevealViewVisible(revealView, contentView, allAppsButtonView); // Calculate the final animation values final float revealViewToXDrift; final float revealViewToYDrift; if (material) { - revealViewToYDrift = pCb.getMaterialRevealViewFinalYDrift(revealView); - revealViewToXDrift = pCb.getMaterialRevealViewFinalXDrift(revealView); + int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, + buttonView, null); + revealViewToYDrift = buttonViewToPanelDelta[1]; + revealViewToXDrift = buttonViewToPanelDelta[0]; } else { revealViewToYDrift = 2 * height / 3; revealViewToXDrift = 0; @@ -666,7 +611,7 @@ public class LauncherStateTransitionAnimation { // Animate the all apps button float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); AnimatorListenerAdapter listener = - pCb.getMaterialRevealViewAnimatorListener(revealView, allAppsButtonView); + pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, height / 2, revealRadius, finalRadius); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java index 09a3242b5..185dfcae3 100644 --- a/src/com/android/launcher3/model/WidgetsModel.java +++ b/src/com/android/launcher3/model/WidgetsModel.java @@ -8,10 +8,10 @@ import android.util.Log; import com.android.launcher3.AppFilter; import com.android.launcher3.IconCache; -import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.Utilities; import com.android.launcher3.compat.AlphabeticIndexCompat; +import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.UserHandleCompat; import java.util.ArrayList; @@ -38,6 +38,7 @@ public class WidgetsModel { private ArrayList<Object> mRawList; + private final AppWidgetManagerCompat mAppWidgetMgr; private final Comparator mWidgetAndShortcutNameComparator; private final Comparator mAppNameComparator; private final IconCache mIconCache; @@ -45,6 +46,7 @@ public class WidgetsModel { private AlphabeticIndexCompat mIndexer; public WidgetsModel(Context context, IconCache iconCache, AppFilter appFilter) { + mAppWidgetMgr = AppWidgetManagerCompat.getInstance(context); mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context); mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator(); mIconCache = iconCache; @@ -53,6 +55,7 @@ public class WidgetsModel { } private WidgetsModel(WidgetsModel model) { + mAppWidgetMgr = model.mAppWidgetMgr; mPackageItemInfos = (ArrayList<PackageItemInfo>) model.mPackageItemInfos.clone(); mWidgetsList = (HashMap<PackageItemInfo, ArrayList<Object>>) model.mWidgetsList.clone(); mRawList = (ArrayList<Object>) model.mRawList.clone(); @@ -104,26 +107,30 @@ public class WidgetsModel { // add and update. for (Object o: rawWidgetsShortcuts) { String packageName = ""; + UserHandleCompat userHandle = null; ComponentName componentName = null; if (o instanceof LauncherAppWidgetProviderInfo) { LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o; componentName = widgetInfo.provider; packageName = widgetInfo.provider.getPackageName(); + userHandle = mAppWidgetMgr.getUser(widgetInfo); } else if (o instanceof ResolveInfo) { ResolveInfo resolveInfo = (ResolveInfo) o; componentName = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); packageName = resolveInfo.activityInfo.packageName; + userHandle = UserHandleCompat.myUserHandle(); } - if (componentName == null) { - Log.e(TAG, String.format("Widget cannot be set for class=%s", - o.getClass().toString())); + if (componentName == null || userHandle == null) { + Log.e(TAG, String.format("Widget cannot be set for %s.", o.getClass().toString())); continue; } if (mAppFilter != null && !mAppFilter.shouldShowApp(componentName)) { - Log.d(TAG, String.format("%s is filtered and not added to the widget tray.", + if (DEBUG) { + Log.d(TAG, String.format("%s is filtered and not added to the widget tray.", packageName)); + } continue; } @@ -135,7 +142,7 @@ public class WidgetsModel { widgetsShortcutsList = new ArrayList<Object>(); widgetsShortcutsList.add(o); pInfo = new PackageItemInfo(packageName); - mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(), + mIconCache.getTitleAndIconForApp(packageName, userHandle, true /* userLowResIcon */, pInfo); pInfo.titleSectionName = mIndexer.computeSectionName(pInfo.title); mWidgetsList.put(pInfo, widgetsShortcutsList); diff --git a/src/com/android/launcher3/util/UiThreadCircularReveal.java b/src/com/android/launcher3/util/UiThreadCircularReveal.java index c8e1df289..3ca3aeeee 100644 --- a/src/com/android/launcher3/util/UiThreadCircularReveal.java +++ b/src/com/android/launcher3/util/UiThreadCircularReveal.java @@ -46,10 +46,8 @@ public class UiThreadCircularReveal { public void onAnimationUpdate(ValueAnimator arg0) { float progress = arg0.getAnimatedFraction(); outlineProvider.setProgress(progress); - if (Utilities.isLmpMR1OrAbove()) { - revealView.invalidateOutline(); - } else { - // On L, a bug requires calling a full view invalidate. + revealView.invalidateOutline(); + if (!Utilities.isLmpMR1OrAbove()) { revealView.invalidate(); } } diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java index 88a6ca420..758287af3 100644 --- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java +++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java @@ -23,6 +23,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.PendingAddItemInfo; +import com.android.launcher3.compat.AppWidgetManagerCompat; /** * Meta data used for late binding of {@link LauncherAppWidgetProviderInfo}. @@ -47,6 +48,7 @@ public class PendingAddWidgetInfo extends PendingAddItemInfo { itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; } this.info = i; + user = AppWidgetManagerCompat.getInstance(launcher).getUser(i); componentName = i.provider; minWidth = i.minWidth; minHeight = i.minHeight; diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java index d07c9553a..a54626a39 100644 --- a/src/com/android/launcher3/widget/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java @@ -87,6 +87,9 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { @Override public int getItemCount() { + if (mWidgetsModel == null) { + return 0; + } return mWidgetsModel.getPackageSize(); } @@ -163,13 +166,15 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { ViewGroup container = (ViewGroup) mLayoutInflater.inflate( R.layout.widgets_list_row_view, parent, false); LinearLayout cellList = (LinearLayout) container.findViewById(R.id.widgets_cell_list); - MarginLayoutParams lp = (MarginLayoutParams) cellList.getLayoutParams(); + + // if the end padding is 0, then container view (horizontal scroll view) doesn't respect + // the end of the linear layout width + the start padding and doesn't allow scrolling. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - lp.setMarginStart(mIndent); + cellList.setPaddingRelative(mIndent, 0, 1, 0); } else { - lp.leftMargin = mIndent; + cellList.setPadding(mIndent, 0, 1, 0); } - cellList.setLayoutParams(lp); + return new WidgetsRowViewHolder(container); } |