diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/BubbleTextView.java | 28 | ||||
-rw-r--r-- | src/com/android/launcher3/DeleteDropTarget.java | 22 | ||||
-rw-r--r-- | src/com/android/launcher3/FolderIcon.java | 9 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 9 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 126 | ||||
-rw-r--r-- | src/com/android/launcher3/PreloadIconDrawable.java | 168 | ||||
-rw-r--r-- | src/com/android/launcher3/ShortcutInfo.java | 11 | ||||
-rw-r--r-- | src/com/android/launcher3/StartupReceiver.java | 15 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 12 | ||||
-rw-r--r-- | src/com/android/launcher3/compat/UserHandleCompat.java | 13 |
10 files changed, 353 insertions, 60 deletions
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 57dcea044..3f619a812 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -136,7 +136,8 @@ public class BubbleTextView extends TextView { setContentDescription(info.contentDescription); } setTag(info); - if (info.isPromise()) { + + if (info.wasPromise) { applyState(); } } @@ -431,42 +432,55 @@ public class BubbleTextView extends TextView { } public void applyState() { - int alpha = getResources().getInteger(R.integer.promise_icon_alpha); + final int progressLevel; final int state = getState(); if (DEBUG) Log.d(TAG, "applying icon state: " + state); switch(state) { case ShortcutInfo.PACKAGE_STATE_DEFAULT: super.setText(mDefaultText); - alpha = 255; + progressLevel = 100; break; case ShortcutInfo.PACKAGE_STATE_ENQUEUED: setText(R.string.package_state_enqueued); + progressLevel = 0; break; case ShortcutInfo.PACKAGE_STATE_DOWNLOADING: setText(R.string.package_state_downloading); + // TODO(sunnygoyal): fix progress + progressLevel = 30; break; case ShortcutInfo.PACKAGE_STATE_INSTALLING: setText(R.string.package_state_installing); + progressLevel = 100; break; case ShortcutInfo.PACKAGE_STATE_ERROR: setText(R.string.package_state_error); + progressLevel = 0; break; case ShortcutInfo.PACKAGE_STATE_UNKNOWN: default: + progressLevel = 0; setText(R.string.package_state_unknown); break; } - if (DEBUG) Log.d(TAG, "setting icon alpha to: " + alpha); + Drawable[] drawables = getCompoundDrawables(); - for (int i = 0; i < drawables.length; i++) { - if (drawables[i] != null) { - drawables[i].setAlpha(alpha); + Drawable top = drawables[1]; + if ((top != null) && !(top instanceof PreloadIconDrawable)) { + top = new PreloadIconDrawable(top, getResources()); + setCompoundDrawables(drawables[0], top, drawables[2], drawables[3]); + } + if (top != null) { + top.setLevel(progressLevel); + if ((top instanceof PreloadIconDrawable) + && (state == ShortcutInfo.PACKAGE_STATE_DEFAULT)) { + ((PreloadIconDrawable) top).maybePerformFinishedAnimation(); } } } diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index 20546b8d8..3d45432c2 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -187,11 +187,6 @@ public class DeleteDropTarget extends ButtonDropTarget { if (!willAcceptDrop(info) || isAllAppsWidget(source, info)) { isVisible = false; } - if (useUninstallLabel && - !(((ItemInfo) info).user.equals(UserHandleCompat.myUserHandle()))) { - // Don't support uninstall for apps from other profiles. - isVisible = false; - } if (useUninstallLabel) { setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null); @@ -287,19 +282,16 @@ public class DeleteDropTarget extends ButtonDropTarget { if (isAllAppsApplication(d.dragSource, item)) { // Uninstall the application if it is being dragged from AppsCustomize AppInfo appInfo = (AppInfo) item; - // We don't support uninstalling apps from other profiles. - if (item.user.equals(UserHandleCompat.myUserHandle())) { - mLauncher.startApplicationUninstallActivity(appInfo.componentName, appInfo.flags); - } + mLauncher.startApplicationUninstallActivity(appInfo.componentName, appInfo.flags, + appInfo.user); } else if (isUninstallFromWorkspace(d)) { ShortcutInfo shortcut = (ShortcutInfo) item; - // We don't support uninstalling apps from other profiles. - if (shortcut.intent != null && shortcut.intent.getComponent() != null && - shortcut.user.equals(UserHandleCompat.myUserHandle())) { + if (shortcut.intent != null && shortcut.intent.getComponent() != null) { final ComponentName componentName = shortcut.intent.getComponent(); final DragSource dragSource = d.dragSource; - mWaitingForUninstall = - mLauncher.startApplicationUninstallActivity(componentName, shortcut.flags); + final UserHandleCompat user = shortcut.user; + mWaitingForUninstall = mLauncher.startApplicationUninstallActivity( + componentName, shortcut.flags, user); if (mWaitingForUninstall) { final Runnable checkIfUninstallWasSuccess = new Runnable() { @Override @@ -307,7 +299,7 @@ public class DeleteDropTarget extends ButtonDropTarget { mWaitingForUninstall = false; String packageName = componentName.getPackageName(); boolean uninstallSuccessful = !AllAppsList.packageHasActivities( - getContext(), packageName, UserHandleCompat.myUserHandle()); + getContext(), packageName, user); if (dragSource instanceof Folder) { ((Folder) dragSource). onUninstallActivityReturned(uninstallSuccessful); diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index ab8976a59..4f674f55a 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -605,7 +605,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { computePreviewDrawingParams(mAnimParams.drawable); } else { v = (TextView) items.get(0); - d = v.getCompoundDrawables()[1]; + d = getTopDrawable(v); computePreviewDrawingParams(d); } @@ -614,7 +614,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { for (int i = nItemsInPreview - 1; i >= 0; i--) { v = (TextView) items.get(i); if (!mHiddenItems.contains(v.getTag())) { - d = v.getCompoundDrawables()[1]; + d = getTopDrawable(v); mParams = computePreviewItemDrawingParams(i, mParams); mParams.drawable = d; drawPreviewItem(canvas, mParams); @@ -625,6 +625,11 @@ public class FolderIcon extends FrameLayout implements FolderListener { } } + private Drawable getTopDrawable(TextView v) { + Drawable d = v.getCompoundDrawables()[1]; + return (d instanceof PreloadIconDrawable) ? ((PreloadIconDrawable) d).mIcon : d; + } + private void animateFirstItem(final Drawable d, int duration, final boolean reverse, final Runnable onCompleteRunnable) { final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a85b5b18d..951b5d459 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1089,6 +1089,9 @@ public class Launcher extends Activity // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing). public void onScrollProgressChanged(float progress); + + // Indicates whether the user is allowed to scroll away from the custom content. + boolean isScrollingAllowed(); } protected boolean hasSettings() { @@ -2718,7 +2721,8 @@ public class Launcher extends Activity } // returns true if the activity was started - boolean startApplicationUninstallActivity(ComponentName componentName, int flags) { + boolean startApplicationUninstallActivity(ComponentName componentName, int flags, + UserHandleCompat user) { if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) { // System applications cannot be installed. For now, show a toast explaining that. // We may give them the option of disabling apps this way. @@ -2732,6 +2736,9 @@ public class Launcher extends Activity Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + if (user != null) { + user.addToIntent(intent, Intent.EXTRA_USER); + } startActivity(intent); return true; } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 29cfbb285..b01db7194 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -19,12 +19,19 @@ package com.android.launcher3; import android.app.SearchManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; -import android.content.*; +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.Intent.ShortcutIconResource; +import android.content.IntentFilter; +import android.content.SharedPreferences; import android.content.pm.ActivityInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.res.Configuration; @@ -45,11 +52,11 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; -import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData; import java.lang.ref.WeakReference; import java.net.URISyntaxException; @@ -63,6 +70,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -157,6 +165,9 @@ public class LauncherModel extends BroadcastReceiver // sBgWorkspaceScreens is the ordered set of workspace screens. static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>(); + // sPendingPackages is a set of packages which could be on sdcard and are not available yet + static final HashMap<UserHandleCompat, HashSet<String>> sPendingPackages = new HashMap<>(); + // </ only access in worker thread > private IconCache mIconCache; @@ -1826,6 +1837,9 @@ public class LauncherModel extends BroadcastReceiver final PackageManager manager = context.getPackageManager(); final AppWidgetManager widgets = AppWidgetManager.getInstance(context); final boolean isSafeMode = manager.isSafeMode(); + final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); + final boolean isSdCardReady = context.registerReceiver(null, + new IntentFilter(StartupReceiver.SYESTEM_READY)) != null; LauncherAppState app = LauncherAppState.getInstance(); DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); @@ -1919,6 +1933,7 @@ public class LauncherModel extends BroadcastReceiver try { int itemType = c.getInt(itemTypeIndex); boolean restored = 0 != c.getInt(restoredIndex); + boolean allowMissingTarget = false; switch (itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: @@ -1935,30 +1950,51 @@ public class LauncherModel extends BroadcastReceiver try { intent = Intent.parseUri(intentDescription, 0); ComponentName cn = intent.getComponent(); - if (cn != null && !isValidPackageActivity(context, cn, user)) { - if (restored) { - // might be installed later + if (cn != null && cn.getPackageName() != null) { + boolean validPkg = launcherApps.isPackageEnabledForProfile( + cn.getPackageName(), user); + boolean validComponent = validPkg && + launcherApps.isActivityEnabledForProfile(cn, user); + + if (validComponent) { + if (restored) { + // no special handling necessary for this item + restoredRows.add(id); + restored = false; + } + } else if (validPkg) { + // The app is installed but the component is no + // longer available. + Launcher.addDumpLog(TAG, + "Invalid component removed: " + cn, true); + itemsToRemove.add(id); + continue; + } else if (restored) { + // Package is not yet available but might be + // installed later. Launcher.addDumpLog(TAG, "package not yet restored: " + cn, true); + } else if (isSdCardReady) { + // Do not wait for external media load anymore. + // Log the invalid package, and remove it + Launcher.addDumpLog(TAG, + "Invalid package removed: " + cn, true); + itemsToRemove.add(id); + continue; } else { - if (!mAppsCanBeOnRemoveableStorage) { - // Log the invalid package, and remove it - Launcher.addDumpLog(TAG, - "Invalid package removed: " + cn, true); - itemsToRemove.add(id); - } else { - // If apps can be on external storage, then we just - // leave them for the user to remove (maybe add - // visual treatment to it) - Launcher.addDumpLog(TAG, - "Invalid package found: " + cn, true); + // SdCard is not ready yet. Package might get available, + // once it is ready. + Launcher.addDumpLog(TAG, "Invalid package: " + cn + + " (check again later)", true); + HashSet<String> pkgs = sPendingPackages.get(user); + if (pkgs == null) { + pkgs = new HashSet<>(); + sPendingPackages.put(user, pkgs); } - continue; + pkgs.add(cn.getPackageName()); + allowMissingTarget = true; + // Add the icon on the workspace anyway. } - } else if (restored) { - // no special handling necessary for this restored item - restoredRows.add(id); - restored = false; } } catch (URISyntaxException e) { Launcher.addDumpLog(TAG, @@ -1980,8 +2016,8 @@ public class LauncherModel extends BroadcastReceiver } } else if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { - info = getShortcutInfo(manager, intent, user, context, c, iconIndex, - titleIndex, mLabelCache); + info = getShortcutInfo(manager, intent, user, context, c, + iconIndex, titleIndex, mLabelCache, allowMissingTarget); } else { info = getShortcutInfo(c, context, iconTypeIndex, iconPackageIndex, iconResourceIndex, iconIndex, @@ -2198,6 +2234,12 @@ public class LauncherModel extends BroadcastReceiver } } + if (!isSdCardReady && !sPendingPackages.isEmpty()) { + context.registerReceiver(new AppsAvailabilityCheck(), + new IntentFilter(StartupReceiver.SYESTEM_READY), + null, sWorker); + } + if (loadedOldDb) { long maxScreenId = 0; // If we're importing we use the old screen order. @@ -2743,6 +2785,33 @@ public class LauncherModel extends BroadcastReceiver sWorker.post(task); } + private class AppsAvailabilityCheck extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + synchronized (sBgLock) { + final LauncherAppsCompat launcherApps = LauncherAppsCompat + .getInstance(mApp.getContext()); + ArrayList<String> packagesRemoved; + for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) { + UserHandleCompat user = entry.getKey(); + packagesRemoved = new ArrayList<>(); + for (String pkg : entry.getValue()) { + if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { + Launcher.addDumpLog(TAG, "Package not found: " + pkg, true); + packagesRemoved.add(pkg); + } + } + if (!packagesRemoved.isEmpty()) { + enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE, + packagesRemoved.toArray(new String[packagesRemoved.size()]), user)); + } + } + sPendingPackages.clear(); + } + } + } + private class PackageUpdatedTask implements Runnable { int mOp; String[] mPackages; @@ -2978,6 +3047,7 @@ public class LauncherModel extends BroadcastReceiver info.setIcon(mIconCache.getIcon(intent, info.title.toString(), info.user)); info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; info.restoredIntent = intent; + info.wasPromise = true; info.setState(ShortcutInfo.PACKAGE_STATE_UNKNOWN); return info; } @@ -3006,7 +3076,7 @@ public class LauncherModel extends BroadcastReceiver */ public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, UserHandleCompat user, Context context) { - return getShortcutInfo(manager, intent, user, context, null, -1, -1, null); + return getShortcutInfo(manager, intent, user, context, null, -1, -1, null, false); } /** @@ -3016,7 +3086,7 @@ public class LauncherModel extends BroadcastReceiver */ public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, UserHandleCompat user, Context context, Cursor c, int iconIndex, int titleIndex, - HashMap<Object, CharSequence> labelCache) { + HashMap<Object, CharSequence> labelCache, boolean allowMissingTarget) { if (user == null) { Log.d(TAG, "Null user found in getShortcutInfo"); return null; @@ -3032,7 +3102,7 @@ public class LauncherModel extends BroadcastReceiver newIntent.addCategory(Intent.CATEGORY_LAUNCHER); newIntent.setComponent(componentName); LauncherActivityInfoCompat lai = mLauncherApps.resolveActivity(newIntent, user); - if (lai == null) { + if ((lai == null) && !allowMissingTarget) { Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName); return null; } diff --git a/src/com/android/launcher3/PreloadIconDrawable.java b/src/com/android/launcher3/PreloadIconDrawable.java new file mode 100644 index 000000000..d9365cc1f --- /dev/null +++ b/src/com/android/launcher3/PreloadIconDrawable.java @@ -0,0 +1,168 @@ +package com.android.launcher3; + +import android.animation.ObjectAnimator; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; + +class PreloadIconDrawable extends Drawable { + private static final float ANIMATION_PROGRESS_STOPPED = -1.0f; + private static final float ANIMATION_PROGRESS_STARTED = 0f; + private static final float ANIMATION_PROGRESS_COMPLETED = 1.0f; + + private static final float ICON_SCALE_FACTOR = 0.6f; + + private static Bitmap sProgressBg, sProgressFill; + + private final Rect mCanvasClipRect = new Rect(); + private final RectF mRect = new RectF(); + private final Path mProgressPath = new Path(); + private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); + + final Drawable mIcon; + + /** + * Indicates the progress of the preloader [0-100]. If it goes above 100, only the icon + * is shown with no progress bar. + */ + private int mProgress = 0; + private boolean mPathChanged; + + private float mAnimationProgress = ANIMATION_PROGRESS_STOPPED; + private ObjectAnimator mAnimator; + + public PreloadIconDrawable(Drawable icon, Resources res) { + mIcon = icon; + + setBounds(icon.getBounds()); + mPathChanged = false; + + if (sProgressBg == null) { + sProgressBg = BitmapFactory.decodeResource(res, R.drawable.bg_preloader); + } + if (sProgressFill == null) { + sProgressFill = BitmapFactory.decodeResource(res, R.drawable.bg_preloader_progress); + } + } + + @Override + public void draw(Canvas canvas) { + final Rect r = getBounds(); + if (canvas.getClipBounds(mCanvasClipRect) && !Rect.intersects(mCanvasClipRect, r)) { + // The draw region has been clipped. + return; + } + final float iconScale; + + if ((mAnimationProgress >= ANIMATION_PROGRESS_STARTED) + && (mAnimationProgress < ANIMATION_PROGRESS_COMPLETED)) { + mPaint.setAlpha((int) ((1 - mAnimationProgress) * 255)); + canvas.drawBitmap(sProgressBg, null, r, mPaint); + canvas.drawBitmap(sProgressFill, null, r, mPaint); + iconScale = ICON_SCALE_FACTOR + (1 - ICON_SCALE_FACTOR) * mAnimationProgress; + + } else if (mAnimationProgress == ANIMATION_PROGRESS_STOPPED) { + mPaint.setAlpha(255); + iconScale = ICON_SCALE_FACTOR; + canvas.drawBitmap(sProgressBg, null, r, mPaint); + + if (mProgress >= 100) { + canvas.drawBitmap(sProgressFill, null, r, mPaint); + } else if (mProgress > 0) { + if (mPathChanged) { + mProgressPath.reset(); + mProgressPath.moveTo(r.exactCenterX(), r.centerY()); + + mRect.set(r); + mProgressPath.arcTo(mRect, -90, mProgress * 3.6f); + mProgressPath.close(); + mPathChanged = false; + } + + canvas.save(); + canvas.clipPath(mProgressPath); + canvas.drawBitmap(sProgressFill, null, r, mPaint); + canvas.restore(); + } + } else { + iconScale = 1; + } + + canvas.save(); + canvas.scale(iconScale, iconScale, r.exactCenterX(), r.exactCenterY()); + mIcon.draw(canvas); + canvas.restore(); + } + + @Override + protected void onBoundsChange(Rect bounds) { + mIcon.setBounds(bounds); + mPathChanged = true; + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public void setAlpha(int alpha) { + mIcon.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter cf) { + mIcon.setColorFilter(cf); + } + + @Override + protected boolean onLevelChange(int level) { + mProgress = level; + mPathChanged = true; + + // Stop Animation + if (mAnimator != null) { + mAnimator.cancel(); + mAnimator = null; + } + mAnimationProgress = ANIMATION_PROGRESS_STOPPED; + + invalidateSelf(); + return true; + } + + /** + * Runs the finish animation if it is has not been run after last level change. + */ + public void maybePerformFinishedAnimation() { + if (mAnimationProgress > ANIMATION_PROGRESS_STOPPED) { + return; + } + if (mAnimator != null) { + mAnimator.cancel(); + } + setAnimationProgress(ANIMATION_PROGRESS_STARTED); + mAnimator = ObjectAnimator.ofFloat(this, "animationProgress", + ANIMATION_PROGRESS_STARTED, ANIMATION_PROGRESS_COMPLETED); + mAnimator.start(); + } + + public void setAnimationProgress(float progress) { + if (progress != mAnimationProgress) { + mAnimationProgress = progress; + invalidateSelf(); + } + } + + public float getAnimationProgress() { + return mAnimationProgress; + } +} diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java index d2573a4a1..7e1f0d649 100644 --- a/src/com/android/launcher3/ShortcutInfo.java +++ b/src/com/android/launcher3/ShortcutInfo.java @@ -16,13 +16,9 @@ package com.android.launcher3; -import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.util.Log; @@ -96,6 +92,11 @@ public class ShortcutInfo extends ItemInfo { */ Intent restoredIntent; + /** + * This is set once to indicate that it was a promise info at some point of its life. + */ + boolean wasPromise = false; + ShortcutInfo() { itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT; } @@ -119,7 +120,7 @@ public class ShortcutInfo extends ItemInfo { } } - ShortcutInfo(Intent intent, CharSequence title, String contentDescrition, + ShortcutInfo(Intent intent, CharSequence title, String contentDescription, Bitmap icon, UserHandleCompat user) { this(); this.intent = intent; diff --git a/src/com/android/launcher3/StartupReceiver.java b/src/com/android/launcher3/StartupReceiver.java new file mode 100644 index 000000000..4499917f0 --- /dev/null +++ b/src/com/android/launcher3/StartupReceiver.java @@ -0,0 +1,15 @@ +package com.android.launcher3; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class StartupReceiver extends BroadcastReceiver { + + static final String SYESTEM_READY = "com.android.launcher3.SYESTEM_READY"; + + @Override + public void onReceive(Context context, Intent intent) { + context.sendStickyBroadcast(new Intent(SYESTEM_READY)); + } +} diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 48795af13..a8e7580c3 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1159,12 +1159,20 @@ public class Workspace extends SmoothPagedView (mTouchDownTime - mCustomContentShowTime) > CUSTOM_CONTENT_GESTURE_DELAY; boolean swipeInIgnoreDirection = isLayoutRtl() ? deltaX < 0 : deltaX > 0; - if (swipeInIgnoreDirection && getScreenIdForPageIndex(getCurrentPage()) == - CUSTOM_CONTENT_SCREEN_ID && passRightSwipesToCustomContent) { + boolean onCustomContentScreen = + getScreenIdForPageIndex(getCurrentPage()) == CUSTOM_CONTENT_SCREEN_ID; + if (swipeInIgnoreDirection && onCustomContentScreen && passRightSwipesToCustomContent) { // Pass swipes to the right to the custom content page. return; } + if (onCustomContentScreen && (mCustomContentCallbacks != null) + && !mCustomContentCallbacks.isScrollingAllowed()) { + // Don't allow workspace scrolling if the current custom content screen doesn't allow + // scrolling. + return; + } + if (theta > MAX_SWIPE_ANGLE) { // Above MAX_SWIPE_ANGLE, we don't want to ever start scrolling the workspace return; diff --git a/src/com/android/launcher3/compat/UserHandleCompat.java b/src/com/android/launcher3/compat/UserHandleCompat.java index 8f5dda238..4baf05247 100644 --- a/src/com/android/launcher3/compat/UserHandleCompat.java +++ b/src/com/android/launcher3/compat/UserHandleCompat.java @@ -16,6 +16,7 @@ package com.android.launcher3.compat; +import android.content.Intent; import android.os.Build; import android.os.UserHandle; @@ -78,4 +79,16 @@ public class UserHandleCompat { return 0; } } + + /** + * Adds {@link UserHandle} to the intent in for L or above. + * Pre-L the launcher doesn't support showing apps for multiple + * profiles so this is a no-op. + */ + public void addToIntent(Intent intent, String name) { + // TODO change this to use api version once L gets an API number. + if ("L".equals(Build.VERSION.CODENAME) && mUser != null) { + intent.putExtra(name, mUser); + } + } }
\ No newline at end of file |