diff options
-rw-r--r-- | src/com/android/launcher3/AppsCustomizePagedView.java | 3 | ||||
-rw-r--r-- | src/com/android/launcher3/InstallShortcutReceiver.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 86 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 83 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 11 |
5 files changed, 157 insertions, 28 deletions
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index be0dd8aaf..0d088acc4 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -1569,9 +1569,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen if (!DISABLE_ALL_APPS) { addAppsWithoutInvalidate(list); updatePageCountsAndInvalidateData(); - } else { - // TODO: Maybe put them somewhere else? - mLauncher.getHotseat().addAppsToAllAppsFolder(list); } } private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) { diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index d647d96a4..3bc7be475 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -253,7 +253,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { // 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 < Launcher.SCREEN_COUNT; i++) { + for (int i = 0; i < Launcher.SCREEN_COUNT && !found; i++) { int si = i; if (0 <= si && si < Launcher.SCREEN_COUNT) { found = installShortcut(context, data, items, name, intent, si, exists, sp, diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 02949612a..c216572a6 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -71,6 +71,7 @@ import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.method.TextKeyListener; import android.util.Log; +import android.util.Pair; import android.view.*; import android.view.View.OnLongClickListener; import android.view.ViewTreeObserver.OnGlobalLayoutListener; @@ -96,6 +97,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -3590,6 +3592,7 @@ public class Launcher extends Activity * Implementation of the method from LauncherModel.Callbacks. */ public void finishBindingItems(final boolean upgradePath) { + if (waitUntilResume(new Runnable() { public void run() { finishBindingItems(upgradePath); @@ -3663,6 +3666,17 @@ public class Launcher extends Activity return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000); } + private ValueAnimator createNewAppBounceAnimation(View v, int i) { + ValueAnimator bounceAnim = LauncherAnimUtils.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()); + return bounceAnim; + } + /** * Runs a new animation that scales up icons that were added while Launcher was in the * background. @@ -3694,14 +3708,7 @@ public class Launcher extends Activity } else { for (int i = 0; i < mNewShortcutAnimateViews.size(); ++i) { View v = mNewShortcutAnimateViews.get(i); - ValueAnimator bounceAnim = LauncherAnimUtils.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); + bounceAnims.add(createNewAppBounceAnimation(v, i)); } anim.playTogether(bounceAnims); anim.addListener(new AnimatorListenerAdapter() { @@ -3789,6 +3796,69 @@ public class Launcher extends Activity return; } + final Launcher launcher = this; + final Context context = this; + final ArrayList<ApplicationInfo> appsCopy = new ArrayList<ApplicationInfo>(); + appsCopy.addAll(apps); + + // Process newly added apps + mWorkspace.post(new Runnable() { + @Override + public void run() { + // Process newly added apps + LauncherModel model = getModel(); + Iterator<ApplicationInfo> iter = appsCopy.iterator(); + ArrayList<View> animatedShortcuts = new ArrayList<View>(); + + while (iter.hasNext()) { + ApplicationInfo a = iter.next(); + Pair<Long, int[]> coords = LauncherModel.findNextAvailableIconSpace(context, + a.title.toString(), a.intent); + if (coords == null) { + // If we can't find a valid position, then just add a new screen. + // This takes time so we need to re-queue the add until the new + // page is added. + long screenId = LauncherAppState.getInstance().getLauncherProvider().generateNewScreenId(); + mWorkspace.insertNewWorkspaceScreen(screenId, false); + model.updateWorkspaceScreenOrder(launcher, mWorkspace.getScreenOrder(), + new Runnable() { + @Override + public void run() { + bindAppsAdded(appsCopy); + } + }); + return; + } else { + final ShortcutInfo shortcutInfo = a.makeShortcut(); + final View shortcut = createShortcut(shortcutInfo); + // Add the view to the screen + mWorkspace.addInScreenFromBind(shortcut, + LauncherSettings.Favorites.CONTAINER_DESKTOP, + coords.first, coords.second[0], coords.second[1], 1, 1); + // Add the shortcut to the db + model.addItemToDatabase(context, shortcutInfo, + LauncherSettings.Favorites.CONTAINER_DESKTOP, + coords.first, coords.second[0], coords.second[1], false); + // Animate the shortcut + animatedShortcuts.add(shortcut); + } + iter.remove(); + } + + // Animate all the applications up + AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); + Collection<Animator> bounceAnims = new ArrayList<Animator>(); + for (int i = 0; i < animatedShortcuts.size(); ++i) { + View shortcut = animatedShortcuts.get(i); + shortcut.setAlpha(0f); + shortcut.setScaleX(0f); + shortcut.setScaleY(0f); + bounceAnims.add(createNewAppBounceAnimation(shortcut, i)); + } + anim.playTogether(bounceAnims); + anim.start(); + } + }); if (mAppsCustomizeContent != null) { mAppsCustomizeContent.addApps(apps); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 11aeb20b0..52535916c 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -19,14 +19,7 @@ package com.android.launcher3; import android.app.SearchManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.ContentProviderClient; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; +import android.content.*; import android.content.Intent.ShortcutIconResource; import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; @@ -47,7 +40,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; - +import android.util.Pair; import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData; import java.lang.ref.WeakReference; @@ -215,6 +208,61 @@ public class LauncherModel extends BroadcastReceiver { } } + static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy, + long screen) { + final int xCount = LauncherModel.getCellCountX(); + final int yCount = LauncherModel.getCellCountY(); + boolean[][] occupied = new boolean[xCount][yCount]; + + int cellX, cellY, spanX, spanY; + for (int i = 0; i < items.size(); ++i) { + final ItemInfo item = items.get(i); + if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (item.screenId == screen) { + cellX = item.cellX; + cellY = item.cellY; + spanX = item.spanX; + spanY = item.spanY; + for (int x = cellX; 0 <= x && x < cellX + spanX && x < xCount; x++) { + for (int y = cellY; 0 <= y && y < cellY + spanY && y < yCount; y++) { + occupied[x][y] = true; + } + } + } + } + } + + return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied); + } + static Pair<Long, int[]> findNextAvailableIconSpace(Context context, String name, + Intent launchIntent) { + // Lock on the app so that we don't try and get the items while apps are being added + LauncherAppState app = LauncherAppState.getInstance(); + LauncherModel model = app.getModel(); + boolean found = false; + synchronized (app) { + // Flush the LauncherModel worker thread, so that if we just did another + // processInstallShortcut, we give it time for its shortcut to get added to the + // database (getItemsInLocalCoordinates reads the database) + model.flushWorkerThread(); + final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context); + final boolean shortcutExists = LauncherModel.shortcutExists(context, name, launchIntent); + + // 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)) + for (int screen = 0; screen < sBgWorkspaceScreens.size() && !found; screen++) { + int[] tmpCoordinates = new int[2]; + if (findNextAvailableIconSpaceInScreen(items, tmpCoordinates, + sBgWorkspaceScreens.get(screen))) { + // Update the Launcher db + return new Pair<Long, int[]>(sBgWorkspaceScreens.get(screen), tmpCoordinates); + } + } + } + // XXX: Create a new page and add it to the first spot + return null; + } + public Bitmap getFallbackIcon() { return Bitmap.createBitmap(mDefaultIcon); } @@ -817,7 +865,10 @@ public class LauncherModel extends BroadcastReceiver { * Update the order of the workspace screens in the database. The array list contains * a list of screen ids in the order that they should appear. */ - static void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { + void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { + updateWorkspaceScreenOrder(context, screens, null); + } + void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens, final Runnable mainThreadCb) { final ContentResolver cr = context.getContentResolver(); final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI; @@ -853,6 +904,14 @@ public class LauncherModel extends BroadcastReceiver { } }; runOnWorkerThread(r); + if (mainThreadCb != null) { + runOnWorkerThread(new Runnable() { + @Override + public void run() { + runOnMainThread(mainThreadCb); + } + }); + } } /** @@ -1713,9 +1772,9 @@ public class LauncherModel extends BroadcastReceiver { String line = ""; Iterator<Long> iter = occupied.keySet().iterator(); - for (int s = 0; s < nScreens; s++) { + while (iter.hasNext()) { long screenId = iter.next(); - if (s > 0) { + if (screenId > 0) { line += " | "; } for (int x = 0; x < mCellCountX; x++) { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index cac3d66f2..88c8e2a5c 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -497,8 +497,6 @@ public class Workspace extends SmoothPagedView return insertNewWorkspaceScreen(screenId, false); } - // If screen id is -1, this indicates there is no screen assigned, so we generate - // a new screen id. public long insertNewWorkspaceScreen(long screenId, boolean updateDb) { CellLayout newScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null); @@ -508,7 +506,7 @@ public class Workspace extends SmoothPagedView mScreenOrder.add(screenId); if (updateDb) { // On bind we don't need to update the screens in the database. - LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder); + mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder); } return screenId; } @@ -537,6 +535,7 @@ public class Workspace extends SmoothPagedView public long commitExtraEmptyScreen() { CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID); + mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID); mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID); long newId = LauncherAppState.getInstance().getLauncherProvider().generateNewScreenId(); @@ -575,11 +574,15 @@ public class Workspace extends SmoothPagedView return mScreenOrder.get(index); } + ArrayList<Long> getScreenOrder() { + return mScreenOrder; + } + public void stripEmptyScreens() { ArrayList<Long> removeScreens = new ArrayList<Long>(); for (Long id: mWorkspaceScreens.keySet()) { CellLayout cl = mWorkspaceScreens.get(id); - if (id != EXTRA_EMPTY_SCREEN_ID && cl.getShortcutsAndWidgets().getChildCount() == 0) { + if (id >= 0 && cl.getShortcutsAndWidgets().getChildCount() == 0) { removeScreens.add(id); } } |