summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher3/BaseRecyclerView.java7
-rw-r--r--src/com/android/launcher3/BubbleTextView.java26
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java2
-rw-r--r--src/com/android/launcher3/CellLayout.java23
-rw-r--r--src/com/android/launcher3/CommonAppTypeParser.java5
-rw-r--r--src/com/android/launcher3/DeviceProfile.java8
-rw-r--r--src/com/android/launcher3/DragView.java4
-rw-r--r--src/com/android/launcher3/FocusHelper.java2
-rw-r--r--src/com/android/launcher3/Folder.java14
-rw-r--r--src/com/android/launcher3/FolderIcon.java15
-rw-r--r--src/com/android/launcher3/Hotseat.java12
-rw-r--r--src/com/android/launcher3/IconCache.java35
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java29
-rw-r--r--src/com/android/launcher3/Launcher.java98
-rw-r--r--src/com/android/launcher3/LauncherAppWidgetHostView.java14
-rw-r--r--src/com/android/launcher3/LauncherAppWidgetProviderInfo.java3
-rw-r--r--src/com/android/launcher3/LauncherBackupHelper.java10
-rw-r--r--src/com/android/launcher3/LauncherCallbacks.java2
-rw-r--r--src/com/android/launcher3/LauncherModel.java16
-rw-r--r--src/com/android/launcher3/LauncherProvider.java4
-rw-r--r--src/com/android/launcher3/PagedView.java9
-rw-r--r--src/com/android/launcher3/PendingAppWidgetHostView.java4
-rw-r--r--src/com/android/launcher3/SettingsActivity.java22
-rw-r--r--src/com/android/launcher3/Stats.java80
-rw-r--r--src/com/android/launcher3/StylusEventHelper.java84
-rw-r--r--src/com/android/launcher3/Utilities.java75
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java19
-rw-r--r--src/com/android/launcher3/Workspace.java12
-rw-r--r--src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java27
-rw-r--r--src/com/android/launcher3/allapps/AllAppsGridAdapter.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java18
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java17
-rw-r--r--src/com/android/launcher3/model/AppNameComparator.java3
-rw-r--r--src/com/android/launcher3/model/PackageItemInfo.java13
-rw-r--r--src/com/android/launcher3/model/WidgetsModel.java8
-rw-r--r--src/com/android/launcher3/util/LongArrayMap.java2
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java13
-rw-r--r--src/com/android/launcher3/widget/WidgetHostViewLoader.java5
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java24
-rw-r--r--src/com/android/launcher3/widget/WidgetsRecyclerView.java59
41 files changed, 602 insertions, 225 deletions
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 8d418f984..a207d9a12 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -86,10 +86,8 @@ public class BaseRecyclerView extends RecyclerView
private int mDownX;
private int mDownY;
- private int mLastX;
private int mLastY;
private int mScrollbarWidth;
- private int mScrollbarMinHeight;
private int mScrollbarInset;
private Rect mBackgroundPadding = new Rect();
@@ -121,8 +119,6 @@ public class BaseRecyclerView extends RecyclerView
mFastScrollTextPaint.setTextSize(res.getDimensionPixelSize(
R.dimen.all_apps_fast_scroll_text_size));
mScrollbarWidth = res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_bar_width);
- mScrollbarMinHeight =
- res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_bar_min_height);
mScrollbarInset =
res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_scrubber_touch_inset);
setFastScrollerAlpha(mFastScrollAlpha);
@@ -173,7 +169,7 @@ public class BaseRecyclerView extends RecyclerView
switch (action) {
case MotionEvent.ACTION_DOWN:
// Keep track of the down positions
- mDownX = mLastX = x;
+ mDownX = x;
mDownY = mLastY = y;
if (shouldStopScroll(ev)) {
stopScroll();
@@ -188,7 +184,6 @@ public class BaseRecyclerView extends RecyclerView
animateFastScrollerVisibility(true);
}
if (mDraggingFastScroller) {
- mLastX = x;
mLastY = y;
// Scroll to the right position, and update the section name
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index edf502112..f4e306af3 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -28,7 +28,6 @@ import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.KeyEvent;
@@ -36,7 +35,6 @@ import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewParent;
import android.widget.TextView;
-
import com.android.launcher3.IconCache.IconLoadRequest;
import com.android.launcher3.model.PackageItemInfo;
@@ -59,10 +57,12 @@ public class BubbleTextView extends TextView {
private static final int DISPLAY_WORKSPACE = 0;
private static final int DISPLAY_ALL_APPS = 1;
+ private final Launcher mLauncher;
private Drawable mIcon;
private final Drawable mBackground;
private final CheckLongPressHelper mLongPressHelper;
private final HolographicOutlineHelper mOutlineHelper;
+ private final StylusEventHelper mStylusEventHelper;
private boolean mBackgroundSizeChanged;
@@ -92,8 +92,8 @@ public class BubbleTextView extends TextView {
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = ((Launcher) context).getDeviceProfile();
+ mLauncher = (Launcher) context;
+ DeviceProfile grid = mLauncher.getDeviceProfile();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
@@ -125,6 +125,7 @@ public class BubbleTextView extends TextView {
}
mLongPressHelper = new CheckLongPressHelper(this);
+ mStylusEventHelper = new StylusEventHelper(this);
mOutlineHelper = HolographicOutlineHelper.obtain(getContext());
if (mCustomShadowsEnabled) {
@@ -142,7 +143,7 @@ public class BubbleTextView extends TextView {
boolean promiseStateChanged) {
Bitmap b = info.getIcon(iconCache);
- FastBitmapDrawable iconDrawable = Utilities.createIconDrawable(b);
+ FastBitmapDrawable iconDrawable = mLauncher.createIconDrawable(b);
iconDrawable.setGhostModeEnabled(info.isDisabled != 0);
setIcon(iconDrawable, mIconSize);
@@ -158,7 +159,7 @@ public class BubbleTextView extends TextView {
}
public void applyFromApplicationInfo(AppInfo info) {
- setIcon(Utilities.createIconDrawable(info.iconBitmap), mIconSize);
+ setIcon(mLauncher.createIconDrawable(info.iconBitmap), mIconSize);
setText(info.title);
if (info.contentDescription != null) {
setContentDescription(info.contentDescription);
@@ -171,7 +172,7 @@ public class BubbleTextView extends TextView {
}
public void applyFromPackageItemInfo(PackageItemInfo info) {
- setIcon(Utilities.createIconDrawable(info.iconBitmap), mIconSize);
+ setIcon(mLauncher.createIconDrawable(info.iconBitmap), mIconSize);
setText(info.title);
if (info.contentDescription != null) {
setContentDescription(info.contentDescription);
@@ -236,6 +237,12 @@ public class BubbleTextView extends TextView {
// isPressed() on an ACTION_UP
boolean result = super.onTouchEvent(event);
+ // Check for a stylus button press, if it occurs cancel any long press checks.
+ if (mStylusEventHelper.checkAndPerformStylusEvent(event)) {
+ mLongPressHelper.cancelLongPress();
+ result = true;
+ }
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// So that the pressed outline is visible immediately on setStayPressed(),
@@ -245,7 +252,10 @@ public class BubbleTextView extends TextView {
mPressedBackground = mOutlineHelper.createMediumDropShadow(this);
}
- mLongPressHelper.postCheckForLongPress();
+ // If we're in a stylus button press, don't check for long press.
+ if (!mStylusEventHelper.inStylusButtonPressed()) {
+ mLongPressHelper.postCheckForLongPress();
+ }
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 4cd28c034..09a71b0cc 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -64,7 +64,7 @@ public abstract class ButtonDropTarget extends TextView
protected Drawable mDrawable;
private AnimatorSet mCurrentColorAnim;
- private ColorMatrix mSrcFilter, mDstFilter, mCurrentFilter;
+ @Thunk ColorMatrix mSrcFilter, mDstFilter, mCurrentFilter;
public ButtonDropTarget(Context context, AttributeSet attrs) {
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 61567ac00..b5d0dca24 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -95,6 +95,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
boolean[][] mTmpOccupied;
private OnTouchListener mInterceptTouchListener;
+ private StylusEventHelper mStylusEventHelper;
private ArrayList<FolderRingAnimator> mFolderOuterRings = new ArrayList<FolderRingAnimator>();
private int[] mFolderLeaveBehindCell = {-1, -1};
@@ -130,10 +131,8 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
private final ClickShadowView mTouchFeedbackView;
- @Thunk HashMap<CellLayout.LayoutParams, Animator> mReorderAnimators = new
- HashMap<CellLayout.LayoutParams, Animator>();
- private HashMap<View, ReorderPreviewAnimation>
- mShakeAnimators = new HashMap<View, ReorderPreviewAnimation>();
+ @Thunk HashMap<CellLayout.LayoutParams, Animator> mReorderAnimators = new HashMap<>();
+ @Thunk HashMap<View, ReorderPreviewAnimation> mShakeAnimators = new HashMap<>();
private boolean mItemPlacementDirty = false;
@@ -286,6 +285,8 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
mCountX, mCountY);
+ mStylusEventHelper = new StylusEventHelper(this);
+
mTouchFeedbackView = new ClickShadowView(context);
addView(mTouchFeedbackView);
addView(mShortcutsAndWidgets);
@@ -338,6 +339,20 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
return false;
}
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean handled = super.onTouchEvent(ev);
+ // Stylus button press on a home screen should not switch between overview mode and
+ // the home screen mode, however, once in overview mode stylus button press should be
+ // enabled to allow rearranging the different home screens. So check what mode
+ // the workspace is in, and only perform stylus button presses while in overview mode.
+ if (mLauncher.mWorkspace.isInOverviewMode()
+ && mStylusEventHelper.checkAndPerformStylusEvent(ev)) {
+ return true;
+ }
+ return handled;
+ }
+
public void enableHardwareLayer(boolean hasLayer) {
mShortcutsAndWidgets.setLayerType(hasLayer ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, sPaint);
}
diff --git a/src/com/android/launcher3/CommonAppTypeParser.java b/src/com/android/launcher3/CommonAppTypeParser.java
index 31641799d..5314ecff1 100644
--- a/src/com/android/launcher3/CommonAppTypeParser.java
+++ b/src/com/android/launcher3/CommonAppTypeParser.java
@@ -26,6 +26,7 @@ import android.util.Log;
import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.backup.BackupProtos.Favorite;
+import com.android.launcher3.util.Thunk;
import org.xmlpull.v1.XmlPullParserException;
@@ -44,8 +45,8 @@ public class CommonAppTypeParser implements LayoutParserCallback {
private final long mItemId;
- private final int mResId;
- private final Context mContext;
+ @Thunk final int mResId;
+ @Thunk final Context mContext;
ContentValues parsedValues;
Intent parsedIntent;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index bee6cb093..82be409dd 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -405,7 +405,8 @@ public class DeviceProfile {
View searchBar = launcher.getSearchBar();
lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
if (hasVerticalBarLayout) {
- // Vertical search bar space
+ // Vertical search bar space -- The search bar is fixed in the layout to be on the left
+ // of the screen regardless of RTL
lp.gravity = Gravity.LEFT;
lp.width = searchBarSpaceHeightPx;
@@ -438,8 +439,9 @@ public class DeviceProfile {
View hotseat = launcher.findViewById(R.id.hotseat);
lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
if (hasVerticalBarLayout) {
- // Vertical hotseat
- lp.gravity = Gravity.END;
+ // Vertical hotseat -- The hotseat is fixed in the layout to be on the right of the
+ // screen regardless of RTL
+ lp.gravity = Gravity.RIGHT;
lp.width = hotseatBarHeightPx;
lp.height = LayoutParams.MATCH_PARENT;
hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
diff --git a/src/com/android/launcher3/DragView.java b/src/com/android/launcher3/DragView.java
index b3323384d..dfa8202a7 100644
--- a/src/com/android/launcher3/DragView.java
+++ b/src/com/android/launcher3/DragView.java
@@ -44,7 +44,7 @@ public class DragView extends View {
private Bitmap mBitmap;
private Bitmap mCrossFadeBitmap;
- private Paint mPaint;
+ @Thunk Paint mPaint;
private int mRegistrationX;
private int mRegistrationY;
@@ -62,7 +62,7 @@ public class DragView extends View {
// size. This is ignored for non-icons.
private float mIntrinsicIconScale = 1f;
- private float[] mCurrentFilter;
+ @Thunk float[] mCurrentFilter;
private ValueAnimator mFilterAnimator;
/**
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index 46e4902f9..70bb01af0 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -426,7 +426,7 @@ public class FocusHelper {
/**
* Private helper method to get the CellLayoutChildren given a CellLayout index.
*/
- private static ShortcutAndWidgetContainer getCellLayoutChildrenForIndex(
+ @Thunk static ShortcutAndWidgetContainer getCellLayoutChildrenForIndex(
ViewGroup container, int i) {
CellLayout parent = (CellLayout) container.getChildAt(i);
return parent.getShortcutsAndWidgets();
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index fcfb717ab..94f8fc875 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -29,6 +29,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
+import android.os.Bundle;
import android.text.InputType;
import android.text.Selection;
import android.text.Spannable;
@@ -66,7 +67,8 @@ import java.util.Collections;
*/
public class Folder extends LinearLayout implements DragSource, View.OnClickListener,
View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener,
- View.OnFocusChangeListener, DragListener, UninstallSource, AccessibilityDragSource {
+ View.OnFocusChangeListener, DragListener, UninstallSource, AccessibilityDragSource,
+ Stats.LaunchSourceProvider {
private static final String TAG = "Launcher.Folder";
/**
@@ -923,7 +925,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
View v = list.get(i);
ItemInfo info = (ItemInfo) v.getTag();
LauncherModel.addItemToDatabase(mLauncher, info, mInfo.id, 0,
- info.cellX, info.cellY);
+ info.cellX, info.cellY);
}
}
@@ -1338,6 +1340,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
outRect.right += mScrollAreaOffset;
}
+ @Override
+ public void fillInLaunchSourceData(Bundle sourceData) {
+ // Fill in from the folder icon's launch source provider first
+ Stats.LaunchSourceUtils.populateSourceDataFromAncestorProvider(mFolderIcon, sourceData);
+ sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER, Stats.SUB_CONTAINER_FOLDER);
+ sourceData.putInt(Stats.SOURCE_EXTRA_SUB_CONTAINER_PAGE, mContent.getCurrentPage());
+ }
+
private class OnScrollHintListener implements OnAlarmListener {
private final DragObject mDragObject;
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 8652eef40..f1e9dc83b 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -57,6 +57,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
@Thunk static boolean sStaticValuesDirty = true;
private CheckLongPressHelper mLongPressHelper;
+ private StylusEventHelper mStylusEventHelper;
// The number of icons to display in the
public static final int NUM_ITEMS_IN_PREVIEW = 3;
@@ -128,6 +129,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private void init() {
mLongPressHelper = new CheckLongPressHelper(this);
+ mStylusEventHelper = new StylusEventHelper(this);
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
@@ -643,9 +645,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
final Runnable onCompleteRunnable) {
final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null);
- final float scale0 = 1.0f;
- final float transX0 = (mAvailableSpaceInPreview - d.getIntrinsicWidth()) / 2;
- final float transY0 = (mAvailableSpaceInPreview - d.getIntrinsicHeight()) / 2 + getPaddingTop();
+ float iconSize = mLauncher.getDeviceProfile().iconSizePx;
+ final float scale0 = iconSize / d.getIntrinsicWidth() ;
+ final float transX0 = (mAvailableSpaceInPreview - iconSize) / 2;
+ final float transY0 = (mAvailableSpaceInPreview - iconSize) / 2 + getPaddingTop();
mAnimParams.drawable = d;
ValueAnimator va = LauncherAnimUtils.ofFloat(this, 0f, 1.0f);
@@ -719,6 +722,12 @@ public class FolderIcon extends FrameLayout implements FolderListener {
// isPressed() on an ACTION_UP
boolean result = super.onTouchEvent(event);
+ // Check for a stylus button press, if it occurs cancel any long press checks.
+ if (mStylusEventHelper.checkAndPerformStylusEvent(event)) {
+ mLongPressHelper.cancelLongPress();
+ return true;
+ }
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLongPressHelper.postCheckForLongPress();
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index ce33164fa..6e33d1014 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -19,15 +19,16 @@ package com.android.launcher3;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.TextView;
-public class Hotseat extends FrameLayout {
+public class Hotseat extends FrameLayout
+ implements Stats.LaunchSourceProvider{
private CellLayout mContent;
@@ -130,7 +131,7 @@ public class Hotseat extends FrameLayout {
inflater.inflate(R.layout.all_apps_button, mContent, false);
Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
- Utilities.resizeIconDrawable(d);
+ mLauncher.resizeIconDrawable(d);
allAppsButton.setCompoundDrawables(null, d, null, null);
allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
@@ -160,4 +161,9 @@ public class Hotseat extends FrameLayout {
}
return false;
}
+
+ @Override
+ public void fillInLaunchSourceData(Bundle sourceData) {
+ sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_HOTSEAT);
+ }
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 6dfca9ef3..3165337c2 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
@@ -69,7 +68,7 @@ public class IconCache {
private static final int LOW_RES_SCALE_FACTOR = 8;
- private static final Object ICON_UPDATE_TOKEN = new Object();
+ @Thunk static final Object ICON_UPDATE_TOKEN = new Object();
@Thunk static class CacheEntry {
public Bitmap icon;
@@ -79,28 +78,25 @@ public class IconCache {
}
private final HashMap<UserHandleCompat, Bitmap> mDefaultIcons = new HashMap<>();
- private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
+ @Thunk final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
private final Context mContext;
private final PackageManager mPackageManager;
- private final UserManagerCompat mUserManager;
+ @Thunk final UserManagerCompat mUserManager;
private final LauncherAppsCompat mLauncherApps;
private final HashMap<ComponentKey, CacheEntry> mCache =
new HashMap<ComponentKey, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
private final int mIconDpi;
- private final IconDB mIconDb;
+ @Thunk final IconDB mIconDb;
- private final Handler mWorkerHandler;
+ @Thunk final Handler mWorkerHandler;
public IconCache(Context context, InvariantDeviceProfile inv) {
- ActivityManager activityManager =
- (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-
mContext = context;
mPackageManager = context.getPackageManager();
mUserManager = UserManagerCompat.getInstance(mContext);
mLauncherApps = LauncherAppsCompat.getInstance(mContext);
- mIconDpi = activityManager.getLauncherLargeIconDensity();
+ mIconDpi = inv.fillResIconDpi;
mIconDb = new IconDB(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
@@ -136,10 +132,6 @@ public class IconCache {
return getFullResDefaultActivityIcon();
}
- public int getFullResIconDpi() {
- return mIconDpi;
- }
-
public Drawable getFullResIcon(ActivityInfo info) {
Resources resources;
try {
@@ -283,6 +275,7 @@ public class IconCache {
ComponentName component = ComponentName.unflattenFromString(cn);
PackageInfo info = pkgInfoMap.get(component.getPackageName());
if (info == null) {
+ remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
continue;
}
@@ -299,6 +292,7 @@ public class IconCache {
continue;
}
if (app == null) {
+ remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
} else {
appsToUpdate.add(app);
@@ -320,7 +314,7 @@ public class IconCache {
}
}
- private void addIconToDBAndMemCache(LauncherActivityInfoCompat app, PackageInfo info,
+ @Thunk void addIconToDBAndMemCache(LauncherActivityInfoCompat app, PackageInfo info,
long userSerial) {
// Reuse the existing entry if it already exists in the DB. This ensures that we do not
// create bitmap if it was already created during loader.
@@ -342,7 +336,7 @@ public class IconCache {
SQLiteDatabase.CONFLICT_REPLACE);
}
- private ContentValues updateCacheAndGetContentValues(LauncherActivityInfoCompat app,
+ @Thunk ContentValues updateCacheAndGetContentValues(LauncherActivityInfoCompat app,
boolean replaceExisting) {
final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser());
CacheEntry entry = null;
@@ -570,9 +564,10 @@ public class IconCache {
*/
private CacheEntry getEntryForPackageLocked(String packageName, UserHandleCompat user,
boolean useLowResIcon) {
- ComponentName cn = new ComponentName(packageName, EMPTY_CLASS_NAME);
+ ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME);
ComponentKey cacheKey = new ComponentKey(cn, user);
CacheEntry entry = mCache.get(cacheKey);
+
if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
entry = new CacheEntry();
boolean entryUpdated = true;
@@ -688,14 +683,14 @@ public class IconCache {
* LauncherActivityInfoCompat list. Items are updated/added one at a time, so that the
* worker thread doesn't get blocked.
*/
- private class SerializedIconUpdateTask implements Runnable {
+ @Thunk class SerializedIconUpdateTask implements Runnable {
private final long mUserSerial;
private final HashMap<String, PackageInfo> mPkgInfoMap;
private final Stack<LauncherActivityInfoCompat> mAppsToAdd;
private final Stack<LauncherActivityInfoCompat> mAppsToUpdate;
private final HashSet<String> mUpdatedPackages = new HashSet<String>();
- private SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap,
+ @Thunk SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap,
Stack<LauncherActivityInfoCompat> appsToAdd,
Stack<LauncherActivityInfoCompat> appsToUpdate) {
mUserSerial = userSerial;
@@ -744,7 +739,7 @@ public class IconCache {
}
private static final class IconDB extends SQLiteOpenHelper {
- private final static int DB_VERSION = 4;
+ private final static int DB_VERSION = 5;
private final static String TABLE_NAME = "icons";
private final static String COLUMN_ROWID = "rowid";
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 7f34593a9..fcaf834a2 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -35,6 +35,8 @@ public class InvariantDeviceProfile {
// This is a static that we use for the default icon size on a 4/5-inch phone
private static float DEFAULT_ICON_SIZE_DP = 60;
+ private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
+
// Constants that affects the interpolation curve between statically defined device profile
// buckets.
private static float KNEARESTNEIGHBOR = 3;
@@ -60,6 +62,8 @@ public class InvariantDeviceProfile {
public int numFolderRows;
public int numFolderColumns;
float iconSize;
+ int iconBitmapSize;
+ int fillResIconDpi;
float iconTextSize;
/**
@@ -135,8 +139,10 @@ public class InvariantDeviceProfile {
numFolderColumns = closestProfile.numFolderColumns;
iconSize = interpolatedDeviceProfileOut.iconSize;
+ iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
+ fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
@@ -187,6 +193,29 @@ public class InvariantDeviceProfile {
return predefinedDeviceProfiles;
}
+ private int getLauncherIconDensity(int requiredSize) {
+ // Densities typically defined by an app.
+ int[] densityBuckets = new int[] {
+ DisplayMetrics.DENSITY_LOW,
+ DisplayMetrics.DENSITY_MEDIUM,
+ DisplayMetrics.DENSITY_TV,
+ DisplayMetrics.DENSITY_HIGH,
+ DisplayMetrics.DENSITY_XHIGH,
+ DisplayMetrics.DENSITY_XXHIGH,
+ DisplayMetrics.DENSITY_XXXHIGH
+ };
+
+ int density = DisplayMetrics.DENSITY_XXXHIGH;
+ for (int i = densityBuckets.length - 1; i >= 0; i--) {
+ float expectedSize = ICON_SIZE_DEFINED_IN_APP_DP * densityBuckets[i]
+ / DisplayMetrics.DENSITY_DEFAULT;
+ if (expectedSize >= requiredSize) {
+ density = densityBuckets[i];
+ }
+ }
+
+ return density;
+ }
/**
* Apply any Partner customization grid overrides.
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ef34660df..6dfe0ebea 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -265,7 +265,7 @@ public class Launcher extends Activity
private int[] mTmpAddItemCellCoordinates = new int[2];
- private Hotseat mHotseat;
+ @Thunk Hotseat mHotseat;
private ViewGroup mOverviewPanel;
private View mAllAppsButton;
@@ -402,23 +402,35 @@ public class Launcher extends Activity
FocusIndicatorView mFocusHandler;
- private boolean mRotationEnabled = false;
- private boolean mPreferenceObserverRegistered = false;
+ @Thunk boolean mRotationEnabled = false;
+ private boolean mScreenOrientationSettingReceiverRegistered = false;
- final private SharedPreferences.OnSharedPreferenceChangeListener mSettingsObserver =
- new SharedPreferences.OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(key)) {
- if (mRotationEnabled = sharedPreferences.getBoolean(
- Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false)) {
- unlockScreenOrientation(true);
- } else {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+ final private BroadcastReceiver mScreenOrientationSettingReceiver =
+ new BroadcastReceiver() {
+ @Thunk Runnable mUpdateOrientationRunnable = new Runnable() {
+ public void run() {
+ setOrientation();
+ }
+ };
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mRotationEnabled = intent.getBooleanExtra(
+ Utilities.SCREEN_ROTATION_SETTING_EXTRA, false);
+ if (!waitUntilResume(mUpdateOrientationRunnable, true)) {
+ setOrientation();
+ }
}
- }
+ };
+
+ @Thunk void setOrientation() {
+ if (mRotationEnabled) {
+ unlockScreenOrientation(true);
+ } else {
+ setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
- };
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -453,9 +465,6 @@ public class Launcher extends Activity
app.getInvariantDeviceProfile().landscapeProfile
: app.getInvariantDeviceProfile().portraitProfile;
- // TODO: Move this to icon cache.
- Utilities.setIconSize(mDeviceProfile.iconSizePx);
-
// the LauncherApplication should call this, but in case of Instrumentation it might not be present yet
mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
Context.MODE_PRIVATE);
@@ -523,16 +532,18 @@ public class Launcher extends Activity
// In case we are on a device with locked rotation, we should look at preferences to check
// if the user has specifically allowed rotation.
if (!mRotationEnabled) {
- getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
- Context.MODE_MULTI_PROCESS).registerOnSharedPreferenceChangeListener(
- mSettingsObserver);
- mPreferenceObserverRegistered = true;
+ String updateOrientationBroadcastPermission = getResources().getString(
+ R.string.receive_update_orientation_broadcasts_permission);
+ registerReceiver(mScreenOrientationSettingReceiver,
+ new IntentFilter(Utilities.SCREEN_ROTATION_SETTING_INTENT),
+ updateOrientationBroadcastPermission, null);
+ mScreenOrientationSettingReceiverRegistered = true;
mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationContext());
}
// On large interfaces, or on devices that a user has specifically enabled screen rotation,
// we want the screen to auto-rotate based on the current orientation
- unlockScreenOrientation(true);
+ setOrientation();
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onCreate(savedInstanceState);
@@ -1531,7 +1542,6 @@ public class Launcher extends Activity
* Add a shortcut to the workspace.
*
* @param data The intent describing the shortcut.
- * @param cellInfo The position on screen where to create the shortcut.
*/
private void completeAddShortcut(Intent data, long container, long screenId, int cellX,
int cellY) {
@@ -2020,11 +2030,9 @@ public class Launcher extends Activity
public void onDestroy() {
super.onDestroy();
- if (mPreferenceObserverRegistered) {
- getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
- Context.MODE_MULTI_PROCESS).unregisterOnSharedPreferenceChangeListener(
- mSettingsObserver);
- mPreferenceObserverRegistered = false;
+ if (mScreenOrientationSettingReceiverRegistered) {
+ unregisterReceiver(mScreenOrientationSettingReceiver);
+ mScreenOrientationSettingReceiverRegistered = false;
}
// Remove all pending runnables
@@ -2549,13 +2557,6 @@ public class Launcher extends Activity
}
}
- public void onClickPagedViewIcon(View v) {
- startAppShortcutOrInfoActivity(v);
- if (mLauncherCallbacks != null) {
- mLauncherCallbacks.onClickPagedViewIcon(v);
- }
- }
-
@SuppressLint("ClickableViewAccessibility")
public boolean onTouch(View v, MotionEvent event) {
return false;
@@ -2714,7 +2715,7 @@ public class Launcher extends Activity
}
boolean success = startActivitySafely(v, intent, tag);
- mStats.recordLaunch(intent, shortcut);
+ mStats.recordLaunch(v, intent, shortcut);
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
@@ -2936,7 +2937,7 @@ public class Launcher extends Activity
}
}
- boolean startActivity(View v, Intent intent, Object tag) {
+ private boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
// Only launch using the new animation if the shortcut has not opted out (this is a
@@ -3007,7 +3008,7 @@ public class Launcher extends Activity
return false;
}
- boolean startActivitySafely(View v, Intent intent, Object tag) {
+ private boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
@@ -3674,7 +3675,7 @@ public class Launcher extends Activity
*
* @return {@code true} if we are currently paused. The caller might be able to skip some work
*/
- private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
+ @Thunk boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
if (mPaused) {
if (LOGD) Log.d(TAG, "Deferring update until onResume");
if (deletePreviousRunnables) {
@@ -4682,6 +4683,23 @@ public class Launcher extends Activity
}
/**
+ * Returns a FastBitmapDrawable with the icon, accurately sized.
+ */
+ public FastBitmapDrawable createIconDrawable(Bitmap icon) {
+ FastBitmapDrawable d = new FastBitmapDrawable(icon);
+ d.setFilterBitmap(true);
+ resizeIconDrawable(d);
+ return d;
+ }
+
+ /**
+ * Resizes an icon drawable to the correct icon size.
+ */
+ public void resizeIconDrawable(Drawable icon) {
+ icon.setBounds(0, 0, mDeviceProfile.iconSizePx, mDeviceProfile.iconSizePx);
+ }
+
+ /**
* Prints out out state for debugging.
*/
public void dumpState() {
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index 71fb2d295..cf461a5b8 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -36,6 +36,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
LayoutInflater mInflater;
private CheckLongPressHelper mLongPressHelper;
+ private StylusEventHelper mStylusEventHelper;
private Context mContext;
private int mPreviousOrientation;
private DragLayer mDragLayer;
@@ -46,6 +47,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
super(context);
mContext = context;
mLongPressHelper = new CheckLongPressHelper(this);
+ mStylusEventHelper = new StylusEventHelper(this);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDragLayer = ((Launcher) context).getDragLayer();
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
@@ -89,11 +91,17 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
return true;
}
- // Watch for longpress events at this level to make sure
- // users can always pick up this widget
+ // Watch for longpress or stylus button press events at this level to
+ // make sure users can always pick up this widget
+ if (mStylusEventHelper.checkAndPerformStylusEvent(ev)) {
+ mLongPressHelper.cancelLongPress();
+ return true;
+ }
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
- mLongPressHelper.postCheckForLongPress();
+ if (!mStylusEventHelper.inStylusButtonPressed()) {
+ mLongPressHelper.postCheckForLongPress();
+ }
mDragLayer.setTouchCompleteListener(this);
break;
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
index 7ca4fe325..85af92f30 100644
--- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
@@ -67,7 +67,8 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
if (isCustomWidget) {
return cache.getFullResIcon(provider.getPackageName(), icon);
}
- return super.loadIcon(context, cache.getFullResIconDpi());
+ return super.loadIcon(context,
+ LauncherAppState.getInstance().getInvariantDeviceProfile().fillResIconDpi);
}
public String toString(PackageManager pm) {
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index af4101221..b40ace3fb 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -51,13 +51,13 @@ import com.android.launcher3.backup.BackupProtos.Screen;
import com.android.launcher3.backup.BackupProtos.Widget;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.Thunk;
import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
import com.google.protobuf.nano.MessageNano;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -135,7 +135,7 @@ public class LauncherBackupHelper implements BackupHelper {
private static final int SCREEN_RANK_INDEX = 2;
- private final Context mContext;
+ @Thunk final Context mContext;
private final HashSet<String> mExistingKeys;
private final ArrayList<Key> mKeys;
private final ItemTypeMatcher[] mItemTypeMatchers;
@@ -1157,15 +1157,15 @@ public class LauncherBackupHelper implements BackupHelper {
.getSerialNumberForUser(UserHandleCompat.myUserHandle());
}
- private class InvalidBackupException extends IOException {
+ @Thunk class InvalidBackupException extends IOException {
private static final long serialVersionUID = 8931456637211665082L;
- private InvalidBackupException(Throwable cause) {
+ @Thunk InvalidBackupException(Throwable cause) {
super(cause);
}
- public InvalidBackupException(String reason) {
+ @Thunk InvalidBackupException(String reason) {
super(reason);
}
}
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index a5f36ba93..70e400bca 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -56,6 +56,8 @@ public interface LauncherCallbacks {
public void bindAllApplications(ArrayList<AppInfo> apps);
public void onClickFolderIcon(View v);
public void onClickAppShortcut(View v);
+
+ @Deprecated
public void onClickPagedViewIcon(View v);
public void onClickWallpaperPicker(View v);
public void onClickSettingsButton(View v);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 224ebbf89..53966a58f 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -275,7 +275,7 @@ public class LauncherModel extends BroadcastReceiver
/**
* Runs the specified runnable after the loader is complete
*/
- private void runAfterBindCompletes(Runnable r) {
+ @Thunk void runAfterBindCompletes(Runnable r) {
if (isLoadingWorkspace() || !mHasLoaderCompletedOnce) {
synchronized (mBindCompleteRunnables) {
mBindCompleteRunnables.add(r);
@@ -2932,6 +2932,9 @@ public class LauncherModel extends BroadcastReceiver
}
});
}
+
+ // Reload widget list. No need to refresh, as we only want to update the icons and labels.
+ loadAndBindWidgetsAndShortcuts(mApp.getContext(), callbacks, false);
}
void enqueuePackageUpdated(PackageUpdatedTask task) {
@@ -3114,8 +3117,9 @@ public class LauncherModel extends BroadcastReceiver
// Update shortcuts which use iconResource.
if ((si.iconResource != null)
&& packageSet.contains(si.iconResource.packageName)) {
- Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName,
- si.iconResource.resourceName, mIconCache, context);
+ Bitmap icon = Utilities.createIconBitmap(
+ si.iconResource.packageName,
+ si.iconResource.resourceName, context);
if (icon != null) {
si.setIcon(icon);
si.usingFallbackIcon = false;
@@ -3350,7 +3354,7 @@ public class LauncherModel extends BroadcastReceiver
*
* @see #loadAndBindWidgetsAndShortcuts
*/
- private WidgetsModel createWidgetsModel(Context context, boolean refresh) {
+ @Thunk WidgetsModel createWidgetsModel(Context context, boolean refresh) {
PackageManager packageManager = context.getPackageManager();
final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>();
widgetsAndShortcuts.addAll(getWidgetProviders(context, refresh));
@@ -3558,7 +3562,7 @@ public class LauncherModel extends BroadcastReceiver
String resourceName = c.getString(iconResourceIndex);
info.customIcon = false;
// the resource
- icon = Utilities.createIconBitmap(packageName, resourceName, mIconCache, context);
+ icon = Utilities.createIconBitmap(packageName, resourceName, context);
// the db
if (icon == null) {
icon = Utilities.createIconBitmap(c, iconIndex, context);
@@ -3612,7 +3616,7 @@ public class LauncherModel extends BroadcastReceiver
if (extra instanceof ShortcutIconResource) {
iconResource = (ShortcutIconResource) extra;
icon = Utilities.createIconBitmap(iconResource.packageName,
- iconResource.resourceName, mIconCache, context);
+ iconResource.resourceName, context);
}
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 27511527d..45070d190 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -88,7 +88,7 @@ public class LauncherProvider extends ContentProvider {
static final Uri CONTENT_APPWIDGET_RESET_URI =
Uri.parse("content://" + AUTHORITY + "/appWidgetReset");
- private DatabaseHelper mOpenHelper;
+ @Thunk DatabaseHelper mOpenHelper;
@Override
public boolean onCreate() {
@@ -665,7 +665,7 @@ public class LauncherProvider extends ContentProvider {
* Replaces all shortcuts of type {@link Favorites#ITEM_TYPE_SHORTCUT} which have a valid
* launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
*/
- private void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
+ @Thunk void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
db.beginTransaction();
Cursor c = null;
SQLiteStatement updateStmt = null;
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 9271e8b15..18832c680 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -22,11 +22,13 @@ import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
+import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -45,9 +47,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
-
import com.android.launcher3.util.Thunk;
-
import java.util.ArrayList;
/**
@@ -186,7 +186,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// We use the min scale to determine how much to expand the actually PagedView measured
// dimensions such that when we are zoomed out, the view is not clipped
private static int REORDERING_DROP_REPOSITION_DURATION = 200;
- private static int REORDERING_REORDER_REPOSITION_DURATION = 300;
+ @Thunk static int REORDERING_REORDER_REPOSITION_DURATION = 300;
private static int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 80;
private float mMinScale = 1f;
@@ -956,7 +956,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return 0;
}
- private void updateMaxScrollX() {
+ @Thunk void updateMaxScrollX() {
int childCount = getChildCount();
if (childCount > 0) {
final int index = mIsRtl ? 0 : childCount - 1;
@@ -2322,6 +2322,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private static final int ANIM_TAG_KEY = 100;
/* Accessibility */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index c8b27efd3..08f8e5601 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -121,7 +121,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
// 2) Preload icon in the center
// 3) Setup icon in the center and app icon in the top right corner.
if (mDisabledForSafeMode) {
- FastBitmapDrawable disabledIcon = Utilities.createIconDrawable(mIcon);
+ FastBitmapDrawable disabledIcon = mLauncher.createIconDrawable(mIcon);
disabledIcon.setGhostModeEnabled(true);
mCenterDrawable = disabledIcon;
mTopCornerDrawable = null;
@@ -134,7 +134,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
sPreloaderTheme.applyStyle(R.style.PreloadIcon, true);
}
- FastBitmapDrawable drawable = Utilities.createIconDrawable(mIcon);
+ FastBitmapDrawable drawable = mLauncher.createIconDrawable(mIcon);
mCenterDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
mCenterDrawable.setCallback(this);
mTopCornerDrawable = null;
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index a1da1b6fd..27763f545 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -18,12 +18,14 @@ package com.android.launcher3;
import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
+import android.preference.Preference;
import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
/**
- * Settings activity for Launcher. Currently implements the following setting:
- * LockToPortrait
+ * Settings activity for Launcher. Currently implements the following setting: Allow rotation
*/
public class SettingsActivity extends Activity {
@Override
@@ -41,13 +43,25 @@ public class SettingsActivity extends Activity {
*/
@SuppressWarnings("WeakerAccess")
public static class LauncherSettingsFragment extends PreferenceFragment {
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
+ getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
getPreferenceManager().setSharedPreferencesName(LauncherFiles.ROTATION_PREF_FILE);
addPreferencesFromResource(R.xml.launcher_preferences);
}
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+ Preference preference) {
+ boolean allowRotation = getPreferenceManager().getSharedPreferences().getBoolean(
+ Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false);
+ Intent rotationSetting = new Intent(Utilities.SCREEN_ROTATION_SETTING_INTENT);
+ String launchBroadcastPermission = getResources().getString(
+ R.string.receive_update_orientation_broadcasts_permission);
+ rotationSetting.putExtra(Utilities.SCREEN_ROTATION_SETTING_EXTRA, allowRotation);
+ getActivity().sendBroadcast(rotationSetting, launchBroadcastPermission);
+ return true;
+ }
}
}
diff --git a/src/com/android/launcher3/Stats.java b/src/com/android/launcher3/Stats.java
index 9d06f755f..cb0e252b2 100644
--- a/src/com/android/launcher3/Stats.java
+++ b/src/com/android/launcher3/Stats.java
@@ -20,9 +20,63 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Bundle;
import android.util.Log;
+import android.view.View;
+import android.view.ViewParent;
public class Stats {
+
+ /**
+ * Implemented by containers to provide a launch source for a given child.
+ */
+ public interface LaunchSourceProvider {
+ void fillInLaunchSourceData(Bundle sourceData);
+ }
+
+ /**
+ * Helpers to add the source to a launch intent.
+ */
+ public static class LaunchSourceUtils {
+ /**
+ * Create a default bundle for LaunchSourceProviders to fill in their data.
+ */
+ public static Bundle createSourceData() {
+ Bundle sourceData = new Bundle();
+ sourceData.putString(SOURCE_EXTRA_CONTAINER, CONTAINER_HOMESCREEN);
+ // Have default container/sub container pages
+ sourceData.putInt(SOURCE_EXTRA_CONTAINER_PAGE, 0);
+ sourceData.putInt(SOURCE_EXTRA_SUB_CONTAINER_PAGE, 0);
+ return sourceData;
+ }
+
+ /**
+ * Finds the next launch source provider in the parents of the view hierarchy and populates
+ * the source data from that provider.
+ */
+ public static void populateSourceDataFromAncestorProvider(View v, Bundle sourceData) {
+ if (v == null) {
+ return;
+ }
+
+ Stats.LaunchSourceProvider provider = null;
+ ViewParent parent = v.getParent();
+ while (parent != null && parent instanceof View) {
+ if (parent instanceof Stats.LaunchSourceProvider) {
+ provider = (Stats.LaunchSourceProvider) parent;
+ break;
+ }
+ parent = parent.getParent();
+ }
+
+ if (provider != null) {
+ provider.fillInLaunchSourceData(sourceData);
+ } else if (LauncherAppState.isDogfoodBuild()) {
+ throw new RuntimeException("Expected LaunchSourceProvider");
+ }
+ }
+ }
+
private static final boolean DEBUG_BROADCASTS = false;
public static final String ACTION_LAUNCH = "com.android.launcher3.action.LAUNCH";
@@ -31,6 +85,22 @@ public class Stats {
public static final String EXTRA_SCREEN = "screen";
public static final String EXTRA_CELLX = "cellX";
public static final String EXTRA_CELLY = "cellY";
+ public static final String EXTRA_SOURCE = "source";
+
+ public static final String SOURCE_EXTRA_CONTAINER = "container";
+ public static final String SOURCE_EXTRA_CONTAINER_PAGE = "container_page";
+ public static final String SOURCE_EXTRA_SUB_CONTAINER = "sub_container";
+ public static final String SOURCE_EXTRA_SUB_CONTAINER_PAGE = "sub_container_page";
+
+ public static final String CONTAINER_SEARCH_BOX = "search_box";
+ public static final String CONTAINER_ALL_APPS = "all_apps";
+ public static final String CONTAINER_HOMESCREEN = "homescreen"; // aka. Workspace
+ public static final String CONTAINER_HOTSEAT = "hotseat";
+
+ public static final String SUB_CONTAINER_FOLDER = "folder";
+ public static final String SUB_CONTAINER_ALL_APPS_A_Z = "a-z";
+ public static final String SUB_CONTAINER_ALL_APPS_PREDICTION = "prediction";
+ public static final String SUB_CONTAINER_ALL_APPS_SEARCH = "search";
private final Launcher mLauncher;
private final String mLaunchBroadcastPermission;
@@ -56,11 +126,7 @@ public class Stats {
}
}
- public void recordLaunch(Intent intent) {
- recordLaunch(intent, null);
- }
-
- public void recordLaunch(Intent intent, ShortcutInfo shortcut) {
+ public void recordLaunch(View v, Intent intent, ShortcutInfo shortcut) {
intent = new Intent(intent);
intent.setSourceBounds(null);
@@ -72,6 +138,10 @@ public class Stats {
.putExtra(EXTRA_CELLX, shortcut.cellX)
.putExtra(EXTRA_CELLY, shortcut.cellY);
}
+
+ Bundle sourceExtras = LaunchSourceUtils.createSourceData();
+ LaunchSourceUtils.populateSourceDataFromAncestorProvider(v, sourceExtras);
+ broadcastIntent.putExtra(EXTRA_SOURCE, sourceExtras);
mLauncher.sendBroadcast(broadcastIntent, mLaunchBroadcastPermission);
}
}
diff --git a/src/com/android/launcher3/StylusEventHelper.java b/src/com/android/launcher3/StylusEventHelper.java
new file mode 100644
index 000000000..da46e6a54
--- /dev/null
+++ b/src/com/android/launcher3/StylusEventHelper.java
@@ -0,0 +1,84 @@
+package com.android.launcher3;
+
+import com.android.launcher3.Utilities;
+
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+/**
+ * Helper for identifying when a stylus touches a view while the primary stylus button is pressed.
+ * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}. On a
+ * stylus button press this performs the view's {@link View#performLongClick()} method, if the view
+ * is long clickable.
+ */
+public class StylusEventHelper {
+ private boolean mIsButtonPressed;
+ private View mView;
+
+ public StylusEventHelper(View view) {
+ mView = view;
+ }
+
+ /**
+ * Call this in onTouchEvent method of a view to identify a stylus button press and perform a
+ * long click (if the view is long clickable).
+ *
+ * @param event The event to check for a stylus button press.
+ * @return Whether a stylus event occurred and was handled.
+ */
+ public boolean checkAndPerformStylusEvent(MotionEvent event) {
+ final float slop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop();
+
+ if (!mView.isLongClickable()) {
+ // We don't do anything unless the view is long clickable.
+ return false;
+ }
+
+ final boolean stylusButtonPressed = isStylusButtonPressed(event);
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mIsButtonPressed = false;
+ if (stylusButtonPressed && mView.performLongClick()) {
+ mIsButtonPressed = true;
+ return true;
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (Utilities.pointInView(mView, event.getX(), event.getY(), slop)) {
+ if (!mIsButtonPressed && stylusButtonPressed && mView.performLongClick()) {
+ mIsButtonPressed = true;
+ return true;
+ } else if (mIsButtonPressed && !stylusButtonPressed) {
+ mIsButtonPressed = false;
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mIsButtonPressed = false;
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Whether a stylus button press is occurring.
+ */
+ public boolean inStylusButtonPressed() {
+ return mIsButtonPressed;
+ }
+
+ /**
+ * Identifies if the provided {@link MotionEvent} is a stylus with the primary stylus button
+ * pressed.
+ *
+ * @param event The event to check.
+ * @return Whether a stylus button press occurred.
+ */
+ public static boolean isStylusButtonPressed(MotionEvent event) {
+ return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+ && event.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index a9cbf6970..b267f759d 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -71,9 +71,6 @@ public final class Utilities {
private static final String TAG = "Launcher.Utilities";
- private static int sIconWidth = -1;
- private static int sIconHeight = -1;
-
private static final Rect sOldBounds = new Rect();
private static final Canvas sCanvas = new Canvas();
@@ -87,32 +84,18 @@ public final class Utilities {
static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
static int sColorIndex = 0;
- static int[] sLoc0 = new int[2];
- static int[] sLoc1 = new int[2];
+ private static final int[] sLoc0 = new int[2];
+ private static final int[] sLoc1 = new int[2];
// To turn on these properties, type
// adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
- static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
- public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
+ private static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
+ private static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
-
- /**
- * Returns a FastBitmapDrawable with the icon, accurately sized.
- */
- public static FastBitmapDrawable createIconDrawable(Bitmap icon) {
- FastBitmapDrawable d = new FastBitmapDrawable(icon);
- d.setFilterBitmap(true);
- resizeIconDrawable(d);
- return d;
- }
-
- /**
- * Resizes an icon drawable to the correct icon size.
- */
- static void resizeIconDrawable(Drawable icon) {
- icon.setBounds(0, 0, sIconWidth, sIconHeight);
- }
+ public static final String SCREEN_ROTATION_SETTING_INTENT =
+ "come.android.launcher3.SCREEN_ORIENTATION_PREF_CHANGED";
+ public static final String SCREEN_ROTATION_SETTING_EXTRA = "screenRotationPref";
public static boolean isPropertyEnabled(String propertyName) {
return Log.isLoggable(propertyName, Log.VERBOSE);
@@ -141,7 +124,7 @@ public final class Utilities {
return Build.VERSION.SDK_INT >= 22;
}
- static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
+ public static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
byte[] data = c.getBlob(iconIndex);
try {
return createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length), context);
@@ -154,7 +137,7 @@ public final class Utilities {
* Returns a bitmap suitable for the all apps view. If the package or the resource do not
* exist, it returns null.
*/
- static Bitmap createIconBitmap(String packageName, String resourceName, IconCache cache,
+ public static Bitmap createIconBitmap(String packageName, String resourceName,
Context context) {
PackageManager packageManager = context.getPackageManager();
// the resource
@@ -163,7 +146,8 @@ public final class Utilities {
if (resources != null) {
final int id = resources.getIdentifier(resourceName, null, null);
return createIconBitmap(
- resources.getDrawableForDensity(id, cache.getFullResIconDpi()), context);
+ resources.getDrawableForDensity(id, LauncherAppState.getInstance()
+ .getInvariantDeviceProfile().fillResIconDpi), context);
}
} catch (Exception e) {
// Icon not found.
@@ -171,16 +155,16 @@ public final class Utilities {
return null;
}
+ private static int getIconBitmapSize() {
+ return LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize;
+ }
+
/**
* Returns a bitmap which is of the appropriate size to be displayed as an icon
*/
- static Bitmap createIconBitmap(Bitmap icon, Context context) {
- synchronized (sCanvas) { // we share the statics :-(
- if (sIconWidth == -1) {
- initStatics(context);
- }
- }
- if (sIconWidth == icon.getWidth() && sIconHeight == icon.getHeight()) {
+ public static Bitmap createIconBitmap(Bitmap icon, Context context) {
+ final int iconBitmapSize = getIconBitmapSize();
+ if (iconBitmapSize == icon.getWidth() && iconBitmapSize == icon.getHeight()) {
return icon;
}
return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context);
@@ -190,13 +174,11 @@ public final class Utilities {
* Returns a bitmap suitable for the all apps view.
*/
public static Bitmap createIconBitmap(Drawable icon, Context context) {
- synchronized (sCanvas) { // we share the statics :-(
- if (sIconWidth == -1) {
- initStatics(context);
- }
+ synchronized (sCanvas) {
+ final int iconBitmapSize = getIconBitmapSize();
- int width = sIconWidth;
- int height = sIconHeight;
+ int width = iconBitmapSize;
+ int height = iconBitmapSize;
if (icon instanceof PaintDrawable) {
PaintDrawable painter = (PaintDrawable) icon;
@@ -223,8 +205,8 @@ public final class Utilities {
}
// no intrinsic size --> use default size
- int textureWidth = sIconWidth;
- int textureHeight = sIconHeight;
+ int textureWidth = iconBitmapSize;
+ int textureHeight = iconBitmapSize;
final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
Bitmap.Config.ARGB_8888);
@@ -354,15 +336,6 @@ public final class Utilities {
localY < (v.getHeight() + slop);
}
- private static void initStatics(Context context) {
- final Resources resources = context.getResources();
- sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
- }
-
- public static void setIconSize(int widthPx) {
- sIconWidth = sIconHeight = widthPx;
- }
-
public static void scaleRect(Rect r, float scale) {
if (scale != 1.0f) {
r.left = (int) (r.left * scale + 0.5f);
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index e8cc48685..a62177142 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -56,7 +56,7 @@ public class WidgetPreviewLoader {
* Weak reference objects, do not prevent their referents from being made finalizable,
* finalized, and then reclaimed.
*/
- private Set<Bitmap> mUnusedBitmaps =
+ @Thunk Set<Bitmap> mUnusedBitmaps =
Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>());
private final Context mContext;
@@ -67,7 +67,7 @@ public class WidgetPreviewLoader {
private final InvariantDeviceProfile mDeviceProfile;
private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
- private final Handler mWorkerHandler;
+ @Thunk final Handler mWorkerHandler;
public WidgetPreviewLoader(Context context, InvariantDeviceProfile inv, IconCache iconCache) {
mContext = context;
@@ -290,7 +290,7 @@ public class WidgetPreviewLoader {
/**
* Reads the preview bitmap from the DB or null if the preview is not in the DB.
*/
- private Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
+ @Thunk Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
Cursor cursor = null;
try {
cursor = mDb.getReadableDatabase().query(
@@ -329,7 +329,7 @@ public class WidgetPreviewLoader {
return null;
}
- private Bitmap generatePreview(Launcher launcher, Object info, Bitmap recycle,
+ @Thunk Bitmap generatePreview(Launcher launcher, Object info, Bitmap recycle,
int previewWidth, int previewHeight) {
if (info instanceof LauncherAppWidgetProviderInfo) {
return generateWidgetPreview(launcher, (LauncherAppWidgetProviderInfo) info,
@@ -512,7 +512,7 @@ public class WidgetPreviewLoader {
/**
* @return an array of containing versionCode and lastUpdatedTime for the package.
*/
- private long[] getPackageVersion(String packageName) {
+ @Thunk long[] getPackageVersion(String packageName) {
synchronized (mPackageVersions) {
long[] versions = mPackageVersions.get(packageName);
if (versions == null) {
@@ -561,14 +561,13 @@ public class WidgetPreviewLoader {
}
public class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap> {
-
- private final WidgetCacheKey mKey;
+ @Thunk final WidgetCacheKey mKey;
private final Object mInfo;
private final int mPreviewHeight;
private final int mPreviewWidth;
private final WidgetCell mCaller;
- private long[] mVersions;
- private Bitmap mBitmapToRecycle;
+ @Thunk long[] mVersions;
+ @Thunk Bitmap mBitmapToRecycle;
PreviewLoadTask(WidgetCacheKey key, Object info, int previewWidth,
int previewHeight, WidgetCell caller) {
@@ -674,7 +673,7 @@ public class WidgetPreviewLoader {
private static final class WidgetCacheKey extends ComponentKey {
// TODO: remove dependency on size
- private final String size;
+ @Thunk final String size;
public WidgetCacheKey(ComponentName componentName, UserHandleCompat user, String size) {
super(componentName, user);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6d5affb59..d0b9a2206 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -28,6 +28,7 @@ import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -42,6 +43,7 @@ import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcelable;
@@ -86,7 +88,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class Workspace extends PagedView
implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener,
- Insettable, UninstallSource, AccessibilityDragSource {
+ Insettable, UninstallSource, AccessibilityDragSource, Stats.LaunchSourceProvider {
private static final String TAG = "Launcher.Workspace";
private static boolean ENFORCE_DRAG_EVENT_ORDER = false;
@@ -1618,7 +1620,7 @@ public class Workspace extends PagedView
// We should only update the drag layer background alpha if we are not in all apps or the
// widgets tray
if (mState == State.NORMAL) {
- mLauncher.getDragLayer().setBackgroundAlpha(progress * 0.8f);
+ mLauncher.getDragLayer().setBackgroundAlpha(progress == 1 ? 0 : progress * 0.8f);
}
if (mLauncher.getHotseat() != null) {
@@ -4461,6 +4463,12 @@ public class Workspace extends PagedView
mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
}
+ @Override
+ public void fillInLaunchSourceData(Bundle sourceData) {
+ sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_HOMESCREEN);
+ sourceData.putInt(Stats.SOURCE_EXTRA_CONTAINER_PAGE, getCurrentPage());
+ }
+
/**
* Used as a workaround to ensure that the AppWidgetService receives the
* PACKAGE_ADDED broadcast before updating widgets.
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 93cf8d050..3c49ccc41 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -251,7 +251,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate {
return actions;
}
- private void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
+ @Thunk void performResizeAction(int action, View host, LauncherAppWidgetInfo info) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams();
CellLayout layout = (CellLayout) host.getParent().getParent();
layout.markCellsAsUnoccupiedForView(host);
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index c05f7c0b9..9386500be 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -26,6 +26,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.InsetDrawable;
import android.os.Build;
+import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
@@ -57,6 +58,7 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherTransitionable;
import com.android.launcher3.R;
+import com.android.launcher3.Stats;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.allapps.AppSearchManager.AppSearchResultCallback;
@@ -172,7 +174,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
TextWatcher, TextView.OnEditorActionListener, LauncherTransitionable,
AlphabeticalAppsList.AdapterChangedCallback, AllAppsGridAdapter.PredictionBarSpacerCallbacks,
View.OnTouchListener, View.OnClickListener, View.OnLongClickListener,
- ViewTreeObserver.OnPreDrawListener, AppSearchResultCallback {
+ ViewTreeObserver.OnPreDrawListener, AppSearchResultCallback, Stats.LaunchSourceProvider {
public static final boolean GRID_MERGE_SECTIONS = true;
@@ -191,14 +193,14 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.ItemDecoration mItemDecoration;
- private FrameLayout mContentView;
+ @Thunk FrameLayout mContentView;
@Thunk AllAppsRecyclerView mAppsRecyclerView;
- private ViewGroup mPredictionBarView;
+ @Thunk ViewGroup mPredictionBarView;
private View mHeaderView;
- private View mSearchBarContainerView;
+ @Thunk View mSearchBarContainerView;
private View mSearchButtonView;
private View mDismissSearchButtonView;
- private AllAppsSearchEditView mSearchBarEditView;
+ @Thunk AllAppsSearchEditView mSearchBarEditView;
private HeaderElevationController mElevationController;
@@ -215,7 +217,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
private int mContainerInset;
private int mPredictionBarHeight;
private int mLastRecyclerViewScrollPos = -1;
- private boolean mFocusPredictionBarOnFirstBind;
+ @Thunk boolean mFocusPredictionBarOnFirstBind;
private CheckLongPressHelper mPredictionIconCheckForLongPress;
private View mPredictionIconUnderTouch;
@@ -870,6 +872,15 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
return false;
}
+ @Override
+ public void fillInLaunchSourceData(Bundle sourceData) {
+ // Since the other cases are caught by the AllAppsRecyclerView LaunchSourceProvider, we just
+ // handle the prediction bar icons here
+ sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_ALL_APPS);
+ sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
+ Stats.SUB_CONTAINER_ALL_APPS_PREDICTION);
+ }
+
/**
* Returns the predicted app in the prediction bar given a set of local coordinates.
*/
@@ -936,7 +947,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
/**
* Hides the search field.
*/
- private void hideSearchField(boolean animated, final boolean returnFocusToRecyclerView) {
+ @Thunk void hideSearchField(boolean animated, final boolean returnFocusToRecyclerView) {
mSearchManager.cancel(true);
final boolean resetTextField = mSearchBarEditView.getText().toString().length() > 0;
@@ -1001,7 +1012,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
/**
* Returns an input method manager.
*/
- private InputMethodManager getInputMethodManager() {
+ @Thunk InputMethodManager getInputMethodManager() {
return (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index e010270ce..307d9403d 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -288,7 +288,7 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
private GridLayoutManager mGridLayoutMgr;
private GridSpanSizer mGridSizer;
private GridItemDecoration mItemDecoration;
- private PredictionBarSpacerCallbacks mPredictionBarCb;
+ @Thunk PredictionBarSpacerCallbacks mPredictionBarCb;
private View.OnTouchListener mTouchListener;
private View.OnClickListener mIconClickListener;
private View.OnLongClickListener mIconLongClickListener;
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index cc5add3b2..e1b5d918e 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -18,14 +18,15 @@ package com.android.launcher3.allapps;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
-
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.Stats;
import com.android.launcher3.Utilities;
import java.util.List;
@@ -33,7 +34,8 @@ import java.util.List;
/**
* A RecyclerView with custom fast scroll support for the all apps view.
*/
-public class AllAppsRecyclerView extends BaseRecyclerView {
+public class AllAppsRecyclerView extends BaseRecyclerView
+ implements Stats.LaunchSourceProvider {
private AlphabeticalAppsList mApps;
private int mNumAppsPerRow;
@@ -125,6 +127,18 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
addOnItemTouchListener(this);
}
+ @Override
+ public void fillInLaunchSourceData(Bundle sourceData) {
+ sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_ALL_APPS);
+ if (mApps.hasFilter()) {
+ sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
+ Stats.SUB_CONTAINER_ALL_APPS_SEARCH);
+ } else {
+ sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
+ Stats.SUB_CONTAINER_ALL_APPS_A_Z);
+ }
+ }
+
/**
* Maps the touch (from 0..1) to the adapter position that should be visible.
*/
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 0dc2d1e63..e284f77c4 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -27,9 +27,10 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.model.AbstractUserComparator;
import com.android.launcher3.model.AppNameComparator;
+import com.android.launcher3.util.Thunk;
+import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -45,6 +46,7 @@ public class AlphabeticalAppsList {
public static final String TAG = "AlphabeticalAppsList";
private static final boolean DEBUG = false;
+ private static final boolean DEBUG_PREDICTIONS = false;
/**
* Info about a section in the alphabetic list
@@ -151,7 +153,7 @@ public class AlphabeticalAppsList {
* The logic we use to merge sections on tablets. Currently, we don't show section names on
* tablet layouts, so just merge all the sections indiscriminately.
*/
- private static class TabletMergeAlgorithm implements MergeAlgorithm {
+ @Thunk static class TabletMergeAlgorithm implements MergeAlgorithm {
@Override
public boolean continueMerging(SectionInfo section, SectionInfo withSection,
@@ -177,7 +179,7 @@ public class AlphabeticalAppsList {
mMinAppsPerRow = minAppsPerRow;
mMinRowsInMergedSection = minRowsInMergedSection;
mMaxAllowableMerges = maxNumMerges;
- mAsciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ mAsciiEncoder = Charset.forName("US-ASCII").newEncoder();
}
@Override
@@ -476,6 +478,15 @@ public class AlphabeticalAppsList {
mAdapterItems.clear();
mSections.clear();
+ if (DEBUG_PREDICTIONS) {
+ if (mPredictedAppComponents.isEmpty() && !mApps.isEmpty()) {
+ mPredictedAppComponents.add(mApps.get(0).componentName);
+ mPredictedAppComponents.add(mApps.get(0).componentName);
+ mPredictedAppComponents.add(mApps.get(0).componentName);
+ mPredictedAppComponents.add(mApps.get(0).componentName);
+ }
+ }
+
// Process the predicted app components
mPredictedApps.clear();
if (mPredictedAppComponents != null && !mPredictedAppComponents.isEmpty() && !hasFilter()) {
diff --git a/src/com/android/launcher3/model/AppNameComparator.java b/src/com/android/launcher3/model/AppNameComparator.java
index cdac40ac0..cd45d2c94 100644
--- a/src/com/android/launcher3/model/AppNameComparator.java
+++ b/src/com/android/launcher3/model/AppNameComparator.java
@@ -19,6 +19,7 @@ import android.content.Context;
import com.android.launcher3.AppInfo;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.util.Thunk;
import java.text.Collator;
import java.util.Comparator;
@@ -82,7 +83,7 @@ public class AppNameComparator {
/**
* Compares two titles with the same return value semantics as Comparator.
*/
- private int compareTitles(String titleA, String titleB) {
+ @Thunk int compareTitles(String titleA, String titleB) {
// Ensure that we de-prioritize any titles that don't start with a linguistic letter or digit
boolean aStartsWithLetter = Character.isLetterOrDigit(titleA.codePointAt(0));
boolean bStartsWithLetter = Character.isLetterOrDigit(titleB.codePointAt(0));
diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java
index 0f0134ae3..30f228c68 100644
--- a/src/com/android/launcher3/model/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/PackageItemInfo.java
@@ -16,7 +16,6 @@
package com.android.launcher3.model;
-import android.content.ComponentName;
import android.graphics.Bitmap;
import com.android.launcher3.ItemInfo;
@@ -27,7 +26,6 @@ import java.util.Arrays;
* Represents a {@link Package} in the widget tray section.
*/
public class PackageItemInfo extends ItemInfo {
- private static final String TAG = "PackageInfo";
/**
* A bitmap version of the application icon.
@@ -35,12 +33,21 @@ public class PackageItemInfo extends ItemInfo {
public Bitmap iconBitmap;
/**
- * Indicates whether we're using a low res icon
+ * Indicates whether we're using a low res icon.
*/
public boolean usingLowResIcon;
+ /**
+ * Package name of the {@link ItemInfo}.
+ */
public String packageName;
+ /**
+ * Character that is used as a section name for the {@link ItemInfo#title}.
+ * (e.g., "G" will be stored if title is "Google")
+ */
+ public String titleSectionName;
+
int flags = 0;
PackageItemInfo(String packageName) {
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index fdb9795d8..625d4d696 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -8,8 +8,8 @@ import android.util.Log;
import com.android.launcher3.IconCache;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
-
import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.UserHandleCompat;
import java.util.ArrayList;
@@ -39,11 +39,13 @@ public class WidgetsModel {
private final Comparator mWidgetAndShortcutNameComparator;
private final Comparator mAppNameComparator;
private final IconCache mIconCache;
+ private AlphabeticIndexCompat mIndexer;
public WidgetsModel(Context context) {
mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context);
mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator();
mIconCache = LauncherAppState.getInstance().getIconCache();
+ mIndexer = new AlphabeticIndexCompat(context);
}
private WidgetsModel(WidgetsModel model) {
@@ -62,6 +64,9 @@ public class WidgetsModel {
// Access methods that may be deleted if the private fields are made package-private.
public PackageItemInfo getPackageItemInfo(int pos) {
+ if (pos >= mPackageItemInfos.size() || pos < 0) {
+ return null;
+ }
return mPackageItemInfos.get(pos);
}
@@ -112,6 +117,7 @@ public class WidgetsModel {
pInfo = new PackageItemInfo(packageName);
mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(),
true /* userLowResIcon */, pInfo);
+ pInfo.titleSectionName = mIndexer.computeSectionName(pInfo.title);
mWidgetsList.put(pInfo, widgetsShortcutsList);
tmpPackageItemInfos.put(packageName, pInfo);
mPackageItemInfos.add(pInfo);
diff --git a/src/com/android/launcher3/util/LongArrayMap.java b/src/com/android/launcher3/util/LongArrayMap.java
index e3c96cd42..a337e85bd 100644
--- a/src/com/android/launcher3/util/LongArrayMap.java
+++ b/src/com/android/launcher3/util/LongArrayMap.java
@@ -43,7 +43,7 @@ public class LongArrayMap<E> extends LongSparseArray<E> implements Iterable<E> {
return new ValueIterator();
}
- private class ValueIterator implements Iterator<E> {
+ @Thunk class ValueIterator implements Iterator<E> {
private int mNextIndex = 0;
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 3ec164506..2714f5182 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -23,6 +23,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.widget.LinearLayout;
@@ -35,6 +36,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
+import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
import com.android.launcher3.compat.AppWidgetManagerCompat;
@@ -73,6 +75,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
private WidgetPreviewLoader mWidgetPreviewLoader;
private PreviewLoadRequest mActiveRequest;
+ private StylusEventHelper mStylusEventHelper;
private Launcher mLauncher;
@@ -89,6 +92,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
final Resources r = context.getResources();
mLauncher = (Launcher) context;
+ mStylusEventHelper = new StylusEventHelper(this);
mDimensionsFormatString = r.getString(R.string.widget_dims_format);
setContainerWidth();
@@ -202,6 +206,15 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
return Math.min(size[0], info.spanX * cellWidth);
}
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean handled = super.onTouchEvent(ev);
+ if (mStylusEventHelper.checkAndPerformStylusEvent(ev)) {
+ return true;
+ }
+ return handled;
+ }
+
/**
* Helper method to get the string info of the tag.
*/
diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
index d65455053..887587905 100644
--- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java
+++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
@@ -15,6 +15,7 @@ import com.android.launcher3.DragLayer;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.util.Thunk;
public class WidgetHostViewLoader {
@@ -38,7 +39,7 @@ public class WidgetHostViewLoader {
PendingAddWidgetInfo mCreateWidgetInfo = null;
// TODO: technically, this class should not have to know the existence of the launcher.
- private Launcher mLauncher;
+ @Thunk Launcher mLauncher;
private Handler mHandler;
public WidgetHostViewLoader(Launcher launcher) {
@@ -188,7 +189,7 @@ public class WidgetHostViewLoader {
return options;
}
- private void setState(int state) {
+ @Thunk void setState(int state) {
if (DEBUG) {
Log.d(TAG, String.format(" state [%d -> %d]", mState, state));
}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 11c2107f2..1184394f7 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -20,8 +20,8 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.State;
import android.util.AttributeSet;
import android.util.Log;
@@ -46,6 +46,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.Workspace;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.util.Thunk;
/**
* The widgets list view container.
@@ -60,7 +61,7 @@ public class WidgetsContainerView extends BaseContainerView
private static final int PRELOAD_SCREEN_HEIGHT_MULTIPLE = 1;
/* Global instances that are used inside this container. */
- private Launcher mLauncher;
+ @Thunk Launcher mLauncher;
private DragController mDragController;
private IconCache mIconCache;
@@ -92,7 +93,6 @@ public class WidgetsContainerView extends BaseContainerView
mWidgetHostViewLoader = new WidgetHostViewLoader(mLauncher);
mAdapter = new WidgetsListAdapter(context, this, this, mLauncher);
mIconCache = (LauncherAppState.getInstance()).getIconCache();
-
if (DEBUG) {
Log.d(TAG, "WidgetsContainerView constructor");
}
@@ -240,6 +240,7 @@ public class WidgetsContainerView extends BaseContainerView
Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.activityInfo);
preview = Utilities.createIconBitmap(icon, mLauncher);
createItemInfo.spanX = createItemInfo.spanY = 1;
+ scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / preview.getWidth();
}
// Don't clip alpha values for the drag outline if we're using the default widget preview
@@ -345,6 +346,23 @@ public class WidgetsContainerView extends BaseContainerView
setPadding(mFixedBounds.left, mFixedBounds.top, getMeasuredWidth() - mFixedBounds.right,
mFixedBounds.bottom);
}
+
+ int inset = mFixedBounds.isEmpty() ? mView.getScrollbarWidth() : mFixedBoundsContainerInset;
+ mView.setPadding(inset + mView.getScrollbarWidth(), inset,
+ inset, inset);
+ }
+
+ @Override
+ protected void onUpdateBackgrounds() {
+ InsetDrawable background;
+ // Update the background of the reveal view and list to be inset with the fixed bound
+ // insets instead of the default insets
+ // TODO: Use quantum_panel instead of quantum_panel_shape.
+ int inset = mFixedBounds.isEmpty() ? mView.getScrollbarWidth() : mFixedBoundsContainerInset;
+ background = new InsetDrawable(
+ getContext().getResources().getDrawable(R.drawable.quantum_panel_shape),
+ inset, 0, inset, 0);
+ mView.updateBackgroundPadding(background);
}
/**
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index bef255908..4aa332380 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -19,20 +19,25 @@ package com.android.launcher3.widget;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
-import android.view.MotionEvent;
+import android.view.View;
import com.android.launcher3.BaseRecyclerView;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.model.PackageItemInfo;
/**
* The widgets recycler view.
*/
public class WidgetsRecyclerView extends BaseRecyclerView {
+ private static final String TAG = "WidgetsRecyclerView";
private WidgetsModel mWidgets;
private Rect mBackgroundPadding = new Rect();
+ private PackageItemInfo mLastPackageItemInfo;
public WidgetsRecyclerView(Context context) {
this(context, null);
@@ -68,8 +73,17 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
*/
@Override
public String scrollToPositionAtProgress(float touchFraction) {
- // Ensure that we have any sections
- return "";
+ float pos = mWidgets.getPackageSize() * touchFraction;
+
+ int posInt = (int) pos;
+ LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());
+ getCurScrollState(scrollPosState);
+ layoutManager.scrollToPositionWithOffset((int) pos,
+ (int) (scrollPosState.rowHeight * ((float) posInt - pos)));
+
+ posInt = (int) ((touchFraction == 1)? pos -1 : pos);
+ PackageItemInfo p = mWidgets.getPackageItemInfo(posInt);
+ return p.titleSectionName;
}
/**
@@ -78,19 +92,41 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
@Override
public void updateVerticalScrollbarBounds() {
int rowCount = mWidgets.getPackageSize();
+ verticalScrollbarBounds.setEmpty();
- // Skip early if there are no items.
+ // Skip early if, there are no items.
if (rowCount == 0) {
- verticalScrollbarBounds.setEmpty();
return;
}
- int x, y;
+ // Skip early if, there no child laid out in the container.
getCurScrollState(scrollPosState);
if (scrollPosState.rowIndex < 0) {
+ return;
+ }
+
+ int actualHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+ int totalScrollHeight = rowCount * scrollPosState.rowHeight;
+ // Skip early if the height of all the rows are actually less than the container height.
+ if (totalScrollHeight < actualHeight) {
verticalScrollbarBounds.setEmpty();
+ return;
}
- // TODO
+
+ int scrollbarHeight = (int) (actualHeight / ((float) totalScrollHeight / actualHeight));
+ int availableY = totalScrollHeight - actualHeight;
+ int availableScrollY = actualHeight - scrollbarHeight;
+ int y = (scrollPosState.rowIndex * scrollPosState.rowHeight)
+ - scrollPosState.rowTopOffset;
+ y = getPaddingTop() +
+ (int) (((float) (getPaddingTop() + y) / availableY) * availableScrollY);
+
+ // Calculate the position and size of the scroll bar.
+ int x = getWidth() - getScrollbarWidth() - mBackgroundPadding.right;
+ if (Utilities.isRtl(getResources())) {
+ x = mBackgroundPadding.left;
+ }
+ verticalScrollbarBounds.set(x, y, x + getScrollbarWidth(), y + scrollbarHeight);
}
/**
@@ -107,6 +143,11 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
if (rowCount == 0) {
return;
}
- // TODO
+ View child = getChildAt(0);
+ int position = getChildPosition(child);
+
+ stateOut.rowIndex = position;
+ stateOut.rowTopOffset = getLayoutManager().getDecoratedTop(child);
+ stateOut.rowHeight = child.getHeight();
}
} \ No newline at end of file