merge in jb-release history after reset to master
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 4e4360a..03dfee6 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -33,7 +33,7 @@
<string name="external_drop_widget_pick_title" msgid="7040647073452295370">"Pilih widget untuk membuat"</string>
<string name="rename_folder_label" msgid="5646236631298452787">"Nama folder"</string>
<string name="rename_folder_title" msgid="4544573104191526550">"Ganti nama folder"</string>
- <string name="rename_action" msgid="6016003384693240896">"OK"</string>
+ <string name="rename_action" msgid="6016003384693240896">"Oke"</string>
<string name="cancel_action" msgid="3811860427489435048">"Batal"</string>
<string name="menu_item_add_item" msgid="6233177331075781114">"Tambahkan ke Layar Utama"</string>
<string name="group_applications" msgid="2103752818818161976">"Apl"</string>
@@ -97,7 +97,7 @@
<string name="folder_cling_title" msgid="4308949882377840953">"Atur apl Anda dengan folder"</string>
<string name="folder_cling_move_item" msgid="270598675060435169">"Untuk memindahkan apl, sentuh & tahan apl tersebut."</string>
<string name="folder_cling_create_folder" msgid="8352867485656129478">"Untuk membuat folder baru di layar Utama Anda, tumpuk satu apl di atas apl yang lain."</string>
- <string name="cling_dismiss" msgid="2780907108735868381">"OK"</string>
+ <string name="cling_dismiss" msgid="2780907108735868381">"Oke"</string>
<string name="folder_opened" msgid="1262064100943801533">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> kali <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="1335478160661137579">"Sentuh untuk menutup folder"</string>
<string name="folder_tap_to_rename" msgid="5201612989905472442">"Sentuh untuk menyimpan pengubahan nama"</string>
diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java
index 4518f90..9df6f32 100644
--- a/src/com/android/launcher2/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -16,8 +16,6 @@
import com.android.launcher.R;
public class AppWidgetResizeFrame extends FrameLayout {
-
- private ItemInfo mItemInfo;
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
private DragLayer mDragLayer;
@@ -49,11 +47,13 @@
private int mMinVSpan;
private int mDeltaX;
private int mDeltaY;
+ private int mDeltaXAddOn;
+ private int mDeltaYAddOn;
private int mBackgroundPadding;
private int mTouchTargetWidth;
- private int mExpandability[] = new int[4];
+ int[] mDirectionVector = new int[2];
final int SNAP_DURATION = 150;
final int BACKGROUND_PADDING = 24;
@@ -67,12 +67,11 @@
private Launcher mLauncher;
- public AppWidgetResizeFrame(Context context, ItemInfo itemInfo,
+ public AppWidgetResizeFrame(Context context,
LauncherAppWidgetHostView widgetView, CellLayout cellLayout, DragLayer dragLayer) {
super(context);
mLauncher = (Launcher) context;
- mItemInfo = itemInfo;
mCellLayout = cellLayout;
mWidgetView = widgetView;
mResizeMode = widgetView.getAppWidgetInfo().resizeMode;
@@ -130,6 +129,11 @@
final float density = mLauncher.getResources().getDisplayMetrics().density;
mBackgroundPadding = (int) Math.ceil(density * BACKGROUND_PADDING);
mTouchTargetWidth = 2 * mBackgroundPadding;
+
+ // When we create the resize frame, we first mark all cells as unoccupied. The appropriate
+ // cells (same if not resized, or different) will be marked as occupied when the resize
+ // frame is dismissed.
+ mCellLayout.markCellsAsUnoccupiedForView(mWidgetView);
}
public boolean beginResizeIfPointInRegion(int x, int y) {
@@ -147,8 +151,6 @@
mBaselineHeight = getMeasuredHeight();
mBaselineX = getLeft();
mBaselineY = getTop();
- mRunningHInc = 0;
- mRunningVInc = 0;
if (anyBordersActive) {
mLeftHandle.setAlpha(mLeftBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
@@ -156,8 +158,6 @@
mTopHandle.setAlpha(mTopBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
mBottomHandle.setAlpha(mBottomBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
}
- mCellLayout.getExpandabilityArrayForView(mWidgetView, mExpandability);
-
return anyBordersActive;
}
@@ -183,10 +183,14 @@
}
}
+ public void visualizeResizeForDelta(int deltaX, int deltaY) {
+ visualizeResizeForDelta(deltaX, deltaY, false);
+ }
+
/**
* Based on the deltas, we resize the frame, and, if needed, we resize the widget.
*/
- public void visualizeResizeForDelta(int deltaX, int deltaY) {
+ private void visualizeResizeForDelta(int deltaX, int deltaY, boolean onDismiss) {
updateDeltas(deltaX, deltaY);
DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
@@ -204,25 +208,31 @@
lp.height = mBaselineHeight + mDeltaY;
}
- resizeWidgetIfNeeded();
+ resizeWidgetIfNeeded(onDismiss);
requestLayout();
}
/**
* Based on the current deltas, we determine if and how to resize the widget.
*/
- private void resizeWidgetIfNeeded() {
+ private void resizeWidgetIfNeeded(boolean onDismiss) {
int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
- float hSpanIncF = 1.0f * mDeltaX / xThreshold - mRunningHInc;
- float vSpanIncF = 1.0f * mDeltaY / yThreshold - mRunningVInc;
+ int deltaX = mDeltaX + mDeltaXAddOn;
+ int deltaY = mDeltaY + mDeltaYAddOn;
+
+ float hSpanIncF = 1.0f * deltaX / xThreshold - mRunningHInc;
+ float vSpanIncF = 1.0f * deltaY / yThreshold - mRunningVInc;
int hSpanInc = 0;
int vSpanInc = 0;
int cellXInc = 0;
int cellYInc = 0;
+ int countX = mCellLayout.getCountX();
+ int countY = mCellLayout.getCountY();
+
if (Math.abs(hSpanIncF) > RESIZE_THRESHOLD) {
hSpanInc = Math.round(hSpanIncF);
}
@@ -230,58 +240,75 @@
vSpanInc = Math.round(vSpanIncF);
}
- if (hSpanInc == 0 && vSpanInc == 0) return;
+ if (!onDismiss && (hSpanInc == 0 && vSpanInc == 0)) return;
- // Before we change the widget, we clear the occupied cells associated with it.
- // The new set of occupied cells is marked below, once the layout params are updated.
- mCellLayout.markCellsAsUnoccupiedForView(mWidgetView);
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams();
+ int spanX = lp.cellHSpan;
+ int spanY = lp.cellVSpan;
+ int cellX = lp.useTmpCoords ? lp.tmpCellX : lp.cellX;
+ int cellY = lp.useTmpCoords ? lp.tmpCellY : lp.cellY;
+
+ int hSpanDelta = 0;
+ int vSpanDelta = 0;
+
// For each border, we bound the resizing based on the minimum width, and the maximum
// expandability.
if (mLeftBorderActive) {
- cellXInc = Math.max(-mExpandability[LEFT], hSpanInc);
+ cellXInc = Math.max(-cellX, hSpanInc);
cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc);
hSpanInc *= -1;
- hSpanInc = Math.min(mExpandability[LEFT], hSpanInc);
+ hSpanInc = Math.min(cellX, hSpanInc);
hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
- mRunningHInc -= hSpanInc;
+ hSpanDelta = -hSpanInc;
+
} else if (mRightBorderActive) {
- hSpanInc = Math.min(mExpandability[RIGHT], hSpanInc);
+ hSpanInc = Math.min(countX - (cellX + spanX), hSpanInc);
hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
- mRunningHInc += hSpanInc;
+ hSpanDelta = hSpanInc;
}
if (mTopBorderActive) {
- cellYInc = Math.max(-mExpandability[TOP], vSpanInc);
+ cellYInc = Math.max(-cellY, vSpanInc);
cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc);
vSpanInc *= -1;
- vSpanInc = Math.min(mExpandability[TOP], vSpanInc);
+ vSpanInc = Math.min(cellY, vSpanInc);
vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
- mRunningVInc -= vSpanInc;
+ vSpanDelta = -vSpanInc;
} else if (mBottomBorderActive) {
- vSpanInc = Math.min(mExpandability[BOTTOM], vSpanInc);
+ vSpanInc = Math.min(countY - (cellY + spanY), vSpanInc);
vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
- mRunningVInc += vSpanInc;
+ vSpanDelta = vSpanInc;
}
+ mDirectionVector[0] = 0;
+ mDirectionVector[1] = 0;
// Update the widget's dimensions and position according to the deltas computed above
if (mLeftBorderActive || mRightBorderActive) {
- lp.cellHSpan += hSpanInc;
- lp.cellX += cellXInc;
+ spanX += hSpanInc;
+ cellX += cellXInc;
+ mDirectionVector[0] = mLeftBorderActive ? -1 : 1;
}
if (mTopBorderActive || mBottomBorderActive) {
- lp.cellVSpan += vSpanInc;
- lp.cellY += cellYInc;
+ spanY += vSpanInc;
+ cellY += cellYInc;
+ mDirectionVector[1] = mTopBorderActive ? -1 : 1;
}
- // Update the expandability array, as we have changed the widget's size.
- mCellLayout.getExpandabilityArrayForView(mWidgetView, mExpandability);
+ if (!onDismiss && vSpanDelta == 0 && hSpanDelta == 0) return;
- // Update the cells occupied by this widget
- mCellLayout.markCellsAsOccupiedForView(mWidgetView);
+ if (mCellLayout.createAreaForResize(cellX, cellY, spanX, spanY, mWidgetView,
+ mDirectionVector, onDismiss)) {
+ lp.tmpCellX = cellX;
+ lp.tmpCellY = cellY;
+ lp.cellHSpan = spanX;
+ lp.cellVSpan = spanY;
+ mRunningVInc += vSpanDelta;
+ mRunningHInc += hSpanDelta;
+ }
+
mWidgetView.requestLayout();
}
@@ -289,16 +316,22 @@
* This is the final step of the resize. Here we save the new widget size and position
* to LauncherModel and animate the resize frame.
*/
- public void commitResizeForDelta(int deltaX, int deltaY) {
- visualizeResizeForDelta(deltaX, deltaY);
+ public void commitResize() {
+ resizeWidgetIfNeeded(true);
+ requestLayout();
+ }
- CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams();
- LauncherModel.resizeItemInDatabase(getContext(), mItemInfo, lp.cellX, lp.cellY,
- lp.cellHSpan, lp.cellVSpan);
- mWidgetView.requestLayout();
+ public void onTouchUp() {
+ int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
+ int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
- // Once our widget resizes (hence the post), we want to snap the resize frame to it
+ mDeltaXAddOn = mRunningHInc * xThreshold;
+ mDeltaYAddOn = mRunningVInc * yThreshold;
+ mDeltaX = 0;
+ mDeltaY = 0;
+
post(new Runnable() {
+ @Override
public void run() {
snapToWidget(true);
}
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 636117b..35bdf14 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -1214,8 +1214,6 @@
// Determine the widget spans and min resize spans.
int[] spanXY = mLauncher.getSpanForWidget(info);
- int[] size = mLauncher.getWorkspace().estimateItemSize(spanXY[0],
- spanXY[1], createItemInfo, true);
createItemInfo.spanX = spanXY[0];
createItemInfo.spanY = spanXY[1];
int[] minSpanXY = mLauncher.getMinSpanForWidget(info);
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 0199d01..0c5bbeb 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -436,6 +436,8 @@
private void setVisibilityOfSiblingsWithLowerZOrder(int visibility) {
ViewGroup parent = (ViewGroup) getParent();
+ if (parent == null) return;
+
final int count = parent.getChildCount();
if (!isChildrenDrawingOrderEnabled()) {
for (int i = 0; i < count; i++) {
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index a775ed5..526fda7 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -20,8 +20,6 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region.Op;
@@ -30,8 +28,6 @@
import android.view.MotionEvent;
import android.widget.TextView;
-import com.android.launcher.R;
-
/**
* TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
* because we want to make the bubble taller than the text and TextView's clip is
@@ -85,7 +81,6 @@
mBackground = getBackground();
final Resources res = getContext().getResources();
- int bubbleColor = res.getColor(R.color.bubble_dark_background);
mFocusedOutlineColor = mFocusedGlowColor = mPressedOutlineColor = mPressedGlowColor =
res.getColor(android.R.color.holo_blue_light);
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index da7c2b0..a48a815 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -268,7 +268,9 @@
// If an animation is started and then stopped very quickly, we can still
// get spurious updates we've cleared the tag. Guard against this.
if (outline == null) {
- if (false) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
Object val = animation.getAnimatedValue();
Log.d(TAG, "anim " + thisIndex + " update: " + val +
", isStopped " + anim.isStopped());
@@ -2083,6 +2085,8 @@
if (info != null) {
info.cellX = lp.cellX = lp.tmpCellX;
info.cellY = lp.cellY = lp.tmpCellY;
+ info.spanX = lp.cellHSpan;
+ info.spanY = lp.cellVSpan;
}
}
mLauncher.getWorkspace().updateItemLocationsInDatabase(this);
@@ -2214,6 +2218,37 @@
setItemPlacementDirty(false);
}
+ boolean createAreaForResize(int cellX, int cellY, int spanX, int spanY,
+ View dragView, int[] direction, boolean commit) {
+ int[] pixelXY = new int[2];
+ regionToCenterPoint(cellX, cellY, spanX, spanY, pixelXY);
+
+ // First we determine if things have moved enough to cause a different layout
+ ItemConfiguration swapSolution = simpleSwap(pixelXY[0], pixelXY[1], spanX, spanY,
+ spanX, spanY, direction, dragView, true, new ItemConfiguration());
+
+ setUseTempCoords(true);
+ if (swapSolution != null && swapSolution.isSolution) {
+ // If we're just testing for a possible location (MODE_ACCEPT_DROP), we don't bother
+ // committing anything or animating anything as we just want to determine if a solution
+ // exists
+ copySolutionToTempState(swapSolution, dragView);
+ setItemPlacementDirty(true);
+ animateItemsToSolution(swapSolution, dragView, commit);
+
+ if (commit) {
+ commitTempPlacement();
+ completeAndClearReorderHintAnimations();
+ setItemPlacementDirty(false);
+ } else {
+ beginOrAdjustHintAnimations(swapSolution, dragView,
+ REORDER_ANIMATION_DURATION);
+ }
+ mShortcutsAndWidgets.requestLayout();
+ }
+ return swapSolution.isSolution;
+ }
+
int[] createArea(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX, int spanY,
View dragView, int[] result, int resultSpan[], int mode) {
// First we determine if things have moved enough to cause a different layout
@@ -2235,7 +2270,6 @@
mPreviousReorderDirection[0] = INVALID_DIRECTION;
mPreviousReorderDirection[1] = INVALID_DIRECTION;
}
-
} else {
getDirectionVectorForDrop(pixelX, pixelY, spanX, spanY, dragView, mDirectionVector);
mPreviousReorderDirection[0] = mDirectionVector[0];
@@ -2694,56 +2728,6 @@
}
}
- /**
- * Given a view, determines how much that view can be expanded in all directions, in terms of
- * whether or not there are other items occupying adjacent cells. Used by the
- * AppWidgetResizeFrame to determine how the widget can be resized.
- */
- public void getExpandabilityArrayForView(View view, int[] expandability) {
- final LayoutParams lp = (LayoutParams) view.getLayoutParams();
- boolean flag;
-
- expandability[AppWidgetResizeFrame.LEFT] = 0;
- for (int x = lp.cellX - 1; x >= 0; x--) {
- flag = false;
- for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) {
- if (mOccupied[x][y]) flag = true;
- }
- if (flag) break;
- expandability[AppWidgetResizeFrame.LEFT]++;
- }
-
- expandability[AppWidgetResizeFrame.TOP] = 0;
- for (int y = lp.cellY - 1; y >= 0; y--) {
- flag = false;
- for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) {
- if (mOccupied[x][y]) flag = true;
- }
- if (flag) break;
- expandability[AppWidgetResizeFrame.TOP]++;
- }
-
- expandability[AppWidgetResizeFrame.RIGHT] = 0;
- for (int x = lp.cellX + lp.cellHSpan; x < mCountX; x++) {
- flag = false;
- for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) {
- if (mOccupied[x][y]) flag = true;
- }
- if (flag) break;
- expandability[AppWidgetResizeFrame.RIGHT]++;
- }
-
- expandability[AppWidgetResizeFrame.BOTTOM] = 0;
- for (int y = lp.cellY + lp.cellVSpan; y < mCountY; y++) {
- flag = false;
- for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) {
- if (mOccupied[x][y]) flag = true;
- }
- if (flag) break;
- expandability[AppWidgetResizeFrame.BOTTOM]++;
- }
- }
-
public void onMove(View view, int newCellX, int newCellY, int newSpanX, int newSpanY) {
markCellsAsUnoccupiedForView(view);
markCellsForView(newCellX, newCellY, newSpanX, newSpanY, mOccupied, true);
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index aec8940..c9bebe3 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -40,7 +40,6 @@
* Class for initiating a drag within a view or across multiple views.
*/
public class DragController {
- @SuppressWarnings({"UnusedDeclaration"})
private static final String TAG = "Launcher.DragController";
/** Indicates the drag is a move. */
@@ -67,7 +66,7 @@
private Launcher mLauncher;
private Handler mHandler;
- private final Vibrator mVibrator = new Vibrator();
+ private final Vibrator mVibrator;
// temporaries to avoid gc thrash
private Rect mRectTemp = new Rect();
@@ -111,6 +110,7 @@
private InputMethodManager mInputMethodManager;
private int mLastTouch[] = new int[2];
+ private long mLastTouchUpTime = -1;
private int mDistanceSinceScroll = 0;
private int mTmpPoint[] = new int[2];
@@ -150,6 +150,7 @@
mHandler = new Handler();
mScrollZone = launcher.getResources().getDimensionPixelSize(R.dimen.scroll_zone);
mVelocityTracker = VelocityTracker.obtain();
+ mVibrator = (Vibrator)launcher.getSystemService(Context.VIBRATOR_SERVICE);
float density = launcher.getResources().getDisplayMetrics().density;
mFlingToDeleteThresholdVelocity = (int) (FLING_TO_DELETE_THRESHOLD_Y_VELOCITY * density);
@@ -346,7 +347,6 @@
* || super.dispatchKeyEvent(event);
* </pre>
*/
- @SuppressWarnings({"UnusedDeclaration"})
public boolean dispatchKeyEvent(KeyEvent event) {
return mDragging;
}
@@ -440,11 +440,25 @@
return mTmpPoint;
}
+ long getLastGestureUpTime() {
+ if (mDragging) {
+ return System.currentTimeMillis();
+ } else {
+ return mLastTouchUpTime;
+ }
+ }
+
+ void resetLastGestureUpTime() {
+ mLastTouchUpTime = -1;
+ }
+
/**
* Call this from a drag source view.
*/
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (false) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " mDragging="
+ mDragging);
}
@@ -467,6 +481,7 @@
mLastDropTarget = null;
break;
case MotionEvent.ACTION_UP:
+ mLastTouchUpTime = System.currentTimeMillis();
if (mDragging) {
PointF vec = isFlingingToDelete(mDragObject.dragSource);
if (vec != null) {
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 9452857..f71baec 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -23,9 +23,6 @@
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
@@ -34,7 +31,6 @@
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -242,7 +238,8 @@
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
+ mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
+ mCurrentResizeFrame.onTouchUp();
mCurrentResizeFrame = null;
}
}
@@ -383,6 +380,7 @@
public void clearAllResizeFrames() {
if (mResizeFrames.size() > 0) {
for (AppWidgetResizeFrame frame: mResizeFrames) {
+ frame.commitResize();
removeView(frame);
}
mResizeFrames.clear();
@@ -400,7 +398,7 @@
public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
CellLayout cellLayout) {
AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
- itemInfo, widget, cellLayout, this);
+ widget, cellLayout, this);
LayoutParams lp = new LayoutParams(-1, -1);
lp.customPosition = true;
diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java
index a6aa595..b6645e1 100644
--- a/src/com/android/launcher2/DragView.java
+++ b/src/com/android/launcher2/DragView.java
@@ -167,8 +167,9 @@
@Override
protected void onDraw(Canvas canvas) {
- if (false) {
- // for debugging
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
Paint p = new Paint();
p.setStyle(Paint.Style.FILL);
p.setColor(0x66ffffff);
diff --git a/src/com/android/launcher2/DrawableStateProxyView.java b/src/com/android/launcher2/DrawableStateProxyView.java
index 498730f..dac9584 100644
--- a/src/com/android/launcher2/DrawableStateProxyView.java
+++ b/src/com/android/launcher2/DrawableStateProxyView.java
@@ -18,12 +18,8 @@
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.view.View;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.launcher.R;
diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
index ecc9d9c..0066440 100644
--- a/src/com/android/launcher2/FocusHelper.java
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -626,7 +626,6 @@
int lineDelta) {
final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
- final int cellCountX = layout.getCountX();
final int cellCountY = layout.getCountY();
final int row = lp.cellY;
final int newRow = row + lineDelta;
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index c502fb7..fcaf020 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -44,7 +44,6 @@
import android.widget.TextView;
import com.android.launcher.R;
-import com.android.launcher2.DropTarget.DragObject;
import com.android.launcher2.FolderInfo.FolderListener;
import java.util.ArrayList;
@@ -56,6 +55,7 @@
View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener,
View.OnFocusChangeListener {
+ @SuppressWarnings("unused")
private static final String TAG = "Launcher.Folder";
protected DragController mDragController;
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index 513fa6b..2377f30 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -119,8 +119,9 @@
static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
FolderInfo folderInfo, IconCache iconCache) {
-
- if (INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION;
+ if (error) {
throw new IllegalStateException("DROP_IN_ANIMATION_DURATION must be greater than " +
"INITIAL_ITEM_ANIMATION_DURATION, as sequencing of adding first two items " +
"is dependent on this");
diff --git a/src/com/android/launcher2/Hotseat.java b/src/com/android/launcher2/Hotseat.java
index fbb45b9..a6c9fb2 100644
--- a/src/com/android/launcher2/Hotseat.java
+++ b/src/com/android/launcher2/Hotseat.java
@@ -28,6 +28,7 @@
import com.android.launcher.R;
public class Hotseat extends FrameLayout {
+ @SuppressWarnings("unused")
private static final String TAG = "Hotseat";
private Launcher mLauncher;
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index 1e8379d..efa9fac 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -33,6 +33,7 @@
* Cache of application icons. Icons can be made from any thread.
*/
public class IconCache {
+ @SuppressWarnings("unused")
private static final String TAG = "Launcher.IconCache";
private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index 4c0974f..19b1c69 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -56,7 +56,6 @@
String spKey = LauncherApplication.getSharedPreferencesKey();
SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
- final int screen = Launcher.getScreen();
final Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
if (intent == null) {
return;
@@ -74,17 +73,23 @@
}
}
- final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
- final boolean exists = LauncherModel.shortcutExists(context, name, intent);
+ // Lock on the app so that we don't try and get the items while apps are being added
+ LauncherApplication app = (LauncherApplication) context.getApplicationContext();
final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL};
-
- // Try adding the target to the workspace screens incrementally, starting at the current
- // screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
boolean found = false;
- for (int i = 0; i < (2 * Launcher.SCREEN_COUNT) + 1 && !found; ++i) {
- int si = screen + (int) ((i / 2f) + 0.5f) * ((i % 2 == 1) ? 1 : -1);
- if (0 <= si && si < Launcher.SCREEN_COUNT) {
- found = installShortcut(context, data, items, name, intent, si, exists, sp, result);
+ synchronized (app) {
+ final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
+ final boolean exists = LauncherModel.shortcutExists(context, name, intent);
+
+ // Try adding to the workspace screens incrementally, starting at the default or center
+ // screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
+ final int screen = Launcher.DEFAULT_SCREEN;
+ for (int i = 0; i < (2 * Launcher.SCREEN_COUNT) + 1 && !found; ++i) {
+ int si = screen + (int) ((i / 2f) + 0.5f) * ((i % 2 == 1) ? 1 : -1);
+ if (0 <= si && si < Launcher.SCREEN_COUNT) {
+ found = installShortcut(context, data, items, name, intent, si, exists, sp,
+ result);
+ }
}
}
@@ -102,8 +107,8 @@
}
private boolean installShortcut(Context context, Intent data, ArrayList<ItemInfo> items,
- String name, Intent intent, int screen, boolean shortcutExists,
- SharedPreferences sharedPrefs, int[] result) {
+ String name, Intent intent, final int screen, boolean shortcutExists,
+ final SharedPreferences sharedPrefs, int[] result) {
if (findEmptyCell(context, items, mCoordinates, screen)) {
if (intent != null) {
if (intent.getAction() == null) {
@@ -122,10 +127,15 @@
newApps = sharedPrefs.getStringSet(NEW_APPS_LIST_KEY, newApps);
}
newApps.add(intent.toUri(0).toString());
- sharedPrefs.edit()
- .putInt(NEW_APPS_PAGE_KEY, screen)
- .putStringSet(NEW_APPS_LIST_KEY, newApps)
- .commit();
+ final Set<String> savedNewApps = newApps;
+ new Thread("setNewAppsThread") {
+ public void run() {
+ sharedPrefs.edit()
+ .putInt(NEW_APPS_PAGE_KEY, screen)
+ .putStringSet(NEW_APPS_LIST_KEY, savedNewApps)
+ .commit();
+ }
+ }.start();
// Update the Launcher db
LauncherApplication app = (LauncherApplication) context.getApplicationContext();
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 97c8373..5965b5c 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -26,8 +26,6 @@
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
import android.app.SearchManager;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
@@ -40,7 +38,6 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
@@ -55,17 +52,16 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Debug;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
+import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.text.Selection;
import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.Log;
import android.view.Display;
@@ -85,11 +81,9 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.Advanceable;
-import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -123,6 +117,7 @@
static final boolean PROFILE_STARTUP = false;
static final boolean DEBUG_WIDGETS = false;
+ static final boolean DEBUG_STRICT_MODE = false;
private static final int MENU_GROUP_WALLPAPER = 1;
private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 1;
@@ -142,9 +137,6 @@
static final int SCREEN_COUNT = 5;
static final int DEFAULT_SCREEN = 2;
- static final int DIALOG_CREATE_SHORTCUT = 1;
- static final int DIALOG_RENAME_FOLDER = 2;
-
private static final String PREFERENCES = "launcher.preferences";
static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher.force_enable_rotation";
@@ -182,6 +174,9 @@
private static final Object sLock = new Object();
private static int sScreen = DEFAULT_SCREEN;
+ // How long to wait before the new-shortcut animation automatically pans the workspace
+ private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 10;
+
private final BroadcastReceiver mCloseSystemDialogsReceiver
= new CloseSystemDialogsIntentReceiver();
private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();
@@ -289,6 +284,21 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
+ if (DEBUG_STRICT_MODE) {
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectDiskReads()
+ .detectDiskWrites()
+ .detectNetwork() // or .detectAll() for all detectable problems
+ .penaltyLog()
+ .build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectLeakedSqlLiteObjects()
+ .detectLeakedClosableObjects()
+ .penaltyLog()
+ .penaltyDeath()
+ .build());
+ }
+
super.onCreate(savedInstanceState);
LauncherApplication app = ((LauncherApplication)getApplication());
mSharedPrefs = getSharedPreferences(LauncherApplication.getSharedPreferencesKey(),
@@ -635,6 +645,7 @@
super.onPause();
mPaused = true;
mDragController.cancelDrag();
+ mDragController.resetLastGestureUpTime();
}
@Override
@@ -1241,23 +1252,6 @@
void closeSystemDialogs() {
getWindow().closeAllPanels();
- /**
- * We should remove this code when we remove all the dialog code.
- try {
- dismissDialog(DIALOG_CREATE_SHORTCUT);
- // Unlock the workspace if the dialog was showing
- } catch (Exception e) {
- // An exception is thrown if the dialog is not visible, which is fine
- }
-
- try {
- dismissDialog(DIALOG_RENAME_FOLDER);
- // Unlock the workspace if the dialog was showing
- } catch (Exception e) {
- // An exception is thrown if the dialog is not visible, which is fine
- }
- */
-
// Whatever we were doing is hereby canceled.
mWaitingForResult = false;
}
@@ -1509,7 +1503,6 @@
void addAppWidgetImpl(final int appWidgetId, final PendingAddWidgetInfo info) {
final AppWidgetProviderInfo appWidget = info.info;
- Runnable configurationActivity = null;
if (appWidget.configure != null) {
// Launch over to configure widget, if needed
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
@@ -2102,130 +2095,6 @@
return mWorkspace;
}
- @Override
- protected Dialog onCreateDialog(int id) {
- switch (id) {
- case DIALOG_CREATE_SHORTCUT:
- return new CreateShortcut().createDialog();
- case DIALOG_RENAME_FOLDER:
- return new RenameFolder().createDialog();
- }
-
- return super.onCreateDialog(id);
- }
-
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch (id) {
- case DIALOG_CREATE_SHORTCUT:
- break;
- case DIALOG_RENAME_FOLDER:
- if (mFolderInfo != null) {
- EditText input = (EditText) dialog.findViewById(R.id.folder_name);
- final CharSequence text = mFolderInfo.title;
- input.setText(text);
- input.setSelection(0, text.length());
- }
- break;
- }
- }
-
- void showRenameDialog(FolderInfo info) {
- mFolderInfo = info;
- mWaitingForResult = true;
- showDialog(DIALOG_RENAME_FOLDER);
- }
-
- private void showAddDialog() {
- resetAddInfo();
- mPendingAddInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
- mPendingAddInfo.screen = mWorkspace.getCurrentPage();
- mWaitingForResult = true;
- showDialog(DIALOG_CREATE_SHORTCUT);
- }
-
- private class RenameFolder {
- private EditText mInput;
-
- Dialog createDialog() {
- final View layout = View.inflate(Launcher.this, R.layout.rename_folder, null);
- mInput = (EditText) layout.findViewById(R.id.folder_name);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
- builder.setIcon(0);
- builder.setTitle(getString(R.string.rename_folder_title));
- builder.setCancelable(true);
- builder.setOnCancelListener(new Dialog.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- cleanup();
- }
- });
- builder.setNegativeButton(getString(R.string.cancel_action),
- new Dialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- cleanup();
- }
- }
- );
- builder.setPositiveButton(getString(R.string.rename_action),
- new Dialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- changeFolderName();
- }
- }
- );
- builder.setView(layout);
-
- final AlertDialog dialog = builder.create();
- dialog.setOnShowListener(new DialogInterface.OnShowListener() {
- public void onShow(DialogInterface dialog) {
- mWaitingForResult = true;
- mInput.requestFocus();
- InputMethodManager inputManager = (InputMethodManager)
- getSystemService(Context.INPUT_METHOD_SERVICE);
- inputManager.showSoftInput(mInput, 0);
- }
- });
-
- return dialog;
- }
-
- private void changeFolderName() {
- final String name = mInput.getText().toString();
- if (!TextUtils.isEmpty(name)) {
- // Make sure we have the right folder info
- mFolderInfo = sFolders.get(mFolderInfo.id);
- mFolderInfo.title = name;
- LauncherModel.updateItemInDatabase(Launcher.this, mFolderInfo);
-
- if (mWorkspaceLoading) {
- lockAllApps();
- mModel.startLoader(false);
- } else {
- final FolderIcon folderIcon = (FolderIcon)
- mWorkspace.getViewForTag(mFolderInfo);
- if (folderIcon != null) {
- // TODO: At some point we'll probably want some version of setting
- // the text for a folder icon.
- //folderIcon.setText(name);
- getWorkspace().requestLayout();
- } else {
- lockAllApps();
- mWorkspaceLoading = true;
- mModel.startLoader(false);
- }
- }
- }
- cleanup();
- }
-
- private void cleanup() {
- dismissDialog(DIALOG_RENAME_FOLDER);
- mWaitingForResult = false;
- mFolderInfo = null;
- }
- }
-
// Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
public boolean isAllAppsVisible() {
return (mState == State.APPS_CUSTOMIZE);
@@ -2451,7 +2320,7 @@
}
}
});
- observer.removeGlobalOnLayoutListener(this);
+ observer.removeOnGlobalLayoutListener(this);
}
};
observer.addOnGlobalLayoutListener(delayedStart);
@@ -2953,83 +2822,6 @@
}
/**
- * Displays the shortcut creation dialog and launches, if necessary, the
- * appropriate activity.
- */
- private class CreateShortcut implements DialogInterface.OnClickListener,
- DialogInterface.OnCancelListener, DialogInterface.OnDismissListener,
- DialogInterface.OnShowListener {
-
- private AddAdapter mAdapter;
-
- Dialog createDialog() {
- mAdapter = new AddAdapter(Launcher.this);
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this,
- AlertDialog.THEME_HOLO_DARK);
- builder.setAdapter(mAdapter, this);
-
- AlertDialog dialog = builder.create();
- dialog.setOnCancelListener(this);
- dialog.setOnDismissListener(this);
- dialog.setOnShowListener(this);
-
- return dialog;
- }
-
- public void onCancel(DialogInterface dialog) {
- mWaitingForResult = false;
- cleanup();
- }
-
- public void onDismiss(DialogInterface dialog) {
- mWaitingForResult = false;
- cleanup();
- }
-
- private void cleanup() {
- try {
- dismissDialog(DIALOG_CREATE_SHORTCUT);
- } catch (Exception e) {
- // An exception is thrown if the dialog is not visible, which is fine
- }
- }
-
- /**
- * Handle the action clicked in the "Add to home" dialog.
- */
- public void onClick(DialogInterface dialog, int which) {
- cleanup();
-
- AddAdapter.ListItem item = (AddAdapter.ListItem) mAdapter.getItem(which);
- switch (item.actionTag) {
- case AddAdapter.ITEM_APPLICATION: {
- if (mAppsCustomizeTabHost != null) {
- mAppsCustomizeTabHost.selectAppsTab();
- }
- showAllApps(true);
- break;
- }
- case AddAdapter.ITEM_APPWIDGET: {
- if (mAppsCustomizeTabHost != null) {
- mAppsCustomizeTabHost.selectWidgetsTab();
- }
- showAllApps(true);
- break;
- }
- case AddAdapter.ITEM_WALLPAPER: {
- startWallpaper();
- break;
- }
- }
- }
-
- public void onShow(DialogInterface dialog) {
- mWaitingForResult = true;
- }
- }
-
- /**
* Receives notifications when system dialogs are to be closed.
*/
private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {
@@ -3250,27 +3042,46 @@
Runnable newAppsRunnable = new Runnable() {
@Override
public void run() {
- runNewAppsAnimation();
+ runNewAppsAnimation(false);
}
};
- if (mNewShortcutAnimatePage > -1 &&
- mNewShortcutAnimatePage != mWorkspace.getCurrentPage()) {
- mWorkspace.snapToPage(mNewShortcutAnimatePage, newAppsRunnable);
+
+ boolean willSnapPage = mNewShortcutAnimatePage > -1 &&
+ mNewShortcutAnimatePage != mWorkspace.getCurrentPage();
+ if (canRunNewAppsAnimation()) {
+ // If the user has not interacted recently, then either snap to the new page to show
+ // the new-apps animation or just run them if they are to appear on the current page
+ if (willSnapPage) {
+ mWorkspace.snapToPage(mNewShortcutAnimatePage, newAppsRunnable);
+ } else {
+ runNewAppsAnimation(false);
+ }
} else {
- newAppsRunnable.run();
+ // If the user has interacted recently, then just add the items in place if they
+ // are on another page (or just normally if they are added to the current page)
+ runNewAppsAnimation(willSnapPage);
}
}
mWorkspaceLoading = false;
}
+ private boolean canRunNewAppsAnimation() {
+ long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();
+ return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);
+ }
+
/**
* Runs a new animation that scales up icons that were added while Launcher was in the
* background.
+ *
+ * @param immediate whether to run the animation or show the results immediately
*/
- private void runNewAppsAnimation() {
+ private void runNewAppsAnimation(boolean immediate) {
AnimatorSet anim = new AnimatorSet();
Collection<Animator> bounceAnims = new ArrayList<Animator>();
+
+ // Order these new views spatially so that they animate in order
Collections.sort(mNewShortcutAnimateViews, new Comparator<View>() {
@Override
public int compare(View a, View b) {
@@ -3280,25 +3091,35 @@
return (alp.cellY * cellCountX + alp.cellX) - (blp.cellY * cellCountX + blp.cellX);
}
});
- for (int i = 0; i < mNewShortcutAnimateViews.size(); ++i) {
- View v = mNewShortcutAnimateViews.get(i);
- ValueAnimator bounceAnim = ObjectAnimator.ofPropertyValuesHolder(v,
- PropertyValuesHolder.ofFloat("alpha", 1f),
- PropertyValuesHolder.ofFloat("scaleX", 1f),
- PropertyValuesHolder.ofFloat("scaleY", 1f));
- bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);
- bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);
- bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());
- bounceAnims.add(bounceAnim);
- }
- anim.playTogether(bounceAnims);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mWorkspace.postDelayed(mBuildLayersRunnable, 500);
+
+ // Animate each of the views in place (or show them immediately if requested)
+ if (immediate) {
+ for (View v : mNewShortcutAnimateViews) {
+ v.setAlpha(1f);
+ v.setScaleX(1f);
+ v.setScaleY(1f);
}
- });
- anim.start();
+ } else {
+ for (int i = 0; i < mNewShortcutAnimateViews.size(); ++i) {
+ View v = mNewShortcutAnimateViews.get(i);
+ ValueAnimator bounceAnim = ObjectAnimator.ofPropertyValuesHolder(v,
+ PropertyValuesHolder.ofFloat("alpha", 1f),
+ PropertyValuesHolder.ofFloat("scaleX", 1f),
+ PropertyValuesHolder.ofFloat("scaleY", 1f));
+ bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);
+ bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);
+ bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());
+ bounceAnims.add(bounceAnim);
+ }
+ anim.playTogether(bounceAnims);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mWorkspace.postDelayed(mBuildLayersRunnable, 500);
+ }
+ });
+ anim.start();
+ }
// Clean up
mNewShortcutAnimatePage = -1;
@@ -3352,7 +3173,6 @@
*/
public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
setLoadOnResume();
- removeDialog(DIALOG_CREATE_SHORTCUT);
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.addApps(apps);
@@ -3366,7 +3186,6 @@
*/
public void bindAppsUpdated(ArrayList<ApplicationInfo> apps) {
setLoadOnResume();
- removeDialog(DIALOG_CREATE_SHORTCUT);
if (mWorkspace != null) {
mWorkspace.updateShortcuts(apps);
}
@@ -3382,7 +3201,6 @@
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAppsRemoved(ArrayList<ApplicationInfo> apps, boolean permanent) {
- removeDialog(DIALOG_CREATE_SHORTCUT);
if (permanent) {
mWorkspace.removeItems(apps);
}
diff --git a/src/com/android/launcher2/LauncherAppWidgetHostView.java b/src/com/android/launcher2/LauncherAppWidgetHostView.java
index d73dd30..e34196e 100644
--- a/src/com/android/launcher2/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher2/LauncherAppWidgetHostView.java
@@ -21,7 +21,6 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import com.android.launcher.R;
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index ef1eb5f..28362fd 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -25,7 +25,6 @@
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Handler;
-import android.view.MotionEvent;
import com.android.launcher.R;
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index a9c4970..efe4711 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -248,6 +248,7 @@
sWorker.post(r);
}
}
+
/**
* Move an item in the DB to a new <container, screen, cellX, cellY>
*/
@@ -276,24 +277,35 @@
}
/**
- * Resize an item in the DB to a new <spanX, spanY, cellX, cellY>
+ * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY>
*/
- static void resizeItemInDatabase(Context context, final ItemInfo item, final int cellX,
- final int cellY, final int spanX, final int spanY) {
- item.spanX = spanX;
- item.spanY = spanY;
+ static void modifyItemInDatabase(Context context, final ItemInfo item, final long container,
+ final int screen, final int cellX, final int cellY, final int spanX, final int spanY) {
+ item.container = container;
item.cellX = cellX;
item.cellY = cellY;
+ item.spanX = spanX;
+ item.spanY = spanY;
+
+ // We store hotseat items in canonical form which is this orientation invariant position
+ // in the hotseat
+ if (context instanceof Launcher && screen < 0 &&
+ container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+ item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
+ } else {
+ item.screen = screen;
+ }
final ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites.CONTAINER, item.container);
- values.put(LauncherSettings.Favorites.SPANX, spanX);
- values.put(LauncherSettings.Favorites.SPANY, spanY);
- values.put(LauncherSettings.Favorites.CELLX, cellX);
- values.put(LauncherSettings.Favorites.CELLY, cellY);
- updateItemInDatabaseHelper(context, values, item, "resizeItemInDatabase");
- }
+ values.put(LauncherSettings.Favorites.CELLX, item.cellX);
+ values.put(LauncherSettings.Favorites.CELLY, item.cellY);
+ values.put(LauncherSettings.Favorites.SPANX, item.spanX);
+ values.put(LauncherSettings.Favorites.SPANY, item.spanY);
+ values.put(LauncherSettings.Favorites.SCREEN, item.screen);
+ updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase");
+ }
/**
* Update an item to the database in a specified container.
@@ -1023,9 +1035,9 @@
(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(
LauncherSettings.Favorites.SPANY);
- final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
- final int displayModeIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.DISPLAY_MODE);
+ //final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
+ //final int displayModeIndex = c.getColumnIndexOrThrow(
+ // LauncherSettings.Favorites.DISPLAY_MODE);
ShortcutInfo info;
String intentDescription;
@@ -1813,7 +1825,9 @@
}
Bitmap getIconFromCursor(Cursor c, int iconIndex, Context context) {
- if (false) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
Log.d(TAG, "getIconFromCursor app="
+ c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE)));
}
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 4149ab6..d2aa31f 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -31,6 +31,7 @@
void iconPressed(PagedViewIcon icon);
}
+ @SuppressWarnings("unused")
private static final String TAG = "PagedViewIcon";
private static final float PRESS_ALPHA = 0.4f;
diff --git a/src/com/android/launcher2/RocketLauncher.java b/src/com/android/launcher2/RocketLauncher.java
index 505ac4c..268769d 100644
--- a/src/com/android/launcher2/RocketLauncher.java
+++ b/src/com/android/launcher2/RocketLauncher.java
@@ -332,7 +332,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setLayerType(View.LAYER_TYPE_HARDWARE, null);
- setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+ setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
reset();
mAnim.start();
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 76d7076..30978a8 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -246,7 +246,7 @@
mQSBSearchBar.setBackgroundResource(0);
} else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
// Restore the background
- mQSBSearchBar.setBackgroundDrawable(mPreviousBackground);
+ mQSBSearchBar.setBackground(mPreviousBackground);
}
}
}
diff --git a/src/com/android/launcher2/ShortcutAndWidgetContainer.java b/src/com/android/launcher2/ShortcutAndWidgetContainer.java
index 7e5e940..8bebdcd 100644
--- a/src/com/android/launcher2/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher2/ShortcutAndWidgetContainer.java
@@ -24,8 +24,6 @@
import android.view.View;
import android.view.ViewGroup;
-import com.android.launcher2.CellLayout.LayoutParams;
-
public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "CellLayoutChildren";
@@ -73,8 +71,10 @@
@Override
protected void dispatchDraw(Canvas canvas) {
- // Debug drawing for hit space
- if (false) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
+ // Debug drawing for hit space
Paint p = new Paint();
p.setColor(0x6600FF00);
for (int i = getChildCount() - 1; i >= 0; i--) {
diff --git a/src/com/android/launcher2/UninstallShortcutReceiver.java b/src/com/android/launcher2/UninstallShortcutReceiver.java
index eb4ee4c..3f6de7c 100644
--- a/src/com/android/launcher2/UninstallShortcutReceiver.java
+++ b/src/com/android/launcher2/UninstallShortcutReceiver.java
@@ -20,11 +20,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.ContentResolver;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;
import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
import com.android.launcher.R;
@@ -36,7 +39,16 @@
if (!ACTION_UNINSTALL_SHORTCUT.equals(data.getAction())) {
return;
}
+ String spKey = LauncherApplication.getSharedPreferencesKey();
+ SharedPreferences sharedPrefs = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+ LauncherApplication app = (LauncherApplication) context.getApplicationContext();
+ synchronized (app) {
+ removeShortcut(context, data, sharedPrefs);
+ }
+ }
+
+ private void removeShortcut(Context context, Intent data, final SharedPreferences sharedPrefs) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
@@ -77,6 +89,29 @@
Toast.makeText(context, context.getString(R.string.shortcut_uninstalled, name),
Toast.LENGTH_SHORT).show();
}
+
+ // Remove any items due to be animated
+ boolean appRemoved;
+ Set<String> newApps = new HashSet<String>();
+ newApps = sharedPrefs.getStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, newApps);
+ do {
+ appRemoved = newApps.remove(intent.toUri(0).toString());
+ } while (appRemoved);
+ if (appRemoved) {
+ final Set<String> savedNewApps = newApps;
+ new Thread("setNewAppsThread-remove") {
+ public void run() {
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ editor.putStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY,
+ savedNewApps);
+ if (savedNewApps.isEmpty()) {
+ // Reset the page index if there are no more items
+ editor.putInt(InstallShortcutReceiver.NEW_APPS_PAGE_KEY, -1);
+ }
+ editor.commit();
+ }
+ }.start();
+ }
}
}
}
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index 0387011..b27f7bb 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -41,6 +41,7 @@
* Various utilities shared amongst the Launcher's classes.
*/
final class Utilities {
+ @SuppressWarnings("unused")
private static final String TAG = "Launcher.Utilities";
private static int sIconWidth = -1;
@@ -83,7 +84,8 @@
return icon;
} else {
// Icon is too small, render to a larger bitmap
- return createIconBitmap(new BitmapDrawable(icon), context);
+ final Resources resources = context.getResources();
+ return createIconBitmap(new BitmapDrawable(resources, icon), context);
}
}
@@ -142,7 +144,9 @@
final int left = (textureWidth-width) / 2;
final int top = (textureHeight-height) / 2;
- if (false) {
+ @SuppressWarnings("all") // suppress dead code warning
+ final boolean debug = false;
+ if (debug) {
// draw a big box for the icon for debugging
canvas.drawColor(sColors[sColorIndex]);
if (++sColorIndex >= sColors.length) sColorIndex = 0;
@@ -205,7 +209,8 @@
if (bitmap.getWidth() == sIconWidth && bitmap.getHeight() == sIconHeight) {
return bitmap;
} else {
- return createIconBitmap(new BitmapDrawable(bitmap), context);
+ final Resources resources = context.getResources();
+ return createIconBitmap(new BitmapDrawable(resources, bitmap), context);
}
}
}
diff --git a/src/com/android/launcher2/WallpaperChooser.java b/src/com/android/launcher2/WallpaperChooser.java
index 8a9d92f..77e1e6f 100644
--- a/src/com/android/launcher2/WallpaperChooser.java
+++ b/src/com/android/launcher2/WallpaperChooser.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
public class WallpaperChooser extends Activity {
+ @SuppressWarnings("unused")
private static final String TAG = "Launcher.WallpaperChooser";
@Override
diff --git a/src/com/android/launcher2/WallpaperChooserDialogFragment.java b/src/com/android/launcher2/WallpaperChooserDialogFragment.java
index eec699e..b99d8ec 100644
--- a/src/com/android/launcher2/WallpaperChooserDialogFragment.java
+++ b/src/com/android/launcher2/WallpaperChooserDialogFragment.java
@@ -137,7 +137,7 @@
*/
if (mEmbedded) {
View view = inflater.inflate(R.layout.wallpaper_chooser, container, false);
- view.setBackgroundDrawable(mWallpaperDrawable);
+ view.setBackground(mWallpaperDrawable);
final Gallery gallery = (Gallery) view.findViewById(R.id.gallery);
gallery.setCallbackDuringFling(false);
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 5b321f3..d2f050c 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -26,7 +26,6 @@
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
-import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,40 +34,32 @@
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region.Op;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.Pair;
import android.view.Display;
-import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.launcher.R;
-import com.android.launcher2.DropTarget.DragObject;
import com.android.launcher2.FolderIcon.FolderRingAnimator;
-import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
import com.android.launcher2.LauncherSettings.Favorites;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
/**
* The workspace is a wide area with a wallpaper and a finite number of pages.
@@ -78,7 +69,6 @@
public class Workspace extends SmoothPagedView
implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
DragController.DragListener, LauncherTransitionable {
- @SuppressWarnings({"UnusedDeclaration"})
private static final String TAG = "Launcher.Workspace";
// Y rotation to apply to the workspace screens
@@ -144,8 +134,6 @@
*/
private CellLayout mDropToLayout = null;
- private boolean mDragHasEnteredWorkspace = false;
-
private Launcher mLauncher;
private IconCache mIconCache;
private DragController mDragController;
@@ -200,8 +188,7 @@
boolean mUpdateWallpaperOffsetImmediately = false;
private Runnable mDelayedResizeRunnable;
private Runnable mDelayedSnapToPageRunnable;
- private int mDisplayWidth;
- private int mDisplayHeight;
+ private Point mDisplaySize = new Point();
private boolean mIsStaticWallpaper;
private int mWallpaperTravelWidth;
@@ -416,10 +403,9 @@
mWallpaperOffset = new WallpaperOffsetInterpolator();
Display display = mLauncher.getWindowManager().getDefaultDisplay();
- mDisplayWidth = display.getWidth();
- mDisplayHeight = display.getHeight();
- mWallpaperTravelWidth = (int) (mDisplayWidth *
- wallpaperTravelToScreenWidthRatio(mDisplayWidth, mDisplayHeight));
+ display.getSize(mDisplaySize);
+ mWallpaperTravelWidth = (int) (mDisplaySize.x *
+ wallpaperTravelToScreenWidthRatio(mDisplaySize.x, mDisplaySize.y));
mMaxDistanceForFolderCreation = (0.6f * res.getDimensionPixelSize(R.dimen.app_icon_size));
mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
@@ -967,7 +953,7 @@
mIsMovingFast = false;
return false;
}
- boolean isLandscape = mDisplayWidth > mDisplayHeight;
+ boolean isLandscape = mDisplaySize.x > mDisplaySize.y;
long currentTime = System.currentTimeMillis();
long timeSinceLastUpdate = currentTime - mLastWallpaperOffsetUpdateTime;
@@ -2408,7 +2394,6 @@
public void onDragEnter(DragObject d) {
mDragEnforcer.onDragEnter();
- mDragHasEnteredWorkspace = true;
mCreateUserFolderOnDrop = false;
mAddToExistingFolderOnDrop = false;
@@ -2426,7 +2411,6 @@
public void onDragExit(DragObject d) {
mDragEnforcer.onDragExit();
- mDragHasEnteredWorkspace = false;
// Here we store the final page that will be dropped to, if the workspace in fact
// receives the drop
@@ -2536,30 +2520,6 @@
return null;
}
- /**
- * Tests to see if the drop will be accepted by Launcher, and if so, includes additional data
- * in the returned structure related to the widgets that match the drop (or a null list if it is
- * a shortcut drop). If the drop is not accepted then a null structure is returned.
- */
- private Pair<Integer, List<WidgetMimeTypeHandlerData>> validateDrag(DragEvent event) {
- final LauncherModel model = mLauncher.getModel();
- final ClipDescription desc = event.getClipDescription();
- final int mimeTypeCount = desc.getMimeTypeCount();
- for (int i = 0; i < mimeTypeCount; ++i) {
- final String mimeType = desc.getMimeType(i);
- if (mimeType.equals(InstallShortcutReceiver.SHORTCUT_MIMETYPE)) {
- return new Pair<Integer, List<WidgetMimeTypeHandlerData>>(i, null);
- } else {
- final List<WidgetMimeTypeHandlerData> widgets =
- model.resolveWidgetsForMimeType(mContext, mimeType);
- if (widgets.size() > 0) {
- return new Pair<Integer, List<WidgetMimeTypeHandlerData>>(i, widgets);
- }
- }
- }
- return null;
- }
-
/*
*
* Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's
@@ -2992,7 +2952,7 @@
public void getHitRect(Rect outRect) {
// We want the workspace to have the whole area of the display (it will find the correct
// cell layout to drop to in the existing drag/drop logic.
- outRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+ outRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
}
/**
@@ -3402,8 +3362,8 @@
ItemInfo info = (ItemInfo) v.getTag();
// Null check required as the AllApps button doesn't have an item info
if (info != null) {
- LauncherModel.moveItemInDatabase(mLauncher, info, container, screen, info.cellX,
- info.cellY);
+ LauncherModel.modifyItemInDatabase(mLauncher, info, container, screen, info.cellX,
+ info.cellY, info.spanX, info.spanY);
}
}
}