summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/AppsCustomizePagedView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/AppsCustomizePagedView.java')
-rw-r--r--src/com/android/launcher3/AppsCustomizePagedView.java1567
1 files changed, 0 insertions, 1567 deletions
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
deleted file mode 100644
index c8187f068..000000000
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ /dev/null
@@ -1,1567 +0,0 @@
-/*
- * Copyright (C) 2011 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.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Process;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.GridLayout;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A simple callback interface which also provides the results of the task.
- */
-interface AsyncTaskCallback {
- void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data);
-}
-
-/**
- * The data needed to perform either of the custom AsyncTasks.
- */
-class AsyncTaskPageData {
- enum Type {
- LoadWidgetPreviewData
- }
-
- AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR,
- AsyncTaskCallback postR, WidgetPreviewLoader w) {
- page = p;
- items = l;
- generatedImages = new ArrayList<Bitmap>();
- maxImageWidth = cw;
- maxImageHeight = ch;
- doInBackgroundCallback = bgR;
- postExecuteCallback = postR;
- widgetPreviewLoader = w;
- }
- void cleanup(boolean cancelled) {
- // Clean up any references to source/generated bitmaps
- if (generatedImages != null) {
- if (cancelled) {
- for (int i = 0; i < generatedImages.size(); i++) {
- widgetPreviewLoader.recycleBitmap(items.get(i), generatedImages.get(i));
- }
- }
- generatedImages.clear();
- }
- }
- int page;
- ArrayList<Object> items;
- ArrayList<Bitmap> sourceImages;
- ArrayList<Bitmap> generatedImages;
- int maxImageWidth;
- int maxImageHeight;
- AsyncTaskCallback doInBackgroundCallback;
- AsyncTaskCallback postExecuteCallback;
- WidgetPreviewLoader widgetPreviewLoader;
-}
-
-/**
- * A generic template for an async task used in AppsCustomize.
- */
-class AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> {
- AppsCustomizeAsyncTask(int p, AsyncTaskPageData.Type ty) {
- page = p;
- threadPriority = Process.THREAD_PRIORITY_DEFAULT;
- dataType = ty;
- }
- @Override
- protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) {
- if (params.length != 1) return null;
- // Load each of the widget previews in the background
- params[0].doInBackgroundCallback.run(this, params[0]);
- return params[0];
- }
- @Override
- protected void onPostExecute(AsyncTaskPageData result) {
- // All the widget previews are loaded, so we can just callback to inflate the page
- result.postExecuteCallback.run(this, result);
- }
-
- void setThreadPriority(int p) {
- threadPriority = p;
- }
- void syncThreadPriority() {
- Process.setThreadPriority(threadPriority);
- }
-
- // The page that this async task is associated with
- AsyncTaskPageData.Type dataType;
- int page;
- int threadPriority;
-}
-
-/**
- * The Apps/Customize page that displays all the applications, widgets, and shortcuts.
- */
-public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
- View.OnClickListener, View.OnKeyListener, DragSource,
- PagedViewWidget.ShortPressListener, LauncherTransitionable {
- static final String TAG = "AppsCustomizePagedView";
-
- private static Rect sTmpRect = new Rect();
-
- /**
- * The different content types that this paged view can show.
- */
- public enum ContentType {
- Applications,
- Widgets
- }
- private ContentType mContentType = ContentType.Applications;
-
- // Refs
- private Launcher mLauncher;
- private DragController mDragController;
- private final LayoutInflater mLayoutInflater;
- private final PackageManager mPackageManager;
-
- // Save and Restore
- private int mSaveInstanceStateItemIndex = -1;
-
- // Content
- private ArrayList<AppInfo> mApps;
- private ArrayList<Object> mWidgets;
-
- // Caching
- private IconCache mIconCache;
-
- // Dimens
- private int mContentWidth, mContentHeight;
- private int mWidgetCountX, mWidgetCountY;
- private PagedViewCellLayout mWidgetSpacingLayout;
- private int mNumAppsPages;
- private int mNumWidgetPages;
- private Rect mAllAppsPadding = new Rect();
-
- // Previews & outlines
- ArrayList<AppsCustomizeAsyncTask> mRunningTasks;
- private static final int sPageSleepDelay = 200;
-
- private Runnable mInflateWidgetRunnable = null;
- private Runnable mBindWidgetRunnable = null;
- static final int WIDGET_NO_CLEANUP_REQUIRED = -1;
- static final int WIDGET_PRELOAD_PENDING = 0;
- static final int WIDGET_BOUND = 1;
- static final int WIDGET_INFLATED = 2;
- int mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
- int mWidgetLoadingId = -1;
- PendingAddWidgetInfo mCreateWidgetInfo = null;
- private boolean mDraggingWidget = false;
- boolean mPageBackgroundsVisible = true;
-
- private Toast mWidgetInstructionToast;
-
- // Deferral of loading widget previews during launcher transitions
- private boolean mInTransition;
- private ArrayList<AsyncTaskPageData> mDeferredSyncWidgetPageItems =
- new ArrayList<AsyncTaskPageData>();
- private ArrayList<Runnable> mDeferredPrepareLoadWidgetPreviewsTasks =
- new ArrayList<Runnable>();
-
- WidgetPreviewLoader mWidgetPreviewLoader;
-
- private boolean mInBulkBind;
- private boolean mNeedToUpdatePageCountsAndInvalidateData;
-
- public AppsCustomizePagedView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mLayoutInflater = LayoutInflater.from(context);
- mPackageManager = context.getPackageManager();
- mApps = new ArrayList<AppInfo>();
- mWidgets = new ArrayList<Object>();
- mIconCache = (LauncherAppState.getInstance()).getIconCache();
- mRunningTasks = new ArrayList<AppsCustomizeAsyncTask>();
-
- // Save the default widget preview background
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0);
- mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2);
- mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2);
- a.recycle();
- mWidgetSpacingLayout = new PagedViewCellLayout(getContext());
-
- // The padding on the non-matched dimension for the default widget preview icons
- // (top + bottom)
- mFadeInAdjacentScreens = false;
-
- // Unless otherwise specified this view is important for accessibility.
- if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
- setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- }
- setSinglePageInViewport();
- }
-
- @Override
- protected void init() {
- super.init();
- mCenterPagesVertically = false;
-
- Context context = getContext();
- Resources r = context.getResources();
- setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
- }
-
- public void onFinishInflate() {
- super.onFinishInflate();
-
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- setPadding(grid.edgeMarginPx, 2 * grid.edgeMarginPx,
- grid.edgeMarginPx, 2 * grid.edgeMarginPx);
- }
-
- void setAllAppsPadding(Rect r) {
- mAllAppsPadding.set(r);
- }
-
- void setWidgetsPageIndicatorPadding(int pageIndicatorHeight) {
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), pageIndicatorHeight);
- }
-
- WidgetPreviewLoader getWidgetPreviewLoader() {
- if (mWidgetPreviewLoader == null) {
- mWidgetPreviewLoader = new WidgetPreviewLoader(mLauncher);
- }
- return mWidgetPreviewLoader;
- }
-
- /** Returns the item index of the center item on this page so that we can restore to this
- * item index when we rotate. */
- private int getMiddleComponentIndexOnCurrentPage() {
- int i = -1;
- if (getPageCount() > 0) {
- int currentPage = getCurrentPage();
- if (mContentType == ContentType.Applications) {
- AppsCustomizeCellLayout layout = (AppsCustomizeCellLayout) getPageAt(currentPage);
- ShortcutAndWidgetContainer childrenLayout = layout.getShortcutsAndWidgets();
- int numItemsPerPage = mCellCountX * mCellCountY;
- int childCount = childrenLayout.getChildCount();
- if (childCount > 0) {
- i = (currentPage * numItemsPerPage) + (childCount / 2);
- }
- } else if (mContentType == ContentType.Widgets) {
- int numApps = mApps.size();
- PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(currentPage);
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
- int childCount = layout.getChildCount();
- if (childCount > 0) {
- i = numApps +
- (currentPage * numItemsPerPage) + (childCount / 2);
- }
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
- }
- return i;
- }
-
- /** Get the index of the item to restore to if we need to restore the current page. */
- int getSaveInstanceStateIndex() {
- if (mSaveInstanceStateItemIndex == -1) {
- mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage();
- }
- return mSaveInstanceStateItemIndex;
- }
-
- /** Returns the page in the current orientation which is expected to contain the specified
- * item index. */
- int getPageForComponent(int index) {
- if (index < 0) return 0;
-
- if (index < mApps.size()) {
- int numItemsPerPage = mCellCountX * mCellCountY;
- return (index / numItemsPerPage);
- } else {
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
- return (index - mApps.size()) / numItemsPerPage;
- }
- }
-
- /** Restores the page for an item at the specified index */
- void restorePageForIndex(int index) {
- if (index < 0) return;
- mSaveInstanceStateItemIndex = index;
- }
-
- private void updatePageCounts() {
- mNumWidgetPages = (int) Math.ceil(mWidgets.size() /
- (float) (mWidgetCountX * mWidgetCountY));
- mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
- }
-
- protected void onDataReady(int width, int height) {
- // Now that the data is ready, we can calculate the content width, the number of cells to
- // use for each page
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- mCellCountX = (int) grid.allAppsNumCols;
- mCellCountY = (int) grid.allAppsNumRows;
- updatePageCounts();
-
- // Force a measure to update recalculate the gaps
- mContentWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
- mContentHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
- int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST);
- int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST);
- mWidgetSpacingLayout.measure(widthSpec, heightSpec);
-
- final boolean hostIsTransitioning = getTabHost().isInTransition();
- int page = getPageForComponent(mSaveInstanceStateItemIndex);
- invalidatePageData(Math.max(0, page), hostIsTransitioning);
- }
-
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
-
- if (!isDataReady()) {
- if ((LauncherAppState.isDisableAllApps() || !mApps.isEmpty()) && !mWidgets.isEmpty()) {
- post(new Runnable() {
- // This code triggers requestLayout so must be posted outside of the
- // layout pass.
- public void run() {
- if (Utilities.isViewAttachedToWindow(AppsCustomizePagedView.this)) {
- setDataIsReady();
- onDataReady(getMeasuredWidth(), getMeasuredHeight());
- }
- }
- });
- }
- }
- }
-
- public void onPackagesUpdated(ArrayList<Object> widgetsAndShortcuts) {
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-
- // Get the list of widgets and shortcuts
- mWidgets.clear();
- for (Object o : widgetsAndShortcuts) {
- if (o instanceof AppWidgetProviderInfo) {
- AppWidgetProviderInfo widget = (AppWidgetProviderInfo) o;
- if (!app.shouldShowAppOrWidgetProvider(widget.provider)) {
- continue;
- }
- if (widget.minWidth > 0 && widget.minHeight > 0) {
- // Ensure that all widgets we show can be added on a workspace of this size
- int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget);
- int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget);
- int minSpanX = Math.min(spanXY[0], minSpanXY[0]);
- int minSpanY = Math.min(spanXY[1], minSpanXY[1]);
- if (minSpanX <= (int) grid.numColumns &&
- minSpanY <= (int) grid.numRows) {
- mWidgets.add(widget);
- } else {
- Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" +
- widget.minWidth + ", " + widget.minHeight + ")");
- }
- } else {
- Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
- widget.minWidth + ", " + widget.minHeight + ")");
- }
- } else {
- // just add shortcuts
- mWidgets.add(o);
- }
- }
- updatePageCountsAndInvalidateData();
- }
-
- public void setBulkBind(boolean bulkBind) {
- if (bulkBind) {
- mInBulkBind = true;
- } else {
- mInBulkBind = false;
- if (mNeedToUpdatePageCountsAndInvalidateData) {
- updatePageCountsAndInvalidateData();
- }
- }
- }
-
- private void updatePageCountsAndInvalidateData() {
- if (mInBulkBind) {
- mNeedToUpdatePageCountsAndInvalidateData = true;
- } else {
- updatePageCounts();
- invalidateOnDataChange();
- mNeedToUpdatePageCountsAndInvalidateData = false;
- }
- }
-
- @Override
- public void onClick(View v) {
- // When we have exited all apps or are in transition, disregard clicks
- if (!mLauncher.isAllAppsVisible()
- || mLauncher.getWorkspace().isSwitchingState()
- || !(v instanceof PagedViewWidget)) return;
-
- // Let the user know that they have to long press to add a widget
- if (mWidgetInstructionToast != null) {
- mWidgetInstructionToast.cancel();
- }
- mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add,
- Toast.LENGTH_SHORT);
- mWidgetInstructionToast.show();
-
- // Create a little animation to show that the widget can move
- float offsetY = getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY);
- final ImageView p = (ImageView) v.findViewById(R.id.widget_preview);
- AnimatorSet bounce = LauncherAnimUtils.createAnimatorSet();
- ValueAnimator tyuAnim = LauncherAnimUtils.ofFloat(p, "translationY", offsetY);
- tyuAnim.setDuration(125);
- ValueAnimator tydAnim = LauncherAnimUtils.ofFloat(p, "translationY", 0f);
- tydAnim.setDuration(100);
- bounce.play(tyuAnim).before(tydAnim);
- bounce.setInterpolator(new AccelerateInterpolator());
- bounce.start();
- }
-
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- return FocusHelper.handleAppsCustomizeKeyEvent(v, keyCode, event);
- }
-
- /*
- * PagedViewWithDraggableItems implementation
- */
- @Override
- protected void determineDraggingStart(android.view.MotionEvent ev) {
- // Disable dragging by pulling an app down for now.
- }
-
- private void beginDraggingApplication(View v) {
- mLauncher.getWorkspace().beginDragShared(v, this);
- }
-
- static Bundle getDefaultOptionsForWidget(Launcher launcher, PendingAddWidgetInfo info) {
- Bundle options = null;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- AppWidgetResizeFrame.getWidgetSizeRanges(launcher, info.spanX, info.spanY, sTmpRect);
- Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(launcher,
- info.componentName, null);
-
- float density = launcher.getResources().getDisplayMetrics().density;
- int xPaddingDips = (int) ((padding.left + padding.right) / density);
- int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
-
- options = new Bundle();
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
- sTmpRect.left - xPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
- sTmpRect.top - yPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
- sTmpRect.right - xPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
- sTmpRect.bottom - yPaddingDips);
- }
- return options;
- }
-
- private void preloadWidget(final PendingAddWidgetInfo info) {
- final AppWidgetProviderInfo pInfo = info.info;
- final Bundle options = getDefaultOptionsForWidget(mLauncher, info);
-
- if (pInfo.configure != null) {
- info.bindOptions = options;
- return;
- }
-
- mWidgetCleanupState = WIDGET_PRELOAD_PENDING;
- mBindWidgetRunnable = new Runnable() {
- @Override
- public void run() {
- mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
- if(AppWidgetManagerCompat.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
- mWidgetLoadingId, pInfo, options)) {
- mWidgetCleanupState = WIDGET_BOUND;
- }
- }
- };
- post(mBindWidgetRunnable);
-
- mInflateWidgetRunnable = new Runnable() {
- @Override
- public void run() {
- if (mWidgetCleanupState != WIDGET_BOUND) {
- return;
- }
- AppWidgetHostView hostView = mLauncher.
- getAppWidgetHost().createView(getContext(), mWidgetLoadingId, pInfo);
- info.boundWidget = hostView;
- mWidgetCleanupState = WIDGET_INFLATED;
- hostView.setVisibility(INVISIBLE);
- int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(info.spanX,
- info.spanY, info, false);
-
- // We want the first widget layout to be the correct size. This will be important
- // for width size reporting to the AppWidgetManager.
- DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0],
- unScaledSize[1]);
- lp.x = lp.y = 0;
- lp.customPosition = true;
- hostView.setLayoutParams(lp);
- mLauncher.getDragLayer().addView(hostView);
- }
- };
- post(mInflateWidgetRunnable);
- }
-
- @Override
- public void onShortPress(View v) {
- // We are anticipating a long press, and we use this time to load bind and instantiate
- // the widget. This will need to be cleaned up if it turns out no long press occurs.
- if (mCreateWidgetInfo != null) {
- // Just in case the cleanup process wasn't properly executed. This shouldn't happen.
- cleanupWidgetPreloading(false);
- }
- mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag());
- preloadWidget(mCreateWidgetInfo);
- }
-
- private void cleanupWidgetPreloading(boolean widgetWasAdded) {
- if (!widgetWasAdded) {
- // If the widget was not added, we may need to do further cleanup.
- PendingAddWidgetInfo info = mCreateWidgetInfo;
- mCreateWidgetInfo = null;
-
- if (mWidgetCleanupState == WIDGET_PRELOAD_PENDING) {
- // We never did any preloading, so just remove pending callbacks to do so
- removeCallbacks(mBindWidgetRunnable);
- removeCallbacks(mInflateWidgetRunnable);
- } else if (mWidgetCleanupState == WIDGET_BOUND) {
- // Delete the widget id which was allocated
- if (mWidgetLoadingId != -1) {
- mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
- }
-
- // We never got around to inflating the widget, so remove the callback to do so.
- removeCallbacks(mInflateWidgetRunnable);
- } else if (mWidgetCleanupState == WIDGET_INFLATED) {
- // Delete the widget id which was allocated
- if (mWidgetLoadingId != -1) {
- mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
- }
-
- // The widget was inflated and added to the DragLayer -- remove it.
- AppWidgetHostView widget = info.boundWidget;
- mLauncher.getDragLayer().removeView(widget);
- }
- }
- mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
- mWidgetLoadingId = -1;
- mCreateWidgetInfo = null;
- PagedViewWidget.resetShortPressTarget();
- }
-
- @Override
- public void cleanUpShortPress(View v) {
- if (!mDraggingWidget) {
- cleanupWidgetPreloading(false);
- }
- }
-
- private boolean beginDraggingWidget(View v) {
- mDraggingWidget = true;
- // Get the widget preview as the drag representation
- ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
- PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
-
- // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
- // we abort the drag.
- if (image.getDrawable() == null) {
- mDraggingWidget = false;
- return false;
- }
-
- // Compose the drag image
- Bitmap preview;
- Bitmap outline;
- float scale = 1f;
- Point previewPadding = null;
-
- if (createItemInfo instanceof PendingAddWidgetInfo) {
- // This can happen in some weird cases involving multi-touch. We can't start dragging
- // the widget if this is null, so we break out.
- if (mCreateWidgetInfo == null) {
- return false;
- }
-
- PendingAddWidgetInfo createWidgetInfo = mCreateWidgetInfo;
- createItemInfo = createWidgetInfo;
- int spanX = createItemInfo.spanX;
- int spanY = createItemInfo.spanY;
- int[] size = mLauncher.getWorkspace().estimateItemSize(spanX, spanY,
- createWidgetInfo, true);
-
- FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable();
- float minScale = 1.25f;
- int maxWidth, maxHeight;
- maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]);
- maxHeight = Math.min((int) (previewDrawable.getIntrinsicHeight() * minScale), size[1]);
-
- int[] previewSizeBeforeScale = new int[1];
-
- preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.info,
- spanX, spanY, maxWidth, maxHeight, null, previewSizeBeforeScale);
-
- // Compare the size of the drag preview to the preview in the AppsCustomize tray
- int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0],
- getWidgetPreviewLoader().maxWidthForWidgetPreview(spanX));
- scale = previewWidthInAppsCustomize / (float) preview.getWidth();
-
- // The bitmap in the AppsCustomize tray is always the the same size, so there
- // might be extra pixels around the preview itself - this accounts for that
- if (previewWidthInAppsCustomize < previewDrawable.getIntrinsicWidth()) {
- int padding =
- (previewDrawable.getIntrinsicWidth() - previewWidthInAppsCustomize) / 2;
- previewPadding = new Point(padding, 0);
- }
- } else {
- PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
- Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.shortcutActivityInfo);
- preview = Utilities.createIconBitmap(icon, mLauncher);
- createItemInfo.spanX = createItemInfo.spanY = 1;
- }
-
- // Don't clip alpha values for the drag outline if we're using the default widget preview
- boolean clipAlpha = !(createItemInfo instanceof PendingAddWidgetInfo &&
- (((PendingAddWidgetInfo) createItemInfo).previewImage == 0));
-
- // Save the preview for the outline generation, then dim the preview
- outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(),
- false);
-
- // Start the drag
- mLauncher.lockScreenOrientation();
- mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, outline, clipAlpha);
- mDragController.startDrag(image, preview, this, createItemInfo,
- DragController.DRAG_ACTION_COPY, previewPadding, scale);
- outline.recycle();
- preview.recycle();
- return true;
- }
-
- @Override
- protected boolean beginDragging(final View v) {
- if (!super.beginDragging(v)) return false;
-
- if (v instanceof BubbleTextView) {
- beginDraggingApplication(v);
- } else if (v instanceof PagedViewWidget) {
- if (!beginDraggingWidget(v)) {
- return 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);
-
- return true;
- }
-
- /**
- * Clean up after dragging.
- *
- * @param target where the item was dragged to (can be null if the item was flung)
- */
- private void endDragging(View target, boolean isFlingToDelete, boolean success) {
- if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
- !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
- // Exit spring loaded mode if we have not successfully dropped or have not handled the
- // drop in Workspace
- mLauncher.exitSpringLoadedDragModeDelayed(true,
- Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
- mLauncher.unlockScreenOrientation(false);
- } else {
- mLauncher.unlockScreenOrientation(false);
- }
- }
-
- @Override
- public View getContent() {
- if (getChildCount() > 0) {
- return getChildAt(0);
- }
- return null;
- }
-
- @Override
- public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
- mInTransition = true;
- if (toWorkspace) {
- cancelAllTasks();
- }
- }
-
- @Override
- public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
- }
-
- @Override
- public void onLauncherTransitionStep(Launcher l, float t) {
- }
-
- @Override
- public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
- mInTransition = false;
- for (AsyncTaskPageData d : mDeferredSyncWidgetPageItems) {
- onSyncWidgetPageItems(d, false);
- }
- mDeferredSyncWidgetPageItems.clear();
- for (Runnable r : mDeferredPrepareLoadWidgetPreviewsTasks) {
- r.run();
- }
- mDeferredPrepareLoadWidgetPreviewsTasks.clear();
- mForceDrawAllChildrenNextFrame = !toWorkspace;
- }
-
- @Override
- public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
- boolean success) {
- // Return early and wait for onFlingToDeleteCompleted if this was the result of a fling
- if (isFlingToDelete) return;
-
- endDragging(target, false, success);
-
- // Display an error message if the drag failed due to there not being enough space on the
- // target layout we were dropping on.
- if (!success) {
- boolean showOutOfSpaceMessage = false;
- if (target instanceof Workspace) {
- int currentScreen = mLauncher.getCurrentWorkspaceScreen();
- Workspace workspace = (Workspace) target;
- CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
- ItemInfo itemInfo = (ItemInfo) d.dragInfo;
- if (layout != null) {
- layout.calculateSpans(itemInfo);
- showOutOfSpaceMessage =
- !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
- }
- }
- if (showOutOfSpaceMessage) {
- mLauncher.showOutOfSpaceMessage(false);
- }
-
- d.deferDragViewCleanupPostAnimation = false;
- }
- cleanupWidgetPreloading(success);
- mDraggingWidget = false;
- }
-
- @Override
- public void onFlingToDeleteCompleted() {
- // We just dismiss the drag when we fling, so cleanup here
- endDragging(null, true, true);
- cleanupWidgetPreloading(false);
- mDraggingWidget = false;
- }
-
- @Override
- public boolean supportsFlingToDelete() {
- return true;
- }
-
- @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();
- return (float) grid.allAppsIconSizePx / grid.iconSizePx;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- cancelAllTasks();
- }
-
- @Override
- public void trimMemory() {
- super.trimMemory();
- clearAllWidgetPages();
- }
-
- public void clearAllWidgetPages() {
- cancelAllTasks();
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- View v = getPageAt(i);
- if (v instanceof PagedViewGridLayout) {
- ((PagedViewGridLayout) v).removeAllViewsOnPage();
- mDirtyPageContent.set(i, true);
- }
- }
- }
-
- private void cancelAllTasks() {
- // Clean up all the async tasks
- Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
- while (iter.hasNext()) {
- AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
- task.cancel(false);
- iter.remove();
- mDirtyPageContent.set(task.page, true);
-
- // We've already preallocated the views for the data to load into, so clear them as well
- View v = getPageAt(task.page);
- if (v instanceof PagedViewGridLayout) {
- ((PagedViewGridLayout) v).removeAllViewsOnPage();
- }
- }
- mDeferredSyncWidgetPageItems.clear();
- mDeferredPrepareLoadWidgetPreviewsTasks.clear();
- }
-
- public void setContentType(ContentType type) {
- // Widgets appear to be cleared every time you leave, always force invalidate for them
- if (mContentType != type || type == ContentType.Widgets) {
- int page = (mContentType != type) ? 0 : getCurrentPage();
- mContentType = type;
- invalidatePageData(page, true);
- }
- }
-
- public ContentType getContentType() {
- return mContentType;
- }
-
- protected void snapToPage(int whichPage, int delta, int duration) {
- super.snapToPage(whichPage, delta, duration);
-
- // Update the thread priorities given the direction lookahead
- Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
- while (iter.hasNext()) {
- AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
- int pageIndex = task.page;
- if ((mNextPage > mCurrentPage && pageIndex >= mCurrentPage) ||
- (mNextPage < mCurrentPage && pageIndex <= mCurrentPage)) {
- task.setThreadPriority(getThreadPriorityForPage(pageIndex));
- } else {
- task.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
- }
- }
- }
-
- /*
- * Apps PagedView implementation
- */
- private void setVisibilityOnChildren(ViewGroup layout, int visibility) {
- int childCount = layout.getChildCount();
- for (int i = 0; i < childCount; ++i) {
- layout.getChildAt(i).setVisibility(visibility);
- }
- }
- private void setupPage(AppsCustomizeCellLayout layout) {
- layout.setGridSize(mCellCountX, mCellCountY);
-
- // Note: We force a measure here to get around the fact that when we do layout calculations
- // immediately after syncing, we don't have a proper width. That said, we already know the
- // expected page width, so we can actually optimize by hiding all the TextView-based
- // children that are expensive to measure, and let that happen naturally later.
- setVisibilityOnChildren(layout, View.GONE);
- int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST);
- int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST);
- layout.measure(widthSpec, heightSpec);
-
- Drawable bg = getContext().getResources().getDrawable(R.drawable.quantum_panel);
- if (bg != null) {
- bg.setAlpha(mPageBackgroundsVisible ? 255: 0);
- layout.setBackground(bg);
- }
-
- setVisibilityOnChildren(layout, View.VISIBLE);
- }
-
- public void setPageBackgroundsVisible(boolean visible) {
- mPageBackgroundsVisible = visible;
- int childCount = getChildCount();
- for (int i = 0; i < childCount; ++i) {
- Drawable bg = getChildAt(i).getBackground();
- if (bg != null) {
- bg.setAlpha(visible ? 255 : 0);
- }
- }
- }
-
- public void syncAppsPageItems(int page, boolean immediate) {
- // ensure that we have the right number of items on the pages
- final boolean isRtl = isLayoutRtl();
- int numCells = mCellCountX * mCellCountY;
- int startIndex = page * numCells;
- int endIndex = Math.min(startIndex + numCells, mApps.size());
- AppsCustomizeCellLayout layout = (AppsCustomizeCellLayout) getPageAt(page);
-
- layout.removeAllViewsOnPage();
- ArrayList<Object> items = new ArrayList<Object>();
- ArrayList<Bitmap> images = new ArrayList<Bitmap>();
- for (int i = startIndex; i < endIndex; ++i) {
- AppInfo info = mApps.get(i);
- BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
- R.layout.apps_customize_application, layout, false);
- icon.applyFromApplicationInfo(info);
- icon.setOnClickListener(mLauncher);
- icon.setOnLongClickListener(this);
- icon.setOnTouchListener(this);
- icon.setOnKeyListener(this);
- icon.setOnFocusChangeListener(layout.mFocusHandlerView);
-
- int index = i - startIndex;
- int x = index % mCellCountX;
- int y = index / mCellCountX;
- if (isRtl) {
- x = mCellCountX - x - 1;
- }
- layout.addViewToCellLayout(icon, -1, i, new CellLayout.LayoutParams(x,y, 1,1), false);
-
- items.add(info);
- images.add(info.iconBitmap);
- }
-
- enableHwLayersOnVisiblePages();
- }
-
- /**
- * A helper to return the priority for loading of the specified widget page.
- */
- private int getWidgetPageLoadPriority(int page) {
- // If we are snapping to another page, use that index as the target page index
- int toPage = mCurrentPage;
- if (mNextPage > -1) {
- toPage = mNextPage;
- }
-
- // We use the distance from the target page as an initial guess of priority, but if there
- // are no pages of higher priority than the page specified, then bump up the priority of
- // the specified page.
- Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
- int minPageDiff = Integer.MAX_VALUE;
- while (iter.hasNext()) {
- AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
- minPageDiff = Math.abs(task.page - toPage);
- }
-
- int rawPageDiff = Math.abs(page - toPage);
- return rawPageDiff - Math.min(rawPageDiff, minPageDiff);
- }
- /**
- * Return the appropriate thread priority for loading for a given page (we give the current
- * page much higher priority)
- */
- private int getThreadPriorityForPage(int page) {
- // TODO-APPS_CUSTOMIZE: detect number of cores and set thread priorities accordingly below
- int pageDiff = getWidgetPageLoadPriority(page);
- if (pageDiff <= 0) {
- return Process.THREAD_PRIORITY_LESS_FAVORABLE;
- } else if (pageDiff <= 1) {
- return Process.THREAD_PRIORITY_LOWEST;
- } else {
- return Process.THREAD_PRIORITY_LOWEST;
- }
- }
- private int getSleepForPage(int page) {
- int pageDiff = getWidgetPageLoadPriority(page);
- return Math.max(0, pageDiff * sPageSleepDelay);
- }
- /**
- * Creates and executes a new AsyncTask to load a page of widget previews.
- */
- private void prepareLoadWidgetPreviewsTask(int page, ArrayList<Object> widgets,
- int cellWidth, int cellHeight, int cellCountX) {
-
- // Prune all tasks that are no longer needed
- Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
- while (iter.hasNext()) {
- AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
- int taskPage = task.page;
- if (taskPage < getAssociatedLowerPageBound(mCurrentPage) ||
- taskPage > getAssociatedUpperPageBound(mCurrentPage)) {
- task.cancel(false);
- iter.remove();
- } else {
- task.setThreadPriority(getThreadPriorityForPage(taskPage));
- }
- }
-
- // We introduce a slight delay to order the loading of side pages so that we don't thrash
- final int sleepMs = getSleepForPage(page);
- AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight,
- new AsyncTaskCallback() {
- @Override
- public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
- try {
- try {
- Thread.sleep(sleepMs);
- } catch (Exception e) {}
- loadWidgetPreviewsInBackground(task, data);
- } finally {
- if (task.isCancelled()) {
- data.cleanup(true);
- }
- }
- }
- },
- new AsyncTaskCallback() {
- @Override
- public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
- mRunningTasks.remove(task);
- if (task.isCancelled()) return;
- // do cleanup inside onSyncWidgetPageItems
- onSyncWidgetPageItems(data, false);
- }
- }, getWidgetPreviewLoader());
-
- // Ensure that the task is appropriately prioritized and runs in parallel
- AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page,
- AsyncTaskPageData.Type.LoadWidgetPreviewData);
- t.setThreadPriority(getThreadPriorityForPage(page));
- t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData);
- mRunningTasks.add(t);
- }
-
- /*
- * Widgets PagedView implementation
- */
- private void setupPage(PagedViewGridLayout layout) {
- // Note: We force a measure here to get around the fact that when we do layout calculations
- // immediately after syncing, we don't have a proper width.
- int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST);
- int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST);
-
- Drawable bg = getContext().getResources().getDrawable(R.drawable.quantum_panel_dark);
- if (bg != null) {
- bg.setAlpha(mPageBackgroundsVisible ? 255 : 0);
- layout.setBackground(bg);
- }
- layout.measure(widthSpec, heightSpec);
- }
-
- public void syncWidgetPageItems(final int page, final boolean immediate) {
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
-
- final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
-
- // Calculate the dimensions of each cell we are giving to each widget
- final ArrayList<Object> items = new ArrayList<Object>();
- int contentWidth = mContentWidth - layout.getPaddingLeft() - layout.getPaddingRight();
- final int cellWidth = contentWidth / mWidgetCountX;
- int contentHeight = mContentHeight - layout.getPaddingTop() - layout.getPaddingBottom();
-
- final int cellHeight = contentHeight / mWidgetCountY;
-
- // Prepare the set of widgets to load previews for in the background
- int offset = page * numItemsPerPage;
- for (int i = offset; i < Math.min(offset + numItemsPerPage, mWidgets.size()); ++i) {
- items.add(mWidgets.get(i));
- }
-
- // Prepopulate the pages with the other widget info, and fill in the previews later
- layout.setColumnCount(layout.getCellCountX());
- for (int i = 0; i < items.size(); ++i) {
- Object rawInfo = items.get(i);
- PendingAddItemInfo createItemInfo = null;
- PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
- R.layout.apps_customize_widget, layout, false);
- if (rawInfo instanceof AppWidgetProviderInfo) {
- // Fill in the widget information
- AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
- createItemInfo = new PendingAddWidgetInfo(info, null, null);
-
- // Determine the widget spans and min resize spans.
- int[] spanXY = Launcher.getSpanForWidget(mLauncher, info);
- createItemInfo.spanX = spanXY[0];
- createItemInfo.spanY = spanXY[1];
- int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, info);
- createItemInfo.minSpanX = minSpanXY[0];
- createItemInfo.minSpanY = minSpanXY[1];
-
- widget.applyFromAppWidgetProviderInfo(info, -1, spanXY, getWidgetPreviewLoader());
- widget.setTag(createItemInfo);
- widget.setShortPressListener(this);
- } else if (rawInfo instanceof ResolveInfo) {
- // Fill in the shortcuts information
- ResolveInfo info = (ResolveInfo) rawInfo;
- createItemInfo = new PendingAddShortcutInfo(info.activityInfo);
- createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
- createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
- info.activityInfo.name);
- widget.applyFromResolveInfo(mPackageManager, info, getWidgetPreviewLoader());
- widget.setTag(createItemInfo);
- }
- widget.setOnClickListener(this);
- widget.setOnLongClickListener(this);
- widget.setOnTouchListener(this);
- widget.setOnKeyListener(this);
-
- // Layout each widget
- int ix = i % mWidgetCountX;
- int iy = i / mWidgetCountX;
-
- if (ix > 0) {
- View border = widget.findViewById(R.id.left_border);
- border.setVisibility(View.VISIBLE);
- }
- if (ix < mWidgetCountX - 1) {
- View border = widget.findViewById(R.id.right_border);
- border.setVisibility(View.VISIBLE);
- }
-
- GridLayout.LayoutParams lp = new GridLayout.LayoutParams(
- GridLayout.spec(iy, GridLayout.START),
- GridLayout.spec(ix, GridLayout.TOP));
- lp.width = cellWidth;
- lp.height = cellHeight;
- lp.setGravity(Gravity.TOP | Gravity.START);
- layout.addView(widget, lp);
- }
-
- // wait until a call on onLayout to start loading, because
- // PagedViewWidget.getPreviewSize() will return 0 if it hasn't been laid out
- // TODO: can we do a measure/layout immediately?
- layout.setOnLayoutListener(new Runnable() {
- public void run() {
- // Load the widget previews
- int maxPreviewWidth = cellWidth;
- int maxPreviewHeight = cellHeight;
- if (layout.getChildCount() > 0) {
- PagedViewWidget w = (PagedViewWidget) layout.getChildAt(0);
- int[] maxSize = w.getPreviewSize();
- maxPreviewWidth = maxSize[0];
- maxPreviewHeight = maxSize[1];
- }
-
- getWidgetPreviewLoader().setPreviewSize(
- maxPreviewWidth, maxPreviewHeight, mWidgetSpacingLayout);
- if (immediate) {
- AsyncTaskPageData data = new AsyncTaskPageData(page, items,
- maxPreviewWidth, maxPreviewHeight, null, null, getWidgetPreviewLoader());
- loadWidgetPreviewsInBackground(null, data);
- onSyncWidgetPageItems(data, immediate);
- } else {
- if (mInTransition) {
- mDeferredPrepareLoadWidgetPreviewsTasks.add(this);
- } else {
- prepareLoadWidgetPreviewsTask(page, items,
- maxPreviewWidth, maxPreviewHeight, mWidgetCountX);
- }
- }
- layout.setOnLayoutListener(null);
- }
- });
- }
- private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task,
- AsyncTaskPageData data) {
- // loadWidgetPreviewsInBackground can be called without a task to load a set of widget
- // previews synchronously
- if (task != null) {
- // Ensure that this task starts running at the correct priority
- task.syncThreadPriority();
- }
-
- // Load each of the widget/shortcut previews
- ArrayList<Object> items = data.items;
- ArrayList<Bitmap> images = data.generatedImages;
- int count = items.size();
- for (int i = 0; i < count; ++i) {
- if (task != null) {
- // Ensure we haven't been cancelled yet
- if (task.isCancelled()) break;
- // Before work on each item, ensure that this task is running at the correct
- // priority
- task.syncThreadPriority();
- }
-
- images.add(getWidgetPreviewLoader().getPreview(items.get(i)));
- }
- }
-
- private void onSyncWidgetPageItems(AsyncTaskPageData data, boolean immediatelySyncItems) {
- if (!immediatelySyncItems && mInTransition) {
- mDeferredSyncWidgetPageItems.add(data);
- return;
- }
- try {
- int page = data.page;
- PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
-
- ArrayList<Object> items = data.items;
- int count = items.size();
- for (int i = 0; i < count; ++i) {
- PagedViewWidget widget = (PagedViewWidget) layout.getChildAt(i);
- if (widget != null) {
- Bitmap preview = data.generatedImages.get(i);
- widget.applyPreview(new FastBitmapDrawable(preview), i);
- }
- }
-
- enableHwLayersOnVisiblePages();
-
- // Update all thread priorities
- Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
- while (iter.hasNext()) {
- AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
- int pageIndex = task.page;
- task.setThreadPriority(getThreadPriorityForPage(pageIndex));
- }
- } finally {
- data.cleanup(false);
- }
- }
-
- @Override
- public void syncPages() {
- disablePagedViewAnimations();
-
- removeAllViews();
- cancelAllTasks();
-
- Context context = getContext();
- if (mContentType == ContentType.Applications) {
- for (int i = 0; i < mNumAppsPages; ++i) {
- AppsCustomizeCellLayout layout = new AppsCustomizeCellLayout(context);
- setupPage(layout);
- addView(layout, new PagedView.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- }
- } else if (mContentType == ContentType.Widgets) {
- for (int j = 0; j < mNumWidgetPages; ++j) {
- PagedViewGridLayout layout = new PagedViewGridLayout(context, mWidgetCountX,
- mWidgetCountY);
- setupPage(layout);
- addView(layout, new PagedView.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- }
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
-
- enablePagedViewAnimations();
- }
-
- @Override
- public void syncPageItems(int page, boolean immediate) {
- if (mContentType == ContentType.Widgets) {
- syncWidgetPageItems(page, immediate);
- } else {
- syncAppsPageItems(page, immediate);
- }
- }
-
- // We want our pages to be z-ordered such that the further a page is to the left, the higher
- // it is in the z-order. This is important to insure touch events are handled correctly.
- View getPageAt(int index) {
- return getChildAt(indexToPage(index));
- }
-
- @Override
- protected int indexToPage(int index) {
- return getChildCount() - index - 1;
- }
-
- // In apps customize, we have a scrolling effect which emulates pulling cards off of a stack.
- @Override
- protected void screenScrolled(int screenCenter) {
- super.screenScrolled(screenCenter);
- enableHwLayersOnVisiblePages();
- }
-
- private void enableHwLayersOnVisiblePages() {
- final int screenCount = getChildCount();
-
- getVisiblePages(mTempVisiblePagesRange);
- int leftScreen = mTempVisiblePagesRange[0];
- int rightScreen = mTempVisiblePagesRange[1];
- int forceDrawScreen = -1;
- if (leftScreen == rightScreen) {
- // make sure we're caching at least two pages always
- if (rightScreen < screenCount - 1) {
- rightScreen++;
- forceDrawScreen = rightScreen;
- } else if (leftScreen > 0) {
- leftScreen--;
- forceDrawScreen = leftScreen;
- }
- } else {
- forceDrawScreen = leftScreen + 1;
- }
-
- for (int i = 0; i < screenCount; i++) {
- final View layout = (View) getPageAt(i);
- if (!(leftScreen <= i && i <= rightScreen &&
- (i == forceDrawScreen || shouldDrawChild(layout)))) {
- layout.setLayerType(LAYER_TYPE_NONE, null);
- }
- }
-
- for (int i = 0; i < screenCount; i++) {
- final View layout = (View) getPageAt(i);
-
- if (leftScreen <= i && i <= rightScreen &&
- (i == forceDrawScreen || shouldDrawChild(layout))) {
- if (layout.getLayerType() != LAYER_TYPE_HARDWARE) {
- layout.setLayerType(LAYER_TYPE_HARDWARE, null);
- }
- }
- }
- }
-
- protected void overScroll(float amount) {
- dampedOverScroll(amount);
- }
-
- /**
- * Used by the parent to get the content width to set the tab bar to
- * @return
- */
- public int getPageContentWidth() {
- return mContentWidth;
- }
-
- @Override
- protected void onPageEndMoving() {
- super.onPageEndMoving();
- mForceDrawAllChildrenNextFrame = true;
- // We reset the save index when we change pages so that it will be recalculated on next
- // rotation
- mSaveInstanceStateItemIndex = -1;
- }
-
- /*
- * AllAppsView implementation
- */
- public void setup(Launcher launcher, DragController dragController) {
- mLauncher = launcher;
- mDragController = dragController;
- }
-
- /**
- * We should call thise method whenever the core data changes (mApps, mWidgets) so that we can
- * appropriately determine when to invalidate the PagedView page data. In cases where the data
- * has yet to be set, we can requestLayout() and wait for onDataReady() to be called in the
- * next onMeasure() pass, which will trigger an invalidatePageData() itself.
- */
- private void invalidateOnDataChange() {
- if (!isDataReady()) {
- // The next layout pass will trigger data-ready if both widgets and apps are set, so
- // request a layout to trigger the page data when ready.
- requestLayout();
- } else {
- cancelAllTasks();
- invalidatePageData();
- }
- }
-
- public void setApps(ArrayList<AppInfo> list) {
- if (!LauncherAppState.isDisableAllApps()) {
- mApps = list;
- Collections.sort(mApps, LauncherModel.getAppNameComparator());
- updatePageCountsAndInvalidateData();
- }
- }
- private void addAppsWithoutInvalidate(ArrayList<AppInfo> list) {
- // We add it in place, in alphabetical order
- int count = list.size();
- for (int i = 0; i < count; ++i) {
- AppInfo info = list.get(i);
- int index = Collections.binarySearch(mApps, info, LauncherModel.getAppNameComparator());
- if (index < 0) {
- mApps.add(-(index + 1), info);
- }
- }
- }
- public void addApps(ArrayList<AppInfo> list) {
- if (!LauncherAppState.isDisableAllApps()) {
- addAppsWithoutInvalidate(list);
- updatePageCountsAndInvalidateData();
- }
- }
- private int findAppByComponent(List<AppInfo> list, AppInfo item) {
- ComponentName removeComponent = item.intent.getComponent();
- int length = list.size();
- for (int i = 0; i < length; ++i) {
- AppInfo info = list.get(i);
- if (info.user.equals(item.user)
- && info.intent.getComponent().equals(removeComponent)) {
- return i;
- }
- }
- return -1;
- }
- private void removeAppsWithoutInvalidate(ArrayList<AppInfo> list) {
- // loop through all the apps and remove apps that have the same component
- int length = list.size();
- for (int i = 0; i < length; ++i) {
- AppInfo info = list.get(i);
- int removeIndex = findAppByComponent(mApps, info);
- if (removeIndex > -1) {
- mApps.remove(removeIndex);
- }
- }
- }
- public void removeApps(ArrayList<AppInfo> appInfos) {
- if (!LauncherAppState.isDisableAllApps()) {
- removeAppsWithoutInvalidate(appInfos);
- updatePageCountsAndInvalidateData();
- }
- }
- public void updateApps(ArrayList<AppInfo> list) {
- // We remove and re-add the updated applications list because it's properties may have
- // changed (ie. the title), and this will ensure that the items will be in their proper
- // place in the list.
- if (!LauncherAppState.isDisableAllApps()) {
- removeAppsWithoutInvalidate(list);
- addAppsWithoutInvalidate(list);
- updatePageCountsAndInvalidateData();
- }
- }
-
- public void reset() {
- // If we have reset, then we should not continue to restore the previous state
- mSaveInstanceStateItemIndex = -1;
-
- if (mContentType != ContentType.Applications) {
- setContentType(ContentType.Applications);
- }
-
- if (mCurrentPage != 0) {
- invalidatePageData(0);
- }
- }
-
- private AppsCustomizeTabHost getTabHost() {
- return (AppsCustomizeTabHost) mLauncher.findViewById(R.id.apps_customize_pane);
- }
-
- public void dumpState() {
- // TODO: Dump information related to current list of Applications, Widgets, etc.
- AppInfo.dumpApplicationInfoList(TAG, "mApps", mApps);
- dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets);
- }
-
- private void dumpAppWidgetProviderInfoList(String tag, String label,
- ArrayList<Object> list) {
- Log.d(tag, label + " size=" + list.size());
- for (Object i: list) {
- if (i instanceof AppWidgetProviderInfo) {
- AppWidgetProviderInfo info = (AppWidgetProviderInfo) i;
- Log.d(tag, " label=\"" + info.label + "\" previewImage=" + info.previewImage
- + " resizeMode=" + info.resizeMode + " configure=" + info.configure
- + " initialLayout=" + info.initialLayout
- + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
- } else if (i instanceof ResolveInfo) {
- ResolveInfo info = (ResolveInfo) i;
- Log.d(tag, " label=\"" + info.loadLabel(mPackageManager) + "\" icon="
- + info.icon);
- }
- }
- }
-
- public void surrender() {
- // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
- // should stop this now.
-
- // Stop all background tasks
- cancelAllTasks();
- }
-
- /*
- * We load an extra page on each side to prevent flashes from scrolling and loading of the
- * widget previews in the background with the AsyncTasks.
- */
- final static int sLookBehindPageCount = 2;
- final static int sLookAheadPageCount = 2;
- protected int getAssociatedLowerPageBound(int page) {
- final int count = getChildCount();
- int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1);
- int windowMinIndex = Math.max(Math.min(page - sLookBehindPageCount, count - windowSize), 0);
- return windowMinIndex;
- }
- protected int getAssociatedUpperPageBound(int page) {
- final int count = getChildCount();
- int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1);
- int windowMaxIndex = Math.min(Math.max(page + sLookAheadPageCount, windowSize - 1),
- count - 1);
- return windowMaxIndex;
- }
-
- protected String getCurrentPageDescription() {
- int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
- int stringId = R.string.default_scroll_format;
- int count = 0;
-
- if (mContentType == ContentType.Applications) {
- stringId = R.string.apps_customize_apps_scroll_format;
- count = mNumAppsPages;
- } else if (mContentType == ContentType.Widgets) {
- stringId = R.string.apps_customize_widgets_scroll_format;
- count = mNumWidgetPages;
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
-
- return String.format(getContext().getString(stringId), page + 1, count);
- }
-}