Merge "Fixing bug when model was not reflected properly on the UI. If launcher submits a job, and then reloads before the job is executed, the correct model is not reflected on the Launcher. In that case, we simply rebind the launcher" into ub-launcher3-master
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7240e48
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+db_files
+*.iml
+.project
+.classpath
+.project.properties
+gen/
+tests/stress/gen/
+WallpaperPicker/gen/
+WallpaperPicker/.project.properties
+bin/
+.idea/
+.gradle/
+local.properties
+gradle/
+build/
+gradlew*
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 12ae85d..b97669b 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
@@ -48,6 +49,7 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.InsettableFrameLayout.LayoutParams;
import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.dragndrop.DragLayer;
@@ -227,7 +229,7 @@
// Resolve the opening task id
int openingTaskId = -1;
for (RemoteAnimationTargetCompat target : targets) {
- if (target.mode == RemoteAnimationTargetCompat.MODE_OPENING) {
+ if (target.mode == MODE_OPENING) {
openingTaskId = target.taskId;
break;
}
@@ -247,8 +249,36 @@
}
// Found a visible recents task that matches the opening app, lets launch the app from there
- return new LauncherTransitionAnimator(getRecentsLauncherAnimator(recentsView, taskView),
- getRecentsWindowAnimator(taskView, targets));
+ Animator launcherAnim;
+ AnimatorListenerAdapter windowAnimEndListener;
+ boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
+ if (launcherClosing) {
+ launcherAnim = getRecentsLauncherAnimator(recentsView, taskView);
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Make sure recents gets fixed up by resetting task alphas and scales, etc.
+ mLauncher.getStateManager().reapplyState();
+ }
+ };
+ } else {
+ AnimatorPlaybackController controller =
+ mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(NORMAL, RECENTS_LAUNCH_DURATION);
+ controller.dispatchOnStart();
+ launcherAnim = controller.getAnimationPlayer().setDuration(RECENTS_LAUNCH_DURATION);
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().goToState(NORMAL, false);
+ }
+ };
+ }
+
+ MutableBoolean skipLauncherChanges = new MutableBoolean(!launcherClosing);
+ Animator windowAnim = getRecentsWindowAnimator(taskView, skipLauncherChanges, targets);
+ windowAnim.addListener(windowAnimEndListener);
+ return new LauncherTransitionAnimator(launcherAnim, windowAnim, skipLauncherChanges);
}
/**
@@ -318,7 +348,7 @@
launcherAnimator.play(allAppsSlideOut);
Workspace workspace = mLauncher.getWorkspace();
- float[] workspaceScaleAndTranslation = LauncherState.NORMAL
+ float[] workspaceScaleAndTranslation = NORMAL
.getWorkspaceScaleAndTranslation(mLauncher);
Animator recenterWorkspace = LauncherAnimUtils.ofPropertyValuesHolder(
workspace, new PropertyListBuilder()
@@ -338,7 +368,7 @@
* @return Animator that controls the window of the opening targets for the recents launch
* animation.
*/
- private ValueAnimator getRecentsWindowAnimator(TaskView v,
+ private ValueAnimator getRecentsWindowAnimator(TaskView v, MutableBoolean skipLauncherChanges,
RemoteAnimationTargetCompat[] targets) {
Rect taskViewBounds = new Rect();
mDragLayer.getDescendantRectRelativeToSelf(v, taskViewBounds);
@@ -374,13 +404,15 @@
final float percent = animation.getAnimatedFraction();
TaskWindowBounds tw = recentsInterpolator.interpolate(percent);
- v.setScaleX(tw.taskScale);
- v.setScaleY(tw.taskScale);
- v.setTranslationX(tw.taskX);
- v.setTranslationY(tw.taskY);
- // Defer fading out the view until after the app window gets faded in
- v.setAlpha(getValue(1f, 0f, 75, 75,
- appAnimator.getDuration() * percent, Interpolators.LINEAR));
+ if (!skipLauncherChanges.value) {
+ v.setScaleX(tw.taskScale);
+ v.setScaleY(tw.taskScale);
+ v.setTranslationX(tw.taskX);
+ v.setTranslationY(tw.taskY);
+ // Defer fading out the view until after the app window gets faded in
+ v.setAlpha(getValue(1f, 0f, 75, 75,
+ appAnimator.getDuration() * percent, Interpolators.LINEAR));
+ }
matrix.setScale(tw.winScale, tw.winScale);
matrix.postTranslate(tw.winX, tw.winY);
@@ -402,7 +434,10 @@
matrix.postTranslate(target.position.x, target.position.y);
t.setMatrix(target.leash, matrix);
t.setWindowCrop(target.leash, crop);
- t.deferTransactionUntil(target.leash, surface, getNextFrameNumber(surface));
+
+ if (!skipLauncherChanges.value) {
+ t.deferTransactionUntil(target.leash, surface, frameNumber);
+ }
}
if (isFirstFrame) {
t.show(target.leash);
@@ -414,13 +449,6 @@
isFirstFrame = false;
}
});
- appAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Make sure recents gets fixed up by resetting task alphas and scales, etc.
- mLauncher.getStateManager().reapplyState();
- }
- });
return appAnimator;
}
diff --git a/quickstep/src/com/android/launcher3/LauncherTransitionAnimator.java b/quickstep/src/com/android/launcher3/LauncherTransitionAnimator.java
index aec2869..ab9234b 100644
--- a/quickstep/src/com/android/launcher3/LauncherTransitionAnimator.java
+++ b/quickstep/src/com/android/launcher3/LauncherTransitionAnimator.java
@@ -27,11 +27,20 @@
*/
public class LauncherTransitionAnimator {
+ private final MutableBoolean mLauncherAnimCancelState;
+
private AnimatorSet mAnimatorSet;
private Animator mLauncherAnimator;
private Animator mWindowAnimator;
LauncherTransitionAnimator(Animator launcherAnimator, Animator windowAnimator) {
+ this(launcherAnimator, windowAnimator, new MutableBoolean(false));
+ }
+
+
+ LauncherTransitionAnimator(Animator launcherAnimator, Animator windowAnimator,
+ MutableBoolean launcherAnimCancelState) {
+ mLauncherAnimCancelState = launcherAnimCancelState;
if (launcherAnimator != null) {
mLauncherAnimator = launcherAnimator;
}
@@ -50,6 +59,7 @@
public void cancel() {
mAnimatorSet.cancel();
+ mLauncherAnimCancelState.value = true;
}
public boolean isRunning() {
@@ -58,6 +68,7 @@
public void finishLauncherAnimation() {
if (mLauncherAnimator != null) {
+ mLauncherAnimCancelState.value = true;
mLauncherAnimator.end();
}
}
diff --git a/quickstep/src/com/android/launcher3/MutableBoolean.java b/quickstep/src/com/android/launcher3/MutableBoolean.java
new file mode 100644
index 0000000..7538217
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/MutableBoolean.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 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;
+
+public class MutableBoolean {
+ public boolean value;
+
+ public MutableBoolean(boolean value) {
+ this.value = value;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 7f98935..352cd9c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -18,28 +18,22 @@
import static com.android.launcher3.LauncherState.NORMAL;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.PointF;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RecentsView;
-import com.android.systemui.shared.recents.view.RecentsTransition;
public class UiFactory {
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
"android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
- public static final boolean USE_HARDWARE_BITMAP = false; // FeatureFlags.IS_DOGFOOD_BUILD;
-
public static TouchController[] createTouchControllers(Launcher launcher) {
if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
return new TouchController[] {
@@ -72,17 +66,6 @@
|| !launcher.isInState(NORMAL) || !launcher.hasWindowFocus());
}
- public static Bitmap createFromRenderer(int width, int height, boolean forceSoftwareRenderer,
- BitmapRenderer renderer) {
- if (USE_HARDWARE_BITMAP && !forceSoftwareRenderer) {
- return RecentsTransition.createHardwareBitmap(width, height, renderer::render);
- } else {
- Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- renderer.render(new Canvas(result));
- return result;
- }
- }
-
public static void resetOverview(Launcher launcher) {
RecentsView recents = launcher.getOverviewPanel();
recents.reset();
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index a7f0026..450d107 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -29,8 +29,6 @@
<include layout="@layout/all_apps_rv_layout" />
- <include layout="@layout/all_apps_fast_scroller" />
-
<include layout="@layout/all_apps_floating_header" />
<!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
@@ -39,10 +37,5 @@
android:id="@id/search_container_all_apps"
layout="@layout/search_container_all_apps"/>
- <View
- android:id="@+id/nav_bar_bg"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_alignParentBottom="true"
- android:background="?attr/allAppsNavBarScrimColor" />
+ <include layout="@layout/all_apps_fast_scroller" />
</com.android.launcher3.allapps.AllAppsContainerView>
\ No newline at end of file
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index ca397bd..978b5a1 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -47,13 +47,5 @@
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/fastscroll_end_margin" />
-
- <View
- android:id="@+id/nav_bar_bg"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_gravity="bottom"
- android:background="?attr/allAppsNavBarScrimColor"
- android:focusable="false" />
</com.android.launcher3.views.TopRoundedCornerView>
</com.android.launcher3.widget.WidgetsFullSheet>
\ No newline at end of file
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index cc13263..74b9cfa 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -33,8 +33,7 @@
* <li> Enable fast scroller.
* </ul>
*/
-public abstract class BaseRecyclerView extends RecyclerView
- implements RecyclerView.OnItemTouchListener {
+public abstract class BaseRecyclerView extends RecyclerView {
protected RecyclerViewFastScroller mScrollbar;
@@ -51,12 +50,6 @@
}
@Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- addOnItemTouchListener(this);
- }
-
- @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
bindFastScrollbar();
@@ -69,40 +62,8 @@
onUpdateScrollbar(0);
}
- /**
- * We intercept the touch handling only to support fast scrolling when initiated from the
- * scroll bar. Otherwise, we fall back to the default RecyclerView touch handling.
- */
- @Override
- public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent ev) {
- return handleTouchEvent(ev);
- }
-
- @Override
- public void onTouchEvent(RecyclerView rv, MotionEvent ev) {
- handleTouchEvent(ev);
- }
-
- /**
- * Handles the touch event and determines whether to show the fast scroller (or updates it if
- * it is already showing).
- */
- private boolean handleTouchEvent(MotionEvent ev) {
- // Move to mScrollbar's coordinate system.
- // We need to take parent into account (view pager's location)
- ViewGroup parent = (ViewGroup) getParent();
- int left = parent.getLeft() - mScrollbar.getLeft();
- int top = parent.getTop() + getTop() - mScrollbar.getTop() - getScrollBarTop();
- ev.offsetLocation(left, top);
- try {
- return mScrollbar.handleTouchEvent(ev);
- } finally {
- ev.offsetLocation(-left, -top);
- }
- }
-
- public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
- // DO NOT REMOVE, NEEDED IMPLEMENTATION FOR M BUILDS
+ public RecyclerViewFastScroller getScrollbar() {
+ return mScrollbar;
}
public int getScrollBarTop() {
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index d0581a2..f4ae62a 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -45,12 +45,10 @@
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.BitmapInfo;
-import com.android.launcher3.graphics.ColorExtractor;
+import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.model.PackageItemInfo;
-import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions;
@@ -126,7 +124,7 @@
// automatically be loaded as ALPHA_8888.
mLowResOptions.inPreferredConfig = Bitmap.Config.RGB_565;
- if (UiFactory.USE_HARDWARE_BITMAP) {
+ if (BitmapRenderer.USE_HARDWARE_BITMAP) {
mHighResOptions = new BitmapFactory.Options();
mHighResOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
} else {
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 77ac9de..f6d0248 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -137,6 +137,8 @@
propertySetter.setViewAlpha(mLauncher.getHotseat(), state.getHoseatAlpha(mLauncher),
pageAlphaProvider.interpolator);
+ propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
+ state.getHoseatAlpha(mLauncher), pageAlphaProvider.interpolator);
// Set scrim
propertySetter.setFloat(ViewScrim.get(mWorkspace), ViewScrim.PROGRESS,
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 5cd54ca..26922ad 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -18,6 +18,9 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Process;
import android.support.annotation.NonNull;
@@ -57,6 +60,7 @@
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BottomUserEducationView;
+import com.android.launcher3.views.RecyclerViewFastScroller;
/**
* The all apps view container.
@@ -70,6 +74,9 @@
private final ItemInfoMatcher mWorkMatcher = ItemInfoMatcher.not(mPersonalMatcher);
private final AllAppsStore mAllAppsStore = new AllAppsStore();
+ private final Paint mNavBarScrimPaint;
+ private int mNavBarScrimHeight = 0;
+
private SearchUiManager mSearchUiManager;
private View mSearchContainer;
private AllAppsPagedView mViewPager;
@@ -80,6 +87,9 @@
private boolean mUsingTabs;
private boolean mSearchModeWhileUsingTabs = false;
+ private RecyclerViewFastScroller mTouchHandler;
+ private final Point mFastScrollerOffset = new Point();
+
public AllAppsContainerView(Context context) {
this(context, null);
}
@@ -101,6 +111,9 @@
mAH[AdapterHolder.MAIN] = new AdapterHolder(false /* isWork */);
mAH[AdapterHolder.WORK] = new AdapterHolder(true /* isWork */);
+ mNavBarScrimPaint = new Paint();
+ mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
+
mAllAppsStore.addUpdateListener(this::onAppsUpdated);
// Attach a scrim to be drawn behind all-apps and hotseat
@@ -108,27 +121,11 @@
.attach();
}
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- applyTouchDelegate();
- }
-
- private void applyTouchDelegate() {
- // TODO: Reimplement once fast scroller is fixed.
- }
-
public AllAppsStore getAppsStore() {
return mAllAppsStore;
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- applyTouchDelegate();
- }
-
- @Override
public void onDeviceProfileChanged(DeviceProfile dp) {
for (AdapterHolder holder : mAH) {
if (holder.recyclerView != null) {
@@ -163,7 +160,38 @@
return true;
}
AllAppsRecyclerView rv = getActiveRecyclerView();
- return rv == null || rv.shouldContainerScroll(ev, mLauncher.getDragLayer());
+ if (rv == null) {
+ return true;
+ }
+ if (rv.getScrollbar().getThumbOffsetY() >= 0 &&
+ mLauncher.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) {
+ return false;
+ }
+ return rv.shouldContainerScroll(ev, mLauncher.getDragLayer());
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null &&
+ rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
+ mTouchHandler = rv.getScrollbar();
+ }
+ }
+ if (mTouchHandler != null) {
+ return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (mTouchHandler != null) {
+ mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ return true;
+ }
+ return false;
}
public AllAppsRecyclerView getActiveRecyclerView() {
@@ -282,14 +310,20 @@
}
setLayoutParams(mlp);
- View navBarBg = findViewById(R.id.nav_bar_bg);
- ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
- navBarBgLp.height = insets.bottom;
- navBarBg.setLayoutParams(navBarBgLp);
-
+ mNavBarScrimHeight = insets.bottom;
InsettableFrameLayout.dispatchInsets(this, insets);
}
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ if (mNavBarScrimHeight > 0) {
+ canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
+ mNavBarScrimPaint);
+ }
+ }
+
public SpringAnimationHandler getSpringAnimationHandler() {
return mUsingTabs ? null : mAH[AdapterHolder.MAIN].animationHandler;
}
@@ -320,8 +354,6 @@
mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
-
- applyTouchDelegate();
}
private void replaceRVContainer(boolean showTabs) {
@@ -352,7 +384,6 @@
public void onTabChanged(int pos) {
mHeader.setMainActive(pos == 0);
reset();
- applyTouchDelegate();
if (mAH[pos].recyclerView != null) {
mAH[pos].recyclerView.bindFastScrollbar();
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 53d19eb..4a393c9 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -97,7 +97,6 @@
int defStyleRes) {
super(context, attrs, defStyleAttr);
Resources res = getResources();
- addOnItemTouchListener(this);
mEmptySearchBackgroundTopOffset = res.getDimensionPixelSize(
R.dimen.all_apps_empty_search_bg_top_offset);
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 1c6f77c..5576d91 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -36,7 +36,7 @@
import com.android.launcher3.R;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
-import com.android.launcher3.uioverrides.UiFactory;
+import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.util.Preconditions;
/**
@@ -113,7 +113,7 @@
final float previewShiftX = shiftFactor * previewWidth;
final float previewShiftY = shiftFactor * previewHeight;
- Bitmap previewBitmap = UiFactory.createFromRenderer(previewWidth, previewHeight, false,
+ Bitmap previewBitmap = BitmapRenderer.createHardwareBitmap(previewWidth, previewHeight,
(canvas) -> {
int count = canvas.save();
canvas.translate(previewShiftX, previewShiftY);
diff --git a/src/com/android/launcher3/graphics/BitmapRenderer.java b/src/com/android/launcher3/graphics/BitmapRenderer.java
index 4652ded..f2a9f7c 100644
--- a/src/com/android/launcher3/graphics/BitmapRenderer.java
+++ b/src/com/android/launcher3/graphics/BitmapRenderer.java
@@ -15,9 +15,40 @@
*/
package com.android.launcher3.graphics;
+import android.annotation.TargetApi;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Picture;
+import android.os.Build;
-public interface BitmapRenderer {
+import com.android.launcher3.Utilities;
- void render(Canvas out);
+public class BitmapRenderer {
+
+ public static final boolean USE_HARDWARE_BITMAP = false && Utilities.ATLEAST_P;
+
+ public static Bitmap createSoftwareBitmap(int width, int height, Renderer renderer) {
+ Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ renderer.draw(new Canvas(result));
+ return result;
+ }
+
+ @TargetApi(Build.VERSION_CODES.P)
+ public static Bitmap createHardwareBitmap(int width, int height, Renderer renderer) {
+ if (!USE_HARDWARE_BITMAP) {
+ return createSoftwareBitmap(width, height, renderer);
+ }
+
+ Picture picture = new Picture();
+ renderer.draw(picture.beginRecording(width, height));
+ picture.endRecording();
+ return Bitmap.createBitmap(picture);
+ }
+
+ /**
+ * Interface representing a bitmap draw operation.
+ */
+ public interface Renderer {
+ void draw(Canvas out);
+ }
}
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index b770785..e60a2c7 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -24,19 +24,17 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
-import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.View;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.nio.ByteBuffer;
@@ -119,28 +117,26 @@
* Responsibility for the bitmap is transferred to the caller.
*/
public Bitmap createDragBitmap() {
- float scale = 1f;
int width = mView.getWidth();
int height = mView.getHeight();
- boolean forceSoftwareRenderer = false;
if (mView instanceof BubbleTextView) {
Drawable d = ((BubbleTextView) mView).getIcon();
Rect bounds = getDrawableBounds(d);
width = bounds.width();
height = bounds.height();
} else if (mView instanceof LauncherAppWidgetHostView) {
- scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
+ float scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
width = (int) (mView.getWidth() * scale);
height = (int) (mView.getHeight() * scale);
// Use software renderer for widgets as we know that they already work
- forceSoftwareRenderer = true;
+ return BitmapRenderer.createSoftwareBitmap(width + blurSizeOutline,
+ height + blurSizeOutline, (c) -> drawDragView(c, scale));
}
- final float scaleFinal = scale;
- return UiFactory.createFromRenderer(width + blurSizeOutline, height + blurSizeOutline,
- forceSoftwareRenderer, (c) -> drawDragView(c, scaleFinal));
+ return BitmapRenderer.createHardwareBitmap(width + blurSizeOutline,
+ height + blurSizeOutline, (c) -> drawDragView(c, 1));
}
public final void generateDragOutline(Bitmap preview) {
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 8abfdea..4a9cdd9 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -52,7 +52,6 @@
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.Provider;
import com.android.launcher3.util.Themes;
@@ -349,7 +348,7 @@
final ItemInfoWithIcon badge = getShortcutInfoBadge(shortcutInfo, cache);
result.color = badge.iconColor;
- result.icon = UiFactory.createFromRenderer(mIconBitmapSize, mIconBitmapSize, false, (c) -> {
+ result.icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> {
getShadowGenerator().recreateIcon(unbadgedfinal, c);
badgeWithDrawable(c, new FastBitmapDrawable(badge));
});
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
index b80e94d..b793f54 100644
--- a/src/com/android/launcher3/util/FocusLogic.java
+++ b/src/com/android/launcher3/util/FocusLogic.java
@@ -177,7 +177,10 @@
}
int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
- matrix[invert ? (m - cx - 1) : cx][cy] = i;
+ int x = invert ? (m - cx - 1) : cx;
+ if (x < m && cy < n) { // check if view fits into matrix, else skip
+ matrix[x][cy] = i;
+ }
}
if (DEBUG) {
printMatrix(matrix);
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 58c9148..1cd6699 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -22,6 +22,8 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Property;
@@ -43,6 +45,7 @@
public class RecyclerViewFastScroller extends View {
private static final int SCROLL_DELTA_THRESHOLD_DP = 4;
+ private static final Rect sTempRect = new Rect();
private static final Property<RecyclerViewFastScroller, Integer> TRACK_WIDTH =
new Property<RecyclerViewFastScroller, Integer>(Integer.class, "width") {
@@ -204,9 +207,9 @@
* Handles the touch event and determines whether to show the fast scroller (or updates it if
* it is already showing).
*/
- public boolean handleTouchEvent(MotionEvent ev) {
- int x = (int) ev.getX();
- int y = (int) ev.getY();
+ public boolean handleTouchEvent(MotionEvent ev, Point offset) {
+ int x = (int) ev.getX() - offset.x;
+ int y = (int) ev.getY() - offset.y;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Keep track of the down positions
@@ -260,7 +263,6 @@
}
private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
- mRv.getParent().requestDisallowInterceptTouchEvent(true);
mIsDragging = true;
if (mCanThumbDetach) {
mIsThumbDetached = true;
@@ -358,4 +360,16 @@
mMaxWidth, mRv.getScrollbarTrackHeight() - mMaxWidth - height);
mPopupView.setTranslationY(top);
}
+
+ public boolean isHitInParent(float x, float y, Point outOffset) {
+ if (mThumbOffsetY < 0) {
+ return false;
+ }
+ getHitRect(sTempRect);
+ sTempRect.top += mRv.getScrollBarTop();
+ if (outOffset != null) {
+ outOffset.set(sTempRect.left, sTempRect.top);
+ }
+ return sTempRect.contains((int) x, (int) y);
+ }
}
diff --git a/src/com/android/launcher3/views/TopRoundedCornerView.java b/src/com/android/launcher3/views/TopRoundedCornerView.java
index ba223c4..3ba8ca3 100644
--- a/src/com/android/launcher3/views/TopRoundedCornerView.java
+++ b/src/com/android/launcher3/views/TopRoundedCornerView.java
@@ -17,12 +17,14 @@
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
/**
* View with top rounded corners.
@@ -33,23 +35,41 @@
private final Path mClipPath = new Path();
private float[] mRadii;
+ private final Paint mNavBarScrimPaint;
+ private int mNavBarScrimHeight = 0;
+
public TopRoundedCornerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
int radius = getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
mRadii = new float[] {radius, radius, radius, radius, 0, 0, 0, 0};
+
+ mNavBarScrimPaint = new Paint();
+ mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
}
public TopRoundedCornerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
+ public void setNavBarScrimHeight(int height) {
+ if (mNavBarScrimHeight != height) {
+ mNavBarScrimHeight = height;
+ invalidate();
+ }
+ }
+
@Override
public void draw(Canvas canvas) {
canvas.save();
canvas.clipPath(mClipPath);
super.draw(canvas);
canvas.restore();
+
+ if (mNavBarScrimHeight > 0) {
+ canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
+ mNavBarScrimPaint);
+ }
}
@Override
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index 48f8afe..b31feed 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -23,7 +23,6 @@
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.View;
import android.view.animation.AnimationUtils;
import com.android.launcher3.Insettable;
@@ -31,6 +30,8 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener;
import com.android.launcher3.R;
+import com.android.launcher3.views.RecyclerViewFastScroller;
+import com.android.launcher3.views.TopRoundedCornerView;
/**
* Popup for showing the full list of available widgets
@@ -46,7 +47,6 @@
private final WidgetsListAdapter mAdapter;
- private View mNavBarScrim;
private WidgetsRecyclerView mRecyclerView;
public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -65,7 +65,6 @@
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findViewById(R.id.container);
- mNavBarScrim = findViewById(R.id.nav_bar_bg);
mRecyclerView = findViewById(R.id.widgets_list_view);
mRecyclerView.setAdapter(mAdapter);
@@ -91,7 +90,6 @@
public void setInsets(Rect insets) {
mInsets.set(insets);
- mNavBarScrim.getLayoutParams().height = insets.bottom;
mRecyclerView.setPadding(
mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(),
mRecyclerView.getPaddingRight(), insets.bottom);
@@ -100,6 +98,8 @@
} else {
clearNavBarColor();
}
+
+ ((TopRoundedCornerView) mContent).setNavBarScrimHeight(mInsets.bottom);
requestLayout();
}
@@ -195,7 +195,11 @@
// Disable swipe down when recycler view is scrolling
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mNoIntercept = false;
- if (mLauncher.getDragLayer().isEventOverView(mContent, ev)) {
+ RecyclerViewFastScroller scroller = mRecyclerView.getScrollbar();
+ if (scroller.getThumbOffsetY() >= 0 &&
+ mLauncher.getDragLayer().isEventOverView(scroller, ev)) {
+ mNoIntercept = true;
+ } else if (mLauncher.getDragLayer().isEventOverView(mContent, ev)) {
mNoIntercept = !mRecyclerView.shouldContainerScroll(ev, mLauncher.getDragLayer());
}
}
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index 89c88a4..124058e 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -17,8 +17,12 @@
package com.android.launcher3.widget;
import android.content.Context;
+import android.graphics.Point;
import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
import com.android.launcher3.BaseRecyclerView;
@@ -27,13 +31,15 @@
/**
* The widgets recycler view.
*/
-public class WidgetsRecyclerView extends BaseRecyclerView {
+public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouchListener {
- private static final String TAG = "WidgetsRecyclerView";
private WidgetsListAdapter mAdapter;
private final int mScrollbarTop;
+ private final Point mFastScrollerOffset = new Point();
+ private boolean mTouchDownOnScroller;
+
public WidgetsRecyclerView(Context context) {
this(context, null);
}
@@ -46,6 +52,7 @@
// API 21 and below only support 3 parameter ctor.
super(context, attrs, defStyleAttr);
mScrollbarTop = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
+ addOnItemTouchListener(this);
}
public WidgetsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
@@ -56,7 +63,6 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- addOnItemTouchListener(this);
// create a layout manager with Launcher's context so that scroll position
// can be preserved during screen rotation.
setLayoutManager(new LinearLayoutManager(getContext()));
@@ -145,4 +151,26 @@
public int getScrollBarTop() {
return mScrollbarTop;
}
+
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ if (e.getAction() == MotionEvent.ACTION_DOWN) {
+ mTouchDownOnScroller =
+ mScrollbar.isHitInParent(e.getX(), e.getY(), mFastScrollerOffset);
+ }
+ if (mTouchDownOnScroller) {
+ return mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
+ }
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+ if (mTouchDownOnScroller) {
+ mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
+ }
+ }
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
}
\ No newline at end of file
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index a16ae48..de75ac9 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -16,25 +16,17 @@
package com.android.launcher3.uioverrides;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.PointF;
-import android.os.Bundle;
-import android.view.View;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
-import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.util.TouchController;
public class UiFactory {
- public static final boolean USE_HARDWARE_BITMAP = false;
-
public static TouchController[] createTouchControllers(Launcher launcher) {
return new TouchController[] {
new AllAppsSwipeController(launcher), new PinchToOverviewListener(launcher)};
@@ -54,13 +46,6 @@
launcher.getStateManager().goToState(OVERVIEW);
}
- public static Bitmap createFromRenderer(int width, int height, boolean forceSoftwareRenderer,
- BitmapRenderer renderer) {
- Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- renderer.render(new Canvas(result));
- return result;
- }
-
public static void resetOverview(Launcher launcher) { }
public static void onLauncherStateOrFocusChanged(Launcher launcher) { }