Merge "Moving ShortcutInfo creation in InstallShortcutReceiver to background thread" into ub-launcher3-master
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 6b27559..33041db 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -63,6 +63,7 @@
FOLDER_ICON = 4;
DEEPSHORTCUT = 5;
SEARCHBOX = 6;
+ EDITTEXT = 7;
}
// Used to define what type of container a Target would represent.
@@ -91,7 +92,9 @@
APPINFO_TARGET = 7;
RESIZE_HANDLE = 8;
VERTICAL_SCROLL = 9;
- // HOME, BACK, GO_TO_PLAYSTORE
+ HOME_INTENT = 10; // Deprecated, use enum Command instead
+ BACK_BUTTON = 11; // Deprecated, use enum Command instead
+ // GO_TO_PLAYSTORE
}
// Used to define the action component of the LauncherEvent.
@@ -99,6 +102,7 @@
enum Type {
TOUCH = 0;
AUTOMATED = 1;
+ COMMAND = 2;
// SOFT_KEYBOARD, HARD_KEYBOARD, ASSIST
}
enum Touch {
@@ -116,9 +120,16 @@
LEFT = 3;
RIGHT = 4;
}
+ enum Command {
+ HOME_INTENT = 0;
+ BACK = 1;
+ }
optional Type type = 1;
optional Touch touch = 2;
optional Direction dir = 3;
+ optional Command command = 4;
+ // Log if the action was performed on outside of the container
+ optional bool is_outside = 5;
}
//
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index d00d5dd..c45ff7b 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -223,8 +223,8 @@
* Based on the current deltas, we determine if and how to resize the widget.
*/
private void resizeWidgetIfNeeded(boolean onDismiss) {
- float xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
- float yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
+ float xThreshold = mCellLayout.getCellWidth();
+ float yThreshold = mCellLayout.getCellHeight();
int hSpanInc = getSpanIncrement((mDeltaX + mDeltaXAddOn) / xThreshold - mRunningHInc);
int vSpanInc = getSpanIncrement((mDeltaY + mDeltaYAddOn) / yThreshold - mRunningVInc);
@@ -337,8 +337,8 @@
}
private void onTouchUp() {
- int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
- int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
+ int xThreshold = mCellLayout.getCellWidth();
+ int yThreshold = mCellLayout.getCellHeight();
mDeltaXAddOn = mRunningHInc * xThreshold;
mDeltaYAddOn = mRunningVInc * yThreshold;
@@ -355,10 +355,11 @@
public void snapToWidget(boolean animate) {
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
- int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding
- - mWidgetPadding.left - mWidgetPadding.right;
- int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding
- - mWidgetPadding.top - mWidgetPadding.bottom;
+ DeviceProfile profile = mLauncher.getDeviceProfile();
+ int newWidth = (int) (mWidgetView.getWidth() * profile.appWidgetScale.x)
+ + 2 * mBackgroundPadding - mWidgetPadding.left - mWidgetPadding.right;
+ int newHeight = (int) (mWidgetView.getHeight() * profile.appWidgetScale.y)
+ + 2 * mBackgroundPadding - mWidgetPadding.top - mWidgetPadding.bottom;
mTmpPt[0] = mWidgetView.getLeft();
mTmpPt[1] = mWidgetView.getTop();
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 8b5a8a8..2a4212a 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -17,7 +17,6 @@
package com.android.launcher3;
import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
@@ -437,7 +436,8 @@
return -1;
}
- ItemInfo.writeBitmap(mValues, LauncherIcons.createIconBitmap(icon, mContext));
+ mValues.put(LauncherSettings.Favorites.ICON,
+ Utilities.flattenBitmap(LauncherIcons.createIconBitmap(icon, mContext)));
mValues.put(Favorites.ICON_PACKAGE, mIconRes.getResourcePackageName(iconId));
mValues.put(Favorites.ICON_RESOURCE, mIconRes.getResourceName(iconId));
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 84b504e..9eaef90 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -87,13 +87,6 @@
@ViewDebug.ExportedProperty(category = "launcher")
private int mCountY;
- private int mOriginalWidthGap;
- private int mOriginalHeightGap;
- @ViewDebug.ExportedProperty(category = "launcher")
- @Thunk int mWidthGap;
- @ViewDebug.ExportedProperty(category = "launcher")
- @Thunk int mHeightGap;
- private int mMaxGap;
private boolean mDropPending = false;
private boolean mIsDragTarget = true;
private boolean mJailContent = true;
@@ -202,9 +195,6 @@
mCellWidth = mCellHeight = -1;
mFixedCellWidth = mFixedCellHeight = -1;
- mWidthGap = mOriginalWidthGap = 0;
- mHeightGap = mOriginalHeightGap = 0;
- mMaxGap = Integer.MAX_VALUE;
mCountX = grid.inv.numColumns;
mCountY = grid.inv.numRows;
@@ -287,8 +277,7 @@
}
mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
- mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
- mCountX, mCountY);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
@@ -373,8 +362,7 @@
public void setCellDimensions(int width, int height) {
mFixedCellWidth = mCellWidth = width;
mFixedCellHeight = mCellHeight = height;
- mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
- mCountX, mCountY);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
}
public void setGridSize(int x, int y) {
@@ -383,8 +371,7 @@
mOccupied = new GridOccupancy(mCountX, mCountY);
mTmpOccupied = new GridOccupancy(mCountX, mCountY);
mTempRectStack.clear();
- mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
- mCountX, mCountY);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
requestLayout();
}
@@ -719,8 +706,8 @@
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- result[0] = (x - hStartPadding) / (mCellWidth + mWidthGap);
- result[1] = (y - vStartPadding) / (mCellHeight + mHeightGap);
+ result[0] = (x - hStartPadding) / mCellWidth;
+ result[1] = (y - vStartPadding) / mCellHeight;
final int xAxis = mCountX;
final int yAxis = mCountY;
@@ -753,8 +740,8 @@
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap);
- result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap);
+ result[0] = hStartPadding + cellX * mCellWidth;
+ result[1] = vStartPadding + cellY * mCellHeight;
}
/**
@@ -780,10 +767,8 @@
void regionToCenterPoint(int cellX, int cellY, int spanX, int spanY, int[] result) {
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap) +
- (spanX * mCellWidth + (spanX - 1) * mWidthGap) / 2;
- result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap) +
- (spanY * mCellHeight + (spanY - 1) * mHeightGap) / 2;
+ result[0] = hStartPadding + cellX * mCellWidth + (spanX * mCellWidth) / 2;
+ result[1] = vStartPadding + cellY * mCellHeight + (spanY * mCellHeight) / 2;
}
/**
@@ -796,10 +781,9 @@
void regionToRect(int cellX, int cellY, int spanX, int spanY, Rect result) {
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- final int left = hStartPadding + cellX * (mCellWidth + mWidthGap);
- final int top = vStartPadding + cellY * (mCellHeight + mHeightGap);
- result.set(left, top, left + (spanX * mCellWidth + (spanX - 1) * mWidthGap),
- top + (spanY * mCellHeight + (spanY - 1) * mHeightGap));
+ final int left = hStartPadding + cellX * mCellWidth;
+ final int top = vStartPadding + cellY * mCellHeight;
+ result.set(left, top, left + (spanX * mCellWidth), top + (spanY * mCellHeight));
}
public float getDistanceFromCell(float x, float y, int[] cell) {
@@ -815,14 +799,6 @@
return mCellHeight;
}
- int getWidthGap() {
- return mWidthGap;
- }
-
- int getHeightGap() {
- return mHeightGap;
- }
-
public void setFixedSize(int width, int height) {
mFixedWidth = width;
mFixedHeight = height;
@@ -842,8 +818,7 @@
if (cw != mCellWidth || ch != mCellHeight) {
mCellWidth = cw;
mCellHeight = ch;
- mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap,
- mHeightGap, mCountX, mCountY);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
}
}
@@ -856,23 +831,6 @@
throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions");
}
- int numWidthGaps = mCountX - 1;
- int numHeightGaps = mCountY - 1;
-
- if (mOriginalWidthGap < 0 || mOriginalHeightGap < 0) {
- int hSpace = childWidthSize;
- int vSpace = childHeightSize;
- int hFreeSpace = hSpace - (mCountX * mCellWidth);
- int vFreeSpace = vSpace - (mCountY * mCellHeight);
- mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
- mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
- mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap,
- mHeightGap, mCountX, mCountY);
- } else {
- mWidthGap = mOriginalWidthGap;
- mHeightGap = mOriginalHeightGap;
- }
-
// Make the feedback view large enough to hold the blur bitmap.
mTouchFeedbackView.measure(
MeasureSpec.makeMeasureSpec(mCellWidth + mTouchFeedbackView.getExtraSize(),
@@ -1085,23 +1043,19 @@
// outside the bounds of the view.
top += (v.getHeight() - dragOutline.getHeight()) / 2;
// We center about the x axis
- left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
- - dragOutline.getWidth()) / 2;
+ left += ((mCellWidth * spanX) - dragOutline.getWidth()) / 2;
} else {
if (dragOffset != null && dragRegion != null) {
// Center the drag region *horizontally* in the cell and apply a drag
// outline offset
- left += dragOffset.x + ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
- - dragRegion.width()) / 2;
+ left += dragOffset.x + ((mCellWidth * spanX) - dragRegion.width()) / 2;
int cHeight = getShortcutsAndWidgets().getCellContentHeight();
int cellPaddingY = (int) Math.max(0, ((mCellHeight - cHeight) / 2f));
top += dragOffset.y + cellPaddingY;
} else {
// Center the drag outline in the cell
- left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
- - dragOutline.getWidth()) / 2;
- top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap)
- - dragOutline.getHeight()) / 2;
+ left += ((mCellWidth * spanX) - dragOutline.getWidth()) / 2;
+ top += ((mCellHeight * spanY) - dragOutline.getHeight()) / 2;
}
}
r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight());
@@ -1190,8 +1144,8 @@
// For items with a spanX / spanY > 1, the passed in point (pixelX, pixelY) corresponds
// to the center of the item, but we are searching based on the top-left cell, so
// we translate the point over to correspond to the top-left.
- pixelX -= (mCellWidth + mWidthGap) * (spanX - 1) / 2f;
- pixelY -= (mCellHeight + mHeightGap) * (spanY - 1) / 2f;
+ pixelX -= mCellWidth * (spanX - 1) / 2f;
+ pixelY -= mCellHeight * (spanY - 1) / 2f;
// Keep track of best-scoring drop area
final int[] bestXY = result != null ? result : new int[2];
@@ -2586,17 +2540,14 @@
public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, Rect resultRect) {
final int cellWidth = mCellWidth;
final int cellHeight = mCellHeight;
- final int widthGap = mWidthGap;
- final int heightGap = mHeightGap;
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- int width = cellHSpan * cellWidth + ((cellHSpan - 1) * widthGap);
- int height = cellVSpan * cellHeight + ((cellVSpan - 1) * heightGap);
-
- int x = hStartPadding + cellX * (cellWidth + widthGap);
- int y = vStartPadding + cellY * (cellHeight + heightGap);
+ int width = cellHSpan * cellWidth;
+ int height = cellVSpan * cellHeight;
+ int x = hStartPadding + cellX * cellWidth;
+ int y = vStartPadding + cellY * cellHeight;
resultRect.set(x, y, x + width, y + height);
}
@@ -2614,13 +2565,11 @@
}
public int getDesiredWidth() {
- return getPaddingLeft() + getPaddingRight() + (mCountX * mCellWidth) +
- (Math.max((mCountX - 1), 0) * mWidthGap);
+ return getPaddingLeft() + getPaddingRight() + (mCountX * mCellWidth);
}
public int getDesiredHeight() {
- return getPaddingTop() + getPaddingBottom() + (mCountY * mCellHeight) +
- (Math.max((mCountY - 1), 0) * mHeightGap);
+ return getPaddingTop() + getPaddingBottom() + (mCountY * mCellHeight);
}
public boolean isOccupied(int x, int y) {
@@ -2740,8 +2689,19 @@
this.cellVSpan = cellVSpan;
}
- public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
- boolean invertHorizontally, int colCount) {
+ public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount) {
+ setup(cellWidth, cellHeight, invertHorizontally, colCount, 1.0f, 1.0f);
+ }
+
+ /**
+ * Use this method, as opposed to {@link #setup(int, int, boolean, int)}, if the view needs
+ * to be scaled.
+ *
+ * ie. In multi-window mode, we setup widgets so that they are measured and laid out
+ * using their full/invariant device profile sizes.
+ */
+ public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount,
+ float cellScaleX, float cellScaleY) {
if (isLockedToGrid) {
final int myCellHSpan = cellHSpan;
final int myCellVSpan = cellVSpan;
@@ -2752,12 +2712,10 @@
myCellX = colCount - myCellX - cellHSpan;
}
- width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
- leftMargin - rightMargin;
- height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
- topMargin - bottomMargin;
- x = (int) (myCellX * (cellWidth + widthGap) + leftMargin);
- y = (int) (myCellY * (cellHeight + heightGap) + topMargin);
+ width = (int) (myCellHSpan * cellWidth / cellScaleX - leftMargin - rightMargin);
+ height = (int) (myCellVSpan * cellHeight / cellScaleY - topMargin - bottomMargin);
+ x = (myCellX * cellWidth + leftMargin);
+ y = (myCellY * cellHeight + topMargin);
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 483c5a9..eb1db1c 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Gravity;
@@ -112,6 +113,7 @@
public int hotseatIconSizePx;
public int hotseatBarHeightPx;
private int hotseatBarTopPaddingPx;
+ private int hotseatBarBottomPaddingPx;
private int hotseatLandGutterPx;
// All apps
@@ -122,6 +124,9 @@
public int allAppsIconDrawablePaddingPx;
public float allAppsIconTextSizePx;
+ // Widgets
+ public final PointF appWidgetScale = new PointF(1.0f, 1.0f);
+
// Drop Target
public int dropTargetBarSizePx;
@@ -185,6 +190,7 @@
hotseatBarHeightPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
+ hotseatBarBottomPaddingPx = 0;
hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_gutter_width);
// Determine sizes.
@@ -215,6 +221,15 @@
profile.cellHeightPx = profile.iconSizePx + profile.iconDrawablePaddingPx
+ Utilities.calculateTextHeight(profile.iconTextSizePx);
+ // The nav bar is black so we add bottom padding to visually center hotseat icons.
+ profile.hotseatBarBottomPaddingPx = profile.hotseatBarTopPaddingPx;
+
+ // We use these scales to measure and layout the widgets using their full invariant profile
+ // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans.
+ float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
+ float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y;
+ profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY);
+
return profile;
}
@@ -404,7 +419,8 @@
availablePaddingX = (int) Math.min(availablePaddingX,
width * MAX_HORIZONTAL_PADDING_PERCENT);
int availablePaddingY = Math.max(0, height - topWorkspacePadding - paddingBottom
- - (int) (2 * inv.numRows * cellHeightPx));
+ - (2 * inv.numRows * cellHeightPx) - hotseatBarTopPaddingPx
+ - hotseatBarBottomPaddingPx);
padding.set(availablePaddingX / 2, topWorkspacePadding + availablePaddingY / 2,
availablePaddingX / 2, paddingBottom + availablePaddingY / 2);
} else {
@@ -537,7 +553,7 @@
lp.height = hotseatBarHeightPx + mInsets.bottom;
hotseat.getLayout().setPadding(hotseatAdjustment + workspacePadding.left,
hotseatBarTopPaddingPx, hotseatAdjustment + workspacePadding.right,
- mInsets.bottom);
+ hotseatBarBottomPaddingPx + mInsets.bottom);
} else {
// For phones, layout the hotseat without any bottom margin
// to ensure that we have space for the folders
@@ -546,7 +562,7 @@
lp.height = hotseatBarHeightPx + mInsets.bottom;
hotseat.getLayout().setPadding(hotseatAdjustment + workspacePadding.left,
hotseatBarTopPaddingPx, hotseatAdjustment + workspacePadding.right,
- mInsets.bottom);
+ hotseatBarBottomPaddingPx + mInsets.bottom);
}
hotseat.setLayoutParams(lp);
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 8b70d1c..c244235 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -16,10 +16,10 @@
package com.android.launcher3;
-import android.content.ContentValues;
import android.content.Context;
import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.util.ContentWriter;
import java.util.ArrayList;
@@ -93,10 +93,10 @@
}
@Override
- void onAddToDatabase(Context context, ContentValues values) {
- super.onAddToDatabase(context, values);
- values.put(LauncherSettings.Favorites.TITLE, title.toString());
- values.put(LauncherSettings.Favorites.OPTIONS, options);
+ void onAddToDatabase(ContentWriter writer) {
+ super.onAddToDatabase(writer);
+ writer.put(LauncherSettings.Favorites.TITLE, title)
+ .put(LauncherSettings.Favorites.OPTIONS, options);
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 04d0c8c..db72b2f 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -494,7 +494,6 @@
shortcutInfo.setIcon(getDefaultIcon(user));
shortcutInfo.title = "";
shortcutInfo.contentDescription = "";
- shortcutInfo.usingFallbackIcon = true;
shortcutInfo.usingLowResIcon = false;
} else {
LauncherActivityInfoCompat info = mLauncherApps.resolveActivity(intent, user);
@@ -512,7 +511,6 @@
shortcutInfo.setIcon(getNonNullIcon(entry, user));
shortcutInfo.title = Utilities.trim(entry.title);
shortcutInfo.contentDescription = entry.contentDescription;
- shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
shortcutInfo.usingLowResIcon = entry.isLowResIcon;
}
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 2043772..3e0ae4f 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -18,12 +18,10 @@
import android.content.ComponentName;
import android.content.ContentValues;
-import android.content.Context;
import android.content.Intent;
-import android.graphics.Bitmap;
import com.android.launcher3.compat.UserHandleCompat;
-import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.ContentWriter;
/**
* Represents an item in the launcher.
@@ -142,15 +140,15 @@
return getIntent() == null ? null : getIntent().getComponent();
}
- public void writeToValues(ContentValues values) {
- values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType);
- values.put(LauncherSettings.Favorites.CONTAINER, container);
- values.put(LauncherSettings.Favorites.SCREEN, screenId);
- values.put(LauncherSettings.Favorites.CELLX, cellX);
- values.put(LauncherSettings.Favorites.CELLY, cellY);
- values.put(LauncherSettings.Favorites.SPANX, spanX);
- values.put(LauncherSettings.Favorites.SPANY, spanY);
- values.put(LauncherSettings.Favorites.RANK, rank);
+ public void writeToValues(ContentWriter writer) {
+ writer.put(LauncherSettings.Favorites.ITEM_TYPE, itemType)
+ .put(LauncherSettings.Favorites.CONTAINER, container)
+ .put(LauncherSettings.Favorites.SCREEN, screenId)
+ .put(LauncherSettings.Favorites.CELLX, cellX)
+ .put(LauncherSettings.Favorites.CELLY, cellY)
+ .put(LauncherSettings.Favorites.SPANX, spanX)
+ .put(LauncherSettings.Favorites.SPANY, spanY)
+ .put(LauncherSettings.Favorites.RANK, rank);
}
public void readFromValues(ContentValues values) {
@@ -166,26 +164,15 @@
/**
* Write the fields of this item to the DB
- *
- * @param context A context object to use for getting UserManagerCompat
- * @param values
*/
- void onAddToDatabase(Context context, ContentValues values) {
- writeToValues(values);
- long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
- values.put(LauncherSettings.Favorites.PROFILE_ID, serialNumber);
-
+ void onAddToDatabase(ContentWriter writer) {
if (screenId == Workspace.EXTRA_EMPTY_SCREEN_ID) {
// We should never persist an item on the extra empty screen.
throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID");
}
- }
- static void writeBitmap(ContentValues values, Bitmap bitmap) {
- if (bitmap != null) {
- byte[] data = Utilities.flattenBitmap(bitmap);
- values.put(LauncherSettings.Favorites.ICON, data);
- }
+ writeToValues(writer);
+ writer.put(LauncherSettings.Favorites.PROFILE_ID, user);
}
@Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 0a5d44e..9160a01 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1681,9 +1681,27 @@
// Can be cases where mWorkspace is null, this prevents a NPE
return;
}
- // In all these cases, only animate if we're already on home
+
+ // Note: There should be at most one log per method call. This is enforced implicitly
+ // by using if-else statements.
+ UserEventDispatcher ued = getUserEventDispatcher();
+
+ // TODO: Log this case.
mWorkspace.exitWidgetResizeMode();
+ AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(this);
+ if (topOpenView instanceof DeepShortcutsContainer) {
+ ued.logActionCommand(LauncherLogProto.Action.HOME_INTENT,
+ topOpenView.getExtendedTouchView(), LauncherLogProto.DEEPSHORTCUTS);
+ } else if (topOpenView instanceof Folder) {
+ ued.logActionCommand(LauncherLogProto.Action.HOME_INTENT,
+ ((Folder) topOpenView).getFolderIcon(), LauncherLogProto.FOLDER);
+ } else if (alreadyOnHome) {
+ ued.logActionCommand(LauncherLogProto.Action.HOME_INTENT,
+ mWorkspace.getState().containerType, mWorkspace.getCurrentPage());
+ }
+
+ // In all these cases, only animate if we're already on home
AbstractFloatingView.closeAllOpenViews(this, alreadyOnHome);
exitSpringLoadedDragMode();
@@ -2187,20 +2205,34 @@
return;
}
+ // Note: There should be at most one log per method call. This is enforced implicitly
+ // by using if-else statements.
+ UserEventDispatcher ued = getUserEventDispatcher();
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
if (topView != null) {
if (topView.getActiveTextView() != null) {
topView.getActiveTextView().dispatchBackKey();
} else {
+ if (topView instanceof DeepShortcutsContainer) {
+ ued.logActionCommand(LauncherLogProto.Action.BACK,
+ topView.getExtendedTouchView(), LauncherLogProto.DEEPSHORTCUTS);
+ } else if (topView instanceof Folder) {
+ ued.logActionCommand(LauncherLogProto.Action.BACK,
+ ((Folder) topView).getFolderIcon(), LauncherLogProto.FOLDER);
+ }
topView.close(true);
}
} else if (isAppsViewVisible()) {
+ ued.logActionCommand(LauncherLogProto.Action.BACK, LauncherLogProto.ALLAPPS);
showWorkspace(true);
} else if (isWidgetsViewVisible()) {
+ ued.logActionCommand(LauncherLogProto.Action.BACK, LauncherLogProto.WIDGETS);
showOverviewMode(true);
} else if (mWorkspace.isInOverviewMode()) {
+ ued.logActionCommand(LauncherLogProto.Action.BACK, LauncherLogProto.OVERVIEW);
showWorkspace(true);
} else {
+ // TODO: Log this case.
mWorkspace.exitWidgetResizeMode();
// Back button is a no-op here, but give at least some feedback for the button press
@@ -2594,7 +2626,7 @@
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
String id = ((ShortcutInfo) info).getDeepShortcutId();
String packageName = intent.getPackage();
- LauncherAppState.getInstance().getShortcutManager().startShortcut(
+ DeepShortcutManager.getInstance(this).startShortcut(
packageName, id, intent.getSourceBounds(), optsBundle, info.user);
} else {
// Could be launching some bookkeeping activity
@@ -2951,10 +2983,9 @@
}
if (toState == State.APPS) {
- mStateTransitionAnimation.startAnimationToAllApps(mWorkspace.getState(), animated,
- focusSearchBar);
+ mStateTransitionAnimation.startAnimationToAllApps(animated, focusSearchBar);
} else {
- mStateTransitionAnimation.startAnimationToWidgets(mWorkspace.getState(), animated);
+ mStateTransitionAnimation.startAnimationToWidgets(animated);
}
// Change the state *after* we've called all the transition code
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 2a43aad..5937d78 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -28,8 +28,6 @@
import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.shortcuts.DeepShortcutManager;
-import com.android.launcher3.shortcuts.ShortcutCache;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.TestingUtils;
import com.android.launcher3.util.Thunk;
@@ -44,7 +42,6 @@
@Thunk final LauncherModel mModel;
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
- private final DeepShortcutManager mDeepShortcutManager;
@Thunk boolean mWallpaperChangedSinceLastCheck;
@@ -98,10 +95,9 @@
mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);
mIconCache = new IconCache(sContext, mInvariantDeviceProfile);
mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache);
- mDeepShortcutManager = new DeepShortcutManager(sContext, new ShortcutCache());
mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class));
- mModel = new LauncherModel(this, mIconCache, mAppFilter, mDeepShortcutManager);
+ mModel = new LauncherModel(this, mIconCache, mAppFilter);
LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel);
@@ -173,10 +169,6 @@
return mWidgetCache;
}
- public DeepShortcutManager getShortcutManager() {
- return mDeepShortcutManager;
- }
-
public boolean hasWallpaperChangedSinceLastCheck() {
boolean result = mWallpaperChangedSinceLastCheck;
mWallpaperChangedSinceLastCheck = false;
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 78f5b8e..2218767 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -18,11 +18,10 @@
import android.appwidget.AppWidgetHostView;
import android.content.ComponentName;
-import android.content.ContentValues;
-import android.content.Context;
import android.content.Intent;
import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.util.ContentWriter;
/**
* Represents a widget (either instantiated or about to be) in the Launcher.
@@ -127,13 +126,12 @@
}
@Override
- void onAddToDatabase(Context context, ContentValues values) {
- super.onAddToDatabase(context, values);
- values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
- values.put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, providerName.flattenToString());
- values.put(LauncherSettings.Favorites.RESTORED, restoreStatus);
- values.put(LauncherSettings.Favorites.INTENT,
- bindOptions == null ? null : bindOptions.toUri(0));
+ void onAddToDatabase(ContentWriter writer) {
+ super.onAddToDatabase(writer);
+ writer.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId)
+ .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, providerName.flattenToString())
+ .put(LauncherSettings.Favorites.RESTORED, restoreStatus)
+ .put(LauncherSettings.Favorites.INTENT, bindOptions);
}
/**
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 3daa2c3..c7bb188 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -76,6 +76,7 @@
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.CursorIconInfo;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -156,7 +157,8 @@
@Override
public void run() {
if (mDeepShortcutsLoaded) {
- boolean hasShortcutHostPermission = mDeepShortcutManager.hasHostPermission();
+ boolean hasShortcutHostPermission =
+ DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission();
if (hasShortcutHostPermission != mHasShortcutHostPermission) {
mApp.reloadWorkspace();
}
@@ -173,7 +175,6 @@
// </ only access in worker thread >
private final IconCache mIconCache;
- private final DeepShortcutManager mDeepShortcutManager;
private final LauncherAppsCompat mLauncherApps;
private final UserManagerCompat mUserManager;
@@ -210,14 +211,12 @@
public void bindDeepShortcutMap(MultiHashMap<ComponentKey, String> deepShortcutMap);
}
- LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter,
- DeepShortcutManager deepShortcutManager) {
+ LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
Context context = app.getContext();
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
mBgWidgetsModel = new WidgetsModel(iconCache, appFilter);
mIconCache = iconCache;
- mDeepShortcutManager = deepShortcutManager;
mLauncherApps = LauncherAppsCompat.getInstance(context);
mUserManager = UserManagerCompat.getInstance(context);
@@ -340,7 +339,7 @@
runOnWorkerThread(r);
}
- static void updateItemInDatabaseHelper(Context context, final ContentValues values,
+ static void updateItemInDatabaseHelper(Context context, final ContentWriter writer,
final ItemInfo item, final String callingFunction) {
final long itemId = item.id;
final Uri uri = LauncherSettings.Favorites.getContentUri(itemId);
@@ -349,7 +348,7 @@
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
Runnable r = new Runnable() {
public void run() {
- cr.update(uri, values, null, null);
+ cr.update(uri, writer.getValues(), null, null);
updateItemArrays(item, itemId, stackTrace);
}
};
@@ -447,14 +446,14 @@
item.screenId = screenId;
}
- final ContentValues values = new ContentValues();
- values.put(LauncherSettings.Favorites.CONTAINER, item.container);
- values.put(LauncherSettings.Favorites.CELLX, item.cellX);
- values.put(LauncherSettings.Favorites.CELLY, item.cellY);
- values.put(LauncherSettings.Favorites.RANK, item.rank);
- values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
+ final ContentWriter writer = new ContentWriter(context)
+ .put(LauncherSettings.Favorites.CONTAINER, item.container)
+ .put(LauncherSettings.Favorites.CELLX, item.cellX)
+ .put(LauncherSettings.Favorites.CELLY, item.cellY)
+ .put(LauncherSettings.Favorites.RANK, item.rank)
+ .put(LauncherSettings.Favorites.SCREEN, item.screenId);
- updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase");
+ updateItemInDatabaseHelper(context, writer, item, "moveItemInDatabase");
}
/**
@@ -514,25 +513,25 @@
item.screenId = screenId;
}
- final ContentValues values = new ContentValues();
- values.put(LauncherSettings.Favorites.CONTAINER, item.container);
- values.put(LauncherSettings.Favorites.CELLX, item.cellX);
- values.put(LauncherSettings.Favorites.CELLY, item.cellY);
- values.put(LauncherSettings.Favorites.RANK, item.rank);
- values.put(LauncherSettings.Favorites.SPANX, item.spanX);
- values.put(LauncherSettings.Favorites.SPANY, item.spanY);
- values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
+ final ContentWriter writer = new ContentWriter(context)
+ .put(LauncherSettings.Favorites.CONTAINER, item.container)
+ .put(LauncherSettings.Favorites.CELLX, item.cellX)
+ .put(LauncherSettings.Favorites.CELLY, item.cellY)
+ .put(LauncherSettings.Favorites.RANK, item.rank)
+ .put(LauncherSettings.Favorites.SPANX, item.spanX)
+ .put(LauncherSettings.Favorites.SPANY, item.spanY)
+ .put(LauncherSettings.Favorites.SCREEN, item.screenId);
- updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase");
+ updateItemInDatabaseHelper(context, writer, item, "modifyItemInDatabase");
}
/**
* Update an item to the database in a specified container.
*/
public static void updateItemInDatabase(Context context, final ItemInfo item) {
- final ContentValues values = new ContentValues();
- item.onAddToDatabase(context, values);
- updateItemInDatabaseHelper(context, values, item, "updateItemInDatabase");
+ ContentWriter writer = new ContentWriter(context);
+ item.onAddToDatabase(writer);
+ updateItemInDatabaseHelper(context, writer, item, "updateItemInDatabase");
}
/**
@@ -554,19 +553,19 @@
item.screenId = screenId;
}
- final ContentValues values = new ContentValues();
+ final ContentWriter writer = new ContentWriter(context);
final ContentResolver cr = context.getContentResolver();
- item.onAddToDatabase(context, values);
+ item.onAddToDatabase(writer);
item.id = LauncherSettings.Settings.call(cr, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
.getLong(LauncherSettings.Settings.EXTRA_VALUE);
- values.put(LauncherSettings.Favorites._ID, item.id);
+ writer.put(LauncherSettings.Favorites._ID, item.id);
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
Runnable r = new Runnable() {
public void run() {
- cr.insert(LauncherSettings.Favorites.CONTENT_URI, values);
+ cr.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues());
synchronized (sBgDataModel) {
checkItemInfoLocked(item.id, item, stackTrace);
@@ -1198,6 +1197,7 @@
final PackageManager manager = context.getPackageManager();
final boolean isSafeMode = manager.isSafeMode();
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+ final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context);
final boolean isSdCardReady = Utilities.isBootCompleted();
final MultiHashMap<UserHandleCompat, String> pendingPackages = new MultiHashMap<>();
@@ -1295,8 +1295,8 @@
// We can only query for shortcuts when the user is unlocked.
if (userUnlocked) {
List<ShortcutInfoCompat> pinnedShortcuts =
- mDeepShortcutManager.queryForPinnedShortcuts(null, user);
- if (mDeepShortcutManager.wasLastCallSuccess()) {
+ shortcutManager.queryForPinnedShortcuts(null, user);
+ if (shortcutManager.wasLastCallSuccess()) {
for (ShortcutInfoCompat shortcut : pinnedShortcuts) {
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
shortcut);
@@ -1780,7 +1780,7 @@
MutableInt numTimesPinned = sBgDataModel.pinnedShortcutCounts.get(key);
if (numTimesPinned == null || numTimesPinned.value == 0) {
// Shortcut is pinned but doesn't exist on the workspace; unpin it.
- mDeepShortcutManager.unpinShortcut(key);
+ shortcutManager.unpinShortcut(key);
}
}
@@ -2333,12 +2333,13 @@
}
if (!mDeepShortcutsLoaded) {
sBgDataModel.deepShortcutMap.clear();
- mHasShortcutHostPermission = mDeepShortcutManager.hasHostPermission();
+ DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext);
+ mHasShortcutHostPermission = shortcutManager.hasHostPermission();
if (mHasShortcutHostPermission) {
for (UserHandleCompat user : mUserManager.getUserProfiles()) {
if (mUserManager.isUserUnlocked(user)) {
- List<ShortcutInfoCompat> shortcuts = mDeepShortcutManager
- .queryForAllShortcuts(user);
+ List<ShortcutInfoCompat> shortcuts =
+ shortcutManager.queryForAllShortcuts(user);
sBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
}
}
@@ -2640,7 +2641,6 @@
// the fallback icon
if (icon == null) {
icon = mIconCache.getDefaultIcon(info.user);
- info.usingFallbackIcon = true;
}
info.setIcon(icon);
}
@@ -2677,7 +2677,6 @@
info.user = UserHandleCompat.myUserHandle();
if (icon == null) {
icon = mIconCache.getDefaultIcon(info.user);
- info.usingFallbackIcon = true;
}
info.setIcon(icon);
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 349f094..b30c3f3 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -650,7 +650,7 @@
if (mWidgetHostResetHandler != null) {
new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID).deleteHost();
mWidgetHostResetHandler.sendEmptyMessage(
- ChangeListenerWrapper.MSG_EXTRACTED_COLORS_CHANGED);
+ ChangeListenerWrapper.MSG_APP_WIDGET_HOST_RESET);
}
// Set the flag for empty DB
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 7e84264..19cc0fb 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -23,13 +23,13 @@
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.res.Resources;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import com.android.launcher3.allapps.AllAppsContainerView;
@@ -135,7 +135,7 @@
* @param startSearchAfterTransition Immediately starts app search after the transition to
* All Apps is completed.
*/
- public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
+ public void startAnimationToAllApps(
final boolean animated, final boolean startSearchAfterTransition) {
final AllAppsContainerView toView = mLauncher.getAppsView();
final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation();
@@ -170,18 +170,17 @@
animType = PULLUP;
}
// Only animate the search bar if animating from spring loaded mode back to all apps
- startAnimationToOverlay(fromWorkspaceState,
+ startAnimationToOverlay(
Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb);
}
/**
* Starts an animation to the widgets view.
*/
- public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
- final boolean animated) {
+ public void startAnimationToWidgets(final boolean animated) {
final WidgetsContainerView toView = mLauncher.getWidgetsView();
final View buttonView = mLauncher.getWidgetsButton();
- startAnimationToOverlay(fromWorkspaceState,
+ startAnimationToOverlay(
Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL,
new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){
@Override
@@ -224,9 +223,8 @@
/**
* Creates and starts a new animation to a particular overlay view.
*/
- @SuppressLint("NewApi")
private void startAnimationToOverlay(
- final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
+ final Workspace.State toWorkspaceState,
final View buttonView, final BaseContainerView toView,
final boolean animated, int animType, final PrivateTransitionCallbacks pCb) {
final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
@@ -237,8 +235,6 @@
final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
- final View fromView = mLauncher.getWorkspace();
-
final AnimationLayerSet layerViews = new AnimationLayerSet();
// If for some reason our views aren't initialized, don't animate
@@ -248,7 +244,7 @@
cancelAnimation();
final View contentView = toView.getContentView();
- playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
+ playCommonTransitionAnimations(toWorkspaceState,
animated, initialized, animation, layerViews);
if (!animated || !initialized) {
if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
@@ -264,13 +260,6 @@
// Show the content view
contentView.setVisibility(View.VISIBLE);
-
- dispatchOnLauncherTransitionPrepare(fromView, animated, false);
- dispatchOnLauncherTransitionStart(fromView, animated, false);
- dispatchOnLauncherTransitionEnd(fromView, animated, false);
- dispatchOnLauncherTransitionPrepare(toView, animated, false);
- dispatchOnLauncherTransitionStart(toView, animated, false);
- dispatchOnLauncherTransitionEnd(toView, animated, false);
pCb.onTransitionComplete();
return;
}
@@ -355,9 +344,6 @@
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- dispatchOnLauncherTransitionEnd(fromView, animated, false);
- dispatchOnLauncherTransitionEnd(toView, animated, false);
-
// Hide the reveal view
revealView.setVisibility(View.INVISIBLE);
@@ -368,31 +354,11 @@
});
- // Dispatch the prepare transition signal
- dispatchOnLauncherTransitionPrepare(fromView, animated, false);
- dispatchOnLauncherTransitionPrepare(toView, animated, false);
-
- final AnimatorSet stateAnimation = animation;
- final Runnable startAnimRunnable = new Runnable() {
- public void run() {
- // Check that mCurrentAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mCurrentAnimation != stateAnimation)
- return;
- dispatchOnLauncherTransitionStart(fromView, animated, false);
- dispatchOnLauncherTransitionStart(toView, animated, false);
-
- // Focus the new view
- toView.requestFocus();
-
- stateAnimation.start();
- }
- };
toView.bringToFront();
toView.setVisibility(View.VISIBLE);
animation.addListener(layerViews);
- toView.post(startAnimRunnable);
+ toView.post(new StartAnimRunnable(animation, toView));
mCurrentAnimation = animation;
} else if (animType == PULLUP) {
// We are animating the content view alpha, so ensure we have a layer for it
@@ -401,32 +367,13 @@
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- dispatchOnLauncherTransitionEnd(fromView, animated, false);
- dispatchOnLauncherTransitionEnd(toView, animated, false);
cleanupAnimation();
pCb.onTransitionComplete();
}
});
boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide);
- dispatchOnLauncherTransitionPrepare(fromView, animated, false);
- dispatchOnLauncherTransitionPrepare(toView, animated, false);
-
- final AnimatorSet stateAnimation = animation;
- final Runnable startAnimRunnable = new Runnable() {
- public void run() {
- // Check that mCurrentAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mCurrentAnimation != stateAnimation)
- return;
-
- dispatchOnLauncherTransitionStart(fromView, animated, false);
- dispatchOnLauncherTransitionStart(toView, animated, false);
-
- toView.requestFocus();
- stateAnimation.start();
- }
- };
+ Runnable startAnimRunnable = new StartAnimRunnable(animation, toView);
mCurrentAnimation = animation;
mCurrentAnimation.addListener(layerViews);
if (shouldPost) {
@@ -441,7 +388,7 @@
* Plays animations used by various transitions.
*/
private void playCommonTransitionAnimations(
- Workspace.State toWorkspaceState, View fromView, View toView,
+ Workspace.State toWorkspaceState,
boolean animated, boolean initialized, AnimatorSet animation,
AnimationLayerSet layerViews) {
// Create the workspace animation.
@@ -454,36 +401,16 @@
if (workspaceAnim != null) {
animation.play(workspaceAnim);
}
- // Dispatch onLauncherTransitionStep() as the animation interpolates.
- animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
}
}
/**
- * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
- * {@param fromView} and {@param toView} as the animation interpolates.
- *
- * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
- */
- private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
- ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
- updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
- dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
- }
- });
- return updateAnimator;
- }
-
- /**
* Starts an animation to the workspace from the apps view.
*/
private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
final Workspace.State toWorkspaceState, final boolean animated, int type,
final Runnable onCompleteRunnable) {
- AllAppsContainerView appsView = mLauncher.getAppsView();
+ final AllAppsContainerView appsView = mLauncher.getAppsView();
// No alpha anim from all apps
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
@Override
@@ -513,6 +440,7 @@
@Override
void onTransitionComplete() {
mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
+ appsView.reset();
}
};
// Only animate the search bar if animating to spring loaded mode from all apps
@@ -564,34 +492,13 @@
// Cancel the current animation
cancelAnimation();
- boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
-
- playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
- animated, animated, animation, layerViews);
-
+ playCommonTransitionAnimations(toWorkspaceState, animated, animated, animation, layerViews);
mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
if (animated) {
- dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
-
- final AnimatorSet stateAnimation = animation;
- final Runnable startAnimRunnable = new Runnable() {
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public void run() {
- // Check that mCurrentAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mCurrentAnimation != stateAnimation)
- return;
-
- dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
- stateAnimation.start();
- }
- };
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
-
// Run any queued runnables
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
@@ -601,14 +508,10 @@
cleanupAnimation();
}
});
- stateAnimation.addListener(layerViews);
- fromWorkspace.post(startAnimRunnable);
+ animation.addListener(layerViews);
+ fromWorkspace.post(new StartAnimRunnable(animation, null));
mCurrentAnimation = animation;
} else /* if (!animated) */ {
- dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
- dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
- dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
-
// Run any queued runnables
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
@@ -646,9 +549,7 @@
// Cancel the current animation
cancelAnimation();
- boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
-
- playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
+ playCommonTransitionAnimations(toWorkspaceState,
animated, initialized, animation, layerViews);
if (!animated || !initialized) {
if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
@@ -656,12 +557,6 @@
mAllAppsController.finishPullDown();
}
fromView.setVisibility(View.GONE);
- dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
- dispatchOnLauncherTransitionStart(fromView, animated, true);
- dispatchOnLauncherTransitionEnd(fromView, animated, true);
- dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
- dispatchOnLauncherTransitionStart(toView, animated, true);
- dispatchOnLauncherTransitionEnd(toView, animated, true);
pCb.onTransitionComplete();
// Run any queued runnables
@@ -774,16 +669,10 @@
}
}
- dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
- dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
-
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
fromView.setVisibility(View.GONE);
- dispatchOnLauncherTransitionEnd(fromView, animated, true);
- dispatchOnLauncherTransitionEnd(toView, animated, true);
-
// Run any queued runnables
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
@@ -802,23 +691,9 @@
}
});
- final AnimatorSet stateAnimation = animation;
- final Runnable startAnimRunnable = new Runnable() {
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public void run() {
- // Check that mCurrentAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mCurrentAnimation != stateAnimation)
- return;
-
- dispatchOnLauncherTransitionStart(fromView, animated, false);
- dispatchOnLauncherTransitionStart(toView, animated, false);
- stateAnimation.start();
- }
- };
mCurrentAnimation = animation;
mCurrentAnimation.addListener(layerViews);
- fromView.post(startAnimRunnable);
+ fromView.post(new StartAnimRunnable(animation, null));
} else if (animType == PULLUP) {
// We are animating the content view alpha, so ensure we have a layer for it
layerViews.addView(contentView);
@@ -833,8 +708,6 @@
@Override
public void onAnimationEnd(Animator animation) {
if (canceled) return;
- dispatchOnLauncherTransitionEnd(fromView, animated, true);
- dispatchOnLauncherTransitionEnd(toView, animated, true);
// Run any queued runnables
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
@@ -847,26 +720,7 @@
});
boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide);
- // Dispatch the prepare transition signal
- dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
- dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
-
- final AnimatorSet stateAnimation = animation;
- final Runnable startAnimRunnable = new Runnable() {
- public void run() {
- // Check that mCurrentAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mCurrentAnimation != stateAnimation)
- return;
-
- dispatchOnLauncherTransitionStart(fromView, animated, false);
- dispatchOnLauncherTransitionStart(toView, animated, false);
-
- // Focus the new view
- toView.requestFocus();
- stateAnimation.start();
- }
- };
+ Runnable startAnimRunnable = new StartAnimRunnable(animation, toView);
mCurrentAnimation = animation;
mCurrentAnimation.addListener(layerViews);
if (shouldPost) {
@@ -879,52 +733,6 @@
}
/**
- * Dispatches the prepare-transition event to suitable views.
- */
- void dispatchOnLauncherTransitionPrepare(View v, boolean animated,
- boolean multiplePagesVisible) {
- if (v instanceof LauncherTransitionable) {
- ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
- multiplePagesVisible);
- }
- }
-
- /**
- * Dispatches the start-transition event to suitable views.
- */
- void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
- if (v instanceof LauncherTransitionable) {
- ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
- toWorkspace);
- }
-
- // Update the workspace transition step as well
- dispatchOnLauncherTransitionStep(v, 0f);
- }
-
- /**
- * Dispatches the step-transition event to suitable views.
- */
- void dispatchOnLauncherTransitionStep(View v, float t) {
- if (v instanceof LauncherTransitionable) {
- ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
- }
- }
-
- /**
- * Dispatches the end-transition event to suitable views.
- */
- void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
- if (v instanceof LauncherTransitionable) {
- ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
- toWorkspace);
- }
-
- // Update the workspace transition step as well
- dispatchOnLauncherTransitionStep(v, 1f);
- }
-
- /**
* Cancels the current animation.
*/
private void cancelAnimation() {
@@ -938,4 +746,26 @@
@Thunk void cleanupAnimation() {
mCurrentAnimation = null;
}
+
+ private class StartAnimRunnable implements Runnable {
+
+ private final AnimatorSet mAnim;
+ private final View mViewToFocus;
+
+ public StartAnimRunnable(AnimatorSet anim, View viewToFocus) {
+ mAnim = anim;
+ mViewToFocus = viewToFocus;
+ }
+
+ @Override
+ public void run() {
+ if (mCurrentAnimation != mAnim) {
+ return;
+ }
+ if (mViewToFocus != null) {
+ mViewToFocus.requestFocus();
+ }
+ mAnim.start();
+ }
+ }
}
diff --git a/src/com/android/launcher3/LauncherTransitionable.java b/src/com/android/launcher3/LauncherTransitionable.java
deleted file mode 100644
index b97aaec..0000000
--- a/src/com/android/launcher3/LauncherTransitionable.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-/**
- * An interface to get callbacks during a launcher transition.
- */
-public interface LauncherTransitionable {
- void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean multiplePagesVisible);
- void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);
- void onLauncherTransitionStep(Launcher l, float t);
- void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);
-}
diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java
index 3cc0f7d..c1d60fd 100644
--- a/src/com/android/launcher3/PinchAnimationManager.java
+++ b/src/com/android/launcher3/PinchAnimationManager.java
@@ -108,7 +108,7 @@
public void onAnimationEnd(Animator animation) {
mIsAnimating = false;
thresholdManager.reset();
- mWorkspace.onLauncherTransitionEnd(mLauncher, false, true);
+ mWorkspace.onEndStateTransition();
}
});
animator.setDuration(duration).start();
diff --git a/src/com/android/launcher3/PinchToOverviewListener.java b/src/com/android/launcher3/PinchToOverviewListener.java
index 66209bf..42515d1 100644
--- a/src/com/android/launcher3/PinchToOverviewListener.java
+++ b/src/com/android/launcher3/PinchToOverviewListener.java
@@ -112,7 +112,7 @@
mInterpolator = mWorkspace.isInOverviewMode() ? new LogDecelerateInterpolator(100, 0)
: new LogAccelerateInterpolator(100, 0);
mPinchStarted = true;
- mWorkspace.onLauncherTransitionPrepare(mLauncher, false, true);
+ mWorkspace.onPrepareStateTransition(true);
return true;
}
@@ -142,7 +142,7 @@
mThresholdManager);
} else {
mThresholdManager.reset();
- mWorkspace.onLauncherTransitionEnd(mLauncher, false, true);
+ mWorkspace.onEndStateTransition();
}
mPinchStarted = false;
mPinchCanceled = false;
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index dafc81a..342479f 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -18,6 +18,7 @@
import android.app.WallpaperManager;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.view.View;
@@ -47,9 +48,6 @@
private int mCellWidth;
private int mCellHeight;
- private int mWidthGap;
- private int mHeightGap;
-
private int mCountX;
private Launcher mLauncher;
@@ -62,12 +60,9 @@
mWallpaperManager = WallpaperManager.getInstance(context);
}
- public void setCellDimensions(int cellWidth, int cellHeight, int widthGap, int heightGap,
- int countX, int countY) {
+ public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
mCellWidth = cellWidth;
mCellHeight = cellHeight;
- mWidthGap = widthGap;
- mHeightGap = heightGap;
mCountX = countX;
}
@@ -102,8 +97,7 @@
}
public void setupLp(CellLayout.LayoutParams lp) {
- lp.setup(mCellWidth, mCellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
- mCountX);
+ lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
}
// Set whether or not to invert the layout horizontally if the layout is in RTL mode.
@@ -127,21 +121,20 @@
}
public void measureChild(View child) {
- final DeviceProfile grid = mLauncher.getDeviceProfile();
- final int cellWidth = mCellWidth;
- final int cellHeight = mCellHeight;
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
if (!lp.isFullscreen) {
- lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
- mCountX);
+ final DeviceProfile profile = mLauncher.getDeviceProfile();
if (child instanceof LauncherAppWidgetHostView) {
- // Widgets have their own padding, so skip
+ lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
+ profile.appWidgetScale.x, profile.appWidgetScale.y);
+ // Widgets have their own padding
} else {
- // Otherwise, center the icon/folder
+ lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
+ // Center the icon/folder
int cHeight = getCellContentHeight();
int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
- int cellPaddingX = (int) (grid.edgeMarginPx / 2f);
+ int cellPaddingX = (int) (profile.edgeMarginPx / 2f);
child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
}
} else {
@@ -166,6 +159,21 @@
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+
+ if (child instanceof LauncherAppWidgetHostView) {
+ // Scale and center the widget to fit within its cells.
+ DeviceProfile profile = mLauncher.getDeviceProfile();
+ float scaleX = profile.appWidgetScale.x;
+ float scaleY = profile.appWidgetScale.y;
+
+ float scale = Math.min(scaleX, scaleY);
+ child.setScaleX(scale);
+ child.setScaleY(scale);
+
+ child.setTranslationX(-(lp.width - (lp.width * scaleX)) / 2.0f);
+ child.setTranslationY(-(lp.height - (lp.height * scaleY)) / 2.0f);
+ }
+
int childLeft = lp.x;
int childTop = lp.y;
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index fc08736..d6d03d3 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -18,7 +18,6 @@
import android.annotation.TargetApi;
import android.content.ComponentName;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -32,7 +31,9 @@
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.util.ContentWriter;
/**
* Represents a launchable icon on the workspaces and in folders.
@@ -77,12 +78,6 @@
public Intent intent;
/**
- * Indicates whether we're using the default fallback icon instead of something from the
- * app.
- */
- public boolean usingFallbackIcon;
-
- /**
* Indicates whether we're using a low res icon
*/
boolean usingLowResIcon;
@@ -187,7 +182,6 @@
status = info.status;
mInstallProgress = info.mInstallProgress;
isDisabled = info.isDisabled;
- usingFallbackIcon = info.usingFallbackIcon;
}
/** TODO: Remove this. It's only called by ApplicationInfo.makeShortcut. */
@@ -240,25 +234,19 @@
}
@Override
- void onAddToDatabase(Context context, ContentValues values) {
- super.onAddToDatabase(context, values);
+ void onAddToDatabase(ContentWriter writer) {
+ super.onAddToDatabase(writer);
+ writer.put(LauncherSettings.BaseLauncherColumns.TITLE, title)
+ .put(LauncherSettings.BaseLauncherColumns.INTENT, getPromisedIntent())
+ .put(LauncherSettings.Favorites.RESTORED, status);
- String titleStr = title != null ? title.toString() : null;
- values.put(LauncherSettings.BaseLauncherColumns.TITLE, titleStr);
-
- String uri = promisedIntent != null ? promisedIntent.toUri(0)
- : (intent != null ? intent.toUri(0) : null);
- values.put(LauncherSettings.BaseLauncherColumns.INTENT, uri);
- values.put(LauncherSettings.Favorites.RESTORED, status);
-
- if (!usingFallbackIcon && !usingLowResIcon) {
- writeBitmap(values, mIcon);
+ if (!usingLowResIcon) {
+ writer.putIcon(mIcon, user);
}
if (iconResource != null) {
- values.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE,
- iconResource.packageName);
- values.put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE,
- iconResource.resourceName);
+ writer.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE, iconResource.packageName)
+ .put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE,
+ iconResource.resourceName);
}
}
@@ -308,7 +296,7 @@
// TODO: Use cache for this
LauncherAppState launcherAppState = LauncherAppState.getInstance();
- Drawable unbadgedDrawable = launcherAppState.getShortcutManager()
+ Drawable unbadgedDrawable = DeepShortcutManager.getInstance(context)
.getShortcutIconDrawable(shortcutInfo,
launcherAppState.getInvariantDeviceProfile().fillResIconDpi);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 5e7fe6b..7758769 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -48,6 +48,7 @@
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
+import android.view.animation.Animation.AnimationListener;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
@@ -96,7 +97,7 @@
*/
public class Workspace extends PagedView
implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
- DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener,
+ DragController.DragListener, ViewGroup.OnHierarchyChangeListener,
Insettable, DropTargetSource {
private static final String TAG = "Launcher.Workspace";
@@ -182,18 +183,20 @@
// in all apps or customize mode)
public enum State {
- NORMAL (false, false),
- NORMAL_HIDDEN (false, false),
- SPRING_LOADED (false, true),
- OVERVIEW (true, true),
- OVERVIEW_HIDDEN (true, false);
+ NORMAL (false, false, LauncherLogProto.WORKSPACE),
+ NORMAL_HIDDEN (false, false, LauncherLogProto.ALLAPPS),
+ SPRING_LOADED (false, true, LauncherLogProto.WORKSPACE),
+ OVERVIEW (true, true, LauncherLogProto.OVERVIEW),
+ OVERVIEW_HIDDEN (true, false, LauncherLogProto.WIDGETS);
public final boolean shouldUpdateWidget;
public final boolean hasMultipleVisiblePages;
+ public final int containerType;
- State(boolean shouldUpdateWidget, boolean hasMultipleVisiblePages) {
+ State(boolean shouldUpdateWidget, boolean hasMultipleVisiblePages, int containerType) {
this.shouldUpdateWidget = shouldUpdateWidget;
this.hasMultipleVisiblePages = hasMultipleVisiblePages;
+ this.containerType = containerType;
}
}
@@ -1968,7 +1971,7 @@
CellLayout cl = ((CellLayout) getChildAt(i));
mScreenOrder.add(getIdForScreen(cl));
}
-
+ mLauncher.getUserEventDispatcher().logOverviewReorder();
mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
// Re-enable auto layout transitions for page deletion.
@@ -2048,6 +2051,20 @@
mOnStateChangeListener.prepareStateChange(toState, animated ? workspaceAnim : null);
}
+ onPrepareStateTransition(mState.hasMultipleVisiblePages);
+
+ StateTransitionListener listener = new StateTransitionListener();
+ if (animated) {
+ ValueAnimator stepAnimator = ValueAnimator.ofFloat(0, 1);
+ stepAnimator.addListener(listener);
+
+ workspaceAnim.play(stepAnimator);
+ workspaceAnim.addListener(listener);
+ } else {
+ listener.onAnimationStart(null);
+ listener.onAnimationEnd(null);
+ }
+
return workspaceAnim;
}
@@ -2100,9 +2117,7 @@
}
}
- @Override
- public void onLauncherTransitionPrepare(Launcher l, boolean animated,
- boolean multiplePagesVisible) {
+ public void onPrepareStateTransition(boolean multiplePagesVisible) {
mIsSwitchingState = true;
mTransitionProgress = 0;
@@ -2115,32 +2130,12 @@
hideCustomContentIfNecessary();
}
- @Override
- public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
- if (mPageIndicator != null) {
- boolean isNewStateSpringLoaded = mState == State.SPRING_LOADED;
- mPageIndicator.setShouldAutoHide(!isNewStateSpringLoaded);
- if (isNewStateSpringLoaded) {
- // Show the page indicator at the same time as the rest of the transition.
- showPageIndicatorAtCurrentScroll();
- }
- }
- }
-
- @Override
- public void onLauncherTransitionStep(Launcher l, float t) {
- mTransitionProgress = t;
- }
-
- @Override
- public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
+ public void onEndStateTransition() {
mIsSwitchingState = false;
updateChildrenLayersEnabled(false);
showCustomContentIfNecessary();
mForceDrawAdjacentPages = false;
- if (mState == State.SPRING_LOADED) {
- showPageIndicatorAtCurrentScroll();
- }
+ mTransitionProgress = 1;
}
void updateCustomContentVisibility() {
@@ -4291,4 +4286,26 @@
public static final boolean isQsbContainerPage(int pageNo) {
return pageNo == 0;
}
+
+ private class StateTransitionListener extends AnimatorListenerAdapter
+ implements AnimatorUpdateListener {
+ @Override
+ public void onAnimationUpdate(ValueAnimator anim) {
+ mTransitionProgress = anim.getAnimatedFraction();
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (mState == State.SPRING_LOADED) {
+ // Show the page indicator at the same time as the rest of the transition.
+ showPageIndicatorAtCurrentScroll();
+ }
+ mTransitionProgress = 0;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ onEndStateTransition();
+ }
+ }
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 1cf4b39..1f36468 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -422,6 +422,11 @@
}
@Override
+ public void onAnimationStart(Animator animation) {
+ mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
mStateAnimator = null;
if (canceled) return;
@@ -434,6 +439,7 @@
} else {
overviewPanel.setAlpha(finalOverviewPanelAlpha);
AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled);
+ mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded);
qsbAlphaAnimation.end();
mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha).end();
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index e468d8d..5fc1d97 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -43,7 +43,6 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherTransitionable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -63,8 +62,7 @@
* The all apps view container.
*/
public class AllAppsContainerView extends BaseContainerView implements DragSource,
- LauncherTransitionable, View.OnLongClickListener, AllAppsSearchBarController.Callbacks,
- Insettable {
+ View.OnLongClickListener, AllAppsSearchBarController.Callbacks, Insettable {
private final Launcher mLauncher;
private final AlphabeticalAppsList mApps;
@@ -450,29 +448,6 @@
}
@Override
- public void onLauncherTransitionPrepare(Launcher l, boolean animated,
- boolean multiplePagesVisible) {
- // Do nothing
- }
-
- @Override
- public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
- // Do nothing
- }
-
- @Override
- public void onLauncherTransitionStep(Launcher l, float t) {
- // Do nothing
- }
-
- @Override
- public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
- if (toWorkspace) {
- reset();
- }
- }
-
- @Override
public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
if (apps != null) {
if (mApps.setOrderedFilter(apps)) {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 53c12b5..e813bb4 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -79,7 +79,6 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.pageindicators.PageIndicatorDots;
-import com.android.launcher3.shortcuts.DeepShortcutsContainer;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.CircleRevealOutlineProvider;
@@ -388,6 +387,10 @@
return isEditingName() ? mFolderName : null;
}
+ public FolderIcon getFolderIcon() {
+ return mFolderIcon;
+ }
+
/**
* We need to handle touch events to prevent them from falling through to the workspace below.
*/
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index c2b97eb..395daa5 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -20,8 +20,16 @@
public class LoggerUtils {
private static final String TAG = "LoggerUtils";
- public static String getActionStr(LauncherLogProto.Action action) {
- switch(action.touch) {
+ private static String getCommandStr(Action action) {
+ switch (action.command) {
+ case Action.HOME_INTENT: return "HOME_INTENT";
+ case Action.BACK: return "BACK";
+ default: return "UNKNOWN";
+ }
+ }
+
+ private static String getTouchStr(Action action) {
+ switch (action.touch) {
case Action.TAP: return "TAP";
case Action.LONGPRESS: return "LONGPRESS";
case Action.DRAGDROP: return "DRAGDROP";
@@ -32,6 +40,14 @@
}
}
+ public static String getActionStr(LauncherLogProto.Action action) {
+ switch (action.type) {
+ case Action.TOUCH: return getTouchStr(action);
+ case Action.COMMAND: return getCommandStr(action);
+ default: return "UNKNOWN";
+ }
+ }
+
public static String getTargetStr(Target t) {
String typeStr = "";
if (t == null){
@@ -61,6 +77,7 @@
case LauncherLogProto.DEEPSHORTCUT: typeStr = "DEEPSHORTCUT"; break;
case LauncherLogProto.FOLDER_ICON: typeStr = "FOLDERICON"; break;
case LauncherLogProto.SEARCHBOX: typeStr = "SEARCHBOX"; break;
+ case LauncherLogProto.EDITTEXT: typeStr = "EDITTEXT"; break;
default: typeStr = "UNKNOWN";
}
@@ -173,23 +190,41 @@
}
/**
+ * Used for commands.
+ */
+ public static LauncherLogProto.LauncherEvent initLauncherEvent(int command,
+ boolean createSrcTarget) {
+ LauncherLogProto.LauncherEvent event = new LauncherLogProto.LauncherEvent();
+ event.action = new LauncherLogProto.Action();
+ event.action.type = Action.COMMAND;
+ event.action.command = command;
+ event.srcTarget = null;
+
+ if (createSrcTarget) {
+ event.srcTarget = new LauncherLogProto.Target[1];
+ event.srcTarget[0] = new LauncherLogProto.Target();
+ event.srcTarget[0].type = Target.CONTAINER;
+ }
+ return event;
+ }
+
+ /**
* Used for drag and drop interaction.
*/
public static LauncherLogProto.LauncherEvent initLauncherEvent(
int actionType,
- View v,
ItemInfo info,
int parentSrcTargetType,
View parentDestTargetType){
LauncherLogProto.LauncherEvent event = new LauncherLogProto.LauncherEvent();
event.srcTarget = new LauncherLogProto.Target[2];
- event.srcTarget[0] = initTarget(v, info);
+ event.srcTarget[0] = initTarget(info);
event.srcTarget[1] = new LauncherLogProto.Target();
event.srcTarget[1].type = parentSrcTargetType;
event.destTarget = new LauncherLogProto.Target[2];
- event.destTarget[0] = initTarget(v, info);
+ event.destTarget[0] = initTarget(info);
event.destTarget[1] = initDropTarget(parentDestTargetType);
event.action = new LauncherLogProto.Action();
@@ -197,7 +232,7 @@
return event;
}
- private static Target initTarget(View v, ItemInfo info) {
+ private static Target initTarget(ItemInfo info) {
Target t = new LauncherLogProto.Target();
t.type = Target.ITEM;
switch (info.itemType) {
@@ -243,6 +278,6 @@
if (!(v.getTag() instanceof ItemInfo)) {
return t;
}
- return initTarget(v, (ItemInfo) v.getTag());
+ return initTarget((ItemInfo) v.getTag());
}
}
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 441d8e5..2fcdd39 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -27,6 +27,7 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -116,29 +117,35 @@
Action.TOUCH, v, Target.CONTAINER);
event.action.touch = Action.TAP;
- // Fill in grid(x,y), pageIndex of the child and container type of the parent
- // TODO: make this percolate up the view hierarchy if needed.
+ // TODO: make idx percolate up the view hierarchy if needed.
int idx = 0;
- LogContainerProvider provider = getLaunchProviderRecursive(v);
- if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
- return null;
- }
- ItemInfo itemInfo = (ItemInfo) v.getTag();
- provider.fillInLogContainerData(v, itemInfo, event.srcTarget[idx], event.srcTarget[idx + 1]);
-
- event.srcTarget[idx].intentHash = intent.hashCode();
- ComponentName cn = intent.getComponent();
- if (cn != null) {
- event.srcTarget[idx].packageNameHash = cn.getPackageName().hashCode();
- event.srcTarget[idx].componentHash = cn.hashCode();
- if (mPredictedApps != null) {
- event.srcTarget[idx].predictedRank = mPredictedApps.indexOf(
- new ComponentKey(cn, itemInfo.user));
+ if (fillInLogContainerData(event, v)) {
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ event.srcTarget[idx].intentHash = intent.hashCode();
+ ComponentName cn = intent.getComponent();
+ if (cn != null) {
+ event.srcTarget[idx].packageNameHash = cn.getPackageName().hashCode();
+ event.srcTarget[idx].componentHash = cn.hashCode();
+ if (mPredictedApps != null) {
+ event.srcTarget[idx].predictedRank = mPredictedApps.indexOf(
+ new ComponentKey(cn, itemInfo.user));
+ }
}
}
return event;
}
+ public boolean fillInLogContainerData(LauncherEvent event, View v) {
+ // Fill in grid(x,y), pageIndex of the child and container type of the parent
+ LogContainerProvider provider = getLaunchProviderRecursive(v);
+ if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
+ return false;
+ }
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ provider.fillInLogContainerData(v, itemInfo, event.srcTarget[0], event.srcTarget[1]);
+ return true;
+ }
+
public void logAppLaunch(View v, Intent intent) {
LauncherEvent ev = createLauncherEvent(v, intent);
if (ev == null) {
@@ -147,10 +154,30 @@
dispatchUserEvent(ev, intent);
}
- public void logActionOnItem(int action, int itemType) {
- LauncherEvent event = LoggerUtils.initLauncherEvent(Action.TOUCH, Target.ITEM);
- event.action.touch = action;
- event.srcTarget[0].itemType = itemType;
+ public void logActionCommand(int command, int containerType) {
+ logActionCommand(command, containerType, 0);
+ }
+
+ public void logActionCommand(int command, int containerType, int pageIndex) {
+ LauncherEvent event = LoggerUtils.initLauncherEvent(command, true);
+ event.srcTarget[0].containerType = containerType;
+ event.srcTarget[0].pageIndex = pageIndex;
+ dispatchUserEvent(event, null);
+ }
+
+ /**
+ * TODO: Make this function work when a container view is passed as the 2nd param.
+ */
+ public void logActionCommand(int command, View itemView, int containerType) {
+ LauncherEvent event = LoggerUtils.initLauncherEvent(Action.COMMAND, itemView,
+ Target.CONTAINER);
+ event.action.command = command;
+ if (fillInLogContainerData(event, itemView)) {
+ // TODO: Remove the following two lines once fillInLogContainerData can take in a
+ // container view.
+ event.srcTarget[0].type = Target.CONTAINER;
+ event.srcTarget[0].containerType = containerType;
+ }
dispatchUserEvent(event, null);
}
@@ -193,9 +220,27 @@
mPredictedApps = predictedApps;
}
+ /* Currently we are only interested in whether this event happens or not and don't
+ * care about which screen moves to where. */
+ public void logOverviewReorder() {
+ LauncherEvent event = new LauncherLogProto.LauncherEvent();
+
+ event.srcTarget = new LauncherLogProto.Target[2];
+ event.srcTarget[0] = new LauncherLogProto.Target();
+ event.srcTarget[0].type = Target.CONTAINER;
+ event.srcTarget[0].containerType = LauncherLogProto.WORKSPACE;
+ event.srcTarget[1] = new LauncherLogProto.Target();
+ event.srcTarget[1].type = Target.CONTAINER;
+ event.srcTarget[1].containerType = LauncherLogProto.OVERVIEW;
+
+ event.action = new LauncherLogProto.Action();
+ event.action.type = Action.TOUCH;
+ event.action.touch = Action.DRAGDROP;
+ dispatchUserEvent(event, null);
+
+ }
public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) {
LauncherEvent event = LoggerUtils.initLauncherEvent(Action.TOUCH,
- dragObj.dragView,
dragObj.originalDragInfo,
Target.CONTAINER,
dropTargetAsView);
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index c18eeef..29defdd 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -26,6 +26,7 @@
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
@@ -123,8 +124,8 @@
ShortcutKey pinnedShortcut = ShortcutKey.fromShortcutInfo((ShortcutInfo) item);
MutableInt count = pinnedShortcutCounts.get(pinnedShortcut);
if (count == null || --count.value == 0) {
- LauncherAppState.getInstance()
- .getShortcutManager().unpinShortcut(pinnedShortcut);
+ DeepShortcutManager.getInstance(LauncherAppState.getInstance().getContext())
+ .unpinShortcut(pinnedShortcut);
}
// Fall through.
}
@@ -161,7 +162,7 @@
// Since this is a new item, pin the shortcut in the system server.
if (newItem && count.value == 1) {
- LauncherAppState.getInstance().getShortcutManager()
+ DeepShortcutManager.getInstance(LauncherAppState.getInstance().getContext())
.pinShortcut(pinnedShortcut);
}
// Fall through
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 7286bf5..176e8ea 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -87,6 +87,7 @@
final int N = packages.length;
FlagOp flagOp = FlagOp.NO_OP;
final HashSet<String> packageSet = new HashSet<>(Arrays.asList(packages));
+ ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(packageSet, mUser);
switch (mOp) {
case OP_ADD: {
for (int i = 0; i < N; i++) {
@@ -135,15 +136,15 @@
FlagOp.addFlag(ShortcutInfo.FLAG_DISABLED_SUSPENDED) :
FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_SUSPENDED);
if (DEBUG) Log.d(TAG, "mAllAppsList.(un)suspend " + N);
- appsList.updateDisabledFlags(
- ItemInfoMatcher.ofPackages(packageSet, mUser), flagOp);
+ appsList.updateDisabledFlags(matcher, flagOp);
break;
case OP_USER_AVAILABILITY_CHANGE:
flagOp = UserManagerCompat.getInstance(context).isQuietModeEnabled(mUser)
? FlagOp.addFlag(ShortcutInfo.FLAG_DISABLED_QUIET_USER)
: FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_QUIET_USER);
// We want to update all packages for this user.
- appsList.updateDisabledFlags(ItemInfoMatcher.ofUser(mUser), flagOp);
+ matcher = ItemInfoMatcher.ofUser(mUser);
+ appsList.updateDisabledFlags(matcher, flagOp);
break;
}
@@ -213,16 +214,15 @@
si.iconResource.resourceName, context);
if (icon != null) {
si.setIcon(icon);
- si.usingFallbackIcon = false;
infoUpdated = true;
}
}
ComponentName cn = si.getTargetComponent();
- if (cn != null && packageSet.contains(cn.getPackageName())) {
+ if (cn != null && matcher.matches(si, cn)) {
AppInfo appInfo = addedOrUpdatedApps.get(cn);
- if (si.isPromise()) {
+ if (si.isPromise() && mOp == OP_ADD) {
if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
// Auto install icon
PackageManager pm = context.getPackageManager();
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index 8f7c21d..3314353 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -51,7 +51,8 @@
@Override
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
- DeepShortcutManager deepShortcutManager = app.getShortcutManager();
+ final Context context = app.getContext();
+ DeepShortcutManager deepShortcutManager = DeepShortcutManager.getInstance(context);
deepShortcutManager.onShortcutsChanged(mShortcuts);
// Find ShortcutInfo's that have changed on the workspace.
@@ -67,7 +68,6 @@
}
}
- final Context context = LauncherAppState.getInstance().getContext();
final ArrayList<ShortcutInfo> updatedShortcutInfos = new ArrayList<>();
if (!idsToWorkspaceShortcutInfos.isEmpty()) {
// Update the workspace to reflect the changes to updated shortcuts residing on it.
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index b7b52a4..a89fe0b 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -50,7 +50,7 @@
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
Context context = app.getContext();
boolean isUserUnlocked = UserManagerCompat.getInstance(context).isUserUnlocked(mUser);
- DeepShortcutManager deepShortcutManager = app.getShortcutManager();
+ DeepShortcutManager deepShortcutManager = DeepShortcutManager.getInstance(context);
HashMap<ShortcutKey, ShortcutInfoCompat> pinnedShortcuts = new HashMap<>();
if (isUserUnlocked) {
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
index c2c7c17..41f1a47 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -45,10 +45,22 @@
private static final int FLAG_GET_ALL = ShortcutQuery.FLAG_MATCH_DYNAMIC
| ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_PINNED;
+ private static DeepShortcutManager sInstance;
+ private static final Object sInstanceLock = new Object();
+
+ public static DeepShortcutManager getInstance(Context context) {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ sInstance = new DeepShortcutManager(context.getApplicationContext());
+ }
+ return sInstance;
+ }
+ }
+
private final LauncherApps mLauncherApps;
private boolean mWasLastCallSuccess;
- public DeepShortcutManager(Context context, ShortcutCache shortcutCache) {
+ private DeepShortcutManager(Context context) {
mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
}
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
index 08ca242..314a862 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
@@ -52,7 +52,6 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherViewPropertyAnimator;
@@ -103,7 +102,7 @@
public DeepShortcutsContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLauncher = Launcher.getLauncher(context);
- mDeepShortcutsManager = LauncherAppState.getInstance().getShortcutManager();
+ mDeepShortcutsManager = DeepShortcutManager.getInstance(context);
mStartDragThreshold = getResources().getDimensionPixelSize(
R.dimen.deep_shortcuts_start_drag_threshold);
diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java
new file mode 100644
index 0000000..33d979c
--- /dev/null
+++ b/src/com/android/launcher3/util/ContentWriter.java
@@ -0,0 +1,98 @@
+package com.android.launcher3.util;
+
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+
+/**
+ * A wrapper around {@link ContentValues} with some utility methods.
+ */
+public class ContentWriter {
+
+ private final ContentValues mValues;
+ private final Context mContext;
+
+ private Bitmap mIcon;
+ private UserHandleCompat mUser;
+
+ public ContentWriter(Context context) {
+ this(new ContentValues(), context);
+ }
+
+ public ContentWriter(ContentValues values, Context context) {
+ mValues = values;
+ mContext = context;
+ }
+
+ public ContentWriter put(String key, Integer value) {
+ mValues.put(key, value);
+ return this;
+ }
+
+ public ContentWriter put(String key, Long value) {
+ mValues.put(key, value);
+ return this;
+ }
+
+ public ContentWriter put(String key, String value) {
+ mValues.put(key, value);
+ return this;
+ }
+
+ public ContentWriter put(String key, CharSequence value) {
+ mValues.put(key, value == null ? null : value.toString());
+ return this;
+ }
+
+ public ContentWriter put(String key, Intent value) {
+ mValues.put(key, value == null ? null : value.toUri(0));
+ return this;
+ }
+
+ public ContentWriter putIcon(Bitmap value, UserHandleCompat user) {
+ mIcon = value;
+ mUser = user;
+ return this;
+ }
+
+ public ContentWriter put(String key, UserHandleCompat user) {
+ return put(key, UserManagerCompat.getInstance(mContext).getSerialNumberForUser(user));
+ }
+
+ /**
+ * Commits any pending validation and returns the final values.
+ * Must not be called on UI thread.
+ */
+ public ContentValues getValues() {
+ Preconditions.assertNonUiThread();
+ if (mIcon != null && !LauncherAppState.getInstance().getIconCache()
+ .isDefaultIcon(mIcon, mUser)) {
+ mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(mIcon));
+ mIcon = null;
+ }
+ return mValues;
+ }
+}
diff --git a/src/com/android/launcher3/util/PendingRequestArgs.java b/src/com/android/launcher3/util/PendingRequestArgs.java
index bade967..8eea28b 100644
--- a/src/com/android/launcher3/util/PendingRequestArgs.java
+++ b/src/com/android/launcher3/util/PendingRequestArgs.java
@@ -73,7 +73,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
ContentValues itemValues = new ContentValues();
- writeToValues(itemValues);
+ writeToValues(new ContentWriter(itemValues, null));
itemValues.writeToParcel(dest, flags);
dest.writeInt(mArg1);
diff --git a/tests/src/com/android/launcher3/BindWidgetTest.java b/tests/src/com/android/launcher3/BindWidgetTest.java
index c133bf6..6be2522 100644
--- a/tests/src/com/android/launcher3/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/BindWidgetTest.java
@@ -17,6 +17,7 @@
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.ui.LauncherInstrumentationTestCase;
+import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.WidgetHostViewLoader;
@@ -218,14 +219,14 @@
mResolver.insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
// Insert the item
- v = new ContentValues();
+ ContentWriter writer = new ContentWriter(mTargetContext);
item.id = LauncherSettings.Settings.call(
mResolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
.getLong(LauncherSettings.Settings.EXTRA_VALUE);
item.screenId = screenId;
- item.onAddToDatabase(mTargetContext, v);
- v.put(LauncherSettings.Favorites._ID, item.id);
- mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, v);
+ item.onAddToDatabase(writer);
+ writer.put(LauncherSettings.Favorites._ID, item.id);
+ mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues());
// Reset loader
try {