Merge "Don't let AllAppsTransitionController intercept when a floating view is open." into ub-launcher3-master
diff --git a/res/layout/folder_page.xml b/res/layout/folder_page.xml
new file mode 100644
index 0000000..084e8fd
--- /dev/null
+++ b/res/layout/folder_page.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<com.android.launcher3.CellLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:hapticFeedbackEnabled="false"
+ android:importantForAccessibility="no"
+ launcher:containerType="folder" />
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index 7bef889..f5b5bbf 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -20,5 +20,6 @@
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_gravity="center" />
+ android:layout_gravity="center"
+ launcher:containerType="hotseat" />
</com.android.launcher3.Hotseat>
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index faf6885..94bdedb 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -19,4 +19,5 @@
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:hapticFeedbackEnabled="false" />
+ android:hapticFeedbackEnabled="false"
+ launcher:containerType="workspace" />
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 32bccb8..1e34c0f 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -112,4 +112,12 @@
<attr name="defaultLayoutId" format="reference" />
</declare-styleable>
+ <declare-styleable name="CellLayout">
+ <attr name="containerType" format="integer">
+ <enum name="workspace" value="0" />
+ <enum name="hotseat" value="1" />
+ <enum name="folder" value="2" />
+ </attr>
+ </declare-styleable>
+
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d5ce786..ccbae58 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -40,6 +40,7 @@
<color name="all_apps_caret_shadow_color">#22000000</color>
<color name="all_apps_container_color">#FFF2F2F2</color>
<color name="all_apps_navbar_color">#28000000</color>
+ <color name="all_apps_light_navbar_color">#AAF2F2F2</color>
<color name="spring_loaded_panel_color">#40FFFFFF</color>
<color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index b13c20b..bbc8650 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -66,7 +66,7 @@
* If the app is already in the list, doesn't add it.
*/
public void add(AppInfo info) {
- if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
+ if (!mAppFilter.shouldShowApp(info.componentName)) {
return;
}
if (findActivity(data, info.componentName, info.user)) {
diff --git a/src/com/android/launcher3/AppFilter.java b/src/com/android/launcher3/AppFilter.java
index e01436d..db8f5dd 100644
--- a/src/com/android/launcher3/AppFilter.java
+++ b/src/com/android/launcher3/AppFilter.java
@@ -1,35 +1,10 @@
package com.android.launcher3;
import android.content.ComponentName;
-import android.text.TextUtils;
-import android.util.Log;
-public abstract class AppFilter {
+public class AppFilter {
- private static final boolean DBG = false;
- private static final String TAG = "AppFilter";
-
- public abstract boolean shouldShowApp(ComponentName app);
-
- public static AppFilter loadByName(String className) {
- if (TextUtils.isEmpty(className)) return null;
- if (DBG) Log.d(TAG, "Loading AppFilter: " + className);
- try {
- Class<?> cls = Class.forName(className);
- return (AppFilter) cls.newInstance();
- } catch (ClassNotFoundException e) {
- Log.e(TAG, "Bad AppFilter class", e);
- return null;
- } catch (InstantiationException e) {
- Log.e(TAG, "Bad AppFilter class", e);
- return null;
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Bad AppFilter class", e);
- return null;
- } catch (ClassCastException e) {
- Log.e(TAG, "Bad AppFilter class", e);
- return null;
- }
+ public boolean shouldShowApp(ComponentName app) {
+ return true;
}
-
}
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index c45ff7b..54faca3 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -354,19 +354,18 @@
}
public void snapToWidget(boolean animate) {
- final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
DeviceProfile profile = mLauncher.getDeviceProfile();
- int newWidth = (int) (mWidgetView.getWidth() * profile.appWidgetScale.x)
- + 2 * mBackgroundPadding - mWidgetPadding.left - mWidgetPadding.right;
- int newHeight = (int) (mWidgetView.getHeight() * profile.appWidgetScale.y)
- + 2 * mBackgroundPadding - mWidgetPadding.top - mWidgetPadding.bottom;
+ float scale = Math.min(profile.appWidgetScale.x, profile.appWidgetScale.y);
- mTmpPt[0] = mWidgetView.getLeft();
- mTmpPt[1] = mWidgetView.getTop();
- mDragLayer.getDescendantCoordRelativeToSelf(mCellLayout.getShortcutsAndWidgets(), mTmpPt);
+ mDragLayer.getViewRectRelativeToSelf(mWidgetView, sTmpRect);
- int newX = mTmpPt[0] - mBackgroundPadding + mWidgetPadding.left;
- int newY = mTmpPt[1] - mBackgroundPadding + mWidgetPadding.top;
+ int newWidth = 2 * mBackgroundPadding
+ + (int) (scale * (sTmpRect.width() - mWidgetPadding.left - mWidgetPadding.right));
+ int newHeight = 2 * mBackgroundPadding
+ + (int) (scale * (sTmpRect.height() - mWidgetPadding.top - mWidgetPadding.bottom));
+
+ int newX = (int) (sTmpRect.left - mBackgroundPadding + scale * mWidgetPadding.left);
+ int newY = (int) (sTmpRect.top - mBackgroundPadding + scale * mWidgetPadding.top);
// We need to make sure the frame's touchable regions lie fully within the bounds of the
// DragLayer. We allow the actual handles to be clipped, but we shift the touch regions
@@ -384,6 +383,7 @@
mBottomTouchRegionAdjustment = 0;
}
+ final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
if (!animate) {
lp.width = newWidth;
lp.height = newHeight;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 866d239..c0087c4 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -24,6 +24,7 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -35,6 +36,7 @@
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Parcelable;
+import android.support.annotation.IntDef;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
@@ -60,6 +62,8 @@
import com.android.launcher3.util.ParcelableSparseArray;
import com.android.launcher3.util.Thunk;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -145,8 +149,16 @@
private TimeInterpolator mEaseOutInterpolator;
private ShortcutAndWidgetContainer mShortcutsAndWidgets;
- private boolean mIsHotseat = false;
- private float mHotseatScale = 1f;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({WORKSPACE, HOTSEAT, FOLDER})
+ public @interface ContainerType{}
+ public static final int WORKSPACE = 0;
+ public static final int HOTSEAT = 1;
+ public static final int FOLDER = 2;
+
+ @ContainerType private final int mContainerType;
+
+ private final float mChildScale;
public static final int MODE_SHOW_REORDER_HINT = 0;
public static final int MODE_DRAG_OVER = 1;
@@ -158,7 +170,7 @@
private static final float REORDER_PREVIEW_MAGNITUDE = 0.12f;
private static final int REORDER_ANIMATION_DURATION = 150;
- @Thunk float mReorderPreviewAnimationMagnitude;
+ @Thunk final float mReorderPreviewAnimationMagnitude;
private ArrayList<View> mIntersectingViews = new ArrayList<View>();
private Rect mOccupiedRect = new Rect();
@@ -184,6 +196,9 @@
public CellLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
+ mContainerType = a.getInteger(R.styleable.CellLayout_containerType, WORKSPACE);
+ a.recycle();
// A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
// the user where a dragged item will land when dropped.
@@ -207,9 +222,10 @@
mFolderLeaveBehind.delegateCellX = -1;
mFolderLeaveBehind.delegateCellY = -1;
+ mChildScale = mContainerType == HOTSEAT ? grid.inv.hotseatScale : 1f;
+
setAlwaysDrawnWithCacheEnabled(false);
final Resources res = getResources();
- mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx;
mBackground = (TransitionDrawable) res.getDrawable(
FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND ? R.drawable.bg_screenpanel
@@ -217,8 +233,7 @@
mBackground.setCallback(this);
mBackground.setAlpha((int) (mBackgroundAlpha * 255));
- mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE *
- grid.iconSizePx);
+ mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * grid.iconSizePx);
// Initialize the data structures used for the drag visualization.
mEaseOutInterpolator = new DecelerateInterpolator(2.5f); // Quint ease out
@@ -276,7 +291,7 @@
mDragOutlineAnims[i] = anim;
}
- mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
+ mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context, mContainerType);
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
@@ -355,10 +370,6 @@
mShortcutsAndWidgets.buildLayer();
}
- public float getChildrenScale() {
- return mIsHotseat ? mHotseatScale : 1.0f;
- }
-
public void setCellDimensions(int width, int height) {
mFixedCellWidth = mCellWidth = width;
mFixedCellHeight = mCellHeight = height;
@@ -603,15 +614,8 @@
return mCountY;
}
- public void setIsHotseat(boolean isHotseat) {
- mIsHotseat = isHotseat;
- mShortcutsAndWidgets.setContainerType(isHotseat
- ? ShortcutAndWidgetContainer.HOTSEAT
- : ShortcutAndWidgetContainer.DEFAULT);
- }
-
- public boolean isHotseat() {
- return mIsHotseat;
+ public boolean acceptsWidget() {
+ return mContainerType == WORKSPACE;
}
public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params,
@@ -621,11 +625,11 @@
// Hotseat icons - remove text
if (child instanceof BubbleTextView) {
BubbleTextView bubbleChild = (BubbleTextView) child;
- bubbleChild.setTextVisibility(!mIsHotseat);
+ bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
}
- child.setScaleX(getChildrenScale());
- child.setScaleY(getChildrenScale());
+ child.setScaleX(mChildScale);
+ child.setScaleY(mChildScale);
// Generate an id for each view, this assumes we have at most 256x256 cells
// per workspace screen
@@ -1061,24 +1065,26 @@
r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight());
}
- Utilities.scaleRectAboutCenter(r, getChildrenScale());
+ Utilities.scaleRectAboutCenter(r, mChildScale);
mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
mDragOutlineAnims[mDragOutlineCurrent].animateIn();
if (dragObject.stateAnnouncer != null) {
- String msg;
- if (isHotseat()) {
- msg = getContext().getString(R.string.move_to_hotseat_position,
- Math.max(cellX, cellY) + 1);
- } else {
- msg = getContext().getString(R.string.move_to_empty_cell,
- cellY + 1, cellX + 1);
- }
- dragObject.stateAnnouncer.announce(msg);
+ dragObject.stateAnnouncer.announce(getItemMoveDescription(cellX, cellY));
}
}
}
+ public String getItemMoveDescription(int cellX, int cellY) {
+ if (mContainerType == HOTSEAT) {
+ return getContext().getString(R.string.move_to_hotseat_position,
+ Math.max(cellX, cellY) + 1);
+ } else {
+ return getContext().getString(R.string.move_to_empty_cell,
+ cellY + 1, cellX + 1);
+ }
+ }
+
public void clearDragOutlines() {
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -2011,7 +2017,7 @@
this.mode = mode;
initDeltaX = child.getTranslationX();
initDeltaY = child.getTranslationY();
- finalScale = getChildrenScale() - 4.0f / child.getWidth();
+ finalScale = mChildScale - 4.0f / child.getWidth();
initScale = child.getScaleX();
this.child = child;
}
@@ -2061,7 +2067,7 @@
// We make sure to end only after a full period
initDeltaX = 0;
initDeltaY = 0;
- initScale = getChildrenScale();
+ initScale = mChildScale;
repeating = true;
}
});
@@ -2081,8 +2087,8 @@
}
a = new LauncherViewPropertyAnimator(child)
- .scaleX(getChildrenScale())
- .scaleY(getChildrenScale())
+ .scaleX(mChildScale)
+ .scaleY(mChildScale)
.translationX(0)
.translationY(0)
.setDuration(REORDER_ANIMATION_DURATION);
@@ -2104,7 +2110,7 @@
long screenId = mLauncher.getWorkspace().getIdForScreen(this);
int container = Favorites.CONTAINER_DESKTOP;
- if (mLauncher.isHotseatLayout(this)) {
+ if (mContainerType == HOTSEAT) {
screenId = -1;
container = Favorites.CONTAINER_HOTSEAT;
}
@@ -2127,7 +2133,7 @@
info.spanY = lp.cellVSpan;
if (requiresDbUpdate) {
- LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId,
+ LauncherModel.modifyItemInDatabase(getContext(), info, container, screenId,
info.cellX, info.cellY, info.spanX, info.spanY);
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index eb1db1c..f79d666 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -30,6 +30,7 @@
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
+import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
@@ -314,19 +315,28 @@
+ res.getDimensionPixelSize(R.dimen.folder_label_padding_bottom)
+ Utilities.calculateTextHeight(res.getDimension(R.dimen.folder_label_text_size));
- updateFolderCellSize(1f, dm, res, folderBottomPanelSize);
+ updateFolderCellSize(1f, dm, res);
- // Check to see if the icons fit within the available height. If not, then scale down.
- float usedHeight = (folderCellHeightPx * inv.numFolderRows) + folderBottomPanelSize;
- int maxHeight = availableHeightPx - getTotalWorkspacePadding().y - (2 * edgeMarginPx);
- if (usedHeight > maxHeight) {
- float scale = maxHeight / usedHeight;
- updateFolderCellSize(scale, dm, res, folderBottomPanelSize);
+ // Don't let the folder get too close to the edges of the screen.
+ int folderMargin = 4 * edgeMarginPx;
+
+ // Check if the icons fit within the available height.
+ float usedHeight = folderCellHeightPx * inv.numFolderRows + folderBottomPanelSize;
+ int maxHeight = availableHeightPx - getTotalWorkspacePadding().y - folderMargin;
+ float scaleY = maxHeight / usedHeight;
+
+ // Check if the icons fit within the available width.
+ float usedWidth = folderCellWidthPx * inv.numFolderColumns;
+ int maxWidth = availableWidthPx - getTotalWorkspacePadding().x - folderMargin;
+ float scaleX = maxWidth / usedWidth;
+
+ float scale = Math.min(scaleX, scaleY);
+ if (scale < 1f) {
+ updateFolderCellSize(scale, dm, res);
}
}
- private void updateFolderCellSize(float scale, DisplayMetrics dm, Resources res,
- int folderBottomPanelSize) {
+ private void updateFolderCellSize(float scale, DisplayMetrics dm, Resources res) {
folderChildIconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale);
folderChildTextSizePx =
(int) (res.getDimensionPixelSize(R.dimen.folder_child_text_size) * scale);
@@ -335,11 +345,8 @@
int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding) * scale);
int cellPaddingY = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_y_padding) * scale);
- // Don't let the folder get too close to the edges of the screen.
- folderCellWidthPx = Math.min(folderChildIconSizePx + 2 * cellPaddingX,
- (availableWidthPx - 4 * edgeMarginPx) / inv.numFolderColumns);
- folderCellHeightPx = Math.min(folderChildIconSizePx + 2 * cellPaddingY + textHeight,
- (availableHeightPx - 4 * edgeMarginPx - folderBottomPanelSize) / inv.numFolderRows);
+ folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX;
+ folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight;
folderChildDrawablePaddingPx = Math.max(0,
(folderCellHeightPx - folderChildIconSizePx - textHeight) / 3);
}
@@ -620,6 +627,19 @@
: Math.max(widthPx, heightPx);
}
+ public int getCellHeight(@ContainerType int containerType) {
+ switch (containerType) {
+ case CellLayout.WORKSPACE:
+ return cellHeightPx;
+ case CellLayout.FOLDER:
+ return folderCellHeightPx;
+ case CellLayout.HOTSEAT:
+ return hotseatCellHeightPx;
+ default:
+ // ??
+ return 0;
+ }
+ }
/**
* @return the left/right paddings for all containers.
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 5c96dde..3648fb7 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -113,12 +113,11 @@
super.onFinishInflate();
DeviceProfile grid = mLauncher.getDeviceProfile();
mContent = (CellLayout) findViewById(R.id.layout);
- if (grid.isLandscape && !grid.isLargeTablet) {
- mContent.setGridSize(1, (int) grid.inv.numHotseatIcons);
+ if (grid.isVerticalBarLayout()) {
+ mContent.setGridSize(1, grid.inv.numHotseatIcons);
} else {
- mContent.setGridSize((int) grid.inv.numHotseatIcons, 1);
+ mContent.setGridSize(grid.inv.numHotseatIcons, 1);
}
- mContent.setIsHotseat(true);
resetLayout();
}
@@ -168,7 +167,7 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
// We don't want any clicks to go through to the hotseat unless the workspace is in
// the normal state or an accessible drag is in progress.
- return mLauncher.getWorkspace().workspaceInModalState() &&
+ return !mLauncher.getWorkspace().workspaceIconsCanBeDragged() &&
!mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index db72b2f..4b09bf8 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -123,9 +123,8 @@
mLowResCanvas = new Canvas();
mLowResPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
- mIconProvider = IconProvider.loadByName(context.getString(R.string.icon_provider_class),
- context);
-
+ mIconProvider = Utilities.getOverrideObject(
+ IconProvider.class, context, R.string.icon_provider_class);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
mActivityBgColor = context.getResources().getColor(R.color.quantum_panel_bg_color);
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index 0a273bb..005bbaa 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -1,13 +1,9 @@
package com.android.launcher3;
-import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Log;
import com.android.launcher3.compat.LauncherActivityInfoCompat;
-import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
public class IconProvider {
@@ -21,19 +17,6 @@
updateSystemStateString();
}
- public static IconProvider loadByName(String className, Context context) {
- if (TextUtils.isEmpty(className)) return new IconProvider();
- if (DBG) Log.d(TAG, "Loading IconProvider: " + className);
- try {
- Class<?> cls = Class.forName(className);
- return (IconProvider) cls.getDeclaredConstructor(Context.class).newInstance(context);
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
- | ClassCastException | NoSuchMethodException | InvocationTargetException e) {
- Log.e(TAG, "Bad IconProvider class", e);
- return new IconProvider();
- }
- }
-
public void updateSystemStateString() {
mSystemState = Locale.getDefault().toString();
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 38545e2..1b0e5b3 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -85,6 +85,7 @@
*/
public int numHotseatIcons;
float hotseatIconSize;
+ public float hotseatScale;
int defaultLayoutId;
DeviceProfile landscapeProfile;
@@ -117,6 +118,8 @@
numHotseatIcons = hs;
hotseatIconSize = his;
defaultLayoutId = dlId;
+
+ hotseatScale = hotseatIconSize / iconSize;
}
@TargetApi(23)
@@ -158,6 +161,8 @@
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, dm);
+ hotseatScale = hotseatIconSize / iconSize;
+
Point realSize = new Point();
display.getRealSize(realSize);
// The real size never changes. smallSide and largeSide will remain the
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7fce079..accc3cd 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -475,25 +475,37 @@
mWorkspace.getPageIndicator().updateColor(mExtractedColors);
// It's possible that All Apps is visible when this is run,
// so always use light status bar in that case.
- activateLightStatusBar(isAllAppsVisible());
+ activateLightStatusBar(isAllAppsVisible(), false);
}
}
+ // TODO: use platform flag on API >= 26
+ private static final int SYSTEM_UI_FLAG_LIGHT_NAV_BAR = 0x10;
+
/**
* Sets the status bar to be light or not. Light status bar means dark icons.
* @param activate if true, make sure the status bar is light, otherwise base on wallpaper.
+ * @param changeNavBar make sure the nav bar is light only if this param and {@param activate}
+ * is also true.
*/
- public void activateLightStatusBar(boolean activate) {
+ public void activateLightStatusBar(boolean activate, boolean changeNavBar) {
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) {
- newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ;
} else {
newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
+ if (Utilities.isAtLeastO() && activate) {
+ if (changeNavBar) {
+ newSystemUiFlags |= SYSTEM_UI_FLAG_LIGHT_NAV_BAR;
+ } else {
+ newSystemUiFlags &= ~(SYSTEM_UI_FLAG_LIGHT_NAV_BAR);
+ }
+ }
if (newSystemUiFlags != oldSystemUiFlags) {
getWindow().getDecorView().setSystemUiVisibility(newSystemUiFlags);
}
@@ -2808,6 +2820,7 @@
}
boolean isHotseatLayout(View layout) {
+ // TODO: Remove this method
return mHotseat != null && layout != null &&
(layout instanceof CellLayout) && (layout == mHotseat.getLayout());
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 5937d78..ca5cd74 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -38,7 +38,6 @@
public static final boolean PROFILE_STARTUP = ProviderConfig.IS_DOGFOOD_BUILD;
- private final AppFilter mAppFilter;
@Thunk final LauncherModel mModel;
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
@@ -96,8 +95,8 @@
mIconCache = new IconCache(sContext, mInvariantDeviceProfile);
mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache);
- mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class));
- mModel = new LauncherModel(this, mIconCache, mAppFilter);
+ mModel = new LauncherModel(this, mIconCache,
+ Utilities.getOverrideObject(AppFilter.class, sContext, R.string.app_filter_class));
LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel);
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 342479f..6c73762 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -20,29 +20,19 @@
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.support.annotation.IntDef;
import android.view.View;
import android.view.ViewGroup;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import com.android.launcher3.CellLayout.ContainerType;
public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "ShortcutAndWidgetContainer";
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({DEFAULT, HOTSEAT, FOLDER})
- public @interface ContainerType{}
- public static final int DEFAULT = 0;
- public static final int HOTSEAT = 1;
- public static final int FOLDER = 2;
-
- private int mContainerType = DEFAULT;
-
// These are temporary variables to prevent having to allocate a new object just to
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
private final int[] mTmpCellXY = new int[2];
+ @ContainerType private final int mContainerType;
private final WallpaperManager mWallpaperManager;
private int mCellWidth;
@@ -51,13 +41,13 @@
private int mCountX;
private Launcher mLauncher;
-
private boolean mInvertIfRtl = false;
- public ShortcutAndWidgetContainer(Context context) {
+ public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
super(context);
mLauncher = Launcher.getLauncher(context);
mWallpaperManager = WallpaperManager.getInstance(context);
+ mContainerType = containerType;
}
public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
@@ -105,19 +95,9 @@
mInvertIfRtl = invert;
}
- public void setContainerType(@ContainerType int containerType) {
- mContainerType = containerType;
- }
-
int getCellContentHeight() {
- final DeviceProfile grid = mLauncher.getDeviceProfile();
- int cellContentHeight = grid.cellHeightPx;
- if (mContainerType == HOTSEAT) {
- cellContentHeight = grid.hotseatCellHeightPx;
- } else if (mContainerType == FOLDER) {
- cellContentHeight = grid.folderCellHeightPx;
- }
- return Math.min(getMeasuredHeight(), cellContentHeight);
+ return Math.min(getMeasuredHeight(),
+ mLauncher.getDeviceProfile().getCellHeight(mContainerType));
}
public void measureChild(View child) {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 416ca8e..197aaf7 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -60,6 +60,7 @@
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Locale;
@@ -655,4 +656,23 @@
return e.getCause() instanceof TransactionTooLargeException
|| e.getCause() instanceof DeadObjectException;
}
+
+ public static <T> T getOverrideObject(Class<T> clazz, Context context, int resId) {
+ String className = context.getString(resId);
+ if (!TextUtils.isEmpty(className)) {
+ try {
+ Class<?> cls = Class.forName(className);
+ return (T) cls.getDeclaredConstructor(Context.class).newInstance(context);
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+ | ClassCastException | NoSuchMethodException | InvocationTargetException e) {
+ Log.e(TAG, "Bad overriden class", e);
+ }
+ }
+
+ try {
+ return clazz.newInstance();
+ } catch (InstantiationException|IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 10680b4..13bea20 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -100,6 +100,14 @@
Insettable, DropTargetSource {
private static final String TAG = "Launcher.Workspace";
+ /** The value that {@link #mTransitionProgress} must be greater than for
+ * {@link #transitionStateShouldAllowDrop()} to return true. */
+ private static final float ALLOW_DROP_TRANSITION_PROGRESS = 0.25f;
+
+ /** The value that {@link #mTransitionProgress} must be greater than for
+ * {@link #isFinishedSwitchingState()} ()} to return true. */
+ private static final float FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS = 0.5f;
+
private static boolean ENFORCE_DRAG_EVENT_ORDER = false;
private static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400;
@@ -1160,7 +1168,7 @@
}
private boolean shouldConsumeTouch(View v) {
- return (workspaceInModalState() || !isFinishedSwitchingState())
+ return !workspaceIconsCanBeDragged()
|| (!workspaceInModalState() && indexOfChild(v) != mCurrentPage);
}
@@ -1171,7 +1179,8 @@
/** This differs from isSwitchingState in that we take into account how far the transition
* has completed. */
public boolean isFinishedSwitchingState() {
- return !mIsSwitchingState || (mTransitionProgress > 0.5f);
+ return !mIsSwitchingState
+ || (mTransitionProgress > FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS);
}
protected void onWindowVisibilityChanged (int visibility) {
@@ -1826,6 +1835,11 @@
return mState != State.NORMAL;
}
+ /** Returns whether a drag should be allowed to be started from the current workspace state. */
+ public boolean workspaceIconsCanBeDragged() {
+ return mState == State.NORMAL || mState == State.SPRING_LOADED;
+ }
+
@Thunk void updateChildrenLayersEnabled(boolean force) {
boolean small = mState == State.OVERVIEW || mIsSwitchingState;
boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageInTransition();
@@ -2273,8 +2287,8 @@
return dv;
}
- public boolean transitionStateShouldAllowDrop() {
- return ((!isSwitchingState() || mTransitionProgress > 0.5f) &&
+ private boolean transitionStateShouldAllowDrop() {
+ return ((!isSwitchingState() || mTransitionProgress > ALLOW_DROP_TRANSITION_PROGRESS) &&
(mState == State.NORMAL || mState == State.SPRING_LOADED));
}
@@ -2563,10 +2577,19 @@
&& item.screenId == screenId && item.container == container
&& item.cellX == mTargetCell[0] && item.cellY == mTargetCell[1];
+ // When quickly moving an item, a user may accidentally rearrange their
+ // workspace. So instead we move the icon back safely to its original position.
+ boolean returnToOriginalCellToPreventShuffling = !isFinishedSwitchingState()
+ && !droppedOnOriginalCellDuringTransition && !dropTargetLayout
+ .isRegionVacant(mTargetCell[0], mTargetCell[1], spanX, spanY);
int[] resultSpan = new int[2];
- mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0],
- (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, cell,
- mTargetCell, resultSpan, CellLayout.MODE_ON_DROP);
+ if (returnToOriginalCellToPreventShuffling) {
+ mTargetCell[0] = mTargetCell[1] = -1;
+ } else {
+ mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, cell,
+ mTargetCell, resultSpan, CellLayout.MODE_ON_DROP);
+ }
boolean foundCell = mTargetCell[0] >= 0 && mTargetCell[1] >= 0;
@@ -2632,7 +2655,9 @@
LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId, lp.cellX,
lp.cellY, item.spanX, item.spanY);
} else {
- onNoCellFound(dropTargetLayout);
+ if (!returnToOriginalCellToPreventShuffling) {
+ 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();
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index c71307d..9a23aa8 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -57,7 +57,7 @@
int y = id / mCountX;
LauncherAccessibilityDelegate.DragInfo dragInfo = mDelegate.getDragInfo();
- if (dragInfo.dragType == DragType.WIDGET && mView.isHotseat()) {
+ if (dragInfo.dragType == DragType.WIDGET && !mView.acceptsWidget()) {
return INVALID_POSITION;
}
@@ -161,11 +161,7 @@
View child = mView.getChildAt(x, y);
if (child == null || child == dragInfo.item) {
- if (mView.isHotseat()) {
- return mContext.getString(R.string.move_to_hotseat_position, id + 1);
- } else {
- return mContext.getString(R.string.move_to_empty_cell, y + 1, x + 1);
- }
+ return mView.getItemMoveDescription(x, y);
} else {
return getDescriptionForDropOver(child, mContext);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 6650aba..e0d145c 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -484,6 +484,10 @@
setLayoutParams(mlp);
} else {
View navBarBg = findViewById(R.id.nav_bar_bg);
+ if (Utilities.isAtLeastO()) {
+ navBarBg.setBackgroundColor(getResources().getColor(
+ R.color.all_apps_light_navbar_color));
+ }
ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
navBarBgLp.height = insets.bottom;
navBarBg.setLayoutParams(navBarBgLp);
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 8ab4a61..4667806 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -286,7 +286,7 @@
// Use a light status bar (dark icons) if all apps is behind at least half of the status
// bar. If the status bar is already light due to wallpaper extraction, keep it that way.
boolean forceLight = shift <= mStatusBarHeight / 2;
- mLauncher.activateLightStatusBar(forceLight);
+ mLauncher.activateLightStatusBar(forceLight, forceLight);
}
/**
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index e71c5e9..8aaeb9e 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -253,11 +253,9 @@
private CellLayout createAndAddNewPage() {
DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
- CellLayout page = new CellLayout(getContext());
+ CellLayout page = (CellLayout) mInflater.inflate(R.layout.folder_page, this, false);
page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
- page.getShortcutsAndWidgets().setContainerType(ShortcutAndWidgetContainer.FOLDER);
- page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
page.setInvertIfRtl(true);
page.setGridSize(mGridCountX, mGridCountY);
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 2926a29..f6a4b84 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -18,13 +18,11 @@
import android.content.Context;
import android.graphics.Bitmap;
-import android.text.TextUtils;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.R;
-
-import java.lang.reflect.InvocationTargetException;
+import com.android.launcher3.Utilities;
/**
* Factory for creating new drawables.
@@ -37,27 +35,13 @@
public static DrawableFactory get(Context context) {
synchronized (LOCK) {
if (sInstance == null) {
- context = context.getApplicationContext();
- sInstance = loadByName(context.getString(R.string.drawable_factory_class), context);
+ sInstance = Utilities.getOverrideObject(DrawableFactory.class,
+ context.getApplicationContext(), R.string.drawable_factory_class);
}
return sInstance;
}
}
- public static DrawableFactory loadByName(String className, Context context) {
- if (!TextUtils.isEmpty(className)) {
- try {
- Class<?> cls = Class.forName(className);
- return (DrawableFactory)
- cls.getDeclaredConstructor(Context.class).newInstance(context);
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
- | ClassCastException | NoSuchMethodException | InvocationTargetException e) {
- return new DrawableFactory();
- }
- }
- return new DrawableFactory();
- }
-
/**
* Returns a FastBitmapDrawable with the icon.
*/
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index 64043f4..5ad6f0f 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -117,7 +117,7 @@
}
}
- if (mAppFilter != null && !mAppFilter.shouldShowApp(item.componentName)) {
+ if (!mAppFilter.shouldShowApp(item.componentName)) {
if (DEBUG) {
Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
item.componentName));
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 293585d..07f59a5 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -29,11 +29,9 @@
import android.widget.TextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.R;
+import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
@@ -182,14 +180,6 @@
ensurePreview();
}
- public int getActualItemWidth() {
- ItemInfo info = (ItemInfo) getTag();
- int[] size = getPreviewSize();
- int cellWidth = mLauncher.getDeviceProfile().cellWidthPx;
-
- return Math.min(size[0], info.spanX * cellWidth);
- }
-
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean handled = super.onTouchEvent(ev);