summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml7
-rw-r--r--res/values-land/styles.xml2
-rw-r--r--src/com/android/launcher3/AppsCustomizePagedView.java10
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java17
-rw-r--r--src/com/android/launcher3/DeviceProfile.java51
-rw-r--r--src/com/android/launcher3/DragSource.java11
-rw-r--r--src/com/android/launcher3/Folder.java12
-rw-r--r--src/com/android/launcher3/InfoDropTarget.java6
-rw-r--r--src/com/android/launcher3/Launcher.java43
-rw-r--r--src/com/android/launcher3/LauncherAppState.java11
-rw-r--r--src/com/android/launcher3/LauncherModel.java30
-rw-r--r--src/com/android/launcher3/LauncherProvider.java9
-rw-r--r--src/com/android/launcher3/PagedView.java13
-rw-r--r--src/com/android/launcher3/PreloadReceiver.java9
-rw-r--r--src/com/android/launcher3/WallpaperChangedReceiver.java28
-rw-r--r--src/com/android/launcher3/WallpaperCropActivity.java68
-rw-r--r--src/com/android/launcher3/Workspace.java102
17 files changed, 287 insertions, 142 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 901b63838..1e418ec2f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -160,6 +160,13 @@
</intent-filter>
</receiver>
+ <receiver
+ android:name="com.android.launcher3.WallpaperChangedReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.WALLPAPER_CHANGED" />
+ </intent-filter>
+ </receiver>
+
<!-- Intent received used to install shortcuts from other applications -->
<receiver
android:name="com.android.launcher3.InstallShortcutReceiver"
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index ccb5fcb06..d18a57b95 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -27,7 +27,7 @@
</style>
<style name="DropTargetButtonContainer">
<item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">0dp</item>
+ <item name="android:layout_height">wrap_content</item>
</style>
<style name="DropTargetButton">
<item name="android:layout_width">wrap_content</item>
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 688ff82aa..2865bc5d5 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -916,6 +916,16 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
}
@Override
+ public boolean supportsAppInfoDropTarget() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return false;
+ }
+
+ @Override
public float getIntrinsicIconScaleFactor() {
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 4023dafb6..a8ac0746c 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -29,6 +29,7 @@ import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.TransitionDrawable;
+import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewConfiguration;
@@ -95,7 +96,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
}
private boolean isAllAppsApplication(DragSource source, Object info) {
- return (source instanceof AppsCustomizePagedView) && (info instanceof AppInfo);
+ return source.supportsAppInfoDropTarget() && (info instanceof AppInfo);
}
private boolean isAllAppsWidget(DragSource source, Object info) {
if (source instanceof AppsCustomizePagedView) {
@@ -175,6 +176,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
boolean isVisible = true;
boolean useUninstallLabel = !AppsCustomizePagedView.DISABLE_ALL_APPS &&
isAllAppsApplication(source, info);
+ boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget();
// If we are dragging an application from AppsCustomize, only show the control if we can
// delete the app (it was downloaded), and rename the string to "uninstall" in such a case.
@@ -185,15 +187,17 @@ public class DeleteDropTarget extends ButtonDropTarget {
if (useUninstallLabel) {
setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null);
- } else {
+ } else if (useDeleteLabel) {
setCompoundDrawablesRelativeWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+ } else {
+ isVisible = false;
}
mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
mActive = isVisible;
resetHoverColor();
((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
- if (getText().length() > 0) {
+ if (isVisible && getText().length() > 0) {
setText(useUninstallLabel ? R.string.delete_target_uninstall_label
: R.string.delete_target_label);
}
@@ -334,11 +338,12 @@ public class DeleteDropTarget extends ButtonDropTarget {
if (appWidgetHost != null) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
- new Thread("deleteAppWidgetId") {
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
+ return null;
}
- }.start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
if (wasWaitingForUninstall && !mWaitingForUninstall) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 626ec42cb..511b7182f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -73,6 +73,7 @@ public class DeviceProfile {
boolean isLandscape;
boolean isTablet;
boolean isLargeTablet;
+ boolean isLayoutRtl;
boolean transposeLayoutWithOrientation;
int desiredWorkspaceLeftRightMarginPx;
@@ -310,7 +311,7 @@ public class DeviceProfile {
searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
- searchBarSpaceHeightPx = searchBarHeightPx + 2 * edgeMarginPx;
+ searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset();
// Calculate the actual text height
Paint textPaint = new Paint();
@@ -356,10 +357,11 @@ public class DeviceProfile {
void updateFromConfiguration(Context context, Resources resources, int wPx, int hPx,
int awPx, int ahPx) {
- isLandscape = (resources.getConfiguration().orientation ==
- Configuration.ORIENTATION_LANDSCAPE);
+ Configuration configuration = resources.getConfiguration();
+ isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);
isTablet = resources.getBoolean(R.bool.is_tablet);
isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);
+ isLayoutRtl = (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
widthPx = wPx;
heightPx = hPx;
availableWidthPx = awPx;
@@ -419,6 +421,15 @@ public class DeviceProfile {
return sum;
}
+ /** Returns the search bar top offset */
+ int getSearchBarTopOffset() {
+ if (isTablet() && !isVerticalBarLayout()) {
+ return 4 * edgeMarginPx;
+ } else {
+ return 2 * edgeMarginPx;
+ }
+ }
+
/** Returns the search bar bounds in the current orientation */
Rect getSearchBarBounds() {
return getSearchBarBounds(isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
@@ -428,7 +439,13 @@ public class DeviceProfile {
Rect bounds = new Rect();
if (orientation == CellLayout.LANDSCAPE &&
transposeLayoutWithOrientation) {
- bounds.set(0, edgeMarginPx, searchBarSpaceHeightPx, availableHeightPx - edgeMarginPx);
+ if (isLayoutRtl) {
+ bounds.set(availableWidthPx - searchBarSpaceHeightPx, edgeMarginPx,
+ availableWidthPx, availableHeightPx - edgeMarginPx);
+ } else {
+ bounds.set(0, edgeMarginPx, searchBarSpaceHeightPx,
+ availableHeightPx - edgeMarginPx);
+ }
} else {
if (isTablet()) {
// Pad the left and right of the workspace to ensure consistent spacing
@@ -440,10 +457,12 @@ public class DeviceProfile {
// that into account here too.
int gap = (int) ((width - 2 * edgeMarginPx -
(numColumns * cellWidthPx)) / (2 * (numColumns + 1)));
- bounds.set(edgeMarginPx + gap, 0, availableWidthPx - (edgeMarginPx + gap),
+ bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(),
+ availableWidthPx - (edgeMarginPx + gap),
searchBarSpaceHeightPx);
} else {
- bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, 0,
+ bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
+ getSearchBarTopOffset(),
availableWidthPx - (desiredWorkspaceLeftRightMarginPx -
defaultWidgetPadding.right), searchBarSpaceHeightPx);
}
@@ -461,8 +480,13 @@ public class DeviceProfile {
if (orientation == CellLayout.LANDSCAPE &&
transposeLayoutWithOrientation) {
// Pad the left and right of the workspace with search/hotseat bar sizes
- padding.set(searchBarBounds.right, edgeMarginPx,
- hotseatBarHeightPx, edgeMarginPx);
+ if (isLayoutRtl) {
+ padding.set(hotseatBarHeightPx, edgeMarginPx,
+ searchBarBounds.width(), edgeMarginPx);
+ } else {
+ padding.set(searchBarBounds.width(), edgeMarginPx,
+ hotseatBarHeightPx, edgeMarginPx);
+ }
} else {
if (isTablet()) {
// Pad the left and right of the workspace to ensure consistent spacing
@@ -561,7 +585,7 @@ public class DeviceProfile {
View searchBar = launcher.getSearchBar();
lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
if (hasVerticalBarLayout) {
- // Vertical search bar
+ // Vertical search bar space
lp.gravity = Gravity.TOP | Gravity.LEFT;
lp.width = searchBarSpaceHeightPx;
lp.height = LayoutParams.MATCH_PARENT;
@@ -569,13 +593,13 @@ public class DeviceProfile {
0, 2 * edgeMarginPx, 0,
2 * edgeMarginPx);
} else {
- // Horizontal search bar
+ // Horizontal search bar space
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
lp.width = searchBarSpaceWidthPx;
lp.height = searchBarSpaceHeightPx;
searchBar.setPadding(
2 * edgeMarginPx,
- 2 * edgeMarginPx,
+ getSearchBarTopOffset(),
2 * edgeMarginPx, 0);
}
searchBar.setLayoutParams(lp);
@@ -616,7 +640,7 @@ public class DeviceProfile {
lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
if (hasVerticalBarLayout) {
// Vertical hotseat
- lp.gravity = Gravity.RIGHT;
+ lp.gravity = Gravity.END;
lp.width = hotseatBarHeightPx;
lp.height = LayoutParams.MATCH_PARENT;
hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
@@ -692,7 +716,8 @@ public class DeviceProfile {
paddingTB = Math.min(paddingTB, (int)((paddingLR + paddingTB) * 0.75f));
int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR));
int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2;
- if (gridPaddingLR > (allAppsCellWidthPx / 4)) {
+ // Only adjust the side paddings on landscape phones, or tablets
+ if ((isTablet() || isLandscape) && gridPaddingLR > (allAppsCellWidthPx / 4)) {
padding.left = padding.right = gridPaddingLR;
}
// The icons are centered, so we can't just offset by the page indicator height
diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java
index cca9ab1a4..7369eeac2 100644
--- a/src/com/android/launcher3/DragSource.java
+++ b/src/com/android/launcher3/DragSource.java
@@ -30,6 +30,17 @@ public interface DragSource {
*/
boolean supportsFlingToDelete();
+ /**
+ * @return whether items dragged from this source supports 'App Info'
+ */
+ boolean supportsAppInfoDropTarget();
+
+ /**
+ * @return whether items dragged from this source supports 'Delete' drop target (e.g. to remove
+ * a shortcut.
+ */
+ boolean supportsDeleteDropTarget();
+
/*
* @return the scale of the icons over the workspace icon size
*/
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 1d234ff8a..bbe6af2f6 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -82,7 +82,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private int mState = STATE_NONE;
private static final int REORDER_ANIMATION_DURATION = 230;
private static final int REORDER_DELAY = 250;
- private static final int ON_EXIT_CLOSE_DELAY = 800;
+ private static final int ON_EXIT_CLOSE_DELAY = 400;
private boolean mRearrangeOnClose = false;
private FolderIcon mFolderIcon;
private int mMaxCountX;
@@ -801,6 +801,16 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
return true;
}
+ @Override
+ public boolean supportsAppInfoDropTarget() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return true;
+ }
+
public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
// Do nothing
}
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 2ad43b6ff..374238c49 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -62,10 +62,6 @@ public class InfoDropTarget extends ButtonDropTarget {
}
}
- private boolean isFromAllApps(DragSource source) {
- return (source instanceof AppsCustomizePagedView);
- }
-
@Override
public boolean acceptDrop(DragObject d) {
// acceptDrop is called just before onDrop. We do the work here, rather than
@@ -93,7 +89,7 @@ public class InfoDropTarget extends ButtonDropTarget {
boolean isVisible = true;
// Hide this button unless we are dragging something from AllApps
- if (!isFromAllApps(source)) {
+ if (!source.supportsAppInfoDropTarget()) {
isVisible = false;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ba3ba9327..e2301ba69 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -585,12 +585,12 @@ public class Launcher extends Activity
mIconCache.flush();
final LocaleConfiguration localeConfiguration = sLocaleConfiguration;
- new Thread("WriteLocaleConfiguration") {
- @Override
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
writeConfiguration(Launcher.this, localeConfiguration);
+ return null;
}
- }.start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
@@ -1490,11 +1490,12 @@ public class Launcher extends Activity
if (appWidgetId != -1) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
- new Thread("deleteAppWidgetId") {
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ return null;
}
- }.start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
showOutOfSpaceMessage(isHotseatLayout(layout));
return;
@@ -1764,7 +1765,7 @@ public class Launcher extends Activity
}
// Reset the apps customize page
- if (mAppsCustomizeTabHost != null) {
+ if (!alreadyOnHome && mAppsCustomizeTabHost != null) {
mAppsCustomizeTabHost.reset();
}
@@ -1878,7 +1879,7 @@ public class Launcher extends Activity
mDragLayer.clearAllResizeFrames();
((ViewGroup) mWorkspace.getParent()).removeAllViews();
- mWorkspace.removeAllViews();
+ mWorkspace.removeAllWorkspaceScreens();
mWorkspace = null;
mDragController = null;
@@ -2374,7 +2375,7 @@ public class Launcher extends Activity
* @param v The view that was clicked.
*/
public void onClickAllAppsButton(View v) {
- showAllApps(true, AppsCustomizePagedView.ContentType.Applications, true);
+ showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
}
public void onTouchDownAllAppsButton(View v) {
@@ -2664,7 +2665,7 @@ public class Launcher extends Activity
}
public void closeFolder() {
- Folder folder = mWorkspace.getOpenFolder();
+ Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;
if (folder != null) {
if (folder.isEditingName()) {
folder.dismissEditingName();
@@ -4024,6 +4025,11 @@ public class Launcher extends Activity
getDeviceProfile().isVerticalBarLayout();
}
+ protected Rect getSearchBarBounds() {
+ return LauncherAppState.getInstance().getDynamicGrid().
+ getDeviceProfile().getSearchBarBounds();
+ }
+
@Override
public void bindSearchablesChanged() {
boolean searchVisible = updateGlobalSearchIcon();
@@ -4267,13 +4273,14 @@ public class Launcher extends Activity
public void run() {
cling.cleanup();
// We should update the shared preferences on a background thread
- new Thread("dismissClingThread") {
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
SharedPreferences.Editor editor = mSharedPrefs.edit();
editor.putBoolean(flag, true);
editor.commit();
+ return null;
}
- }.start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
if (postAnimationCb != null) {
postAnimationCb.run();
}
@@ -4582,9 +4589,8 @@ public class Launcher extends Activity
public void dumpLogsToLocalData() {
if (DEBUG_DUMP_LOG) {
- new Thread("DumpLogsToLocalData") {
- @Override
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
boolean success = false;
sDateStamp.setTime(sRunStart);
String FILENAME = sDateStamp.getMonth() + "-"
@@ -4622,8 +4628,9 @@ public class Launcher extends Activity
} catch (IOException e) {
e.printStackTrace();
}
+ return null;
}
- }.start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 9a47eaa32..5daa845f3 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -39,6 +39,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
private boolean mIsScreenLarge;
private float mScreenDensity;
private int mLongPressTimeout = 300;
+ private boolean mWallpaperChangedSinceLastCheck;
private static WeakReference<LauncherProvider> sLauncherProvider;
private static Context sContext;
@@ -217,6 +218,16 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
return mLongPressTimeout;
}
+ public void onWallpaperChanged() {
+ mWallpaperChangedSinceLastCheck = true;
+ }
+
+ public boolean hasWallpaperChangedSinceLastCheck() {
+ boolean result = mWallpaperChangedSinceLastCheck;
+ mWallpaperChangedSinceLastCheck = false;
+ return result;
+ }
+
@Override
public void onAvailableSizeChanged(DeviceProfile grid) {
Utilities.setIconSize(grid.iconSizePx);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 6a6cb3538..74f28b304 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2041,12 +2041,6 @@ public class LauncherModel extends BroadcastReceiver {
}
}
- // If we aren't filtering on a screen, then the set of items to load is the full set of
- // items given.
- if (currentScreenId < 0) {
- throw new RuntimeException("Unexpected screen id");
- }
-
// Order the set of items by their containers first, this allows use to walk through the
// list sequentially, build up a list of containers that are in the specified screen,
// as well as all items in those containers.
@@ -2084,11 +2078,6 @@ public class LauncherModel extends BroadcastReceiver {
ArrayList<LauncherAppWidgetInfo> appWidgets,
ArrayList<LauncherAppWidgetInfo> currentScreenWidgets,
ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) {
- // If we aren't filtering on a screen, then the set of items to load is the full set of
- // widgets given.
- if (currentScreenId < 0) {
- throw new RuntimeException("Unexpected screen id");
- }
for (LauncherAppWidgetInfo widget : appWidgets) {
if (widget == null) continue;
@@ -2107,11 +2096,6 @@ public class LauncherModel extends BroadcastReceiver {
HashMap<Long, FolderInfo> folders,
HashMap<Long, FolderInfo> currentScreenFolders,
HashMap<Long, FolderInfo> otherScreenFolders) {
- // If we aren't filtering on a screen, then the set of items to load is the full set of
- // widgets given.
- if (currentScreenId < 0) {
- throw new RuntimeException("Unexpected screen id");
- }
for (long id : folders.keySet()) {
ItemInfo info = itemsIdMap.get(id);
@@ -2261,13 +2245,15 @@ public class LauncherModel extends BroadcastReceiver {
}
final boolean isLoadingSynchronously = (synchronizeBindPage > -1);
- final int currentScreen = isLoadingSynchronously ? synchronizeBindPage :
+ int currScreen = isLoadingSynchronously ? synchronizeBindPage :
oldCallbacks.getCurrentWorkspaceScreen();
- if (currentScreen >= orderedScreenIds.size()) {
- Log.w(TAG, "Invalid screen id to synchronously load");
- return;
+ if (currScreen >= orderedScreenIds.size()) {
+ // There may be no workspace screens (just hotseat items and an empty page).
+ currScreen = -1;
}
- final long currentScreenId = orderedScreenIds.get(currentScreen);
+ final int currentScreen = currScreen;
+ final long currentScreenId =
+ currentScreen < 0 ? -1 : orderedScreenIds.get(currentScreen);
// Load all the items that are on the current page first (and in the process, unbind
// all the existing workspace items before we call startBinding() below.
@@ -2312,7 +2298,7 @@ public class LauncherModel extends BroadcastReceiver {
r = new Runnable() {
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
- if (callbacks != null) {
+ if (callbacks != null && currentScreen >= 0) {
callbacks.onPageBoundSynchronously(currentScreen);
}
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index dbc1b1ce1..27b7dae2a 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -290,6 +290,13 @@ public class LauncherProvider extends ContentProvider {
public void onRow(ContentValues values);
}
+ private static boolean shouldImportLauncher2Database(Context context) {
+ boolean isTablet = context.getResources().getBoolean(R.bool.is_tablet);
+
+ // We don't import the old databse for tablets, as the grid size has changed.
+ return !isTablet && IMPORT_LAUNCHER2_DATABASE;
+ }
+
private static class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG_FAVORITES = "favorites";
private static final String TAG_FAVORITE = "favorite";
@@ -369,7 +376,7 @@ public class LauncherProvider extends ContentProvider {
sendAppWidgetResetNotify();
}
- if (IMPORT_LAUNCHER2_DATABASE) {
+ if (shouldImportLauncher2Database(mContext)) {
// Try converting the old database
ContentValuesCallback permuteScreensCb = new ContentValuesCallback() {
public void onRow(ContentValues values) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index bb79c2c40..c216f926f 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -153,7 +153,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int mTouchState = TOUCH_STATE_REST;
protected boolean mForceScreenScrolled = false;
- private boolean mScrollAbortedFromIntercept = false;
protected OnLongClickListener mLongClickListener;
@@ -1395,13 +1394,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* being flinged.
*/
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
- final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+ final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop / 3);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
- if (!mScroller.isFinished()) {
- mScrollAbortedFromIntercept = true;
- abortScrollerAnimation(false);
+ if (!mScroller.isFinished() && !mFreeScroll) {
+ setCurrentPage(getNextPage());
+ pageEndMoving();
}
} else {
if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
@@ -1429,9 +1428,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (mScrollAbortedFromIntercept) {
- snapToDestination();
- }
resetTouchState();
break;
@@ -2000,7 +1996,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
releaseVelocityTracker();
endReordering();
mCancelTap = false;
- mScrollAbortedFromIntercept = false;
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
}
diff --git a/src/com/android/launcher3/PreloadReceiver.java b/src/com/android/launcher3/PreloadReceiver.java
index 75e5c98bc..ca25746eb 100644
--- a/src/com/android/launcher3/PreloadReceiver.java
+++ b/src/com/android/launcher3/PreloadReceiver.java
@@ -19,6 +19,7 @@ package com.android.launcher3;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
@@ -39,12 +40,12 @@ public class PreloadReceiver extends BroadcastReceiver {
if (LOGD) {
Log.d(TAG, "workspace name: " + name + " id: " + workspaceResId);
}
- new Thread(new Runnable() {
- @Override
- public void run() {
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
provider.loadDefaultFavoritesIfNecessary(workspaceResId);
+ return null;
}
- }).start();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
}
diff --git a/src/com/android/launcher3/WallpaperChangedReceiver.java b/src/com/android/launcher3/WallpaperChangedReceiver.java
new file mode 100644
index 000000000..28e41d8a5
--- /dev/null
+++ b/src/com/android/launcher3/WallpaperChangedReceiver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class WallpaperChangedReceiver extends BroadcastReceiver {
+ public void onReceive(Context context, Intent data) {
+ LauncherAppState appState = LauncherAppState.getInstance();
+ appState.onWallpaperChanged();
+ }
+}
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index 65223ad22..b3ef07309 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -71,6 +71,8 @@ public class WallpaperCropActivity extends Activity {
public static final int MAX_BMAP_IN_INTENT = 750000;
private static final float WALLPAPER_SCREENS_SPAN = 2f;
+ protected static Point sDefaultWallpaperSize;
+
protected CropView mCropView;
protected Uri mUri;
@@ -204,32 +206,34 @@ public class WallpaperCropActivity extends Activity {
}
static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
- Point minDims = new Point();
- Point maxDims = new Point();
- windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
-
- int maxDim = Math.max(maxDims.x, maxDims.y);
- int minDim = Math.max(minDims.x, minDims.y);
-
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
- Point realSize = new Point();
- windowManager.getDefaultDisplay().getRealSize(realSize);
- maxDim = Math.max(realSize.x, realSize.y);
- minDim = Math.min(realSize.x, realSize.y);
- }
+ if (sDefaultWallpaperSize == null) {
+ Point minDims = new Point();
+ Point maxDims = new Point();
+ windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+
+ int maxDim = Math.max(maxDims.x, maxDims.y);
+ int minDim = Math.max(minDims.x, minDims.y);
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ Point realSize = new Point();
+ windowManager.getDefaultDisplay().getRealSize(realSize);
+ maxDim = Math.max(realSize.x, realSize.y);
+ minDim = Math.min(realSize.x, realSize.y);
+ }
- // We need to ensure that there is enough extra space in the wallpaper
- // for the intended
- // parallax effects
- final int defaultWidth, defaultHeight;
- if (isScreenLarge(res)) {
- defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
- defaultHeight = maxDim;
- } else {
- defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
- defaultHeight = maxDim;
+ // We need to ensure that there is enough extra space in the wallpaper
+ // for the intended parallax effects
+ final int defaultWidth, defaultHeight;
+ if (isScreenLarge(res)) {
+ defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+ defaultHeight = maxDim;
+ } else {
+ defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
+ defaultHeight = maxDim;
+ }
+ sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
}
- return new Point(defaultWidth, defaultHeight);
+ return sDefaultWallpaperSize;
}
public static int getRotationFromExif(String path) {
@@ -785,15 +789,13 @@ public class WallpaperCropActivity extends Activity {
WindowManager windowManager,
final WallpaperManager wallpaperManager) {
final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
-
- new Thread("suggestWallpaperDimension") {
- public void run() {
- // If we have saved a wallpaper width/height, use that instead
- int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
- int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
- wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
- }
- }.start();
+ // If we have saved a wallpaper width/height, use that instead
+ int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
+ int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
+ if (savedWidth != wallpaperManager.getDesiredMinimumWidth() ||
+ savedHeight != wallpaperManager.getDesiredMinimumHeight()) {
+ wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
+ }
}
protected static RectF getMaxCropRect(
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f8db240e0..bf4f561e0 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -31,7 +31,6 @@ import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -44,6 +43,7 @@ import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.IBinder;
import android.os.Parcelable;
import android.support.v4.view.ViewCompat;
@@ -55,10 +55,7 @@ import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
@@ -338,6 +335,14 @@ public class Workspace extends SmoothPagedView
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
+
+ CellLayout customScreen = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID);
+ if (customScreen != null) {
+ View customContent = customScreen.getShortcutsAndWidgets().getChildAt(0);
+ if (customContent instanceof Insettable) {
+ ((Insettable) customContent).setInsets(mInsets);
+ }
+ }
}
// estimate the size of a widget with spans hSpan, vSpan. return MAX_VALUE for each
@@ -433,6 +438,9 @@ public class Workspace extends SmoothPagedView
mMaxDistanceForFolderCreation = (0.55f * grid.iconSizePx);
mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
+
+ // Set the wallpaper dimensions when Launcher starts up
+ setWallpaperDimension();
}
private void setupLayoutTransition() {
@@ -623,6 +631,12 @@ public class Workspace extends SmoothPagedView
if (customContent instanceof Insettable) {
((Insettable)customContent).setInsets(mInsets);
}
+
+ // Verify that the child is removed from any existing parent.
+ if (customContent.getParent() instanceof ViewGroup) {
+ ViewGroup parent = (ViewGroup) customContent.getParent();
+ parent.removeView(customContent);
+ }
customScreen.removeAllViews();
customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
mCustomContentDescription = description;
@@ -1222,10 +1236,16 @@ public class Workspace extends SmoothPagedView
}
protected void setWallpaperDimension() {
- String spKey = WallpaperCropActivity.getSharedPreferencesKey();
- SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
- WallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
- sp, mLauncher.getWindowManager(), mWallpaperManager);
+ new AsyncTask<Void, Void, Void>() {
+ public Void doInBackground(Void ... args) {
+ String spKey = WallpaperCropActivity.getSharedPreferencesKey();
+ SharedPreferences sp =
+ mLauncher.getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
+ WallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
+ sp, mLauncher.getWindowManager(), mWallpaperManager);
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
protected void snapToPage(int whichPage, Runnable r) {
@@ -1683,6 +1703,12 @@ public class Workspace extends SmoothPagedView
AccessibilityManager am = (AccessibilityManager)
getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
sAccessibilityEnabled = am.isEnabled();
+
+ // Update wallpaper dimensions if they were changed since last onResume
+ // (we also always set the wallpaper dimensions in the constructor)
+ if (LauncherAppState.getInstance().hasWallpaperChangedSinceLastCheck()) {
+ setWallpaperDimension();
+ }
}
@Override
@@ -2114,7 +2140,6 @@ public class Workspace extends SmoothPagedView
enableFreeScroll();
}
-
if (state != State.NORMAL) {
if (stateIsSpringLoaded) {
mNewScale = mSpringLoadedShrinkFactor;
@@ -2182,6 +2207,7 @@ public class Workspace extends SmoothPagedView
final View searchBar = mLauncher.getQsbBar();
final View overviewPanel = mLauncher.getOverviewPanel();
final View hotseat = mLauncher.getHotseat();
+ final View pageIndicator = getPageIndicator();
if (animated) {
anim.setDuration(duration);
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(this);
@@ -2221,31 +2247,38 @@ public class Workspace extends SmoothPagedView
}
}
}
- ObjectAnimator pageIndicatorAlpha = null;
- if (getPageIndicator() != null) {
- pageIndicatorAlpha = ObjectAnimator.ofFloat(getPageIndicator(), "alpha",
- finalHotseatAndPageIndicatorAlpha);
+ Animator pageIndicatorAlpha = null;
+ if (pageIndicator != null) {
+ pageIndicatorAlpha = new LauncherViewPropertyAnimator(pageIndicator)
+ .alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
+ pageIndicatorAlpha.addListener(new AlphaUpdateListener(pageIndicator));
+ } else {
+ // create a dummy animation so we don't need to do null checks later
+ pageIndicatorAlpha = ValueAnimator.ofFloat(0, 0);
}
- ObjectAnimator hotseatAlpha = ObjectAnimator.ofFloat(hotseat, "alpha",
- finalHotseatAndPageIndicatorAlpha);
- ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(searchBar,
- "alpha", finalSearchBarAlpha);
- ObjectAnimator overviewPanelAlpha = ObjectAnimator.ofFloat(overviewPanel,
- "alpha", finalOverviewPanelAlpha);
- overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
+ Animator hotseatAlpha = new LauncherViewPropertyAnimator(hotseat)
+ .alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
+
+ Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
+ .alpha(finalSearchBarAlpha).withLayer();
searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
+ Animator overviewPanelAlpha = new LauncherViewPropertyAnimator(overviewPanel)
+ .alpha(finalOverviewPanelAlpha).withLayer();
+ overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
+
if (workspaceToOverview) {
+ pageIndicatorAlpha.setInterpolator(new DecelerateInterpolator(2));
hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
+ overviewPanelAlpha.setInterpolator(null);
} else if (overviewToWorkspace) {
+ pageIndicatorAlpha.setInterpolator(null);
+ hotseatAlpha.setInterpolator(null);
overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
}
-
- if (getPageIndicator() != null) {
- pageIndicatorAlpha.addListener(new AlphaUpdateListener(getPageIndicator()));
- }
+ searchBarAlpha.setInterpolator(null);
anim.play(overviewPanelAlpha);
anim.play(hotseatAlpha);
@@ -2257,9 +2290,9 @@ public class Workspace extends SmoothPagedView
AlphaUpdateListener.updateVisibility(overviewPanel);
hotseat.setAlpha(finalHotseatAndPageIndicatorAlpha);
AlphaUpdateListener.updateVisibility(hotseat);
- if (getPageIndicator() != null) {
- getPageIndicator().setAlpha(finalHotseatAndPageIndicatorAlpha);
- AlphaUpdateListener.updateVisibility(getPageIndicator());
+ if (pageIndicator != null) {
+ pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
+ AlphaUpdateListener.updateVisibility(pageIndicator);
}
searchBar.setAlpha(finalSearchBarAlpha);
AlphaUpdateListener.updateVisibility(searchBar);
@@ -3984,7 +4017,6 @@ public class Workspace extends SmoothPagedView
// hardware layers on children are enabled on startup, but should be disabled until
// needed
updateChildrenLayersEnabled(false);
- setWallpaperDimension();
}
/**
@@ -4206,6 +4238,16 @@ public class Workspace extends SmoothPagedView
}
@Override
+ public boolean supportsAppInfoDropTarget() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return true;
+ }
+
+ @Override
public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
// Do nothing
}
@@ -4237,7 +4279,9 @@ public class Workspace extends SmoothPagedView
if (mSavedStates != null) {
mRestoredPages.add(child);
CellLayout cl = (CellLayout) getChildAt(child);
- cl.restoreInstanceState(mSavedStates);
+ if (cl != null) {
+ cl.restoreInstanceState(mSavedStates);
+ }
}
}