Merge "Don't allow multiple shortcuts to be dragged simultaneously." into ub-launcher3-master
diff --git a/res/drawable-hdpi/ic_all_apps_bg_hand.png b/res/drawable-hdpi/ic_all_apps_bg_hand.png
index dff2f54..437fd37 100644
--- a/res/drawable-hdpi/ic_all_apps_bg_hand.png
+++ b/res/drawable-hdpi/ic_all_apps_bg_hand.png
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel_bitmap.9.png b/res/drawable-hdpi/quantum_panel_bitmap.9.png
deleted file mode 100644
index d2aee73..0000000
--- a/res/drawable-hdpi/quantum_panel_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png
deleted file mode 100644
index 78345b8..0000000
--- a/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_all_apps_bg_hand.png b/res/drawable-mdpi/ic_all_apps_bg_hand.png
index 0d1d7bb..0a00241 100644
--- a/res/drawable-mdpi/ic_all_apps_bg_hand.png
+++ b/res/drawable-mdpi/ic_all_apps_bg_hand.png
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel_bitmap.9.png b/res/drawable-mdpi/quantum_panel_bitmap.9.png
deleted file mode 100644
index 9325d49..0000000
--- a/res/drawable-mdpi/quantum_panel_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png
deleted file mode 100644
index bf74fa0..0000000
--- a/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-v21/quantum_panel.xml b/res/drawable-v21/quantum_panel.xml
deleted file mode 100644
index d1c0783..0000000
--- a/res/drawable-v21/quantum_panel.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/quantum_panel_shape"
- android:insetBottom="@dimen/quantum_panel_outer_padding"
- android:insetLeft="@dimen/quantum_panel_outer_padding"
- android:insetRight="@dimen/quantum_panel_outer_padding"
- android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable-v21/quantum_panel_dark.xml b/res/drawable-v21/quantum_panel_dark.xml
deleted file mode 100644
index 405ad51..0000000
--- a/res/drawable-v21/quantum_panel_dark.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/quantum_panel_shape_dark"
- android:insetBottom="@dimen/quantum_panel_outer_padding"
- android:insetLeft="@dimen/quantum_panel_outer_padding"
- android:insetRight="@dimen/quantum_panel_outer_padding"
- android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable-xhdpi/ic_all_apps_bg_hand.png b/res/drawable-xhdpi/ic_all_apps_bg_hand.png
index e727d37..1acb378 100644
--- a/res/drawable-xhdpi/ic_all_apps_bg_hand.png
+++ b/res/drawable-xhdpi/ic_all_apps_bg_hand.png
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel_bitmap.9.png b/res/drawable-xhdpi/quantum_panel_bitmap.9.png
deleted file mode 100644
index b89e8b4..0000000
--- a/res/drawable-xhdpi/quantum_panel_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png
deleted file mode 100644
index 1d17136..0000000
--- a/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxhdpi/ic_all_apps_bg_hand.png
index fffcc6b..09c6c8d 100644
--- a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png
+++ b/res/drawable-xxhdpi/ic_all_apps_bg_hand.png
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel_bitmap.9.png b/res/drawable-xxhdpi/quantum_panel_bitmap.9.png
deleted file mode 100644
index 1dd1f6d..0000000
--- a/res/drawable-xxhdpi/quantum_panel_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png
deleted file mode 100644
index 48d584b..0000000
--- a/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png
index 4d065d8..49c004d 100644
--- a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png
+++ b/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png b/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png
deleted file mode 100644
index 915177d..0000000
--- a/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png
deleted file mode 100644
index 27b8466..0000000
--- a/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/quantum_panel.xml b/res/drawable/quantum_panel.xml
index 1f4fb71..fda1003 100644
--- a/res/drawable/quantum_panel.xml
+++ b/res/drawable/quantum_panel.xml
@@ -14,5 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/quantum_panel_bitmap" />
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/quantum_panel_shape"
+ android:insetBottom="@dimen/quantum_panel_outer_padding"
+ android:insetLeft="@dimen/quantum_panel_outer_padding"
+ android:insetRight="@dimen/quantum_panel_outer_padding"
+ android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable/quantum_panel_dark.xml b/res/drawable/quantum_panel_dark.xml
index 6642e78..b113b37 100644
--- a/res/drawable/quantum_panel_dark.xml
+++ b/res/drawable/quantum_panel_dark.xml
@@ -14,5 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/quantum_panel_dark_bitmap" />
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/quantum_panel_shape_dark"
+ android:insetBottom="@dimen/quantum_panel_outer_padding"
+ android:insetLeft="@dimen/quantum_panel_outer_padding"
+ android:insetRight="@dimen/quantum_panel_outer_padding"
+ android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 64d34e7..803a1b5 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -53,6 +53,7 @@
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true"
+ android:paddingEnd="@dimen/container_fastscroll_thumb_max_width"
android:theme="@style/CustomOverscroll.Light" />
<!-- Fast scroller popup -->
diff --git a/res/layout/qsb_blocker_view.xml b/res/layout/qsb_blocker_view.xml
index 58a148e..453eebe 100644
--- a/res/layout/qsb_blocker_view.xml
+++ b/res/layout/qsb_blocker_view.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.QsbBlockerView
+<com.android.launcher3.qsb.QsbBlockerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/res/layout/qsb_container.xml b/res/layout/qsb_container.xml
index b75e3b5..6fa843d 100644
--- a/res/layout/qsb_container.xml
+++ b/res/layout/qsb_container.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.QsbContainerView
+<com.android.launcher3.qsb.QsbContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
@@ -23,8 +23,8 @@
android:padding="0dp" >
<fragment
- android:name="com.android.launcher3.QsbContainerView$QsbFragment"
+ android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
android:layout_width="match_parent"
android:tag="qsb_view"
android:layout_height="match_parent"/>
-</com.android.launcher3.QsbContainerView>
\ No newline at end of file
+</com.android.launcher3.qsb.QsbContainerView>
\ No newline at end of file
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 33eb3bb..55fe36c 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -36,7 +36,7 @@
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ಅಪ್ಲಿಕೇಷನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕು"</string>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="out_of_space" msgid="4691004494942118364">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"</string>
@@ -75,7 +75,7 @@
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string>
- <string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕು"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕಿ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 2838088..ead666c 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -16,8 +16,6 @@
<resources>
<!-- All Apps -->
- <dimen name="all_apps_grid_view_start_margin">0dp</dimen>
- <dimen name="all_apps_grid_section_text_size">26sp</dimen>
<dimen name="all_apps_background_canvas_width">850dp</dimen>
<dimen name="all_apps_background_canvas_height">525dp</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9967b7e..316e748 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -62,9 +62,6 @@
<!-- All Apps -->
<dimen name="all_apps_button_scale_down">0dp</dimen>
- <dimen name="all_apps_grid_view_start_margin">0dp</dimen>
- <dimen name="all_apps_grid_section_y_offset">8dp</dimen>
- <dimen name="all_apps_grid_section_text_size">24sp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
<dimen name="all_apps_search_bar_height">60dp</dimen>
<dimen name="all_apps_search_bar_icon_margin_right">4dp</dimen>
diff --git a/src/com/android/launcher3/AnotherWindowDropTarget.java b/src/com/android/launcher3/AnotherWindowDropTarget.java
index 0e18874..7074f78 100644
--- a/src/com/android/launcher3/AnotherWindowDropTarget.java
+++ b/src/com/android/launcher3/AnotherWindowDropTarget.java
@@ -27,7 +27,7 @@
public class AnotherWindowDropTarget implements DropTarget {
final Launcher mLauncher;
- public AnotherWindowDropTarget (Context context) { mLauncher = (Launcher) context; }
+ public AnotherWindowDropTarget (Context context) { mLauncher = Launcher.getLauncher(context); }
@Override
public boolean isDropEnabled() { return true; }
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 9bdbe25..6fdf454 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -48,7 +47,6 @@
private int mDownX;
private int mDownY;
private int mLastY;
- protected Rect mBackgroundPadding = new Rect();
public BaseRecyclerView(Context context) {
this(context, null);
@@ -164,28 +162,11 @@
return false;
}
- public void updateBackgroundPadding(Rect padding) {
- mBackgroundPadding.set(padding);
- }
-
- public Rect getBackgroundPadding() {
- return mBackgroundPadding;
- }
-
/**
- * Returns the scroll bar width when the user is scrolling.
+ * Returns the height of the fast scroll bar
*/
- public int getMaxScrollbarWidth() {
- return mScrollbar.getThumbMaxWidth();
- }
-
- /**
- * Returns the visible height of the recycler view:
- * VisibleHeight = View height - top padding - bottom padding
- */
- protected int getVisibleHeight() {
- int visibleHeight = getHeight() - mBackgroundPadding.top - mBackgroundPadding.bottom;
- return visibleHeight;
+ protected int getScrollbarTrackHeight() {
+ return getHeight();
}
/**
@@ -199,7 +180,7 @@
* AvailableScrollBarHeight = Total height of the visible view - thumb height
*/
protected int getAvailableScrollBarHeight() {
- int availableScrollBarHeight = getVisibleHeight() - mScrollbar.getThumbHeight();
+ int availableScrollBarHeight = getScrollbarTrackHeight() - mScrollbar.getThumbHeight();
return availableScrollBarHeight;
}
@@ -211,13 +192,6 @@
}
/**
- * Returns the inactive thumb color, can be overridden by each subclass.
- */
- public int getFastScrollerThumbInactiveColor(int defaultInactiveThumbColor) {
- return defaultInactiveThumbColor;
- }
-
- /**
* Returns the scrollbar for this recycler view.
*/
public BaseRecyclerViewFastScrollBar getScrollBar() {
@@ -241,7 +215,6 @@
protected void synchronizeScrollBarThumbOffsetToViewScroll(int scrollY,
int availableScrollHeight) {
// Only show the scrollbar if there is height to be scrolled
- int availableScrollBarHeight = getAvailableScrollBarHeight();
if (availableScrollHeight <= 0) {
mScrollbar.setThumbOffsetY(-1);
return;
@@ -250,8 +223,8 @@
// Calculate the current scroll position, the scrollY of the recycler view accounts for the
// view padding, while the scrollBarY is drawn right up to the background padding (ignoring
// padding)
- int scrollBarY = mBackgroundPadding.top +
- (int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
+ int scrollBarY =
+ (int) (((float) scrollY / availableScrollHeight) * getAvailableScrollBarHeight());
// Calculate the position and size of the scroll bar
mScrollbar.setThumbOffsetY(scrollBarY);
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
index 770166d..40c5ed6 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
@@ -150,7 +150,7 @@
}
int left = getDrawLeft();
// Invalidate the whole scroll bar area.
- mRv.invalidate(left, 0, left + mMaxWidth, mRv.getVisibleHeight());
+ mRv.invalidate(left, 0, left + mMaxWidth, mRv.getScrollbarTrackHeight());
mWidth = width;
updateThumbPath();
@@ -177,10 +177,6 @@
return mThumbHeight;
}
- public int getThumbMaxWidth() {
- return mMaxWidth;
- }
-
public boolean isDraggingThumb() {
return mIsDragging;
}
@@ -222,11 +218,9 @@
}
if (mIsDragging) {
// Update the fastscroller section name at this touch position
- int top = mRv.getBackgroundPadding().top;
- int bottom = top + mRv.getVisibleHeight() - mThumbHeight;
- float boundedY = (float) Math.max(top, Math.min(bottom, y - mTouchOffsetY));
- String sectionName = mRv.scrollToPositionAtProgress((boundedY - top) /
- (bottom - top));
+ int bottom = mRv.getScrollbarTrackHeight() - mThumbHeight;
+ float boundedY = (float) Math.max(0, Math.min(bottom, y - mTouchOffsetY));
+ String sectionName = mRv.scrollToPositionAtProgress(boundedY / bottom);
if (!sectionName.equals(mPopupSectionName)) {
mPopupSectionName = sectionName;
mPopupView.setText(sectionName);
@@ -261,7 +255,7 @@
}
// Draw the track
int thumbWidth = mIsRtl ? mWidth : -mWidth;
- canvas.drawRect(0, 0, thumbWidth, mRv.getVisibleHeight(), mTrackPaint);
+ canvas.drawRect(0, 0, thumbWidth, mRv.getScrollbarTrackHeight(), mTrackPaint);
canvas.translate(0, mThumbOffsetY);
canvas.drawPath(mThumbPath, mThumbPaint);
@@ -303,7 +297,7 @@
private void updatePopupY(int lastTouchY) {
int height = mPopupView.getHeight();
float top = lastTouchY - (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * height);
- top = Math.max(mMaxWidth, Math.min(top, mRv.getVisibleHeight() - mMaxWidth - height));
+ top = Math.max(mMaxWidth, Math.min(top, mRv.getScrollbarTrackHeight() - mMaxWidth - height));
mPopupView.setTranslationY(top);
}
}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index cf8abae..60a2cc3 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -83,7 +83,7 @@
public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
Resources resources = getResources();
mBottomDragPadding = resources.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 5d3cbb2..5c7ea76 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -196,7 +196,7 @@
// the user where a dragged item will land when dropped.
setWillNotDraw(false);
setClipToPadding(false);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
DeviceProfile grid = mLauncher.getDeviceProfile();
@@ -2215,10 +2215,6 @@
return solution;
}
- public void prepareChildForDrag(View child) {
- markCellsAsUnoccupiedForView(child);
- }
-
/* This seems like it should be obvious and straight-forward, but when the direction vector
needs to match with the notion of the dragView pushing other views, we have to employ
a slightly more subtle notion of the direction vector. The question is what two points is
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e830250..655c218 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -463,7 +463,6 @@
public void layout(Launcher launcher, boolean notifyListeners) {
FrameLayout.LayoutParams lp;
boolean hasVerticalBarLayout = isVerticalBarLayout();
- final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources());
// Layout the search bar space
Point searchBarBounds = getSearchBarDimensForWidgetOpts();
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index de079fe..b36734b 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -204,7 +204,7 @@
return consume;
}
- final Launcher launcher = (Launcher) v.getContext();
+ final Launcher launcher = Launcher.getLauncher(v.getContext());
final DeviceProfile profile = launcher.getDeviceProfile();
if (DEBUG) {
@@ -333,7 +333,7 @@
return consume;
}
- Launcher launcher = (Launcher) v.getContext();
+ Launcher launcher = Launcher.getLauncher(v.getContext());
DeviceProfile profile = launcher.getDeviceProfile();
if (DEBUG) {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 11d6b50..b93c6df 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -67,7 +67,7 @@
public Hotseat(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
mHasVerticalHotseat = mLauncher.getDeviceProfile().isVerticalBarLayout();
mBackgroundColor = ColorUtils.setAlphaComponent(
ContextCompat.getColor(context, R.color.all_apps_container_color), 0);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 43a250b..40820fa 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -69,7 +69,6 @@
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -104,7 +103,8 @@
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.DeepShortcutsContainer;
@@ -173,9 +173,6 @@
static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
"com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";
- public static final String ACTION_APPWIDGET_HOST_RESET =
- "com.android.launcher3.intent.ACTION_APPWIDGET_HOST_RESET";
-
// Type: int
private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
// Type: int
@@ -206,20 +203,6 @@
private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk static int NEW_APPS_ANIMATION_DELAY = 500;
- private final BroadcastReceiver mUiBroadcastReceiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
- closeSystemDialogs();
- } else if (ACTION_APPWIDGET_HOST_RESET.equals(intent.getAction())) {
- if (mAppWidgetHost != null) {
- mAppWidgetHost.startListening();
- }
- }
- }
- };
-
@Thunk Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@@ -247,7 +230,7 @@
// Main container view and the model for the widget tray screen.
@Thunk WidgetsContainerView mWidgetsView;
- @Thunk WidgetsModel mWidgetsModel;
+ @Thunk MultiHashMap<PackageItemInfo, WidgetItem> mAllWidgets;
// We set the state in both onCreate and then onNewIntent in some cases, which causes both
// scroll issues (because the workspace may not have been measured yet) and extra work.
@@ -443,10 +426,6 @@
mDefaultKeySsb = new SpannableStringBuilder();
Selection.setSelection(mDefaultKeySsb, 0);
- IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- filter.addAction(ACTION_APPWIDGET_HOST_RESET);
- registerReceiver(mUiBroadcastReceiver, filter);
-
mRotationEnabled = getResources().getBoolean(R.bool.allow_rotation);
// In case we are on a device with locked rotation, we should look at preferences to check
// if the user has specifically allowed rotation.
@@ -470,6 +449,13 @@
loadExtractedColorsAndColorItems();
}
+ @Override
+ public void onAppWidgetHostReset() {
+ if (mAppWidgetHost != null) {
+ mAppWidgetHost.startListening();
+ }
+ }
+
private void loadExtractedColorsAndColorItems() {
// TODO: do this in pre-N as well, once the extraction part is complete.
if (Utilities.isNycOrAbove()) {
@@ -487,9 +473,9 @@
* @param activate if true, make sure the status bar is light, otherwise base on wallpaper.
*/
public void activateLightStatusBar(boolean activate) {
- boolean lightStatusBar = activate
- || mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
- ExtractedColors.DEFAULT_DARK) == ExtractedColors.DEFAULT_LIGHT;
+ boolean lightStatusBar = activate || (FeatureFlags.LIGHT_STATUS_BAR
+ && mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
+ ExtractedColors.DEFAULT_DARK) == ExtractedColors.DEFAULT_LIGHT);
int oldSystemUiFlags = getWindow().getDecorView().getSystemUiVisibility();
int newSystemUiFlags = oldSystemUiFlags;
if (lightStatusBar) {
@@ -573,7 +559,7 @@
}
@Override
- public void onLauncherProviderChange() {
+ public void onLauncherProviderChanged() {
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onLauncherProviderChange();
}
@@ -1469,7 +1455,7 @@
}
if (!foundCellSpan) {
- showOutOfSpaceMessage(isHotseatLayout(layout));
+ mWorkspace.onNoCellFound(layout);
return;
}
@@ -1615,11 +1601,6 @@
}
}
- public void showOutOfSpaceMessage(boolean isHotseatLayout) {
- int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);
- Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();
- }
-
public DragLayer getDragLayer() {
return mDragLayer;
}
@@ -1668,13 +1649,6 @@
return mDeviceProfile;
}
- public void closeSystemDialogs() {
- getWindow().closeAllPanels();
-
- // Whatever we were doing is hereby canceled.
- setWaitingForResult(null);
- }
-
@Override
protected void onNewIntent(Intent intent) {
long startTime = 0;
@@ -1693,9 +1667,6 @@
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
if (isActionMain) {
- // also will cancel mWaitingForResult.
- closeSystemDialogs();
-
if (mWorkspace == null) {
// Can be cases where mWorkspace is null, this prevents a NPE
return;
@@ -1833,8 +1804,6 @@
((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
.removeAccessibilityStateChangeListener(this);
- unregisterReceiver(mUiBroadcastReceiver);
-
LauncherAnimUtils.onDestroyActivity();
if (mLauncherCallbacks != null) {
@@ -3868,22 +3837,22 @@
}
}
- private Runnable mBindWidgetModelRunnable = new Runnable() {
+ private Runnable mBindAllWidgetsRunnable = new Runnable() {
public void run() {
- bindWidgetsModel(mWidgetsModel);
+ bindAllWidgets(mAllWidgets);
}
};
@Override
- public void bindWidgetsModel(WidgetsModel model) {
- if (waitUntilResume(mBindWidgetModelRunnable, true)) {
- mWidgetsModel = model;
+ public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> allWidgets) {
+ if (waitUntilResume(mBindAllWidgetsRunnable, true)) {
+ mAllWidgets = allWidgets;
return;
}
- if (mWidgetsView != null && model != null) {
- mWidgetsView.addWidgets(model);
- mWidgetsModel = null;
+ if (mWidgetsView != null && allWidgets != null) {
+ mWidgetsView.setWidgets(allWidgets);
+ mAllWidgets = null;
}
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index fa5e519..b3db092 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -63,8 +63,6 @@
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mChildrenFocused;
- protected int mErrorViewId = R.layout.appwidget_error;
-
private boolean mIsAttachedToWindow;
private boolean mIsAutoAdvanceRegistered;
private Runnable mAutoAdvanceRunnable;
@@ -81,7 +79,7 @@
@Override
protected View getErrorView() {
- return mInflater.inflate(mErrorViewId, this, false);
+ return mInflater.inflate(R.layout.appwidget_error, this, false);
}
public void updateLastInflationOrientation() {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 3f9c2a3..55bd0a4 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -61,7 +61,9 @@
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.GridSizeMigrationTask;
+import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.SdCardAvailableReceiver;
+import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.provider.ImportDataTask;
import com.android.launcher3.provider.LauncherDbUtils;
@@ -198,7 +200,7 @@
UserHandleCompat user);
public void bindAppInfosRemoved(ArrayList<AppInfo> appInfos);
public void notifyWidgetProvidersChanged();
- public void bindWidgetsModel(WidgetsModel model);
+ public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets);
public void onPageBoundSynchronously(int page);
public void executeOnNextDraw(ViewOnDrawExecutor executor);
public void bindDeepShortcutMap(MultiHashMap<ComponentKey, String> deepShortcutMap);
@@ -209,7 +211,7 @@
Context context = app.getContext();
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
- mBgWidgetsModel = new WidgetsModel(context, iconCache, appFilter);
+ mBgWidgetsModel = new WidgetsModel(iconCache, appFilter);
mIconCache = iconCache;
mDeepShortcutManager = deepShortcutManager;
@@ -688,7 +690,8 @@
// in the hotseat
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
+ item.screenId = Launcher.getLauncher(context).getHotseat()
+ .getOrderInHotseat(cellX, cellY);
} else {
item.screenId = screenId;
}
@@ -721,7 +724,7 @@
// in the hotseat
if (context instanceof Launcher && screen < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX,
+ item.screenId = Launcher.getLauncher(context).getHotseat().getOrderInHotseat(item.cellX,
item.cellY);
} else {
item.screenId = screen;
@@ -754,7 +757,8 @@
// in the hotseat
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
+ item.screenId = Launcher.getLauncher(context).getHotseat()
+ .getOrderInHotseat(cellX, cellY);
} else {
item.screenId = screenId;
}
@@ -847,7 +851,8 @@
// in the hotseat
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
+ item.screenId = Launcher.getLauncher(context).getHotseat()
+ .getOrderInHotseat(cellX, cellY);
} else {
item.screenId = screenId;
}
@@ -3260,13 +3265,15 @@
}
}
- private void bindWidgetsModel(final Callbacks callbacks, final WidgetsModel model) {
+ private void bindWidgetsModel(final Callbacks callbacks) {
+ final MultiHashMap<PackageItemInfo, WidgetItem> widgets
+ = mBgWidgetsModel.getWidgetsMap().clone();
mHandler.post(new Runnable() {
@Override
public void run() {
Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
- callbacks.bindWidgetsModel(model);
+ callbacks.bindAllWidgets(widgets);
}
}
});
@@ -3278,13 +3285,13 @@
@Override
public void run() {
if (bindFirst && !mBgWidgetsModel.isEmpty()) {
- bindWidgetsModel(callbacks, mBgWidgetsModel.clone());
+ bindWidgetsModel(callbacks);
}
- final WidgetsModel model = mBgWidgetsModel.updateAndClone(mApp.getContext());
- bindWidgetsModel(callbacks, model);
+ ArrayList<WidgetItem> allWidgets = mBgWidgetsModel.update(mApp.getContext());
+ bindWidgetsModel(callbacks);
+
// update the Widget entries inside DB on the worker thread.
- LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(
- model.getRawList());
+ LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(allWidgets);
}
});
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 229dd9c..349f094 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -649,11 +649,8 @@
// Database was just created, so wipe any previous widgets
if (mWidgetHostResetHandler != null) {
new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID).deleteHost();
- mWidgetHostResetHandler.sendMessage(Message.obtain(
- mWidgetHostResetHandler,
- ChangeListenerWrapper.MSG_APP_WIDGET_HOST_RESET,
- mContext
- ));
+ mWidgetHostResetHandler.sendEmptyMessage(
+ ChangeListenerWrapper.MSG_EXTRACTED_COLORS_CHANGED);
}
// Set the flag for empty DB
@@ -1136,17 +1133,13 @@
if (mListener != null) {
switch (msg.what) {
case MSG_LAUNCHER_PROVIDER_CHANGED:
- mListener.onLauncherProviderChange();
+ mListener.onLauncherProviderChanged();
break;
case MSG_EXTRACTED_COLORS_CHANGED:
mListener.onExtractedColorsChanged();
break;
case MSG_APP_WIDGET_HOST_RESET:
- Context context = (Context) msg.obj;
- if (context != null) {
- context.sendBroadcast(new Intent(Launcher.ACTION_APPWIDGET_HOST_RESET)
- .setPackage(context.getPackageName()));
- }
+ mListener.onAppWidgetHostReset();
break;
}
}
diff --git a/src/com/android/launcher3/LauncherProviderChangeListener.java b/src/com/android/launcher3/LauncherProviderChangeListener.java
index 5998dad..7044812 100644
--- a/src/com/android/launcher3/LauncherProviderChangeListener.java
+++ b/src/com/android/launcher3/LauncherProviderChangeListener.java
@@ -7,7 +7,9 @@
*/
public interface LauncherProviderChangeListener {
- public void onLauncherProviderChange();
+ void onLauncherProviderChanged();
- public void onExtractedColorsChanged();
+ void onExtractedColorsChanged();
+
+ void onAppWidgetHostReset();
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 136d48d..ce6ce68 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1817,7 +1817,7 @@
}
protected void onUnhandledTap(MotionEvent ev) {
- ((Launcher) getContext()).onClick(this);
+ Launcher.getLauncher(getContext()).onClick(this);
}
@Override
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index d98734b..37cbf98 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -48,7 +48,7 @@
public ShortcutAndWidgetContainer(Context context) {
super(context);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
mWallpaperManager = WallpaperManager.getInstance(context);
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 79a81ec..ae34638 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -52,6 +52,7 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
+import android.widget.Toast;
import com.android.launcher3.Launcher.CustomContentCallbacks;
import com.android.launcher3.Launcher.LauncherOverlay;
@@ -338,7 +339,7 @@
public Workspace(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
mStateTransitionAnimation = new WorkspaceStateTransitionAnimation(mLauncher, this);
final Resources res = getResources();
DeviceProfile grid = mLauncher.getDeviceProfile();
@@ -410,6 +411,11 @@
enforceDragParity("onDragStart", 0, 0);
}
+ if (mDragInfo != null && mDragInfo.cell != null) {
+ CellLayout layout = (CellLayout) mDragInfo.cell.getParent().getParent();
+ layout.markCellsAsUnoccupiedForView(mDragInfo.cell);
+ }
+
if (mOutlineProvider != null) {
// The outline is used to visualize where the item will land if dropped
mOutlineProvider.generateDragOutline(mCanvas);
@@ -477,6 +483,8 @@
// Re-enable any Un/InstallShortcutReceiver and now process any queued items
InstallShortcutReceiver.disableAndFlushInstallQueue(getContext());
+ mOutlineProvider = null;
+ mDragInfo = null;
mDragSourceInternal = null;
mLauncher.onInteractionEnd();
}
@@ -2244,8 +2252,6 @@
mDragInfo = cellInfo;
child.setVisibility(INVISIBLE);
- CellLayout layout = (CellLayout) child.getParent().getParent();
- layout.prepareChildForDrag(child);
if (options.isAccessibleDrag) {
mDragController.addDragListener(new AccessibleDragListenerAdapter(
@@ -2406,18 +2412,7 @@
// Don't accept the drop if there's no room for the item
if (!foundCell) {
- // Don't show the message if we are dropping on the AllApps button and the hotseat
- // is full
- boolean isHotseat = mLauncher.isHotseatLayout(dropTargetLayout);
- if (mTargetCell != null && isHotseat && !FeatureFlags.NO_ALL_APPS_ICON) {
- Hotseat hotseat = mLauncher.getHotseat();
- if (mLauncher.getDeviceProfile().inv.isAllAppsButtonRank(
- hotseat.getOrderInHotseat(mTargetCell[0], mTargetCell[1]))) {
- return false;
- }
- }
-
- mLauncher.showOutOfSpaceMessage(isHotseat);
+ onNoCellFound(dropTargetLayout);
return false;
}
}
@@ -2703,6 +2698,8 @@
LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId, lp.cellX,
lp.cellY, item.spanX, item.spanY);
} else {
+ onNoCellFound(dropTargetLayout);
+
// If we can't find a drop location, we return the item to its original position
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
mTargetCell[0] = lp.cellX;
@@ -2748,6 +2745,26 @@
}
}
+ public void onNoCellFound(View dropTargetLayout) {
+ if (mLauncher.isHotseatLayout(dropTargetLayout)) {
+ Hotseat hotseat = mLauncher.getHotseat();
+ boolean droppedOnAllAppsIcon = !FeatureFlags.NO_ALL_APPS_ICON
+ && mTargetCell != null && !mLauncher.getDeviceProfile().inv.isAllAppsButtonRank(
+ hotseat.getOrderInHotseat(mTargetCell[0], mTargetCell[1]));
+ if (!droppedOnAllAppsIcon) {
+ // Only show message when hotseat is full and drop target was not AllApps button
+ showOutOfSpaceMessage(true);
+ }
+ } else {
+ showOutOfSpaceMessage(false);
+ }
+ }
+
+ private void showOutOfSpaceMessage(boolean isHotseatLayout) {
+ int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);
+ Toast.makeText(mLauncher, mLauncher.getString(strId), Toast.LENGTH_SHORT).show();
+ }
+
/**
* Computes the area relative to dragLayer which is used to display a page.
*/
@@ -3668,8 +3685,6 @@
&& mDragInfo.cell != null) {
mDragInfo.cell.setVisibility(VISIBLE);
}
- mOutlineProvider = null;
- mDragInfo = null;
if (!isFlingToDelete) {
// Fling to delete already exits spring loaded mode after the animation finishes.
diff --git a/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
index 4efe445..bd3bb4d 100644
--- a/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
@@ -50,7 +50,7 @@
super(forView);
mView = forView;
mContext = mView.getContext();
- mDelegate = ((Launcher) mContext).getAccessibilityDelegate();
+ mDelegate = Launcher.getLauncher(mContext).getAccessibilityDelegate();
}
@Override
diff --git a/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java
index a6e89d3..29dd95c 100644
--- a/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java
@@ -53,7 +53,7 @@
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
- Launcher launcher = (Launcher) host.getContext();
+ Launcher launcher = Launcher.getLauncher(host.getContext());
if (action == OVERVIEW) {
launcher.showOverviewMode(true);
return true;
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 5c9e3f7..768d17b 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -16,7 +16,6 @@
package com.android.launcher3.allapps;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.text.Selection;
@@ -33,7 +32,6 @@
import com.android.launcher3.AppInfo;
import com.android.launcher3.BaseContainerView;
-import com.android.launcher3.CellLayout;
import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
@@ -45,7 +43,6 @@
import com.android.launcher3.LauncherTransitionable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
@@ -56,78 +53,9 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ComponentKey;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.List;
-
-/**
- * A merge algorithm that merges every section indiscriminately.
- */
-final class FullMergeAlgorithm implements AlphabeticalAppsList.MergeAlgorithm {
-
- @Override
- public boolean continueMerging(AlphabeticalAppsList.SectionInfo section,
- AlphabeticalAppsList.SectionInfo withSection,
- int sectionAppCount, int numAppsPerRow, int mergeCount) {
- // Don't merge the predicted apps
- if (section.firstAppItem.viewType != AllAppsGridAdapter.VIEW_TYPE_ICON) {
- return false;
- }
- // Otherwise, merge every other section
- return true;
- }
-}
-
-/**
- * The logic we use to merge multiple sections. We only merge sections when their final row
- * contains less than a certain number of icons, and stop at a specified max number of merges.
- * In addition, we will try and not merge sections that identify apps from different scripts.
- */
-final class SimpleSectionMergeAlgorithm implements AlphabeticalAppsList.MergeAlgorithm {
-
- private int mMinAppsPerRow;
- private int mMinRowsInMergedSection;
- private int mMaxAllowableMerges;
- private CharsetEncoder mAsciiEncoder;
-
- public SimpleSectionMergeAlgorithm(int minAppsPerRow, int minRowsInMergedSection, int maxNumMerges) {
- mMinAppsPerRow = minAppsPerRow;
- mMinRowsInMergedSection = minRowsInMergedSection;
- mMaxAllowableMerges = maxNumMerges;
- mAsciiEncoder = Charset.forName("US-ASCII").newEncoder();
- }
-
- @Override
- public boolean continueMerging(AlphabeticalAppsList.SectionInfo section,
- AlphabeticalAppsList.SectionInfo withSection,
- int sectionAppCount, int numAppsPerRow, int mergeCount) {
- // Don't merge the predicted apps
- if (section.firstAppItem.viewType != AllAppsGridAdapter.VIEW_TYPE_ICON) {
- return false;
- }
-
- // Continue merging if the number of hanging apps on the final row is less than some
- // fixed number (ragged), the merged rows has yet to exceed some minimum row count,
- // and while the number of merged sections is less than some fixed number of merges
- int rows = sectionAppCount / numAppsPerRow;
- int cols = sectionAppCount % numAppsPerRow;
-
- // Ensure that we do not merge across scripts, currently we only allow for english and
- // native scripts so we can test if both can just be ascii encoded
- boolean isCrossScript = false;
- if (section.firstAppItem != null && withSection.firstAppItem != null) {
- isCrossScript = mAsciiEncoder.canEncode(section.firstAppItem.sectionName) !=
- mAsciiEncoder.canEncode(withSection.firstAppItem.sectionName);
- }
- return (0 < cols && cols < mMinAppsPerRow) &&
- rows < mMinRowsInMergedSection &&
- mergeCount < mMaxAllowableMerges &&
- !isCrossScript;
- }
-}
-
/**
* The all apps view container.
*/
@@ -135,14 +63,10 @@
LauncherTransitionable, View.OnLongClickListener, AllAppsSearchBarController.Callbacks,
Insettable {
- private static final int MIN_ROWS_IN_MERGED_SECTION_PHONE = 3;
- private static final int MAX_NUM_MERGES_PHONE = 2;
-
private final Launcher mLauncher;
private final AlphabeticalAppsList mApps;
private final AllAppsGridAdapter mAdapter;
private final RecyclerView.LayoutManager mLayoutManager;
- private final RecyclerView.ItemDecoration mItemDecoration;
private AllAppsRecyclerView mAppsRecyclerView;
private AllAppsSearchBarController mSearchBarController;
@@ -153,7 +77,6 @@
private SpannableStringBuilder mSearchQueryBuilder = null;
- private int mSectionNamesMargin;
private int mNumAppsPerRow;
private int mNumPredictedAppsPerRow;
@@ -167,15 +90,12 @@
public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- Resources res = context.getResources();
mLauncher = Launcher.getLauncher(context);
- mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);
mApps = new AlphabeticalAppsList(context);
mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this);
mApps.setAdapter(mAdapter);
mLayoutManager = mAdapter.getLayoutManager();
- mItemDecoration = mAdapter.getItemDecoration();
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
}
@@ -337,10 +257,6 @@
mAppsRecyclerView.addOnScrollListener(mElevationController);
mAppsRecyclerView.setElevationController(mElevationController);
- if (mItemDecoration != null) {
- mAppsRecyclerView.addItemDecoration(mItemDecoration);
- }
-
FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mAppsRecyclerView);
mAppsRecyclerView.addItemDecoration(focusedItemDecorator);
mAppsRecyclerView.preMeasureViews(mAdapter);
@@ -351,14 +267,6 @@
getContentView().setVisibility(View.VISIBLE);
getContentView().setBackground(null);
}
-
- int maxScrollBarWidth = mAppsRecyclerView.getMaxScrollbarWidth();
- int startInset = Math.max(mSectionNamesMargin, maxScrollBarWidth);
- if (Utilities.isRtl(getResources())) {
- mAppsRecyclerView.setPadding(maxScrollBarWidth, 0, startInset, 0);
- } else {
- mAppsRecyclerView.setPadding(startInset, 0, maxScrollBarWidth, 0);
- }
}
@Override
@@ -381,7 +289,7 @@
mAppsRecyclerView.setNumAppsPerRow(grid, mNumAppsPerRow);
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
- mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, new FullMergeAlgorithm());
+ mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
}
if (!grid.isVerticalBarLayout()) {
MarginLayoutParams searchContainerLp =
@@ -396,25 +304,15 @@
// --- remove START when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
// Update the number of items in the grid before we measure the view
- // TODO: mSectionNamesMargin is currently 0, but also account for it,
- // if it's enabled in the future.
grid.updateAppsViewNumCols();
if (mNumAppsPerRow != grid.allAppsNumCols ||
mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) {
mNumAppsPerRow = grid.allAppsNumCols;
mNumPredictedAppsPerRow = grid.allAppsNumPredictiveCols;
- // If there is a start margin to draw section names, determine how we are going to merge
- // app sections
- boolean mergeSectionsFully = mSectionNamesMargin == 0 || !grid.isPhone;
- AlphabeticalAppsList.MergeAlgorithm mergeAlgorithm = mergeSectionsFully ?
- new FullMergeAlgorithm() :
- new SimpleSectionMergeAlgorithm((int) Math.ceil(mNumAppsPerRow / 2f),
- MIN_ROWS_IN_MERGED_SECTION_PHONE, MAX_NUM_MERGES_PHONE);
-
mAppsRecyclerView.setNumAppsPerRow(grid, mNumAppsPerRow);
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
- mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, mergeAlgorithm);
+ mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
}
// --- remove END when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
@@ -519,24 +417,7 @@
}
mLauncher.unlockScreenOrientation(false);
- // 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 = d.dragInfo;
- if (layout != null) {
- showOutOfSpaceMessage =
- !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
- }
- }
- if (showOutOfSpaceMessage) {
- mLauncher.showOutOfSpaceMessage(false);
- }
-
d.deferDragViewCleanupPostAnimation = false;
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
index 808de47..28b7685 100644
--- a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
+++ b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
@@ -29,7 +29,6 @@
private static final int INITIAL_TOUCH_SETTLING_DURATION = 100;
private static final int REPEAT_TOUCH_SETTLING_DURATION = 200;
- private static final float FAST_SCROLL_TOUCH_VELOCITY_BARRIER = 1900f;
private AllAppsRecyclerView mRv;
private AlphabeticalAppsList mApps;
@@ -187,9 +186,9 @@
public void onBindView(AllAppsGridAdapter.ViewHolder holder) {
// Update newly bound views to the current fast scroll state if we are fast scrolling
if (mCurrentFastScrollSection != null || mTargetFastScrollSection != null) {
- if (holder.mContent instanceof BaseRecyclerViewFastScrollBar.FastScrollFocusableView) {
+ if (holder.itemView instanceof BaseRecyclerViewFastScrollBar.FastScrollFocusableView) {
BaseRecyclerViewFastScrollBar.FastScrollFocusableView v =
- (BaseRecyclerViewFastScrollBar.FastScrollFocusableView) holder.mContent;
+ (BaseRecyclerViewFastScrollBar.FastScrollFocusableView) holder.itemView;
updateViewFastScrollFocusState(v, holder.getPosition(), false /* animated */);
mTrackedFastScrollViews.add(v);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 7b6aef1..bd877f2 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -18,10 +18,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Point;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -41,10 +38,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-
-import java.util.HashMap;
-import java.util.List;
/**
* The grid view adapter of all the apps.
@@ -52,10 +45,7 @@
public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHolder> {
public static final String TAG = "AppsGridAdapter";
- private static final boolean DEBUG = false;
- // A section break in the grid
- public static final int VIEW_TYPE_SECTION_BREAK = 1 << 0;
// A normal icon
public static final int VIEW_TYPE_ICON = 1 << 1;
// A prediction icon
@@ -78,25 +68,22 @@
// Common view type masks
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_DIVIDER
| VIEW_TYPE_SEARCH_MARKET_DIVIDER
- | VIEW_TYPE_PREDICTION_DIVIDER
- | VIEW_TYPE_SECTION_BREAK;
+ | VIEW_TYPE_PREDICTION_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON
| VIEW_TYPE_PREDICTION_ICON;
public interface BindViewCallback {
- public void onBindView(ViewHolder holder);
+ void onBindView(ViewHolder holder);
}
/**
* ViewHolder for each icon.
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
- public View mContent;
public ViewHolder(View v) {
super(v);
- mContent = v;
}
}
@@ -158,189 +145,14 @@
}
}
- /**
- * Helper class to draw the section headers
- */
- public class GridItemDecoration extends RecyclerView.ItemDecoration {
-
- private static final boolean DEBUG_SECTION_MARGIN = false;
- private static final boolean FADE_OUT_SECTIONS = false;
-
- private HashMap<String, PointF> mCachedSectionBounds = new HashMap<>();
- private Rect mTmpBounds = new Rect();
-
- @Override
- public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
- if (mApps.hasFilter() || mAppsPerRow == 0) {
- return;
- }
-
- if (DEBUG_SECTION_MARGIN) {
- Paint p = new Paint();
- p.setColor(0x33ff0000);
- c.drawRect(mBackgroundPadding.left, 0, mBackgroundPadding.left + mSectionNamesMargin,
- parent.getMeasuredHeight(), p);
- }
-
- List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
- boolean showSectionNames = mSectionNamesMargin > 0;
- int childCount = parent.getChildCount();
- int lastSectionTop = 0;
- int lastSectionHeight = 0;
- for (int i = 0; i < childCount; i++) {
- View child = parent.getChildAt(i);
- ViewHolder holder = (ViewHolder) parent.getChildViewHolder(child);
- if (!isValidHolderAndChild(holder, child, items)) {
- continue;
- }
-
- if (showSectionNames && shouldDrawItemSection(holder, i, items)) {
- // At this point, we only draw sections for each section break;
- int viewTopOffset = (2 * child.getPaddingTop());
- int pos = holder.getPosition();
- AlphabeticalAppsList.AdapterItem item = items.get(pos);
- AlphabeticalAppsList.SectionInfo sectionInfo = item.sectionInfo;
-
- // Draw all the sections for this index
- String lastSectionName = item.sectionName;
- for (int j = item.sectionAppIndex; j < sectionInfo.numApps; j++, pos++) {
- AlphabeticalAppsList.AdapterItem nextItem = items.get(pos);
- String sectionName = nextItem.sectionName;
- if (nextItem.sectionInfo != sectionInfo) {
- break;
- }
- if (j > item.sectionAppIndex && sectionName.equals(lastSectionName)) {
- continue;
- }
-
- // Find the section name bounds
- PointF sectionBounds = getAndCacheSectionBounds(sectionName);
-
- // Calculate where to draw the section
- int sectionBaseline = (int) (viewTopOffset + sectionBounds.y);
- int x = mIsRtl ?
- parent.getWidth() - mBackgroundPadding.left - mSectionNamesMargin :
- mBackgroundPadding.left;
- x += (int) ((mSectionNamesMargin - sectionBounds.x) / 2f);
- int y = child.getTop() + sectionBaseline;
-
- // Determine whether this is the last row with apps in that section, if
- // so, then fix the section to the row allowing it to scroll past the
- // baseline, otherwise, bound it to the baseline so it's in the viewport
- int appIndexInSection = items.get(pos).sectionAppIndex;
- int nextRowPos = Math.min(items.size() - 1,
- pos + mAppsPerRow - (appIndexInSection % mAppsPerRow));
- AlphabeticalAppsList.AdapterItem nextRowItem = items.get(nextRowPos);
- boolean fixedToRow = !sectionName.equals(nextRowItem.sectionName);
- if (!fixedToRow) {
- y = Math.max(sectionBaseline, y);
- }
-
- // In addition, if it overlaps with the last section that was drawn, then
- // offset it so that it does not overlap
- if (lastSectionHeight > 0 && y <= (lastSectionTop + lastSectionHeight)) {
- y += lastSectionTop - y + lastSectionHeight;
- }
-
- // Draw the section header
- if (FADE_OUT_SECTIONS) {
- int alpha = 255;
- if (fixedToRow) {
- alpha = Math.min(255,
- (int) (255 * (Math.max(0, y) / (float) sectionBaseline)));
- }
- mSectionTextPaint.setAlpha(alpha);
- }
- c.drawText(sectionName, x, y, mSectionTextPaint);
-
- lastSectionTop = y;
- lastSectionHeight = (int) (sectionBounds.y + mSectionHeaderOffset);
- lastSectionName = sectionName;
- }
- i += (sectionInfo.numApps - item.sectionAppIndex);
- }
- }
- }
-
- @Override
- public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
- RecyclerView.State state) {
- // Do nothing
- }
-
- /**
- * Given a section name, return the bounds of the given section name.
- */
- private PointF getAndCacheSectionBounds(String sectionName) {
- PointF bounds = mCachedSectionBounds.get(sectionName);
- if (bounds == null) {
- mSectionTextPaint.getTextBounds(sectionName, 0, sectionName.length(), mTmpBounds);
- bounds = new PointF(mSectionTextPaint.measureText(sectionName), mTmpBounds.height());
- mCachedSectionBounds.put(sectionName, bounds);
- }
- return bounds;
- }
-
- /**
- * Returns whether we consider this a valid view holder for us to draw a divider or section for.
- */
- private boolean isValidHolderAndChild(ViewHolder holder, View child,
- List<AlphabeticalAppsList.AdapterItem> items) {
- // Ensure item is not already removed
- GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
- child.getLayoutParams();
- if (lp.isItemRemoved()) {
- return false;
- }
- // Ensure we have a valid holder
- if (holder == null) {
- return false;
- }
- // Ensure we have a holder position
- int pos = holder.getPosition();
- if (pos < 0 || pos >= items.size()) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns whether to draw the section for the given child.
- */
- private boolean shouldDrawItemSection(ViewHolder holder, int childIndex,
- List<AlphabeticalAppsList.AdapterItem> items) {
- int pos = holder.getPosition();
- AlphabeticalAppsList.AdapterItem item = items.get(pos);
-
- // Ensure it's an icon
- if (item.viewType != AllAppsGridAdapter.VIEW_TYPE_ICON) {
- return false;
- }
- // Draw the section header for the first item in each section
- return (childIndex == 0) ||
- (items.get(pos - 1).viewType == AllAppsGridAdapter.VIEW_TYPE_SECTION_BREAK);
- }
- }
-
private final Launcher mLauncher;
private final LayoutInflater mLayoutInflater;
private final AlphabeticalAppsList mApps;
private final GridLayoutManager mGridLayoutMgr;
private final GridSpanSizer mGridSizer;
- private final GridItemDecoration mItemDecoration;
private final View.OnClickListener mIconClickListener;
private final View.OnLongClickListener mIconLongClickListener;
- private final Rect mBackgroundPadding = new Rect();
- private final boolean mIsRtl;
-
- // Section drawing
- @Deprecated
- private final int mSectionNamesMargin;
- @Deprecated
- private final int mSectionHeaderOffset;
- private final Paint mSectionTextPaint;
-
private int mAppsPerRow;
private BindViewCallback mBindViewCallback;
@@ -361,18 +173,9 @@
mGridSizer = new GridSpanSizer();
mGridLayoutMgr = new AppsGridLayoutManager(launcher);
mGridLayoutMgr.setSpanSizeLookup(mGridSizer);
- mItemDecoration = new GridItemDecoration();
mLayoutInflater = LayoutInflater.from(launcher);
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
- mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);
- mSectionHeaderOffset = res.getDimensionPixelSize(R.dimen.all_apps_grid_section_y_offset);
- mIsRtl = Utilities.isRtl(res);
-
- mSectionTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mSectionTextPaint.setTextSize(res.getDimensionPixelSize(
- R.dimen.all_apps_grid_section_text_size));
- mSectionTextPaint.setColor(Utilities.getColorAccent(launcher));
}
public static boolean isDividerViewType(int viewType) {
@@ -421,33 +224,15 @@
}
/**
- * Notifies the adapter of the background padding so that it can draw things correctly in the
- * item decorator.
- */
- public void updateBackgroundPadding(Rect padding) {
- mBackgroundPadding.set(padding);
- }
-
- /**
* Returns the grid layout manager.
*/
public GridLayoutManager getLayoutManager() {
return mGridLayoutMgr;
}
- /**
- * Returns the item decoration for the recycler view.
- */
- public RecyclerView.ItemDecoration getItemDecoration() {
- // We don't draw any headers when we are uncomfortably dense
- return mItemDecoration;
- }
-
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
- case VIEW_TYPE_SECTION_BREAK:
- return new ViewHolder(new View(parent.getContext()));
case VIEW_TYPE_ICON:
/* falls through */
case VIEW_TYPE_PREDICTION_ICON: {
@@ -499,26 +284,26 @@
switch (holder.getItemViewType()) {
case VIEW_TYPE_ICON: {
AppInfo info = mApps.getAdapterItems().get(position).appInfo;
- BubbleTextView icon = (BubbleTextView) holder.mContent;
+ BubbleTextView icon = (BubbleTextView) holder.itemView;
icon.applyFromApplicationInfo(info);
icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
break;
}
case VIEW_TYPE_PREDICTION_ICON: {
AppInfo info = mApps.getAdapterItems().get(position).appInfo;
- BubbleTextView icon = (BubbleTextView) holder.mContent;
+ BubbleTextView icon = (BubbleTextView) holder.itemView;
icon.applyFromApplicationInfo(info);
icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
break;
}
case VIEW_TYPE_EMPTY_SEARCH:
- TextView emptyViewText = (TextView) holder.mContent;
+ TextView emptyViewText = (TextView) holder.itemView;
emptyViewText.setText(mEmptySearchMessage);
emptyViewText.setGravity(mApps.hasNoFilteredResults() ? Gravity.CENTER :
Gravity.START | Gravity.CENTER_VERTICAL);
break;
case VIEW_TYPE_SEARCH_MARKET:
- TextView searchView = (TextView) holder.mContent;
+ TextView searchView = (TextView) holder.itemView;
if (mMarketSearchIntent != null) {
searchView.setVisibility(View.VISIBLE);
} else {
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 5a9ea6b..ab34287 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -101,7 +101,6 @@
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * mNumAppsPerRow);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_ICON, mNumAppsPerRow);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER, 1);
- pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SECTION_BREAK, approxRows);
}
/**
@@ -116,21 +115,21 @@
// Icons
BubbleTextView icon = (BubbleTextView) adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_ICON).mContent;
+ AllAppsGridAdapter.VIEW_TYPE_ICON).itemView;
int iconHeight = icon.getLayoutParams().height;
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, iconHeight);
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_ICON, iconHeight);
// Search divider
View searchDivider = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER).mContent;
+ AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER).itemView;
searchDivider.measure(widthMeasureSpec, heightMeasureSpec);
int searchDividerHeight = searchDivider.getMeasuredHeight();
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER, searchDividerHeight);
// Generic dividers
View divider = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER).mContent;
+ AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER).itemView;
divider.measure(widthMeasureSpec, heightMeasureSpec);
int dividerHeight = divider.getMeasuredHeight();
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER, dividerHeight);
@@ -138,18 +137,15 @@
// Search views
View emptySearch = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH).mContent;
+ AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH).itemView;
emptySearch.measure(widthMeasureSpec, heightMeasureSpec);
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH,
emptySearch.getMeasuredHeight());
View searchMarket = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET).mContent;
+ AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET).itemView;
searchMarket.measure(widthMeasureSpec, heightMeasureSpec);
mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET,
searchMarket.getMeasuredHeight());
-
- // Section breaks
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SECTION_BREAK, 0);
}
/**
@@ -166,27 +162,10 @@
}
}
- /**
- * We need to override the draw to ensure that we don't draw the overscroll effect beyond the
- * background bounds.
- */
- @Override
- protected void dispatchDraw(Canvas canvas) {
- // Clip to ensure that we don't draw the overscroll effect beyond the background bounds
- canvas.clipRect(mBackgroundPadding.left, mBackgroundPadding.top,
- getWidth() - mBackgroundPadding.right,
- getHeight() - mBackgroundPadding.bottom);
- super.dispatchDraw(canvas);
- }
-
@Override
public void onDraw(Canvas c) {
// Draw the background
if (mEmptySearchBackground != null && mEmptySearchBackground.getAlpha() > 0) {
- c.clipRect(mBackgroundPadding.left, mBackgroundPadding.top,
- getWidth() - mBackgroundPadding.right,
- getHeight() - mBackgroundPadding.bottom);
-
mEmptySearchBackground.draw(c);
}
@@ -323,8 +302,8 @@
// Calculate the current scroll position, the scrollY of the recycler view accounts
// for the view padding, while the scrollBarY is drawn right up to the background
// padding (ignoring padding)
- int scrollBarY = mBackgroundPadding.top +
- (int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
+ int scrollBarY = (int)
+ (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
int thumbScrollY = mScrollbar.getThumbOffsetY();
int diffScrollY = scrollBarY - thumbScrollY;
@@ -415,8 +394,8 @@
}
@Override
- protected int getVisibleHeight() {
- return super.getVisibleHeight()
+ protected int getScrollbarTrackHeight() {
+ return super.getScrollbarTrackHeight()
- Launcher.getLauncher(getContext()).getDragLayer().getInsets().bottom;
}
@@ -428,7 +407,7 @@
protected int getAvailableScrollHeight() {
int paddedHeight = getCurrentScrollY(mApps.getAdapterItems().size(), 0);
int totalHeight = paddedHeight + getPaddingBottom();
- return totalHeight - getVisibleHeight();
+ return totalHeight - getScrollbarTrackHeight();
}
/**
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
index cac388c..6587ad7 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
@@ -50,7 +50,7 @@
public AllAppsRecyclerViewContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- Launcher launcher = (Launcher) context;
+ Launcher launcher = Launcher.getLauncher(context);
DeviceProfile grid = launcher.getDeviceProfile();
mTouchFeedbackView = new ClickShadowView(context);
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 0be2b41..8b7a6ba 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -23,8 +23,8 @@
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;
-import com.android.launcher3.model.AppNameComparator;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.LabelComparator;
import java.util.ArrayList;
import java.util.Collections;
@@ -49,18 +49,6 @@
private final int mFastScrollDistributionMode = FAST_SCROLL_FRACTION_DISTRIBUTE_BY_NUM_SECTIONS;
/**
- * Info about a section in the alphabetic list
- */
- public static class SectionInfo {
- // The number of applications in this section
- public int numApps;
- // The section break AdapterItem for this section
- public AdapterItem sectionBreakItem;
- // The first app AdapterItem for this section
- public AdapterItem firstAppItem;
- }
-
- /**
* Info about a fast scroller section, depending if sections are merged, the fast scroller
* sections will not be the same set as the section headers.
*/
@@ -87,16 +75,10 @@
// The type of this item
public int viewType;
- /** Section & App properties */
- // The section for this item
- public SectionInfo sectionInfo;
-
/** App-only properties */
// The section name of this app. Note that there can be multiple items with different
// sectionNames in the same section
public String sectionName = null;
- // The index of this app in the section
- public int sectionAppIndex = -1;
// The row that this item shows up on
public int rowIndex;
// The index of this app in the row
@@ -106,30 +88,19 @@
// The index of this app not including sections
public int appIndex = -1;
- public static AdapterItem asSectionBreak(int pos, SectionInfo section) {
- AdapterItem item = new AdapterItem();
- item.viewType = AllAppsGridAdapter.VIEW_TYPE_SECTION_BREAK;
- item.position = pos;
- item.sectionInfo = section;
- section.sectionBreakItem = item;
- return item;
- }
-
- public static AdapterItem asPredictedApp(int pos, SectionInfo section, String sectionName,
- int sectionAppIndex, AppInfo appInfo, int appIndex) {
- AdapterItem item = asApp(pos, section, sectionName, sectionAppIndex, appInfo, appIndex);
+ public static AdapterItem asPredictedApp(int pos, String sectionName, AppInfo appInfo,
+ int appIndex) {
+ AdapterItem item = asApp(pos, sectionName, appInfo, appIndex);
item.viewType = AllAppsGridAdapter.VIEW_TYPE_PREDICTION_ICON;
return item;
}
- public static AdapterItem asApp(int pos, SectionInfo section, String sectionName,
- int sectionAppIndex, AppInfo appInfo, int appIndex) {
+ public static AdapterItem asApp(int pos, String sectionName, AppInfo appInfo,
+ int appIndex) {
AdapterItem item = new AdapterItem();
item.viewType = AllAppsGridAdapter.VIEW_TYPE_ICON;
item.position = pos;
- item.sectionInfo = section;
item.sectionName = sectionName;
- item.sectionAppIndex = sectionAppIndex;
item.appInfo = appInfo;
item.appIndex = appIndex;
return item;
@@ -171,14 +142,6 @@
}
}
- /**
- * Common interface for different merging strategies.
- */
- public interface MergeAlgorithm {
- boolean continueMerging(SectionInfo section, SectionInfo withSection,
- int sectionAppCount, int numAppsPerRow, int mergeCount);
- }
-
private Launcher mLauncher;
// The set of apps from the system not including predictions
@@ -189,8 +152,6 @@
private List<AppInfo> mFilteredApps = new ArrayList<>();
// The current set of adapter items
private List<AdapterItem> mAdapterItems = new ArrayList<>();
- // The set of sections for the apps with the current filter
- private List<SectionInfo> mSections = new ArrayList<>();
// The set of sections that we allow fast-scrolling to (includes non-merged sections)
private List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
// The set of predicted app component names
@@ -202,26 +163,23 @@
private HashMap<CharSequence, String> mCachedSectionNames = new HashMap<>();
private AllAppsGridAdapter mAdapter;
private AlphabeticIndexCompat mIndexer;
- private AppNameComparator mAppNameComparator;
- private MergeAlgorithm mMergeAlgorithm;
+ private AppInfoComparator mAppNameComparator;
private int mNumAppsPerRow;
private int mNumPredictedAppsPerRow;
private int mNumAppRowsInAdapter;
public AlphabeticalAppsList(Context context) {
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
- mAppNameComparator = new AppNameComparator(context);
+ mAppNameComparator = new AppInfoComparator(context);
}
/**
* Sets the number of apps per row.
*/
- public void setNumAppsPerRow(int numAppsPerRow, int numPredictedAppsPerRow,
- MergeAlgorithm mergeAlgorithm) {
+ public void setNumAppsPerRow(int numAppsPerRow, int numPredictedAppsPerRow) {
mNumAppsPerRow = numAppsPerRow;
mNumPredictedAppsPerRow = numPredictedAppsPerRow;
- mMergeAlgorithm = mergeAlgorithm;
updateAdapterItems();
}
@@ -241,13 +199,6 @@
}
/**
- * Returns sections of all the current filtered applications.
- */
- public List<SectionInfo> getSections() {
- return mSections;
- }
-
- /**
* Returns fast scroller sections of all the current filtered applications.
*/
public List<FastScrollSectionInfo> getFastScrollerSections() {
@@ -354,17 +305,16 @@
// Sort the list of apps
mApps.clear();
mApps.addAll(mComponentToAppMap.values());
- Collections.sort(mApps, mAppNameComparator.getAppInfoComparator());
+ Collections.sort(mApps, mAppNameComparator);
// As a special case for some languages (currently only Simplified Chinese), we may need to
// coalesce sections
Locale curLocale = mLauncher.getResources().getConfiguration().locale;
- TreeMap<String, ArrayList<AppInfo>> sectionMap = null;
boolean localeRequiresSectionSorting = curLocale.equals(Locale.SIMPLIFIED_CHINESE);
if (localeRequiresSectionSorting) {
- // Compute the section headers. We use a TreeMap with the section name comparator to
+ // Compute the section headers. We use a TreeMap with the section name comparator to
// ensure that the sections are ordered when we iterate over it later
- sectionMap = new TreeMap<>(mAppNameComparator.getSectionNameComparator());
+ TreeMap<String, ArrayList<AppInfo>> sectionMap = new TreeMap<>(new LabelComparator());
for (AppInfo info : mApps) {
// Add the section to the cache
String sectionName = getAndUpdateCachedSectionName(info.title);
@@ -379,13 +329,10 @@
}
// Add each of the section apps to the list in order
- List<AppInfo> allApps = new ArrayList<>(mApps.size());
- for (Map.Entry<String, ArrayList<AppInfo>> entry : sectionMap.entrySet()) {
- allApps.addAll(entry.getValue());
- }
-
mApps.clear();
- mApps.addAll(allApps);
+ for (Map.Entry<String, ArrayList<AppInfo>> entry : sectionMap.entrySet()) {
+ mApps.addAll(entry.getValue());
+ }
} else {
// Just compute the section headers for use below
for (AppInfo info : mApps) {
@@ -403,7 +350,6 @@
* mCachedSectionNames to have been calculated for the set of all apps in mApps.
*/
private void updateAdapterItems() {
- SectionInfo lastSectionInfo = null;
String lastSectionName = null;
FastScrollSectionInfo lastFastScrollerSectionInfo = null;
int position = 0;
@@ -413,7 +359,6 @@
mFilteredApps.clear();
mFastScrollerSections.clear();
mAdapterItems.clear();
- mSections.clear();
if (DEBUG_PREDICTIONS) {
if (mPredictedAppComponents.isEmpty() && !mApps.isEmpty()) {
@@ -451,19 +396,14 @@
if (!mPredictedApps.isEmpty()) {
// Add a section for the predictions
- lastSectionInfo = new SectionInfo();
lastFastScrollerSectionInfo = new FastScrollSectionInfo("");
- AdapterItem sectionItem = AdapterItem.asSectionBreak(position++, lastSectionInfo);
- mSections.add(lastSectionInfo);
mFastScrollerSections.add(lastFastScrollerSectionInfo);
- mAdapterItems.add(sectionItem);
// Add the predicted app items
for (AppInfo info : mPredictedApps) {
- AdapterItem appItem = AdapterItem.asPredictedApp(position++, lastSectionInfo,
- "", lastSectionInfo.numApps++, info, appIndex++);
- if (lastSectionInfo.firstAppItem == null) {
- lastSectionInfo.firstAppItem = appItem;
+ AdapterItem appItem = AdapterItem.asPredictedApp(position++, "", info,
+ appIndex++);
+ if (lastFastScrollerSectionInfo.fastScrollToItem == null) {
lastFastScrollerSectionInfo.fastScrollToItem = appItem;
}
mAdapterItems.add(appItem);
@@ -480,25 +420,15 @@
String sectionName = getAndUpdateCachedSectionName(info.title);
// Create a new section if the section names do not match
- if (lastSectionInfo == null || !sectionName.equals(lastSectionName)) {
+ if (!sectionName.equals(lastSectionName)) {
lastSectionName = sectionName;
- lastSectionInfo = new SectionInfo();
lastFastScrollerSectionInfo = new FastScrollSectionInfo(sectionName);
- mSections.add(lastSectionInfo);
mFastScrollerSections.add(lastFastScrollerSectionInfo);
-
- // Create a new section item to break the flow of items in the list
- if (!hasFilter()) {
- AdapterItem sectionItem = AdapterItem.asSectionBreak(position++, lastSectionInfo);
- mAdapterItems.add(sectionItem);
- }
}
// Create an app item
- AdapterItem appItem = AdapterItem.asApp(position++, lastSectionInfo, sectionName,
- lastSectionInfo.numApps++, info, appIndex++);
- if (lastSectionInfo.firstAppItem == null) {
- lastSectionInfo.firstAppItem = appItem;
+ AdapterItem appItem = AdapterItem.asApp(position++, sectionName, info, appIndex++);
+ if (lastFastScrollerSectionInfo.fastScrollToItem == null) {
lastFastScrollerSectionInfo.fastScrollToItem = appItem;
}
mAdapterItems.add(appItem);
@@ -515,9 +445,6 @@
mAdapterItems.add(AdapterItem.asMarketSearch(position++));
}
- // Merge multiple sections together as requested by the merge strategy for this device
- mergeSections();
-
if (mNumAppsPerRow != 0) {
// Update the number of rows in the adapter after we do all the merging (otherwise, we
// would have to shift the values again)
@@ -594,61 +521,6 @@
}
/**
- * Merges multiple sections to reduce visual raggedness.
- */
- private void mergeSections() {
- // Ignore merging until we have an algorithm and a valid row size
- if (mMergeAlgorithm == null || mNumAppsPerRow == 0) {
- return;
- }
-
- // Go through each section and try and merge some of the sections
- if (!hasFilter()) {
- int sectionAppCount = 0;
- for (int i = 0; i < mSections.size() - 1; i++) {
- SectionInfo section = mSections.get(i);
- sectionAppCount = section.numApps;
- int mergeCount = 1;
-
- // Merge rows based on the current strategy
- while (i < (mSections.size() - 1) &&
- mMergeAlgorithm.continueMerging(section, mSections.get(i + 1),
- sectionAppCount, mNumAppsPerRow, mergeCount)) {
- SectionInfo nextSection = mSections.remove(i + 1);
-
- // Remove the next section break
- mAdapterItems.remove(nextSection.sectionBreakItem);
- int pos = mAdapterItems.indexOf(section.firstAppItem);
-
- // Point the section for these new apps to the merged section
- int nextPos = pos + section.numApps;
- for (int j = nextPos; j < (nextPos + nextSection.numApps); j++) {
- AdapterItem item = mAdapterItems.get(j);
- item.sectionInfo = section;
- item.sectionAppIndex += section.numApps;
- }
-
- // Update the following adapter items of the removed section item
- pos = mAdapterItems.indexOf(nextSection.firstAppItem);
- for (int j = pos; j < mAdapterItems.size(); j++) {
- AdapterItem item = mAdapterItems.get(j);
- item.position--;
- }
- section.numApps += nextSection.numApps;
- sectionAppCount += nextSection.numApps;
-
- if (DEBUG) {
- Log.d(TAG, "Merging: " + nextSection.firstAppItem.sectionName +
- " to " + section.firstAppItem.sectionName +
- " mergedNumRows: " + (sectionAppCount / mNumAppsPerRow));
- }
- mergeCount++;
- }
- }
- }
- }
-
- /**
* Returns the cached section name for the given title, recomputing and updating the cache if
* the title has no cached section name.
*/
diff --git a/src/com/android/launcher3/model/AbstractUserComparator.java b/src/com/android/launcher3/allapps/AppInfoComparator.java
similarity index 61%
rename from src/com/android/launcher3/model/AbstractUserComparator.java
rename to src/com/android/launcher3/allapps/AppInfoComparator.java
index bd28560..1f5fece 100644
--- a/src/com/android/launcher3/model/AbstractUserComparator.java
+++ b/src/com/android/launcher3/allapps/AppInfoComparator.java
@@ -13,36 +13,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.model;
+package com.android.launcher3.allapps;
import android.content.Context;
-import com.android.launcher3.ItemInfo;
+import com.android.launcher3.AppInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.LabelComparator;
import java.util.Comparator;
/**
* A comparator to arrange items based on user profiles.
*/
-public abstract class AbstractUserComparator<T extends ItemInfo> implements Comparator<T> {
+public class AppInfoComparator implements Comparator<AppInfo> {
private final UserManagerCompat mUserManager;
private final UserHandleCompat mMyUser;
+ private final LabelComparator mLabelComparator;
- public AbstractUserComparator(Context context) {
+ public AppInfoComparator(Context context) {
mUserManager = UserManagerCompat.getInstance(context);
mMyUser = UserHandleCompat.myUserHandle();
+ mLabelComparator = new LabelComparator();
}
@Override
- public int compare(T lhs, T rhs) {
- if (mMyUser.equals(lhs.user)) {
+ public int compare(AppInfo a, AppInfo b) {
+ // Order by the title in the current locale
+ int result = mLabelComparator.compare(a.title.toString(), b.title.toString());
+ if (result != 0) {
+ return result;
+ }
+
+ // If labels are same, compare component names
+ result = a.componentName.compareTo(b.componentName);
+ if (result != 0) {
+ return result;
+ }
+
+ if (mMyUser.equals(a.user)) {
return -1;
} else {
- Long aUserSerial = mUserManager.getSerialNumberForUser(lhs.user);
- Long bUserSerial = mUserManager.getSerialNumberForUser(rhs.user);
+ Long aUserSerial = mUserManager.getSerialNumberForUser(a.user);
+ Long bUserSerial = mUserManager.getSerialNumberForUser(b.user);
return aUserSerial.compareTo(bUserSerial);
}
}
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
index ac22dd2..06cf9aa 100644
--- a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
@@ -115,7 +115,7 @@
return prevType != Character.UPPERCASE_LETTER;
case Character.LOWERCASE_LETTER:
// Break point if previous was not a letter.
- return prevType > Character.OTHER_LETTER;
+ return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED;
case Character.DECIMAL_DIGIT_NUMBER:
case Character.LETTER_NUMBER:
case Character.OTHER_NUMBER:
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 019a174..59d18c2 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -145,10 +145,12 @@
setChildrenDrawingOrderEnabled(true);
final Resources res = getResources();
- mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left);
- mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right);
- mLeftHoverDrawableActive = res.getDrawable(R.drawable.page_hover_left_active);
- mRightHoverDrawableActive = res.getDrawable(R.drawable.page_hover_right_active);
+ if (FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND) {
+ mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left);
+ mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right);
+ mLeftHoverDrawableActive = res.getDrawable(R.drawable.page_hover_left_active);
+ mRightHoverDrawableActive = res.getDrawable(R.drawable.page_hover_right_active);
+ }
mIsRtl = Utilities.isRtl(res);
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
}
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index c15b710..1369f60 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -27,6 +27,7 @@
import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
/**
* Extracts colors from the wallpaper, and saves results to {@link LauncherProvider}.
@@ -62,12 +63,15 @@
.generate();
extractedColors.updateHotseatPalette(hotseatPalette);
- int statusBarHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_height);
- Palette statusBarPalette = Palette.from(wallpaper)
- .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight)
- .clearFilters()
- .generate();
- extractedColors.updateStatusBarPalette(statusBarPalette);
+ if (FeatureFlags.LIGHT_STATUS_BAR) {
+ int statusBarHeight = getResources()
+ .getDimensionPixelSize(R.dimen.status_bar_height);
+ Palette statusBarPalette = Palette.from(wallpaper)
+ .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight)
+ .clearFilters()
+ .generate();
+ extractedColors.updateStatusBarPalette(statusBarPalette);
+ }
}
// Save the extracted colors and wallpaper id to LauncherProvider.
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index 4db0797..6a3011d 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -47,7 +47,7 @@
// public static final int MUTED_LIGHT_INDEX = 7;
public static final int NUM_COLOR_PROFILES = 2;
- private static final int VERSION = 2;
+ private static final int VERSION = 1;
private static final String COLOR_SEPARATOR = ",";
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5ab6ddb..2952196 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -214,7 +214,7 @@
if (sHintText == null) {
sHintText = res.getString(R.string.folder_hint_text);
}
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
// We need this view to be focusable in touch mode so that when text editing of the folder
// name is complete, we have something to focus on, thus hiding the cursor and giving
// reliable behavior when clicking the text field (since it will always gain focus on click).
@@ -702,6 +702,7 @@
}
if (!(getParent() instanceof DragLayer)) return;
+ DragLayer parent = (DragLayer) getParent();
if (animate) {
animateClosed();
@@ -711,8 +712,7 @@
// Notify the accessibility manager that this folder "window" has disappeared and no
// longer occludes the workspace items
- ((DragLayer) getParent())
- .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ parent.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
private void animateClosed() {
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 1702163..dcd3ec4 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -252,7 +252,7 @@
}
private CellLayout createAndAddNewPage() {
- DeviceProfile grid = ((Launcher) getContext()).getDeviceProfile();
+ DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
CellLayout page = new CellLayout(getContext());
page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
diff --git a/src/com/android/launcher3/model/AppNameComparator.java b/src/com/android/launcher3/model/AppNameComparator.java
deleted file mode 100644
index 5f80037..0000000
--- a/src/com/android/launcher3/model/AppNameComparator.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2015 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.model;
-
-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;
-
-/**
- * Class to manage access to an app name comparator.
- * <p>
- * Used to sort application name in all apps view and widget tray view.
- */
-public class AppNameComparator {
- private final Collator mCollator;
- private final AbstractUserComparator<ItemInfo> mAppInfoComparator;
- private final Comparator<String> mSectionNameComparator;
-
- public AppNameComparator(Context context) {
- mCollator = Collator.getInstance();
- mAppInfoComparator = new AbstractUserComparator<ItemInfo>(context) {
-
- @Override
- public final int compare(ItemInfo a, ItemInfo b) {
- // Order by the title in the current locale
- int result = compareTitles(a.title.toString(), b.title.toString());
- if (result == 0 && a instanceof AppInfo && b instanceof AppInfo) {
- AppInfo aAppInfo = (AppInfo) a;
- AppInfo bAppInfo = (AppInfo) b;
- // If two apps have the same title, then order by the component name
- result = aAppInfo.componentName.compareTo(bAppInfo.componentName);
- if (result == 0) {
- // If the two apps are the same component, then prioritize by the order that
- // the app user was created (prioritizing the main user's apps)
- return super.compare(a, b);
- }
- }
- return result;
- }
- };
- mSectionNameComparator = new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- return compareTitles(o1, o2);
- }
- };
- }
-
- /**
- * Returns a locale-aware comparator that will alphabetically order a list of applications.
- */
- public Comparator<ItemInfo> getAppInfoComparator() {
- return mAppInfoComparator;
- }
-
- /**
- * Returns a locale-aware comparator that will alphabetically order a list of section names.
- */
- public Comparator<String> getSectionNameComparator() {
- return mSectionNameComparator;
- }
-
- /**
- * Compares two titles with the same return value semantics as Comparator.
- */
- @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 = (titleA.length() > 0) &&
- Character.isLetterOrDigit(titleA.codePointAt(0));
- boolean bStartsWithLetter = (titleB.length() > 0) &&
- Character.isLetterOrDigit(titleB.codePointAt(0));
- if (aStartsWithLetter && !bStartsWithLetter) {
- return -1;
- } else if (!aStartsWithLetter && bStartsWithLetter) {
- return 1;
- }
-
- // Order by the title in the current locale
- return mCollator.compare(titleA, titleB);
- }
-}
diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java
index c86ba86..00470e1 100644
--- a/src/com/android/launcher3/model/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/PackageItemInfo.java
@@ -40,12 +40,6 @@
*/
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;
-
PackageItemInfo(String packageName) {
this.packageName = packageName;
}
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index b2a94bb..3953f39 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -18,7 +18,9 @@
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.Preconditions;
import java.util.ArrayList;
@@ -37,74 +39,31 @@
private static final String TAG = "WidgetsModel";
private static final boolean DEBUG = false;
- /* List of packages that is tracked by this model. */
- private final ArrayList<PackageItemInfo> mPackageItemInfos;
-
/* Map of widgets and shortcuts that are tracked per package. */
- private final HashMap<PackageItemInfo, ArrayList<WidgetItem>> mWidgetsList;
+ private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList;
- private final AppWidgetManagerCompat mAppWidgetMgr;
- private final Comparator<ItemInfo> mAppNameComparator;
private final IconCache mIconCache;
private final AppFilter mAppFilter;
- private final AlphabeticIndexCompat mIndexer;
- private ArrayList<WidgetItem> mRawList;
-
- public WidgetsModel(Context context, IconCache iconCache, AppFilter appFilter) {
- mAppWidgetMgr = AppWidgetManagerCompat.getInstance(context);
- mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator();
+ public WidgetsModel(IconCache iconCache, AppFilter appFilter) {
mIconCache = iconCache;
mAppFilter = appFilter;
- mIndexer = new AlphabeticIndexCompat(context);
- mPackageItemInfos = new ArrayList<>();
- mWidgetsList = new HashMap<>();
-
- mRawList = new ArrayList<>();
+ mWidgetsList = new MultiHashMap<>();
}
- @SuppressWarnings("unchecked")
- private WidgetsModel(WidgetsModel model) {
- mAppWidgetMgr = model.mAppWidgetMgr;
- mPackageItemInfos = (ArrayList<PackageItemInfo>) model.mPackageItemInfos.clone();
- mWidgetsList = (HashMap<PackageItemInfo, ArrayList<WidgetItem>>) model.mWidgetsList.clone();
- mAppNameComparator = model.mAppNameComparator;
- mIconCache = model.mIconCache;
- mAppFilter = model.mAppFilter;
- mIndexer = model.mIndexer;
- mRawList = (ArrayList<WidgetItem>) model.mRawList.clone();
- }
-
- // Access methods that may be deleted if the private fields are made package-private.
- public int getPackageSize() {
- return mPackageItemInfos.size();
- }
-
- // 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);
- }
-
- public List<WidgetItem> getSortedWidgets(int pos) {
- return mWidgetsList.get(mPackageItemInfos.get(pos));
- }
-
- public ArrayList<WidgetItem> getRawList() {
- return mRawList;
+ public MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() {
+ return mWidgetsList;
}
public boolean isEmpty() {
- return mRawList.isEmpty();
+ return mWidgetsList.isEmpty();
}
- public WidgetsModel updateAndClone(Context context) {
+ public ArrayList<WidgetItem> update(Context context) {
Preconditions.assertWorkerThread();
+ final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
try {
- final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
// Widgets
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders()) {
@@ -132,11 +91,10 @@
throw e;
}
}
- return clone();
+ return widgetsAndShortcuts;
}
private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts) {
- mRawList = rawWidgetsShortcuts;
if (DEBUG) {
Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
}
@@ -147,9 +105,9 @@
// clear the lists.
mWidgetsList.clear();
- mPackageItemInfos.clear();
InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+ UserHandleCompat myUser = UserHandleCompat.myUserHandle();
// add and update.
for (WidgetItem item: rawWidgetsShortcuts) {
@@ -177,43 +135,20 @@
String packageName = item.componentName.getPackageName();
PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName);
- ArrayList<WidgetItem> widgetsShortcutsList = mWidgetsList.get(pInfo);
-
- if (widgetsShortcutsList == null) {
- widgetsShortcutsList = new ArrayList<>();
-
+ if (pInfo == null) {
pInfo = new PackageItemInfo(packageName);
+ pInfo.user = item.user;
tmpPackageItemInfos.put(packageName, pInfo);
-
- mPackageItemInfos.add(pInfo);
- mWidgetsList.put(pInfo, widgetsShortcutsList);
+ } else if (!myUser.equals(pInfo.user)) {
+ // Keep updating the user, until we get the primary user.
+ pInfo.user = item.user;
}
-
- widgetsShortcutsList.add(item);
+ mWidgetsList.addToList(pInfo, item);
}
// Update each package entry
- for (PackageItemInfo p : mPackageItemInfos) {
- ArrayList<WidgetItem> widgetsShortcutsList = mWidgetsList.get(p);
- Collections.sort(widgetsShortcutsList);
-
- // Update the package entry based on the first item.
- p.user = widgetsShortcutsList.get(0).user;
+ for (PackageItemInfo p : tmpPackageItemInfos.values()) {
mIconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
- p.titleSectionName = mIndexer.computeSectionName(p.title);
}
-
- // sort the package entries.
- Collections.sort(mPackageItemInfos, mAppNameComparator);
- }
-
- /**
- * Create a snapshot of the widgets model.
- * <p>
- * Usage case: view binding without being modified from package updates.
- */
- @Override
- public WidgetsModel clone(){
- return new WidgetsModel(this);
}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
index fea47a9..aedf283 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
@@ -49,7 +49,7 @@
caretDrawable.setBounds(0, 0, caretSize, caretSize);
setCaretDrawable(caretDrawable);
- Launcher l = (Launcher) context;
+ Launcher l = Launcher.getLauncher(context);
setOnTouchListener(l.getHapticFeedbackTouchListener());
setOnClickListener(l);
setOnLongClickListener(l);
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
index 0e1a708..3ceba84 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
@@ -125,7 +125,7 @@
mLinePaint = new Paint();
mLinePaint.setAlpha(0);
- mLauncher = (Launcher) context;
+ mLauncher = Launcher.getLauncher(context);
mLineHeight = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_line_height);
setCaretDrawable(new CaretDrawable(context));
}
diff --git a/src/com/android/launcher3/QsbBlockerView.java b/src/com/android/launcher3/qsb/QsbBlockerView.java
similarity index 91%
rename from src/com/android/launcher3/QsbBlockerView.java
rename to src/com/android/launcher3/qsb/QsbBlockerView.java
index 6a2bce0..5379336 100644
--- a/src/com/android/launcher3/QsbBlockerView.java
+++ b/src/com/android/launcher3/qsb/QsbBlockerView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.qsb;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
@@ -27,12 +27,15 @@
import android.util.AttributeSet;
import android.view.View;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.Workspace.OnStateChangeListener;
import com.android.launcher3.Workspace.State;
/**
* A simple view used to show the region blocked by QSB during drag and drop.
*/
-public class QsbBlockerView extends View implements Workspace.OnStateChangeListener {
+public class QsbBlockerView extends View implements OnStateChangeListener {
private static final int VISIBLE_ALPHA = 100;
diff --git a/src/com/android/launcher3/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
similarity index 61%
rename from src/com/android/launcher3/QsbContainerView.java
rename to src/com/android/launcher3/qsb/QsbContainerView.java
index 65711e1..c83143b 100644
--- a/src/com/android/launcher3/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -14,19 +14,18 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.qsb;
import android.app.Activity;
import android.app.Fragment;
import android.app.SearchManager;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -35,6 +34,11 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.launcher3.AppWidgetResizeFrame;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
/**
@@ -68,25 +72,14 @@
private static final int REQUEST_BIND_QSB = 1;
private static final String QSB_WIDGET_ID = "qsb_widget_id";
- private static int sSavedWidgetId = -1;
-
+ private QsbWidgetHost mQsbWidgetHost;
private AppWidgetProviderInfo mWidgetInfo;
- private LauncherAppWidgetHostView mQsb;
-
- private BroadcastReceiver mRebindReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- rebindFragment();
- }
- };
+ private QsbWidgetHostView mQsb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- IntentFilter filter = new IntentFilter(Launcher.ACTION_APPWIDGET_HOST_RESET);
- filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
- getActivity().registerReceiver(mRebindReceiver, filter);
+ mQsbWidgetHost = new QsbWidgetHost(getActivity());
}
private FrameLayout mWrapper;
@@ -95,109 +88,96 @@
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- if (savedInstanceState != null) {
- sSavedWidgetId = savedInstanceState.getInt(QSB_WIDGET_ID, -1);
- }
mWrapper = new FrameLayout(getActivity());
- mWrapper.addView(createQsb(inflater, mWrapper));
+ mWrapper.addView(createQsb(mWrapper));
return mWrapper;
}
- private View createQsb(LayoutInflater inflater, ViewGroup container) {
- Launcher launcher = (Launcher) getActivity();
- mWidgetInfo = getSearchWidgetProvider(launcher);
+ private View createQsb(ViewGroup container) {
+ Activity activity = getActivity();
+ mWidgetInfo = getSearchWidgetProvider(activity);
if (mWidgetInfo == null) {
// There is no search provider, just show the default widget.
- return getDefaultView(inflater, container, false);
- } else {
- mWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(launcher, mWidgetInfo);
+ return QsbWidgetHostView.getDefaultView(container);
}
- SharedPreferences prefs = Utilities.getPrefs(launcher);
- AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(launcher);
- LauncherAppWidgetHost widgetHost = launcher.getAppWidgetHost();
+ AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(activity);
InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
Bundle opts = new Bundle();
- Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(launcher, idp.numColumns, 1, null);
+ Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(activity, idp.numColumns, 1, null);
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left);
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top);
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right);
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom);
- int widgetId = prefs.getInt(QSB_WIDGET_ID, -1);
+ int widgetId = Utilities.getPrefs(activity).getInt(QSB_WIDGET_ID, -1);
AppWidgetProviderInfo widgetInfo = widgetManager.getAppWidgetInfo(widgetId);
boolean isWidgetBound = (widgetInfo != null) &&
widgetInfo.provider.equals(mWidgetInfo.provider);
+ int oldWidgetId = widgetId;
if (!isWidgetBound) {
- // widgetId is already bound and its not the correct provider.
- // Delete the widget id.
if (widgetId > -1) {
- widgetHost.deleteAppWidgetId(widgetId);
+ // widgetId is already bound and its not the correct provider. reset host.
+ mQsbWidgetHost.deleteHost();
+ }
+
+ widgetId = mQsbWidgetHost.allocateAppWidgetId();
+ isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts);
+ if (!isWidgetBound) {
+ mQsbWidgetHost.deleteAppWidgetId(widgetId);
widgetId = -1;
}
- widgetId = widgetHost.allocateAppWidgetId();
- isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts);
- if (!isWidgetBound) {
- widgetHost.deleteAppWidgetId(widgetId);
- widgetId = -1;
+ if (oldWidgetId != widgetId) {
+ saveWidgetId(widgetId);
}
}
if (isWidgetBound) {
- mQsb = (LauncherAppWidgetHostView)
- widgetHost.createView(launcher, widgetId, mWidgetInfo);
+ mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(activity, widgetId, mWidgetInfo);
mQsb.setId(R.id.qsb_widget);
- mQsb.mErrorViewId = R.layout.qsb_default_view;
- if (!Utilities.containsAll(AppWidgetManager.getInstance(launcher)
+ if (!Utilities.containsAll(AppWidgetManager.getInstance(activity)
.getAppWidgetOptions(widgetId), opts)) {
mQsb.updateAppWidgetOptions(opts);
}
mQsb.setPadding(0, 0, 0, 0);
+ mQsbWidgetHost.startListening();
return mQsb;
}
// Return a default widget with setup icon.
- return getDefaultView(inflater, container, true);
+ View v = QsbWidgetHostView.getDefaultView(container);
+ View setupButton = v.findViewById(R.id.btn_qsb_setup);
+ setupButton.setVisibility(View.VISIBLE);
+ setupButton.setOnClickListener(this);
+ return v;
+ }
+
+ private void saveWidgetId(int widgetId) {
+ Utilities.getPrefs(getActivity()).edit().putInt(QSB_WIDGET_ID, widgetId).apply();
}
@Override
public void onClick(View view) {
- if (view.getId() == R.id.btn_qsb_search) {
- getActivity().startSearch("", false, null, true);
- } else if (view.getId() == R.id.btn_qsb_setup) {
- // Allocate a new widget id for QSB
- sSavedWidgetId = ((Launcher) getActivity())
- .getAppWidgetHost().allocateAppWidgetId();
- // Start intent for bind the widget
- Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, sSavedWidgetId);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mWidgetInfo.provider);
- startActivityForResult(intent, REQUEST_BIND_QSB);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(QSB_WIDGET_ID, sSavedWidgetId);
+ // Start intent for bind the widget
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
+ // Allocate a new widget id for QSB
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mQsbWidgetHost.allocateAppWidgetId());
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mWidgetInfo.provider);
+ startActivityForResult(intent, REQUEST_BIND_QSB);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_BIND_QSB) {
if (resultCode == Activity.RESULT_OK) {
- int widgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
- sSavedWidgetId);
- Utilities.getPrefs(getActivity()).edit().putInt(QSB_WIDGET_ID, widgetId).apply();
- sSavedWidgetId = -1;
+ saveWidgetId(data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1));
rebindFragment();
- } else if (sSavedWidgetId != -1) {
- ((Launcher) getActivity()).getAppWidgetHost().deleteAppWidgetId(sSavedWidgetId);
- sSavedWidgetId = -1;
+ } else {
+ mQsbWidgetHost.deleteHost();
}
}
}
@@ -212,27 +192,16 @@
@Override
public void onDestroy() {
- getActivity().unregisterReceiver(mRebindReceiver);
+ mQsbWidgetHost.stopListening();
super.onDestroy();
}
private void rebindFragment() {
if (mWrapper != null && getActivity() != null) {
mWrapper.removeAllViews();
- mWrapper.addView(createQsb(getActivity().getLayoutInflater(), mWrapper));
+ mWrapper.addView(createQsb(mWrapper));
}
}
-
- private View getDefaultView(LayoutInflater inflater, ViewGroup parent, boolean showSetup) {
- View v = inflater.inflate(R.layout.qsb_default_view, parent, false);
- if (showSetup) {
- View setupButton = v.findViewById(R.id.btn_qsb_setup);
- setupButton.setVisibility(View.VISIBLE);
- setupButton.setOnClickListener(this);
- }
- v.findViewById(R.id.btn_qsb_search).setOnClickListener(this);
- return v;
- }
}
/**
@@ -262,4 +231,19 @@
}
return defaultWidgetForSearchPackage;
}
+
+ private static class QsbWidgetHost extends AppWidgetHost {
+
+ private static final int QSB_WIDGET_HOST_ID = 1026;
+
+ public QsbWidgetHost(Context context) {
+ super(context, QSB_WIDGET_HOST_ID);
+ }
+
+ @Override
+ protected AppWidgetHostView onCreateView(
+ Context context, int appWidgetId, AppWidgetProviderInfo appWidget) {
+ return new QsbWidgetHostView(context);
+ }
+ }
}
diff --git a/src/com/android/launcher3/qsb/QsbWidgetHostView.java b/src/com/android/launcher3/qsb/QsbWidgetHostView.java
new file mode 100644
index 0000000..8b6fa16
--- /dev/null
+++ b/src/com/android/launcher3/qsb/QsbWidgetHostView.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 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.qsb;
+
+import android.appwidget.AppWidgetHostView;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.widget.RemoteViews;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+
+/**
+ * Appwidget host view with QSB specific logic.
+ */
+public class QsbWidgetHostView extends AppWidgetHostView {
+
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private int mPreviousOrientation;
+
+ public QsbWidgetHostView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void updateAppWidget(RemoteViews remoteViews) {
+ // Store the orientation in which the widget was inflated
+ mPreviousOrientation = getResources().getConfiguration().orientation;
+ super.updateAppWidget(remoteViews);
+ }
+
+
+ public boolean isReinflateRequired() {
+ // Re-inflate is required if the orientation has changed since last inflation.
+ return mPreviousOrientation != getResources().getConfiguration().orientation;
+ }
+
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ try {
+ super.onLayout(changed, left, top, right, bottom);
+ } catch (final RuntimeException e) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ // Update the widget with 0 Layout id, to reset the view to error view.
+ updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0));
+ }
+ });
+ }
+ }
+
+ @Override
+ protected View getErrorView() {
+ return getDefaultView(this);
+ }
+
+ public static View getDefaultView(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.qsb_default_view, parent, false);
+ v.findViewById(R.id.btn_qsb_search).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Launcher.getLauncher(view.getContext()).startSearch("", false, null, true);
+ }
+ });
+ return v;
+ }
+}
diff --git a/src/com/android/launcher3/util/LabelComparator.java b/src/com/android/launcher3/util/LabelComparator.java
new file mode 100644
index 0000000..5da9ddf
--- /dev/null
+++ b/src/com/android/launcher3/util/LabelComparator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 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.util;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Extension of {@link java.text.Collator} with special handling for digits. Used for comparing
+ * user visible labels.
+ */
+public class LabelComparator implements Comparator<String> {
+
+ private final Collator mCollator = Collator.getInstance();
+
+ @Override
+ public int compare(String titleA, String titleB) {
+ // Ensure that we de-prioritize any titles that don't start with a
+ // linguistic letter or digit
+ boolean aStartsWithLetter = (titleA.length() > 0) &&
+ Character.isLetterOrDigit(titleA.codePointAt(0));
+ boolean bStartsWithLetter = (titleB.length() > 0) &&
+ Character.isLetterOrDigit(titleB.codePointAt(0));
+ if (aStartsWithLetter && !bStartsWithLetter) {
+ return -1;
+ } else if (!aStartsWithLetter && bStartsWithLetter) {
+ return 1;
+ }
+
+ // Order by the title in the current locale
+ return mCollator.compare(titleA, titleB);
+ }
+}
diff --git a/src/com/android/launcher3/util/PendingRequestArgs.java b/src/com/android/launcher3/util/PendingRequestArgs.java
index 4e402f3..bade967 100644
--- a/src/com/android/launcher3/util/PendingRequestArgs.java
+++ b/src/com/android/launcher3/util/PendingRequestArgs.java
@@ -74,6 +74,7 @@
public void writeToParcel(Parcel dest, int flags) {
ContentValues itemValues = new ContentValues();
writeToValues(itemValues);
+ itemValues.writeToParcel(dest, flags);
dest.writeInt(mArg1);
dest.writeInt(mObjectType);
diff --git a/src/com/android/launcher3/widget/WidgetItemComparator.java b/src/com/android/launcher3/widget/WidgetItemComparator.java
new file mode 100644
index 0000000..b5aaeb9
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetItemComparator.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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.widget;
+
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.model.WidgetItem;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Comparator for sorting WidgetItem based on their user, title and size.
+ */
+public class WidgetItemComparator implements Comparator<WidgetItem> {
+
+ private final UserHandleCompat mMyUserHandle = UserHandleCompat.myUserHandle();
+ private final Collator mCollator = Collator.getInstance();
+
+ @Override
+ public int compare(WidgetItem a, WidgetItem b) {
+ // Independent of how the labels compare, if only one of the two widget info belongs to
+ // work profile, put that one in the back.
+ boolean thisWorkProfile = !mMyUserHandle.equals(a.user);
+ boolean otherWorkProfile = !mMyUserHandle.equals(b.user);
+ if (thisWorkProfile ^ otherWorkProfile) {
+ return thisWorkProfile ? 1 : -1;
+ }
+
+ int labelCompare = mCollator.compare(a.label, b.label);
+ if (labelCompare != 0) {
+ return labelCompare;
+ }
+
+ // If the label is same, put the smaller widget before the larger widget. If the area is
+ // also same, put the widget with smaller height before.
+ int thisArea = a.spanX * a.spanY;
+ int otherArea = b.spanX * b.spanY;
+ return thisArea == otherArea
+ ? Integer.compare(a.spanY, b.spanY)
+ : Integer.compare(thisArea, otherArea);
+ }
+}
diff --git a/src/com/android/launcher3/widget/WidgetListRowEntry.java b/src/com/android/launcher3/widget/WidgetListRowEntry.java
new file mode 100644
index 0000000..3e89eeb
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetListRowEntry.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.widget;
+
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.model.WidgetItem;
+
+import java.util.ArrayList;
+
+/**
+ * Holder class to store all the information related to a single row in the widget list
+ */
+public class WidgetListRowEntry {
+
+ public final PackageItemInfo pkgItem;
+
+ public final ArrayList<WidgetItem> widgets;
+
+ /**
+ * 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;
+
+ public WidgetListRowEntry(PackageItemInfo pkgItem, ArrayList<WidgetItem> items) {
+ this.pkgItem = pkgItem;
+ this.widgets = items;
+ }
+
+}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index ecc853d..2e12942 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -28,7 +28,6 @@
import android.widget.Toast;
import com.android.launcher3.BaseContainerView;
-import com.android.launcher3.CellLayout;
import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget.DragObject;
@@ -42,12 +41,14 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.WidgetPreviewLoader;
-import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.Thunk;
/**
@@ -291,23 +292,7 @@
}
mLauncher.unlockScreenOrientation(false);
- // 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 = d.dragInfo;
- if (layout != null) {
- showOutOfSpaceMessage =
- !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
- }
- }
- if (showOutOfSpaceMessage) {
- mLauncher.showOutOfSpaceMessage(false);
- }
d.deferDragViewCleanupPostAnimation = false;
}
}
@@ -315,9 +300,8 @@
/**
* Initialize the widget data model.
*/
- public void addWidgets(WidgetsModel model) {
- mRecyclerView.setWidgets(model);
- mAdapter.setWidgetsModel(model);
+ public void setWidgets(MultiHashMap<PackageItemInfo, WidgetItem> model) {
+ mAdapter.setWidgets(model);
mAdapter.notifyDataSetChanged();
View loader = getContentView().findViewById(R.id.loader);
diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java
index 6b8ea49..a5846ec 100644
--- a/src/com/android/launcher3/widget/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java
@@ -27,16 +27,21 @@
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
-import com.android.launcher3.BubbleTextView;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.WidgetPreviewLoader;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.util.LabelComparator;
+import com.android.launcher3.util.MultiHashMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
+import java.util.Map;
/**
* List view adapter for the widget tray.
@@ -57,7 +62,8 @@
private final View.OnClickListener mIconClickListener;
private final View.OnLongClickListener mIconLongClickListener;
- private WidgetsModel mWidgetsModel;
+ private final ArrayList<WidgetListRowEntry> mEntries = new ArrayList<>();
+ private final AlphabeticIndexCompat mIndexer;
private final int mIndent;
@@ -67,26 +73,40 @@
mLayoutInflater = LayoutInflater.from(context);
mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+ mIndexer = new AlphabeticIndexCompat(context);
+
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent);
}
- public void setWidgetsModel(WidgetsModel w) {
- mWidgetsModel = w;
+ public void setWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets) {
+ mEntries.clear();
+ WidgetItemComparator widgetComparator = new WidgetItemComparator();
+
+ for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : widgets.entrySet()) {
+ WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue());
+ row.titleSectionName = mIndexer.computeSectionName(row.pkgItem.title);
+ Collections.sort(row.widgets, widgetComparator);
+ mEntries.add(row);
+ }
+
+ Collections.sort(mEntries, new WidgetListRowEntryComparator());
}
@Override
public int getItemCount() {
- if (mWidgetsModel == null) {
- return 0;
- }
- return mWidgetsModel.getPackageSize();
+ return mEntries.size();
+ }
+
+ public String getSectionName(int pos) {
+ return mEntries.get(pos).titleSectionName;
}
@Override
public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) {
- List<WidgetItem> infoList = mWidgetsModel.getSortedWidgets(pos);
+ WidgetListRowEntry entry = mEntries.get(pos);
+ List<WidgetItem> infoList = entry.widgets;
ViewGroup row = holder.cellContainer;
if (DEBUG) {
@@ -121,7 +141,7 @@
}
// Bind the views in the application info section.
- holder.title.applyFromPackageItemInfo(mWidgetsModel.getPackageItemInfo(pos));
+ holder.title.applyFromPackageItemInfo(entry.pkgItem);
// Bind the view in the widget horizontal tray region.
for (int i=0; i < infoList.size(); i++) {
@@ -175,4 +195,18 @@
public long getItemId(int pos) {
return pos;
}
+
+ /**
+ * Comparator for sorting WidgetListRowEntry based on package title
+ */
+ public static class WidgetListRowEntryComparator implements Comparator<WidgetListRowEntry> {
+
+ private final LabelComparator mComparator = new LabelComparator();
+
+ @Override
+ public int compare(WidgetListRowEntry a, WidgetListRowEntry b) {
+ return mComparator.compare(a.pkgItem.title.toString(), b.pkgItem.title.toString());
+ }
+ }
+
}
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index c33978e..e0a80c6 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -17,7 +17,6 @@
package com.android.launcher3.widget;
import android.content.Context;
-import android.graphics.Canvas;
import android.graphics.Color;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
@@ -32,7 +31,7 @@
public class WidgetsRecyclerView extends BaseRecyclerView {
private static final String TAG = "WidgetsRecyclerView";
- private WidgetsModel mWidgets;
+ private WidgetsListAdapter mAdapter;
public WidgetsRecyclerView(Context context) {
this(context, null);
@@ -65,23 +64,10 @@
return Color.WHITE;
}
- /**
- * Sets the widget model in this view, used to determine the fast scroll position.
- */
- public void setWidgets(WidgetsModel widgets) {
- mWidgets = widgets;
- }
-
- /**
- * We need to override the draw to ensure that we don't draw the overscroll effect beyond the
- * background bounds.
- */
@Override
- protected void dispatchDraw(Canvas canvas) {
- canvas.clipRect(mBackgroundPadding.left, mBackgroundPadding.top,
- getWidth() - mBackgroundPadding.right,
- getHeight() - mBackgroundPadding.bottom);
- super.dispatchDraw(canvas);
+ public void setAdapter(Adapter adapter) {
+ super.setAdapter(adapter);
+ mAdapter = (WidgetsListAdapter) adapter;
}
/**
@@ -97,15 +83,14 @@
// Stop the scroller if it is scrolling
stopScroll();
- int rowCount = mWidgets.getPackageSize();
+ int rowCount = mAdapter.getItemCount();
float pos = rowCount * touchFraction;
int availableScrollHeight = getAvailableScrollHeight();
LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());
layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction));
int posInt = (int) ((touchFraction == 1)? pos -1 : pos);
- PackageItemInfo p = mWidgets.getPackageItemInfo(posInt);
- return p.titleSectionName;
+ return mAdapter.getSectionName(posInt);
}
/**
@@ -150,13 +135,13 @@
@Override
protected int getAvailableScrollHeight() {
View child = getChildAt(0);
- int height = child.getMeasuredHeight() * mWidgets.getPackageSize();
+ int height = child.getMeasuredHeight() * mAdapter.getItemCount();
int totalHeight = getPaddingTop() + height + getPaddingBottom();
- int availableScrollHeight = totalHeight - getVisibleHeight();
+ int availableScrollHeight = totalHeight - getScrollbarTrackHeight();
return availableScrollHeight;
}
private boolean isModelNotReady() {
- return mWidgets == null || mWidgets.getPackageSize() == 0;
+ return mAdapter.getItemCount() == 0;
}
}
\ No newline at end of file
diff --git a/src_config/com/android/launcher3/config/FeatureFlags.java b/src_config/com/android/launcher3/config/FeatureFlags.java
index fe7bcbd..8ee5497 100644
--- a/src_config/com/android/launcher3/config/FeatureFlags.java
+++ b/src_config/com/android/launcher3/config/FeatureFlags.java
@@ -37,4 +37,6 @@
public static final boolean NO_ALL_APPS_ICON = true;
// When enabled fling down gesture on the first workspace triggers search.
public static final boolean PULLDOWN_SEARCH = false;
+ // When enabled the status bar may show dark icons based on the top of the wallpaper.
+ public static final boolean LIGHT_STATUS_BAR = false;
}
diff --git a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
index 4d0a7a9..18570de 100644
--- a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
@@ -67,6 +67,10 @@
assertTrue(mAlgorithm.matches(getInfo("Q"), "q"));
assertTrue(mAlgorithm.matches(getInfo(" Q"), "q"));
+
+ // match lower case words
+ assertTrue(mAlgorithm.matches(getInfo("elephant"), "e"));
+
}
private AppInfo getInfo(String title) {