summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/Workspace.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/Workspace.java')
-rw-r--r--src/com/android/launcher3/Workspace.java344
1 files changed, 156 insertions, 188 deletions
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 774996e56..8bd799198 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -67,6 +67,7 @@ import android.widget.TextView;
import com.android.launcher3.FolderIcon.FolderRingAnimator;
import com.android.launcher3.Launcher.CustomContentCallbacks;
+import com.android.launcher3.Launcher.LauncherOverlay;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
@@ -282,6 +283,7 @@ public class Workspace extends SmoothPagedView
private float[] mNewAlphas;
private int mLastChildCount = -1;
private float mTransitionProgress;
+ private Animator mStateAnimator = null;
float mOverScrollEffect = 0f;
@@ -289,6 +291,13 @@ public class Workspace extends SmoothPagedView
private boolean mDeferDropAfterUninstall;
private boolean mUninstallSuccessful;
+ // State related to Launcher Overlay
+ LauncherOverlay mLauncherOverlay;
+ boolean mScrollInteractionBegan;
+ boolean mStartedSendingScrollEvents;
+ boolean mShouldSendPageSettled;
+ int mLastOverlaySroll = 0;
+
private final Runnable mBindPages = new Runnable() {
@Override
public void run() {
@@ -1249,6 +1258,66 @@ public class Workspace extends SmoothPagedView
stripEmptyScreens();
mStripScreensOnPageStopMoving = false;
}
+
+ if (mShouldSendPageSettled) {
+ mLauncherOverlay.onScrollSettled();
+ mShouldSendPageSettled = false;
+ }
+ }
+
+ protected void onScrollInteractionBegin() {
+ super.onScrollInteractionEnd();
+ mScrollInteractionBegan = true;
+ }
+
+ protected void onScrollInteractionEnd() {
+ super.onScrollInteractionEnd();
+ mScrollInteractionBegan = false;
+ if (mStartedSendingScrollEvents) {
+ mStartedSendingScrollEvents = false;
+ mLauncherOverlay.onScrollInteractionEnd();
+ }
+ }
+
+ public void setLauncherOverlay(LauncherOverlay overlay) {
+ mLauncherOverlay = overlay;
+ }
+
+ @Override
+ protected void overScroll(float amount) {
+ boolean isRtl = isLayoutRtl();
+ boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || isRtl)) ||
+ (amount >= 0 && (!hasCustomContent() || !isRtl));
+
+ boolean shouldScrollOverlay = mLauncherOverlay != null &&
+ ((amount <= 0 && !isRtl) || (amount >= 0 && isRtl));
+
+ boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlaySroll != 0 &&
+ ((amount >= 0 && !isRtl) || (amount <= 0 && isRtl));
+
+ if (shouldScrollOverlay) {
+ if (!mStartedSendingScrollEvents && mScrollInteractionBegan) {
+ mStartedSendingScrollEvents = true;
+ mLauncherOverlay.onScrollInteractionBegin();
+ mShouldSendPageSettled = true;
+ }
+ int screenSize = getViewportWidth();
+ float f = (amount / screenSize);
+
+ int progress = (int) Math.abs((f * 100));
+
+ mLastOverlaySroll = progress;
+ mLauncherOverlay.onScrollChange(progress, isRtl);
+ } else if (shouldOverScroll) {
+ dampedOverScroll(amount);
+ mOverScrollEffect = acceleratedOverFactor(amount);
+ } else {
+ mOverScrollEffect = 0;
+ }
+
+ if (shouldZeroOverlay) {
+ mLauncherOverlay.onScrollChange(0, isRtl);
+ }
}
@Override
@@ -1261,14 +1330,11 @@ public class Workspace extends SmoothPagedView
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onShow(false);
mCustomContentShowTime = System.currentTimeMillis();
- mLauncher.updateVoiceButtonProxyVisible(false);
}
} else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
mCustomContentShowing = false;
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onHide();
- mLauncher.resetQSBScroll();
- mLauncher.updateVoiceButtonProxyVisible(false);
}
}
}
@@ -1711,18 +1777,6 @@ public class Workspace extends SmoothPagedView
}
}
- @Override
- protected void overScroll(float amount) {
- boolean shouldOverScroll = (amount < 0 && (!hasCustomContent() || isLayoutRtl())) ||
- (amount > 0 && (!hasCustomContent() || !isLayoutRtl()));
- if (shouldOverScroll) {
- dampedOverScroll(amount);
- mOverScrollEffect = acceleratedOverFactor(amount);
- } else {
- mOverScrollEffect = 0;
- }
- }
-
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mWindowToken = getWindowToken();
@@ -2148,16 +2202,6 @@ public class Workspace extends SmoothPagedView
return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
}
- boolean shouldVoiceButtonProxyBeVisible() {
- if (isOnOrMovingToCustomContent()) {
- return false;
- }
- if (mState != State.NORMAL) {
- return false;
- }
- return true;
- }
-
public void updateInteractionForState() {
if (mState != State.NORMAL) {
mLauncher.onInteractionBegin();
@@ -2200,6 +2244,13 @@ public class Workspace extends SmoothPagedView
AnimatorSet anim = animated ? LauncherAnimUtils.createAnimatorSet() : null;
+ // We only want a single instance of a workspace animation to be running at once, so
+ // we cancel any incomplete transition.
+ if (mStateAnimator != null) {
+ mStateAnimator.cancel();
+ }
+ mStateAnimator = anim;
+
final State oldState = mState;
final boolean oldStateIsNormal = (oldState == State.NORMAL);
final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED);
@@ -2354,10 +2405,6 @@ public class Workspace extends SmoothPagedView
.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));
@@ -2365,11 +2412,9 @@ public class Workspace extends SmoothPagedView
// For animation optimations, we may need to provide the Launcher transition
// with a set of views on which to force build layers in certain scenarios.
hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
overviewPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
if (layerViews != null) {
layerViews.add(hotseat);
- layerViews.add(searchBar);
layerViews.add(overviewPanel);
}
@@ -2386,13 +2431,29 @@ public class Workspace extends SmoothPagedView
overviewPanelAlpha.setDuration(duration);
pageIndicatorAlpha.setDuration(duration);
hotseatAlpha.setDuration(duration);
- searchBarAlpha.setDuration(duration);
+
+ if (searchBar != null) {
+ Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
+ .alpha(finalSearchBarAlpha).withLayer();
+ searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
+ searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ if (layerViews != null) {
+ layerViews.add(searchBar);
+ }
+ searchBarAlpha.setDuration(duration);
+ anim.play(searchBarAlpha);
+ }
anim.play(overviewPanelAlpha);
anim.play(hotseatAlpha);
- anim.play(searchBarAlpha);
anim.play(pageIndicatorAlpha);
anim.setStartDelay(delay);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStateAnimator = null;
+ }
+ });
} else {
overviewPanel.setAlpha(finalOverviewPanelAlpha);
AlphaUpdateListener.updateVisibility(overviewPanel);
@@ -2402,14 +2463,15 @@ public class Workspace extends SmoothPagedView
pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
AlphaUpdateListener.updateVisibility(pageIndicator);
}
- searchBar.setAlpha(finalSearchBarAlpha);
- AlphaUpdateListener.updateVisibility(searchBar);
+ if (searchBar != null) {
+ searchBar.setAlpha(finalSearchBarAlpha);
+ AlphaUpdateListener.updateVisibility(searchBar);
+ }
updateCustomContentVisibility();
setScaleX(mNewScale);
setScaleY(mNewScale);
setTranslationY(finalWorkspaceTranslationY);
}
- mLauncher.updateVoiceButtonProxyVisible(false);
if (stateIsNormal) {
animateBackgroundGradient(0f, animated);
@@ -4629,6 +4691,34 @@ public class Workspace extends SmoothPagedView
});
}
+ public void disableShortcutsByPackageName(final ArrayList<String> packages,
+ final UserHandleCompat user, final int reason) {
+ final HashSet<String> packageNames = new HashSet<String>();
+ packageNames.addAll(packages);
+
+ mapOverItems(MAP_RECURSE, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
+ ShortcutInfo shortcutInfo = (ShortcutInfo) info;
+ ComponentName cn = shortcutInfo.getTargetComponent();
+ if (user.equals(shortcutInfo.user) && cn != null
+ && packageNames.contains(cn.getPackageName())) {
+ shortcutInfo.isDisabled |= reason;
+ BubbleTextView shortcut = (BubbleTextView) v;
+ shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache, true, false);
+
+ if (parent != null) {
+ parent.invalidate();
+ }
+ }
+ }
+ // process all the shortcuts
+ return false;
+ }
+ });
+ }
+
// Removes ALL items that match a given package name, this is usually called when a package
// has been removed and we want to remove all components (widgets, shortcuts, apps) that
// belong to that package.
@@ -4666,20 +4756,11 @@ public class Workspace extends SmoothPagedView
removeItemsByComponentName(cns, user);
}
- // Removes items that match the application info specified, when applications are removed
- // as a part of an update, this is called to ensure that other widgets and application
- // shortcuts are not removed.
- void removeItemsByApplicationInfo(final ArrayList<AppInfo> appInfos, UserHandleCompat user) {
- // Just create a hash table of all the specific components that this will affect
- HashSet<ComponentName> cns = new HashSet<ComponentName>();
- for (AppInfo info : appInfos) {
- cns.add(info.componentName);
- }
-
- // Remove all the things
- removeItemsByComponentName(cns, user);
- }
-
+ /**
+ * Removes items that match the item info specified. When applications are removed
+ * as a part of an update, this is called to ensure that other widgets and application
+ * shortcuts are not removed.
+ */
void removeItemsByComponentName(final HashSet<ComponentName> componentNames,
final UserHandleCompat user) {
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
@@ -4800,118 +4881,28 @@ public class Workspace extends SmoothPagedView
}
}
- void updateShortcutsAndWidgets(ArrayList<AppInfo> apps) {
- // Break the appinfo list per user
- final HashMap<UserHandleCompat, ArrayList<AppInfo>> appsPerUser =
- new HashMap<UserHandleCompat, ArrayList<AppInfo>>();
- for (AppInfo info : apps) {
- ArrayList<AppInfo> filtered = appsPerUser.get(info.user);
- if (filtered == null) {
- filtered = new ArrayList<AppInfo>();
- appsPerUser.put(info.user, filtered);
- }
- filtered.add(info);
- }
-
- for (Map.Entry<UserHandleCompat, ArrayList<AppInfo>> entry : appsPerUser.entrySet()) {
- updateShortcutsAndWidgetsPerUser(entry.getValue(), entry.getKey());
- }
- }
-
- private void updateShortcutsAndWidgetsPerUser(ArrayList<AppInfo> apps,
- final UserHandleCompat user) {
- // Create a map of the apps to test against
- final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
- final HashSet<String> pkgNames = new HashSet<String>();
- for (AppInfo ai : apps) {
- appsMap.put(ai.componentName, ai);
- pkgNames.add(ai.componentName.getPackageName());
- }
- final HashSet<ComponentName> iconsToRemove = new HashSet<ComponentName>();
-
+ void updateShortcuts(ArrayList<ShortcutInfo> shortcuts) {
+ final HashSet<ShortcutInfo> updates = new HashSet<ShortcutInfo>(shortcuts);
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
- if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
- ShortcutInfo shortcutInfo = (ShortcutInfo) info;
- ComponentName cn = shortcutInfo.getTargetComponent();
- AppInfo appInfo = appsMap.get(cn);
- if (user.equals(shortcutInfo.user) && cn != null
- && LauncherModel.isShortcutInfoUpdateable(info)
- && pkgNames.contains(cn.getPackageName())) {
- boolean promiseStateChanged = false;
- boolean infoUpdated = false;
- if (shortcutInfo.isPromise()) {
- if (shortcutInfo.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
- // Auto install icon
- PackageManager pm = getContext().getPackageManager();
- ResolveInfo matched = pm.resolveActivity(
- new Intent(Intent.ACTION_MAIN)
- .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
- PackageManager.MATCH_DEFAULT_ONLY);
- if (matched == null) {
- // Try to find the best match activity.
- Intent intent = pm.getLaunchIntentForPackage(
- cn.getPackageName());
- if (intent != null) {
- cn = intent.getComponent();
- appInfo = appsMap.get(cn);
- }
-
- if ((intent == null) || (appsMap == null)) {
- // Could not find a default activity. Remove this item.
- iconsToRemove.add(shortcutInfo.getTargetComponent());
-
- // process next shortcut.
- return false;
- }
- shortcutInfo.promisedIntent = intent;
- }
- }
-
- // Restore the shortcut.
- shortcutInfo.intent = shortcutInfo.promisedIntent;
- shortcutInfo.promisedIntent = null;
- shortcutInfo.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
- & ~ShortcutInfo.FLAG_AUTOINTALL_ICON
- & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
-
- promiseStateChanged = true;
- infoUpdated = true;
- shortcutInfo.updateIcon(mIconCache);
- LauncherModel.updateItemInDatabase(getContext(), shortcutInfo);
- }
-
-
- if (appInfo != null) {
- shortcutInfo.updateIcon(mIconCache);
- shortcutInfo.title = appInfo.title.toString();
- shortcutInfo.contentDescription = appInfo.contentDescription;
- infoUpdated = true;
- }
-
- if (infoUpdated) {
- BubbleTextView shortcut = (BubbleTextView) v;
- shortcut.applyFromShortcutInfo(shortcutInfo,
- mIconCache, true, promiseStateChanged);
-
- if (parent != null) {
- parent.invalidate();
- }
- }
+ if (info instanceof ShortcutInfo && v instanceof BubbleTextView &&
+ updates.contains(info)) {
+ ShortcutInfo si = (ShortcutInfo) info;
+ BubbleTextView shortcut = (BubbleTextView) v;
+ boolean oldPromiseState = shortcut.getCompoundDrawables()[1]
+ instanceof PreloadIconDrawable;
+ shortcut.applyFromShortcutInfo(si, mIconCache, true,
+ si.isPromise() != oldPromiseState);
+
+ if (parent != null) {
+ parent.invalidate();
}
}
// process all the shortcuts
return false;
}
});
-
- if (!iconsToRemove.isEmpty()) {
- removeItemsByComponentName(iconsToRemove, user);
- }
- if (user.equals(UserHandleCompat.myUserHandle())) {
- restorePendingWidgets(pkgNames);
- }
}
public void removeAbandonedPromise(String packageName, UserHandleCompat user) {
@@ -4954,9 +4945,11 @@ public class Workspace extends SmoothPagedView
}
public void updatePackageState(ArrayList<PackageInstallInfo> installInfos) {
- HashSet<String> completedPackages = new HashSet<String>();
-
for (final PackageInstallInfo installInfo : installInfos) {
+ if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
+ continue;
+ }
+
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
@@ -4984,42 +4977,10 @@ public class Workspace extends SmoothPagedView
return false;
}
});
-
- if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
- completedPackages.add(installInfo.packageName);
- }
- }
-
- // Note that package states are sent only for myUser
- if (!completedPackages.isEmpty()) {
- restorePendingWidgets(completedPackages);
}
}
- private void restorePendingWidgets(final Set<String> installedPackaged) {
- final ArrayList<LauncherAppWidgetInfo> changedInfo = new ArrayList<LauncherAppWidgetInfo>();
-
- // Iterate non recursively as widgets can't be inside a folder.
- mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
-
- @Override
- public boolean evaluate(ItemInfo info, View v, View parent) {
- if (info instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
- if (widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
- && installedPackaged.contains(widgetInfo.providerName.getPackageName())) {
-
- changedInfo.add(widgetInfo);
-
- // Remove the provider not ready flag
- widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
- LauncherModel.updateItemInDatabase(getContext(), widgetInfo);
- }
- }
- // process all the widget
- return false;
- }
- });
+ void widgetsRestored(ArrayList<LauncherAppWidgetInfo> changedInfo) {
if (!changedInfo.isEmpty()) {
DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
mLauncher.getAppWidgetHost());
@@ -5029,6 +4990,13 @@ public class Workspace extends SmoothPagedView
widgetRefresh.run();
} else {
// widgetRefresh will automatically run when the packages are updated.
+ // For now just update the progress bars
+ for (LauncherAppWidgetInfo info : changedInfo) {
+ if (info.hostView instanceof PendingAppWidgetHostView) {
+ info.installProgress = 100;
+ ((PendingAppWidgetHostView) info.hostView).applyState();
+ }
+ }
}
}
}