Merge "Adding workprofile shortcuts after the loader has completed" into ub-launcher3-burnaby
diff --git a/res/values/config.xml b/res/values/config.xml
index 7ce4059..21e1d69 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -99,4 +99,5 @@
<item type="id" name="action_info" />
<item type="id" name="action_add_to_workspace" />
<item type="id" name="action_move" />
+ <item type="id" name="action_move_to_workspace" />
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a5a681a..57f23ae 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -241,4 +241,6 @@
<!-- Accessibility confirmation for folder created [DO NOT TRANSLATE] -->
<string name="folder_created">Folder created</string>
+ <!-- Accessibility action to move an item from folder to workspace. [CHAR_LIMIT=30] [DO NOT TRANSLATE] -->
+ <string name="action_move_to_workspace">Move to home screen</string>
</resources>
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index b247145..c3cf629 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -232,8 +232,15 @@
mFixedBounds.set(fixedBounds);
}
- updateBackgrounds();
- updatePaddings();
+ // Post the updates since they can trigger a relayout, and this call can be triggered from
+ // a layout pass itself.
+ post(new Runnable() {
+ @Override
+ public void run() {
+ updateBackgrounds();
+ updatePaddings();
+ }
+ });
}
@Override
@@ -269,19 +276,8 @@
// Start the drag
mLauncher.getWorkspace().beginDragShared(v, mLastTouchPos, this, false);
-
- // We delay entering spring-loaded mode slightly to make sure the UI
- // thready is free of any work.
- postDelayed(new Runnable() {
- @Override
- public void run() {
- // We don't enter spring-loaded mode if the drag has been cancelled
- if (mLauncher.getDragController().isDragging()) {
- // Go into spring loaded mode (must happen before we startDrag())
- mLauncher.enterSpringLoadedDragMode();
- }
- }
- }, 150);
+ // Enter spring loaded mode
+ mLauncher.enterSpringLoadedDragMode();
return false;
}
diff --git a/src/com/android/launcher3/AppsGridAdapter.java b/src/com/android/launcher3/AppsGridAdapter.java
index 954c59f..5bc3981 100644
--- a/src/com/android/launcher3/AppsGridAdapter.java
+++ b/src/com/android/launcher3/AppsGridAdapter.java
@@ -33,13 +33,13 @@
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
public View mContent;
- public boolean mIsSectionRow;
+ public boolean mIsSectionHeader;
public boolean mIsEmptyRow;
- public ViewHolder(View v, boolean isSectionRow, boolean isEmptyRow) {
+ public ViewHolder(View v, boolean isSectionHeader, boolean isEmptyRow) {
super(v);
mContent = v;
- mIsSectionRow = isSectionRow;
+ mIsSectionHeader = isSectionHeader;
mIsEmptyRow = isEmptyRow;
}
}
@@ -72,36 +72,26 @@
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
- if (items.isEmpty()) {
- return;
- }
-
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
ViewHolder holder = (ViewHolder) parent.getChildViewHolder(child);
- if (holder != null) {
- GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
- child.getLayoutParams();
- if (!holder.mIsSectionRow && !holder.mIsEmptyRow && !lp.isItemRemoved()) {
- if (items.get(holder.getPosition() - 1).isSectionHeader) {
- // Draw at the parent
- AlphabeticalAppsList.AdapterItem item =
- items.get(holder.getPosition());
- String section = item.sectionName;
- mSectionTextPaint.getTextBounds(section, 0, section.length(),
- mTmpBounds);
- if (mIsRtl) {
- int left = parent.getWidth() - mPaddingStart - mStartMargin;
- c.drawText(section, left + (mStartMargin - mTmpBounds.width()) / 2,
- child.getTop() + (2 * child.getPaddingTop()) +
- mTmpBounds.height(), mSectionTextPaint);
- } else {
- int left = mPaddingStart;
- c.drawText(section, left + (mStartMargin - mTmpBounds.width()) / 2,
- child.getTop() + (2 * child.getPaddingTop()) +
- mTmpBounds.height(), mSectionTextPaint);
- }
- }
+ if (shouldDrawItemSection(holder, child, items)) {
+ // Draw at the parent
+ AlphabeticalAppsList.AdapterItem item =
+ items.get(holder.getPosition());
+ String section = item.sectionName;
+ mSectionTextPaint.getTextBounds(section, 0, section.length(),
+ mTmpBounds);
+ if (mIsRtl) {
+ int left = parent.getWidth() - mPaddingStart - mStartMargin;
+ c.drawText(section, left + (mStartMargin - mTmpBounds.width()) / 2,
+ child.getTop() + (2 * child.getPaddingTop()) +
+ mTmpBounds.height(), mSectionTextPaint);
+ } else {
+ int left = mPaddingStart;
+ c.drawText(section, left + (mStartMargin - mTmpBounds.width()) / 2,
+ child.getTop() + (2 * child.getPaddingTop()) +
+ mTmpBounds.height(), mSectionTextPaint);
}
}
}
@@ -112,6 +102,31 @@
RecyclerView.State state) {
// Do nothing
}
+
+ private boolean shouldDrawItemSection(ViewHolder holder, View child,
+ List<AlphabeticalAppsList.AdapterItem> items) {
+ // Ensure item is not already removed
+ GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
+ child.getLayoutParams();
+ if (lp.isItemRemoved()) {
+ return false;
+ }
+ // Ensure we have a valid holder
+ if (holder == null) {
+ return false;
+ }
+ // Ensure it's not an empty row
+ if (holder.mIsEmptyRow) {
+ return false;
+ }
+ // Ensure we have a holder position
+ int pos = holder.getPosition();
+ if (pos <= 0 || pos >= items.size()) {
+ return false;
+ }
+ // Only draw the first item in the section (the first one after the section header)
+ return items.get(pos - 1).isSectionHeader && !items.get(pos).isSectionHeader;
+ }
}
private LayoutInflater mLayoutInflater;
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 27dda64..23bcc85 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -146,10 +146,13 @@
return;
}
- if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0));
PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
- info = convertToLauncherActivityIfPossible(info);
+ if (info.launchIntent == null || info.label == null) {
+ if (DBG) Log.e(TAG, "Invalid install shortcut intent");
+ return;
+ }
+ info = convertToLauncherActivityIfPossible(info);
queuePendingShortcutInfo(info, context);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2ef5d0a..339b4e4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -522,13 +522,19 @@
mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {
@Override
public void onAllAppsBoundsChanged(Rect bounds) {
+ if (LOGD) {
+ Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);
+ }
mAppsView.setFixedBounds(Launcher.this, bounds);
}
@Override
public void dismissAllApps() {
- showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true, null,
- false /* notifyLauncherCallbacks */);
+ // Dismiss All Apps if we aren't already paused/invisible
+ if (!mPaused) {
+ showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true,
+ null /* onCompleteRunnable */, false /* notifyLauncherCallbacks */);
+ }
}
});
return true;
@@ -1012,6 +1018,13 @@
}
mOnResumeState = State.NONE;
+ // Restore the apps state if we are in all apps
+ if (mState == State.APPS) {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onAllAppsShown();
+ }
+ }
+
// Background was set to gradient in onPause(), restore to black if in all apps.
setWorkspaceBackground(mState == State.WORKSPACE);
@@ -1072,7 +1085,7 @@
mWorkspace.getCustomContentCallbacks().onShow(true);
}
}
- mWorkspace.updateInteractionForState();
+ updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());
mWorkspace.onResume();
if (!isWorkspaceLoading()) {
@@ -1675,9 +1688,6 @@
mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
| LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
- } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)
- || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
- getModel().forceReload();
}
}
};
@@ -1691,8 +1701,6 @@
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
// For handling managed profiles
- filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);
- filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);
if (ENABLE_DEBUG_INTENTS) {
filter.addAction(DebugIntents.DELETE_DATABASE);
filter.addAction(DebugIntents.MIGRATE_DATABASE);
@@ -2101,8 +2109,6 @@
public void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
- showWorkspace(true);
-
if (initialQuery == null) {
// Use any text typed in the launcher as the initial query
initialQuery = getTypedText();
@@ -2121,6 +2127,9 @@
if (clearTextImmediately) {
clearTypedText();
}
+
+ // We need to show the workspace after starting the search
+ showWorkspace(true);
}
/**
@@ -2866,6 +2875,21 @@
}
}
+ /** Updates the interaction state. */
+ public void updateInteraction(Workspace.State fromState, Workspace.State toState) {
+ // Only update the interacting state if we are transitioning to/from a view without an
+ // overlay
+ boolean fromStateWithoutOverlay = fromState != Workspace.State.NORMAL &&
+ fromState != Workspace.State.NORMAL_HIDDEN;
+ boolean toStateWithoutOverlay = toState != Workspace.State.NORMAL &&
+ toState != Workspace.State.NORMAL_HIDDEN;
+ if (toStateWithoutOverlay) {
+ onInteractionBegin();
+ } else if (fromStateWithoutOverlay) {
+ onInteractionEnd();
+ }
+ }
+
void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {
try {
LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
@@ -3170,7 +3194,6 @@
if (v instanceof Workspace) {
if (!mWorkspace.isInOverviewMode()) {
-
if (!mWorkspace.isTouchActive()) {
showOverviewMode(true);
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
@@ -3342,8 +3365,12 @@
// Send an accessibility event to announce the context change
getWindow().getDecorView()
.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-
- onWorkspaceShown(animated);
+ if (notifyLauncherCallbacks) {
+ // Dismiss all apps when the workspace is shown
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onAllAppsHidden();
+ }
+ }
}
}
@@ -3353,10 +3380,6 @@
WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,
null /* onCompleteRunnable */);
mState = State.WORKSPACE;
- onWorkspaceShown(animated);
- }
-
- public void onWorkspaceShown(boolean animated) {
}
/**
@@ -3416,6 +3439,18 @@
.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
+ /**
+ * Updates the workspace and interaction state on state change, and return the animation to this
+ * new state.
+ */
+ public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, int toPage,
+ boolean animated, HashMap<View, Integer> layerViews) {
+ Workspace.State fromState = mWorkspace.getState();
+ Animator anim = mWorkspace.setStateWithAnimation(toState, toPage, animated, layerViews);
+ updateInteraction(fromState, toState);
+ return anim;
+ }
+
public void enterSpringLoadedDragMode() {
Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s",
mState.name()));
@@ -3434,6 +3469,14 @@
final Runnable onCompleteRunnable) {
if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;
+ if (successfulDrop) {
+ // We need to trigger all apps hidden to notify search to update itself before the
+ // delayed call to showWorkspace below
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onAllAppsHidden();
+ }
+ }
+
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
@@ -3454,13 +3497,10 @@
void exitSpringLoadedDragMode() {
if (mState == State.APPS_SPRING_LOADED) {
- mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);
- mState = State.APPS;
+ showAppsView(true, false);
} else if (mState == State.WIDGETS_SPRING_LOADED) {
- mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);
- mState = State.WIDGETS;
+ showWidgetsView(true, false);
}
- // Otherwise, we are not in spring loaded mode, so don't do anything.
}
void lockAllApps() {
@@ -3584,14 +3624,13 @@
* in onResume.
*
* This needs to be called from incoming places where resources might have been loaded
- * while we are paused. That is becaues the Configuration might be wrong
- * when we're not running, and if it comes back to what it was when we
- * were paused, we are not restarted.
+ * while the activity is paused. That is because the Configuration (e.g., rotation) might be
+ * wrong when we're not running, and if the activity comes back to what the configuration was
+ * when we were paused, activity is not restarted.
*
* Implementation of the method from LauncherModel.Callbacks.
*
- * @return true if we are currently paused. The caller might be able to
- * skip some work in that case since we will come back again.
+ * @return {@code true} if we are currently paused. The caller might be able to skip some work
*/
private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
if (mPaused) {
@@ -4127,18 +4166,31 @@
}
/**
+ * A runnable that we can dequeue and re-enqueue when all applications are bound (to prevent
+ * multiple calls to bind the same list.)
+ */
+ @Thunk ArrayList<AppInfo> mTmpAppsList;
+ private Runnable mBindAllApplicationsRunnable = new Runnable() {
+ public void run() {
+ bindAllApplications(mTmpAppsList);
+ mTmpAppsList = null;
+ }
+ };
+
+ /**
* Add the icons for all apps.
*
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(final ArrayList<AppInfo> apps) {
+ if (waitUntilResume(mBindAllApplicationsRunnable, true)) {
+ mTmpAppsList = apps;
+ return;
+ }
+
if (mAppsView != null) {
mAppsView.setApps(apps);
}
- if (mWidgetsView != null) {
- mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
- getPackageManager());
- }
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
}
@@ -4274,26 +4326,23 @@
}
}
- /**
- * A number of packages were updated.
- */
@Thunk ArrayList<Object> mWidgetsAndShortcuts;
private Runnable mBindPackagesUpdatedRunnable = new Runnable() {
public void run() {
- bindPackagesUpdated(mWidgetsAndShortcuts);
- mWidgetsAndShortcuts = null;
+ bindAllPackages(mWidgetsAndShortcuts);
}
};
- public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
+ @Override
+ public void bindAllPackages(final ArrayList<Object> widgetsAndShortcuts) {
if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
mWidgetsAndShortcuts = widgetsAndShortcuts;
return;
}
- if (mWidgetsView != null) {
- mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
- getPackageManager());
+ if (mWidgetsView != null && widgetsAndShortcuts != null) {
+ mWidgetsView.addWidgets(widgetsAndShortcuts, getPackageManager());
+ mWidgetsAndShortcuts = null;
}
}
diff --git a/src/com/android/launcher3/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/LauncherAccessibilityDelegate.java
index a527db4..8a9a050 100644
--- a/src/com/android/launcher3/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/LauncherAccessibilityDelegate.java
@@ -4,6 +4,7 @@
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@@ -26,6 +27,7 @@
private static final int UNINSTALL = R.id.action_uninstall;
private static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
private static final int MOVE = R.id.action_move;
+ private static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
public enum DragType {
ICON,
@@ -58,6 +60,8 @@
launcher.getText(R.string.action_add_to_workspace)));
mActions.put(MOVE, new AccessibilityAction(MOVE,
launcher.getText(R.string.action_move)));
+ mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE,
+ launcher.getText(R.string.action_move_to_workspace)));
}
@Override
@@ -80,6 +84,10 @@
|| (item instanceof LauncherAppWidgetInfo)
|| (item instanceof FolderInfo)) {
info.addAction(mActions.get(MOVE));
+
+ if (item.container >= 0) {
+ info.addAction(mActions.get(MOVE_TO_WORKSPACE));
+ }
} if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
info.addAction(mActions.get(ADD_TO_WORKSPACE));
}
@@ -135,6 +143,30 @@
}
});
return true;
+ } else if (action == MOVE_TO_WORKSPACE) {
+ Folder folder = mLauncher.getWorkspace().getOpenFolder();
+ mLauncher.closeFolder(folder);
+ ShortcutInfo info = (ShortcutInfo) item;
+ folder.getInfo().remove(info);
+
+ final int[] coordinates = new int[2];
+ final long screenId = findSpaceOnWorkspace(item, coordinates);
+ LauncherModel.moveItemInDatabase(mLauncher, info,
+ LauncherSettings.Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates[0], coordinates[1]);
+
+ // Bind the item in next frame so that if a new workspace page was created,
+ // it will get laid out.
+ new Handler().post(new Runnable() {
+
+ @Override
+ public void run() {
+ ArrayList<ItemInfo> itemList = new ArrayList<>();
+ itemList.add(item);
+ mLauncher.bindItems(itemList, 0, itemList.size(), true);
+ announceConfirmation(R.string.item_moved);
+ }
+ });
}
return false;
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 7f31e49..d51df32 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -112,6 +112,10 @@
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
+ // For handling managed profiles
+ filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);
+ filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);
+
sContext.registerReceiver(mModel, filter);
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index e32e0d9..c274f2e 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -79,7 +79,8 @@
}
protected void onProvidersChanged() {
- mLauncher.getModel().loadAndBindWidgetsAndShortcuts(mLauncher, mLauncher);
+ mLauncher.getModel().loadAndBindWidgetsAndShortcuts(mLauncher, mLauncher,
+ true /* refresh */);
if (!mProviderChangeListeners.isEmpty()) {
for (Runnable callback : new ArrayList<>(mProviderChangeListeners)) {
callback.run();
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index 2fee81c..25c86c9 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -51,6 +51,7 @@
public void finishBindingItems(final boolean upgradePath);
public void onClickAllAppsButton(View v);
public void onAllAppsShown();
+ public void onAllAppsHidden();
public void bindAllApplications(ArrayList<AppInfo> apps);
public void onClickFolderIcon(View v);
public void onClickAppShortcut(View v);
diff --git a/src/com/android/launcher3/LauncherExtension.java b/src/com/android/launcher3/LauncherExtension.java
index e4fdbbc..8174af0 100644
--- a/src/com/android/launcher3/LauncherExtension.java
+++ b/src/com/android/launcher3/LauncherExtension.java
@@ -128,6 +128,10 @@
}
@Override
+ public void onAllAppsHidden() {
+ }
+
+ @Override
public void bindAllApplications(ArrayList<AppInfo> apps) {
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 92f076f..0138a91 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -204,7 +204,7 @@
public void bindRestoreItemsChange(HashSet<ItemInfo> updates);
public void bindComponentsRemoved(ArrayList<String> packageNames,
ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason);
- public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
+ public void bindAllPackages(ArrayList<Object> widgetsAndShortcuts);
public void bindSearchablesChanged();
public boolean isAllAppsButtonRank(int rank);
public void onPageBoundSynchronously(int page);
@@ -1305,6 +1305,9 @@
if (callbacks != null) {
callbacks.bindSearchablesChanged();
}
+ } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)
+ || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
+ forceReload();
}
}
@@ -1632,9 +1635,6 @@
if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
loadAndBindAllApps();
- // Remove entries for packages which changed while the launcher was dead.
- LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews();
-
// Restore the default thread priority after we are done loading items
synchronized (mLock) {
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
@@ -2904,10 +2904,13 @@
// Post callback on main thread
mHandler.post(new Runnable() {
public void run() {
+
final long bindTime = SystemClock.uptimeMillis();
final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindAllApplications(added);
+ loadAndBindWidgetsAndShortcuts(mApp.getContext(), callbacks,
+ true /* refresh */);
if (DEBUG_LOADERS) {
Log.d(TAG, "bound " + added.size() + " apps in "
+ (SystemClock.uptimeMillis() - bindTime) + "ms");
@@ -3268,9 +3271,10 @@
}
});
}
- if (Build.VERSION.SDK_INT < 17) {
- loadAndBindWidgetsAndShortcuts(context, callbacks);
- }
+
+ // onProvidersChanged method (API >= 17) already refreshed the widget list
+ loadAndBindWidgetsAndShortcuts(context, callbacks, Build.VERSION.SDK_INT < 17);
+
// Write all the logs to disk
mHandler.post(new Runnable() {
public void run() {
@@ -3319,33 +3323,38 @@
}
}
- public void loadAndBindWidgetsAndShortcuts(final Context context, final Callbacks callbacks) {
+ public void loadAndBindWidgetsAndShortcuts(final Context context, final Callbacks callbacks,
+ final boolean refresh) {
runOnWorkerThread(new Runnable(){
@Override
public void run() {
- final ArrayList<Object> list =
- getSortedWidgetsAndShortcuts(context, true /* refresh */);
+ final ArrayList<Object> list = getWidgetsAndShortcuts(context, refresh);
mHandler.post(new Runnable() {
@Override
public void run() {
Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
- callbacks.bindPackagesUpdated(list);
+ callbacks.bindAllPackages(list);
}
}
});
+ // update the Widget entries inside DB on the worker thread.
+ LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(list);
}
});
}
- // Returns a list of ResolveInfos/AppWidgetInfos in sorted order
- public static ArrayList<Object> getSortedWidgetsAndShortcuts(Context context, boolean refresh) {
+ /**
+ * Returns a list of ResolveInfos/AppWidgetInfos.
+ *
+ * @see #loadAndBindWidgetsAndShortcuts
+ */
+ private ArrayList<Object> getWidgetsAndShortcuts(Context context, boolean refresh) {
PackageManager packageManager = context.getPackageManager();
final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>();
widgetsAndShortcuts.addAll(getWidgetProviders(context, refresh));
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0));
- Collections.sort(widgetsAndShortcuts, new WidgetAndShortcutNameComparator(context));
return widgetsAndShortcuts;
}
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 9e005f2..51f84bf 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -249,8 +249,8 @@
// Create the workspace animation.
// NOTE: this call apparently also sets the state for the workspace if !animated
- Animator workspaceAnim = mLauncher.getWorkspace().setStateWithAnimation(
- toWorkspaceState, -1, animated, layerViews);
+ Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, -1,
+ animated, layerViews);
if (animated && initialized) {
mStateAnimation = LauncherAnimUtils.createAnimatorSet();
@@ -546,8 +546,8 @@
// Create the workspace animation.
// NOTE: this call apparently also sets the state for the workspace if !animated
- Animator workspaceAnim = mLauncher.getWorkspace().setStateWithAnimation(
- toWorkspaceState, toWorkspacePage, animated, layerViews);
+ Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
+ toWorkspacePage, animated, layerViews);
if (animated && initialized) {
mStateAnimation = LauncherAnimUtils.createAnimatorSet();
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index 44a76b7..4cdf1ca 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -180,9 +180,6 @@
prepareStartAnimation(mDropTargetBar);
mShowDropTargetBarAnim.start();
hideSearchBar(true);
- if (mQSBSearchBar != null) {
- mQSBSearchBar.setVisibility(View.GONE);
- }
}
/**
@@ -193,9 +190,6 @@
prepareStartAnimation(mDropTargetBar);
mShowDropTargetBarAnim.reverse();
showSearchBar(true);
- if (mQSBSearchBar != null) {
- mQSBSearchBar.setVisibility(View.VISIBLE);
- }
}
/*
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 412cbcd..93bfeaf 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.Process;
import android.util.Log;
import android.util.LongSparseArray;
@@ -34,6 +35,9 @@
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.WidgetCell;
+import junit.framework.Assert;
+
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -202,11 +206,14 @@
* 2. Any preview for an absent package is removed
* This ensures that we remove entries for packages which changed while the launcher was dead.
*/
- public void removeObsoletePreviews() {
+ public void removeObsoletePreviews(ArrayList<Object> list) {
+ // This method should always be called from the worker thread.
+ Assert.assertTrue(LauncherModel.sWorkerThread.getThreadId() == Process.myTid());
+
LongSparseArray<UserHandleCompat> userIdCache = new LongSparseArray<>();
LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
- for (Object obj : LauncherModel.getSortedWidgetsAndShortcuts(mContext, false)) {
+ for (Object obj : list) {
final UserHandleCompat user;
final String pkg;
if (obj instanceof ResolveInfo) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4c76092..e7a41e0 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2047,14 +2047,6 @@
return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
}
- public void updateInteractionForState() {
- if (mState != State.NORMAL) {
- mLauncher.onInteractionBegin();
- } else {
- mLauncher.onInteractionEnd();
- }
- }
-
/**
* Sets the current workspace {@link State}, returning an animation transitioning the workspace
* to that new state.
@@ -2067,7 +2059,6 @@
// Update the current state
mState = toState;
- updateInteractionForState();
updateAccessibilityFlags();
return workspaceAnim;
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 8090c88..22e29f3 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.State;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -62,6 +63,9 @@
private static final int SPRING_MODE_DELAY_MS = 150;
+ /* Coefficient multiplied to the screen height for preloading widgets. */
+ private static final int PRELOAD_SCREEN_HEIGHT_MULTIPLE = 1;
+
/* Global instances that are used inside this container. */
private Launcher mLauncher;
private DragController mDragController;
@@ -114,8 +118,15 @@
}
mView = (RecyclerView) findViewById(R.id.widgets_list_view);
mView.setAdapter(mAdapter);
- mView.setLayoutManager(new LinearLayoutManager(getContext()));
+ // This extends the layout space so that preloading happen for the {@link RecyclerView}
+ mView.setLayoutManager(new LinearLayoutManager(getContext()) {
+ @Override
+ protected int getExtraLayoutSpace(State state) {
+ return super.getExtraLayoutSpace(state)
+ + WidgetsContainerView.this.getHeight() * PRELOAD_SCREEN_HEIGHT_MULTIPLE;
+ }
+ });
mPadding.set(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
getPaddingBottom());
}