diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java index 79e50ef35b..67e9d898e5 100644 --- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java +++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java @@ -49,6 +49,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { public static final String ACTION_SEARCH = "com.android.quickstep.ACTION_SEARCH"; public static final String ELAPSED_NANOS = "niu_actions_elapsed_realtime_nanos"; public static final String ACTIONS_URL = "niu_actions_app_url"; + public static final String ACTIONS_APP_PACKAGE = "niu_actions_app_package"; public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code"; public static final int ERROR_PERMISSIONS = 1; private static final String TAG = "TaskOverlayFactoryGo"; @@ -72,6 +73,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { */ public static final class TaskOverlayGo extends TaskOverlay { private String mNIUPackageName; + private String mTaskPackageName; private String mWebUrl; private boolean mAssistPermissionsEnabled; @@ -87,7 +89,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { boolean rotated) { getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null); mNIUPackageName = - mApplicationContext.getResources().getString(R.string.niu_actions_package); + mApplicationContext.getString(R.string.niu_actions_package); if (thumbnail == null || TextUtils.isEmpty(mNIUPackageName)) { return; @@ -96,6 +98,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated); boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot(); getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task)); + mTaskPackageName = task.key.getPackageName(); checkPermissions(); if (!mAssistPermissionsEnabled) { @@ -150,6 +153,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) .setPackage(mNIUPackageName) + .putExtra(ACTIONS_APP_PACKAGE, mTaskPackageName) .putExtra(ELAPSED_NANOS, SystemClock.elapsedRealtimeNanos()); if (mWebUrl != null) { diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 910e473401..c6c6c01542 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -460,7 +460,8 @@ public abstract class BaseQuickstepLauncher extends Launcher case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: - // Fall through and continue if it's an app or shortcut + case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: + // Fall through and continue if it's an app, shortcut, or widget break; default: return; diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index fb676459a3..36764a1519 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -60,6 +60,7 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemProperties; import android.util.Pair; +import android.util.Size; import android.view.View; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; @@ -780,7 +781,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final float finalWindowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources()); final FloatingWidgetView floatingView = FloatingWidgetView.getFloatingWidgetView(mLauncher, - v, widgetBackgroundBounds, windowTargetBounds, finalWindowRadius); + v, widgetBackgroundBounds, + new Size(windowTargetBounds.width(), windowTargetBounds.height()), + finalWindowRadius); final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) ? floatingView.getInitialCornerRadius() : 0; diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index 66e4f4c61c..5c19ab8bf4 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -23,6 +23,7 @@ import android.util.Pair; import android.view.View; import android.widget.RemoteViews; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ActivityOptionsWrapper; import com.android.launcher3.widget.LauncherAppWidgetHostView; @@ -49,6 +50,10 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { Pair options = remoteResponse.getLaunchOptions(hostView); ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager() .getActivityLaunchOptions(mLauncher, hostView); + Object itemInfo = hostView.getTag(); + if (itemInfo instanceof ItemInfo) { + mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options); + } options = Pair.create(options.first, activityOptions.options); return RemoteViews.startPendingIntent(hostView, pendingIntent, options); } diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index 2ea34d7f93..9398277032 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -30,9 +30,11 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.content.Context; +import android.graphics.Rect; import android.graphics.RectF; import android.os.IBinder; import android.os.UserHandle; +import android.util.Size; import android.view.View; import androidx.annotation.NonNull; @@ -50,9 +52,11 @@ import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.ObjectWrapper; import com.android.launcher3.views.FloatingIconView; +import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.quickstep.util.AppCloseConfig; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.StaggeredWorkspaceAnim; +import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.plugins.ResourceProvider; @@ -77,155 +81,206 @@ public class LauncherSwipeHandlerV2 extends @Override protected HomeAnimationFactory createHomeAnimationFactory(ArrayList launchCookies, long duration) { - HomeAnimationFactory homeAnimFactory; - if (mActivity != null) { - final View workspaceView = findWorkspaceView(launchCookies, - mRecentsView.getRunningTaskView()); - boolean canUseWorkspaceView = - workspaceView != null && workspaceView.isAttachedToWindow(); - - mActivity.getRootView().setForceHideBackArrow(true); - mActivity.setHintUserWillBeActive(); - - if (canUseWorkspaceView) { - final ResourceProvider rp = DynamicResource.provider(mActivity); - final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp)); - float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s)); - final float launcherAlphaMax = - rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress); - - RectF iconLocation = new RectF(); - FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, - true /* hideOriginal */, iconLocation, false /* isOpening */); - - // We want the window alpha to be 0 once this threshold is met, so that the - // FolderIconView can be seen morphing into the icon shape. - float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION; - homeAnimFactory = new LauncherHomeAnimationFactory() { - - // There is a delay in loading the icon, so we need to keep the window - // opaque until it is ready. - private boolean mIsFloatingIconReady = false; - - private @Nullable ValueAnimator mBounceBackAnimator; - - @Override - public RectF getWindowTargetRect() { - if (PROTOTYPE_APP_CLOSE.get()) { - // We want the target rect to be at this offset position, so that all - // launcher content can spring back upwards. - floatingIconView.setPositionOffsetY(transY); - } - return iconLocation; - } - - @Override - public void setAnimation(RectFSpringAnim anim) { - anim.addAnimatorListener(floatingIconView); - floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged); - floatingIconView.setFastFinishRunnable(anim::end); - if (PROTOTYPE_APP_CLOSE.get()) { - mBounceBackAnimator = bounceBackToRestingPosition(); - // Use a spring to put drag layer translation back to 0. - anim.addAnimatorListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - floatingIconView.setPositionOffsetY(0); - mBounceBackAnimator.start(); - } - }); - - Workspace workspace = mActivity.getWorkspace(); - workspace.setPivotToScaleWithSelf(mActivity.getHotseat()); - } - } - - private ValueAnimator bounceBackToRestingPosition() { - DragLayer dl = mActivity.getDragLayer(); - Workspace workspace = mActivity.getWorkspace(); - Hotseat hotseat = mActivity.getHotseat(); - - final float startValue = transY; - final float endValue = 0; - // Ensures the velocity is always aligned with the direction. - float pixelPerSecond = Math.abs(dpPerSecond) - * Math.signum(endValue - transY); - - ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext()) - .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness)) - .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping)) - .setMinimumVisibleChange(1f) - .setStartValue(startValue) - .setEndValue(endValue) - .setStartVelocity(pixelPerSecond) - .build(dl, VIEW_TRANSLATE_Y); - springTransY.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - dl.setTranslationY(0f); - dl.setAlpha(1f); - SCALE_PROPERTY.set(workspace, 1f); - SCALE_PROPERTY.set(hotseat, 1f); - } - }); - return springTransY; - } - - @Override - public boolean keepWindowOpaque() { - if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) { - mIsFloatingIconReady = true; - return false; - } - return true; - } - - @Override - public void update(@Nullable AppCloseConfig config, RectF currentRect, - float progress, float radius) { - int fgAlpha = 255; - if (config != null && PROTOTYPE_APP_CLOSE.get()) { - DragLayer dl = mActivity.getDragLayer(); - float translationY = config.getWorkspaceTransY(); - dl.setTranslationY(translationY); - - float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR); - dl.setAlpha(Math.min(alpha, 1f)); - - float scale = Math.min(1f, config.getWorkspaceScale()); - SCALE_PROPERTY.set(mActivity.getWorkspace(), scale); - SCALE_PROPERTY.set(mActivity.getHotseat(), scale); - SCALE_PROPERTY.set(mActivity.getAppsView(), scale); - - progress = config.getInterpolatedProgress(); - fgAlpha = config.getFgAlpha(); - } - floatingIconView.update(1f, fgAlpha, currentRect, progress, - windowAlphaThreshold, radius, false); - } - - @Override - public void onCancel() { - floatingIconView.fastFinish(); - if (mBounceBackAnimator != null) { - mBounceBackAnimator.cancel(); - } - } - }; - } else { - homeAnimFactory = new LauncherHomeAnimationFactory(); - } - } else { - homeAnimFactory = new HomeAnimationFactory() { + if (mActivity == null) { + mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, + isPresent -> mRecentsView.startHome()); + return new HomeAnimationFactory() { @Override public AnimatorPlaybackController createActivityAnimationToHome() { return AnimatorPlaybackController.wrap(new AnimatorSet(), duration); } }; - mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, - isPresent -> mRecentsView.startHome()); } - return homeAnimFactory; + + final View workspaceView = findWorkspaceView(launchCookies, + mRecentsView.getRunningTaskView()); + boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow(); + + mActivity.getRootView().setForceHideBackArrow(true); + mActivity.setHintUserWillBeActive(); + + if (!canUseWorkspaceView) { + return new LauncherHomeAnimationFactory(); + } + if (workspaceView instanceof LauncherAppWidgetHostView) { + return createWidgetHomeAnimationFactory((LauncherAppWidgetHostView) workspaceView); + } + return createIconHomeAnimationFactory(workspaceView); + } + + private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) { + final ResourceProvider rp = DynamicResource.provider(mActivity); + final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp)); + float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s)); + final float launcherAlphaMax = + rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress); + + RectF iconLocation = new RectF(); + FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, + true /* hideOriginal */, iconLocation, false /* isOpening */); + + // We want the window alpha to be 0 once this threshold is met, so that the + // FolderIconView can be seen morphing into the icon shape. + float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION; + return new LauncherHomeAnimationFactory() { + + // There is a delay in loading the icon, so we need to keep the window + // opaque until it is ready. + private boolean mIsFloatingIconReady = false; + + private @Nullable ValueAnimator mBounceBackAnimator; + + @Override + public RectF getWindowTargetRect() { + if (PROTOTYPE_APP_CLOSE.get()) { + // We want the target rect to be at this offset position, so that all + // launcher content can spring back upwards. + floatingIconView.setPositionOffsetY(transY); + } + return iconLocation; + } + + @Override + public void setAnimation(RectFSpringAnim anim) { + anim.addAnimatorListener(floatingIconView); + floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged); + floatingIconView.setFastFinishRunnable(anim::end); + if (PROTOTYPE_APP_CLOSE.get()) { + mBounceBackAnimator = bounceBackToRestingPosition(); + // Use a spring to put drag layer translation back to 0. + anim.addAnimatorListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + floatingIconView.setPositionOffsetY(0); + mBounceBackAnimator.start(); + } + }); + + Workspace workspace = mActivity.getWorkspace(); + workspace.setPivotToScaleWithSelf(mActivity.getHotseat()); + } + } + + private ValueAnimator bounceBackToRestingPosition() { + DragLayer dl = mActivity.getDragLayer(); + Workspace workspace = mActivity.getWorkspace(); + Hotseat hotseat = mActivity.getHotseat(); + + final float startValue = transY; + final float endValue = 0; + // Ensures the velocity is always aligned with the direction. + float pixelPerSecond = Math.abs(dpPerSecond) * Math.signum(endValue - transY); + + ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext()) + .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness)) + .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping)) + .setMinimumVisibleChange(1f) + .setStartValue(startValue) + .setEndValue(endValue) + .setStartVelocity(pixelPerSecond) + .build(dl, VIEW_TRANSLATE_Y); + springTransY.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + dl.setTranslationY(0f); + dl.setAlpha(1f); + SCALE_PROPERTY.set(workspace, 1f); + SCALE_PROPERTY.set(hotseat, 1f); + } + }); + return springTransY; + } + + @Override + public boolean keepWindowOpaque() { + if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) { + mIsFloatingIconReady = true; + return false; + } + return true; + } + + @Override + public void update(@Nullable AppCloseConfig config, RectF currentRect, + float progress, float radius) { + int fgAlpha = 255; + if (config != null && PROTOTYPE_APP_CLOSE.get()) { + DragLayer dl = mActivity.getDragLayer(); + float translationY = config.getWorkspaceTransY(); + dl.setTranslationY(translationY); + + float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR); + dl.setAlpha(Math.min(alpha, 1f)); + + float scale = Math.min(1f, config.getWorkspaceScale()); + SCALE_PROPERTY.set(mActivity.getWorkspace(), scale); + SCALE_PROPERTY.set(mActivity.getHotseat(), scale); + SCALE_PROPERTY.set(mActivity.getAppsView(), scale); + + progress = config.getInterpolatedProgress(); + fgAlpha = config.getFgAlpha(); + } + floatingIconView.update(1f, fgAlpha, currentRect, progress, + windowAlphaThreshold, radius, false); + } + + @Override + public void onCancel() { + floatingIconView.fastFinish(); + if (mBounceBackAnimator != null) { + mBounceBackAnimator.cancel(); + } + } + }; + } + + private HomeAnimationFactory createWidgetHomeAnimationFactory( + LauncherAppWidgetHostView hostView) { + + RectF backgroundLocation = new RectF(); + Rect crop = new Rect(); + mTaskViewSimulator.getCurrentCropRect().roundOut(crop); + Size windowSize = new Size(crop.width(), crop.height()); + FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity, + hostView, backgroundLocation, windowSize, + mTaskViewSimulator.getCurrentCornerRadius()); + + return new LauncherHomeAnimationFactory() { + + @Override + public RectF getWindowTargetRect() { + return backgroundLocation; + } + + @Override + public float getEndRadius(RectF cropRectF) { + return floatingWidgetView.getInitialCornerRadius(); + } + + @Override + public void setAnimation(RectFSpringAnim anim) { + anim.addAnimatorListener(floatingWidgetView); + floatingWidgetView.setFastFinishRunnable(anim::end); + } + + @Override + public boolean keepWindowOpaque() { + return false; + } + + @Override + public void update(@Nullable AppCloseConfig config, RectF currentRect, + float progress, float radius) { + floatingWidgetView.update(currentRect, 1 /* floatingWidgetAlpha */, + config != null ? config.getFgAlpha() : 1f /* foregroundAlpha */, + 0 /* fallbackBackgroundAlpha */, 1 - progress); + } + + @Override + public void onCancel() { + floatingWidgetView.fastFinish(); + } + }; } /** diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index 0f34a72ad4..29a00d16b0 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -145,6 +145,11 @@ public abstract class SwipeUpAnimationLogic { targetX + halfIconSize, targetY + halfIconSize); } + /** Returns the corner radius of the window at the end of the animation. */ + public float getEndRadius(RectF cropRectF) { + return cropRectF.width() / 2f; + } + public abstract @NonNull AnimatorPlaybackController createActivityAnimationToHome(); public void playAtomicAnimation(float velocity) { @@ -197,8 +202,7 @@ public abstract class SwipeUpAnimationLogic { final RectF targetRect = homeAnimationFactory.getWindowTargetRect(); Matrix homeToWindowPositionMap = new Matrix(); - final RectF startRect = updateProgressForStartRect( - homeToWindowPositionMap, startProgress); + final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress); RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect()); // Move the startRect to Launcher space as floatingIconView runs in Launcher @@ -210,7 +214,7 @@ public abstract class SwipeUpAnimationLogic { if (PROTOTYPE_APP_CLOSE.get()) { anim = new RectFSpringAnim2(startRect, targetRect, mContext, mTaskViewSimulator.getCurrentCornerRadius(), - cropRectF.width() / 2f); + homeAnimationFactory.getEndRadius(cropRectF)); } else { anim = new RectFSpringAnim(startRect, targetRect, mContext); } @@ -269,7 +273,7 @@ public abstract class SwipeUpAnimationLogic { // End on a "round-enough" radius so that the shape reveal doesn't have to do too much // rounding at the end of the animation. mStartRadius = mTaskViewSimulator.getCurrentCornerRadius(); - mEndRadius = cropRectF.width() / 2f; + mEndRadius = factory.getEndRadius(cropRectF); } @Override diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java index d23884c9ef..8499902f23 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java @@ -20,10 +20,10 @@ import android.animation.Animator.AnimatorListener; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Matrix; -import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; +import android.util.Size; import android.view.GhostView; import android.view.View; import android.view.ViewGroup; @@ -113,7 +113,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener } private void init(DragLayer dragLayer, LauncherAppWidgetHostView originalView, - RectF widgetBackgroundPosition, Rect windowTargetBounds, float windowCornerRadius) { + RectF widgetBackgroundPosition, Size windowSize, float windowCornerRadius) { mAppWidgetView = originalView; mAppWidgetView.beginDeferringUpdates(); mBackgroundPosition = widgetBackgroundPosition; @@ -128,7 +128,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener getRelativePosition(mAppWidgetBackgroundView, mAppWidgetView, mBackgroundOffset); mBackgroundView.init(mAppWidgetView, mAppWidgetBackgroundView, windowCornerRadius); // Layout call before GhostView creation so that the overlaid view isn't clipped - layout(0, 0, windowTargetBounds.width(), windowTargetBounds.height()); + layout(0, 0, windowSize.getWidth(), windowSize.getHeight()); mForegroundOverlayView = GhostView.addGhost(mAppWidgetView, this); positionViews(); @@ -219,19 +219,19 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener * * @param widgetBackgroundPosition a {@link RectF} that will be updated with the widget's * background bounds - * @param windowTargetBounds the bounds of the window when launched + * @param windowSize the size of the window when launched * @param windowCornerRadius the corner radius of the window */ public static FloatingWidgetView getFloatingWidgetView(Launcher launcher, LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition, - Rect windowTargetBounds, float windowCornerRadius) { + Size windowSize, float windowCornerRadius) { final DragLayer dragLayer = launcher.getDragLayer(); ViewGroup parent = (ViewGroup) dragLayer.getParent(); FloatingWidgetView floatingView = launcher.getViewCache().getView(R.layout.floating_widget_view, launcher, parent); floatingView.recycle(); - floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowTargetBounds, + floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowSize, windowCornerRadius); parent.addView(floatingView); return floatingView; @@ -240,7 +240,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener private static void getRelativePosition(View descendant, View ancestor, RectF position) { float[] points = new float[]{0, 0, descendant.getWidth(), descendant.getHeight()}; Utilities.getDescendantCoordRelativeToAncestor(descendant, ancestor, points, - false /* includeRootScroll */); + false /* includeRootScroll */, true /* ignoreTransform */); position.set( Math.min(points[0], points[2]), Math.min(points[1], points[3]), diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index c9e7a73c72..53f880fbb3 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -2481,6 +2481,15 @@ public abstract class RecentsView finishRecentsAnimation(true, this::onConfigurationChangedInternal)); + } else { + onConfigurationChangedInternal(); + } + } + + private void onConfigurationChangedInternal() { final int rotation = mActivity.getDisplay().getRotation(); if (mOrientationState.setRecentsRotation(rotation)) { updateOrientationHandler(); @@ -3433,7 +3442,7 @@ public abstract class RecentsView - diff --git a/res/color/cell_layout_bg_color_inactive.xml b/res/color/cell_layout_bg_color_inactive.xml index d60a27a120..0632100dfc 100644 --- a/res/color/cell_layout_bg_color_inactive.xml +++ b/res/color/cell_layout_bg_color_inactive.xml @@ -1,5 +1,5 @@ - \ No newline at end of file diff --git a/res/values/config.xml b/res/values/config.xml index f8a517d1d0..1e7837353f 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -35,7 +35,7 @@ - 900 + 500 255 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index dd14eaa0ff..a57ccde802 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -293,7 +293,7 @@ 0dp - 28dp + 22dp 6dp diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index a037675029..2f755e11e0 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -18,7 +18,6 @@ package com.android.launcher3; import static android.animation.ValueAnimator.areAnimatorsEnabled; -import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; import android.animation.Animator; @@ -194,7 +193,6 @@ public class CellLayout extends ViewGroup { private static final int INVALID_DIRECTION = -100; private final Rect mTempRect = new Rect(); - private final RectF mTempRectF = new RectF(); private static final Paint sPaint = new Paint(); @@ -504,7 +502,7 @@ public class CellLayout extends ViewGroup { } private void updateBgAlpha() { - mBackground.setAlpha((int) (mSpringLoadedProgress * mScrollProgress * 255)); + mBackground.setAlpha((int) (mSpringLoadedProgress * 255)); } /** @@ -527,9 +525,12 @@ public class CellLayout extends ViewGroup { } protected void visualizeGrid(Canvas canvas) { - mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding, - mCellWidth - mGridVisualizationPadding, - mCellHeight - mGridVisualizationPadding); + DeviceProfile dp = mActivity.getDeviceProfile(); + int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding); + int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding); + mVisualizeGridRect.set(paddingX, paddingY, + mCellWidth - paddingX, + mCellHeight - paddingY); mVisualizeGridPaint.setStrokeWidth(8); int paintAlpha = (int) (120 * mGridAlpha); @@ -539,9 +540,9 @@ public class CellLayout extends ViewGroup { for (int i = 0; i < mCountX; i++) { for (int j = 0; j < mCountY; j++) { int transX = i * mCellWidth + (i * mBorderSpacing) + getPaddingLeft() - + mGridVisualizationPadding; + + paddingX; int transY = j * mCellHeight + (j * mBorderSpacing) + getPaddingTop() - + mGridVisualizationPadding; + + paddingY; mVisualizeGridRect.offsetTo(transX, transY); mVisualizeGridPaint.setStyle(Paint.Style.FILL); @@ -562,14 +563,14 @@ public class CellLayout extends ViewGroup { int spanX = mDragOutlines[i].cellHSpan; int spanY = mDragOutlines[i].cellVSpan; - mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding, - mCellWidth * spanX - mGridVisualizationPadding, - mCellHeight * spanY - mGridVisualizationPadding); + mVisualizeGridRect.set(paddingX, paddingY, + mCellWidth * spanX - paddingX, + mCellHeight * spanY - paddingY); int transX = x * mCellWidth + (x * mBorderSpacing) - + getPaddingLeft() + mGridVisualizationPadding; + + getPaddingLeft() + paddingX; int transY = y * mCellHeight + (y * mBorderSpacing) - + getPaddingTop() + mGridVisualizationPadding; + + getPaddingTop() + paddingY; mVisualizeGridRect.offsetTo(transX, transY); @@ -1069,16 +1070,11 @@ public class CellLayout extends ViewGroup { // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable. View view = dragObject.dragView.getContentView(); if (view instanceof LauncherAppWidgetHostView) { - Launcher launcher = Launcher.getLauncher(dragObject.dragView.getContext()); - Workspace workspace = launcher.getWorkspace(); + Workspace workspace = + Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace(); int screenId = workspace.getIdForScreen(this); int pageId = workspace.getPageIndexForScreenId(screenId); cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect); - - // Now get the rect in drag layer coordinates. - getBoundsForViewInDragLayer(launcher.getDragLayer(), workspace, mTempRect, false, - mTempRectF); - Utilities.setRect(mTempRectF, mTempRect); ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId); } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 073a46c0e0..a799b4a33a 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -33,7 +33,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; -import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; @@ -85,7 +84,6 @@ import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.PackageManagerHelper; -import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.PendingAddShortcutInfo; import java.lang.reflect.Method; @@ -106,8 +104,6 @@ public final class Utilities { private static final Pattern sTrimPattern = Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$"); - private static final float[] sTmpFloatArray = new float[4]; - private static final int[] sLoc0 = new int[2]; private static final int[] sLoc1 = new int[2]; private static final Matrix sMatrix = new Matrix(); @@ -137,15 +133,6 @@ public final class Utilities { Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") || Build.TYPE.toLowerCase(Locale.ROOT).equals("eng"); - /** - * Returns true if theme is dark. - */ - public static boolean isDarkTheme(Context context) { - Configuration configuration = context.getResources().getConfiguration(); - int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; - return nightMode == Configuration.UI_MODE_NIGHT_YES; - } - public static boolean isDevelopersOptionsEnabled(Context context) { return Settings.Global.getInt(context.getApplicationContext().getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; @@ -231,33 +218,6 @@ public final class Utilities { return scale; } - /** - * Returns bounds for a child view of DragLayer, in drag layer coordinates. - * - * see {@link com.android.launcher3.dragndrop.DragLayer}. - * - * @param viewBounds Bounds of the view wanted in drag layer coordinates, relative to the view - * itself. eg. (0, 0, view.getWidth, view.getHeight) - * @param ignoreTransform If true, view transform is ignored - * @param outRect The out rect where we return the bounds of {@param view} in drag layer coords. - */ - public static void getBoundsForViewInDragLayer(BaseDragLayer dragLayer, View view, - Rect viewBounds, boolean ignoreTransform, RectF outRect) { - float[] points = sTmpFloatArray; - points[0] = viewBounds.left; - points[1] = viewBounds.top; - points[2] = viewBounds.right; - points[3] = viewBounds.bottom; - - Utilities.getDescendantCoordRelativeToAncestor(view, dragLayer, points, - false, ignoreTransform); - outRect.set( - Math.min(points[0], points[2]), - Math.min(points[1], points[3]), - Math.max(points[0], points[2]), - Math.max(points[1], points[3])); - } - /** * Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}. */ @@ -313,16 +273,6 @@ public final class Utilities { return new int[] {sLoc1[0] - sLoc0[0], sLoc1[1] - sLoc0[1]}; } - /** - * Helper method to set rectOut with rectFSrc. - */ - public static void setRect(RectF rectFSrc, Rect rectOut) { - rectOut.left = (int) rectFSrc.left; - rectOut.top = (int) rectFSrc.top; - rectOut.right = (int) rectFSrc.right; - rectOut.bottom = (int) rectFSrc.bottom; - } - public static void scaleRectFAboutCenter(RectF r, float scale) { if (scale != 1.0f) { float cx = r.centerX(); diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java index e45b8f7918..13ae866efb 100644 --- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java +++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java @@ -21,6 +21,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; @@ -33,7 +34,6 @@ import android.util.Property; import android.util.SparseArray; import android.view.ContextThemeWrapper; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.GraphicsUtils; @@ -119,7 +119,9 @@ public class PreloadIconDrawable extends FastBitmapDrawable { info, IconPalette.getPreloadProgressColor(context, info.bitmap.color), getPreloadColors(context), - Utilities.isDarkTheme(context)); + (context.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK + & Configuration.UI_MODE_NIGHT_YES) != 0) /* isDarkMode */; } public PreloadIconDrawable( diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 48c5d0a854..c19dfe9300 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -16,9 +16,9 @@ package com.android.launcher3.popup; +import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS; -import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -31,7 +31,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Outline; import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; @@ -42,21 +41,17 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; -import android.view.ViewTreeObserver; import android.widget.FrameLayout; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.InsettableFrameLayout; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.Workspace; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.dragndrop.DragLayer; @@ -64,11 +59,9 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; -import com.android.launcher3.widget.LocalColorExtractor; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; /** * A container for shortcuts to deep links and notifications associated with an app. @@ -80,9 +73,6 @@ public abstract class ArrowPopup> // +1 for system shortcut view private static final int MAX_NUM_CHILDREN = MAX_SHORTCUTS + 1; - // Index used to get background color when using local wallpaper color extraction, - private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50; - private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_800; private final Rect mTempRect = new Rect(); @@ -114,14 +104,8 @@ public abstract class ArrowPopup> private Runnable mOnCloseCallback = () -> { }; - // The rect string of the view that the arrow is attached to, in screen reference frame. - private String mArrowColorRectString; private int mArrowColor; private final int[] mColors; - private final HashMap mViewForRect = new HashMap<>(); - - private final int mColorExtractionIndex; - @Nullable private LocalColorExtractor mColorExtractor; public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @@ -129,9 +113,7 @@ public abstract class ArrowPopup> mOutlineRadius = Themes.getDialogCornerRadius(context); mLauncher = BaseDraggingActivity.fromContext(context); mIsRtl = Utilities.isRtl(getResources()); - mColorExtractionIndex = Utilities.isDarkTheme(context) - ? DARK_COLOR_EXTRACTION_INDEX - : LIGHT_COLOR_EXTRACTION_INDEX; + setClipToOutline(true); setOutlineProvider(new ViewOutlineProvider() { @Override @@ -176,10 +158,6 @@ public abstract class ArrowPopup> mColors[i] = (int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor); } - - if (Utilities.ATLEAST_S) { - setupColorExtraction(); - } } } @@ -364,15 +342,6 @@ public abstract class ArrowPopup> // so we centered it instead. In that case we don't want to showDefaultOptions the arrow. mArrow.setVisibility(INVISIBLE); } else { - updateArrowColor(); - } - - mArrow.setPivotX(mArrowWidth / 2.0f); - mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0); - } - - private void updateArrowColor() { - if (!Gravity.isVertical(mGravity)) { mArrow.setBackground(new RoundedArrowDrawable( mArrowWidth, mArrowHeight, mArrowPointRadius, mOutlineRadius, getMeasuredWidth(), getMeasuredHeight(), @@ -381,6 +350,9 @@ public abstract class ArrowPopup> mArrowColor)); mArrow.setElevation(getElevation()); } + + mArrow.setPivotX(mArrowWidth / 2.0f); + mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0); } /** @@ -699,11 +671,6 @@ public abstract class ArrowPopup> getPopupContainer().removeView(this); getPopupContainer().removeView(mArrow); mOnCloseCallback.run(); - mArrowColorRectString = null; - mViewForRect.clear(); - if (mColorExtractor != null) { - mColorExtractor.removeLocations(); - } } /** @@ -713,68 +680,6 @@ public abstract class ArrowPopup> mOnCloseCallback = callback; } - private void setupColorExtraction() { - Workspace workspace = mLauncher.findViewById(R.id.workspace); - if (workspace == null) { - return; - } - - mColorExtractor = LocalColorExtractor.newInstance(mLauncher); - mColorExtractor.setListener((rect, extractedColors) -> { - String rectString = rect.toShortString(); - View v = mViewForRect.get(rectString); - if (v != null) { - int newColor = extractedColors.get(mColorExtractionIndex); - setChildColor(v, newColor); - if (rectString.equals(mArrowColorRectString)) { - mArrowColor = newColor; - updateArrowColor(); - } - } - }); - - getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - getViewTreeObserver().removeOnPreDrawListener(this); - - ArrayList locations = new ArrayList<>(); - Rect r = new Rect(); - - int count = getChildCount(); - int numVisibleChild = 0; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE) { - RectF rf = new RectF(); - getColorExtractionRect(Launcher.getLauncher(getContext()), - workspace.getCurrentPage(), view, rf); - if (rf.isEmpty()) { - numVisibleChild++; - continue; - } - - locations.add(rf); - String rectString = rf.toShortString(); - mViewForRect.put(rectString, view); - - // Arrow color matches the first child or the last child. - if (!mIsAboveIcon && numVisibleChild == 0) { - mArrowColorRectString = rectString; - } else if (mIsAboveIcon) { - mArrowColorRectString = rectString; - } - - numVisibleChild++; - } - } - - mColorExtractor.addLocation(locations); - return false; - } - }); - } - protected BaseDragLayer getPopupContainer() { return mLauncher.getDragLayer(); } diff --git a/src/com/android/launcher3/util/ColorExtractionUtils.java b/src/com/android/launcher3/util/ColorExtractionUtils.java deleted file mode 100644 index b377ded44a..0000000000 --- a/src/com/android/launcher3/util/ColorExtractionUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2021 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 android.content.res.Resources; -import android.graphics.Rect; -import android.graphics.RectF; -import android.view.View; - -import com.android.launcher3.DeviceProfile; -import com.android.launcher3.Launcher; -import com.android.launcher3.Utilities; - -/** - * Utility class used to map launcher views to wallpaper rect. - */ -public class ColorExtractionUtils { - - public static final String TAG = "ColorExtractionUtils"; - - private static final Rect sTempRect = new Rect(); - private static final RectF sTempRectF = new RectF(); - - /** - * Takes a view and returns its rect that can be used by the wallpaper local color extractor. - * - * @param launcher Launcher class class. - * @param pageId The page the workspace item is on. - * @param v The view. - * @param colorExtractionRectOut The location rect, but converted to a format expected by the - * wallpaper local color extractor. - */ - public static void getColorExtractionRect(Launcher launcher, int pageId, View v, - RectF colorExtractionRectOut) { - Rect viewRect = sTempRect; - viewRect.set(0, 0, v.getWidth(), v.getHeight()); - Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, viewRect, false, - sTempRectF); - Utilities.setRect(sTempRectF, viewRect); - getColorExtractionRect(launcher, pageId, viewRect, colorExtractionRectOut); - } - - /** - * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper - * local color extractor. - * - * @param launcher Launcher class. - * @param pageId The page the workspace item is on. - * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates. - * @param colorExtractionRectOut The location rect, but converted to a format expected by the - * wallpaper local color extractor. - */ - public static void getColorExtractionRect(Launcher launcher, int pageId, Rect rectInDragLayer, - RectF colorExtractionRectOut) { - // If the view hasn't been measured and laid out, we cannot do this. - if (rectInDragLayer.isEmpty()) { - colorExtractionRectOut.setEmpty(); - return; - } - - Resources res = launcher.getResources(); - DeviceProfile dp = launcher.getDeviceProfile().inv.getDeviceProfile(launcher); - float screenWidth = dp.widthPx; - float screenHeight = dp.heightPx; - int numScreens = launcher.getWorkspace().getNumPagesForWallpaperParallax(); - pageId = Utilities.isRtl(res) ? numScreens - pageId - 1 : pageId; - float relativeScreenWidth = 1f / numScreens; - - int[] dragLayerBounds = new int[2]; - launcher.getDragLayer().getLocationOnScreen(dragLayerBounds); - // Translate from drag layer coordinates to screen coordinates. - int screenLeft = rectInDragLayer.left + dragLayerBounds[0]; - int screenTop = rectInDragLayer.top + dragLayerBounds[1]; - int screenRight = rectInDragLayer.right + dragLayerBounds[0]; - int screenBottom = rectInDragLayer.bottom + dragLayerBounds[1]; - - // This is the position of the view relative to the wallpaper, as expected by the - // local color extraction of the WallpaperManager. - // The coordinate system is such that, on the horizontal axis, each screen has a - // distinct range on the [0,1] segment. So if there are 3 screens, they will have the - // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be - // the position of the view relative to the screen. For the vertical axis, this is - // simply the location of the view relative to the screen. - // Translate from drag layer coordinates to screen coordinates - colorExtractionRectOut.left = (screenLeft / screenWidth + pageId) * relativeScreenWidth; - colorExtractionRectOut.right = (screenRight / screenWidth + pageId) * relativeScreenWidth; - colorExtractionRectOut.top = screenTop / screenHeight; - colorExtractionRectOut.bottom = screenBottom / screenHeight; - - if (colorExtractionRectOut.left < 0 - || colorExtractionRectOut.right > 1 - || colorExtractionRectOut.top < 0 - || colorExtractionRectOut.bottom > 1) { - colorExtractionRectOut.setEmpty(); - } - } -} diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java index 898ac255d5..99942aa56d 100644 --- a/src/com/android/launcher3/util/Themes.java +++ b/src/com/android/launcher3/util/Themes.java @@ -19,8 +19,10 @@ package com.android.launcher3.util; import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT; import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME; +import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; +import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.ColorMatrix; @@ -40,19 +42,28 @@ import com.android.launcher3.icons.GraphicsUtils; public class Themes { public static int getActivityThemeRes(Context context) { - int colorHints = Utilities.ATLEAST_P ? context.getSystemService(WallpaperManager.class) - .getWallpaperColors(WallpaperManager.FLAG_SYSTEM).getColorHints() - : 0; + final int colorHints; + if (Utilities.ATLEAST_P) { + WallpaperColors colors = context.getSystemService(WallpaperManager.class) + .getWallpaperColors(WallpaperManager.FLAG_SYSTEM); + colorHints = colors == null ? 0 : colors.getColorHints(); + } else { + colorHints = 0; + } return getActivityThemeRes(context, colorHints); } public static int getActivityThemeRes(Context context, int wallpaperColorHints) { + Configuration configuration = context.getResources().getConfiguration(); + int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; + boolean darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES; + boolean supportsDarkText = Utilities.ATLEAST_S && (wallpaperColorHints & HINT_SUPPORTS_DARK_TEXT) != 0; boolean isMainColorDark = Utilities.ATLEAST_S && (wallpaperColorHints & HINT_SUPPORTS_DARK_THEME) != 0; - if (Utilities.isDarkTheme(context)) { + if (darkTheme) { return supportsDarkText ? R.style.AppTheme_Dark_DarkText : isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark; } else { diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 1ddd1ba89f..d49320b073 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -233,8 +233,15 @@ public class FloatingIconView extends FrameLayout implements outViewBounds.set(0, 0, v.getWidth(), v.getHeight()); } - Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, outViewBounds, - ignoreTransform, outRect); + float[] points = new float[] {outViewBounds.left, outViewBounds.top, outViewBounds.right, + outViewBounds.bottom}; + Utilities.getDescendantCoordRelativeToAncestor(v, launcher.getDragLayer(), points, + false, ignoreTransform); + outRect.set( + Math.min(points[0], points[2]), + Math.min(points[1], points[3]), + Math.max(points[0], points[2]), + Math.max(points[1], points[3])); } /** diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index 697c4531c2..620604a4d1 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -16,10 +16,6 @@ package com.android.launcher3.widget; -import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer; -import static com.android.launcher3.Utilities.setRect; -import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect; - import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; @@ -29,6 +25,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; import android.os.SystemClock; +import android.util.Log; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.view.LayoutInflater; @@ -98,11 +95,11 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView private RectF mLastLocationRegistered = null; @Nullable private AppWidgetHostViewDragListener mDragListener; - // Used to store the widget sizes in drag layer coordinates. + // Used to store the widget size during onLayout. private final Rect mCurrentWidgetSize = new Rect(); private final Rect mWidgetSizeAtDrag = new Rect(); - private final RectF mTempRectF = new RectF(); + private final boolean mIsRtl; private final Rect mEnforcedRectangle = new Rect(); private final float mEnforcedCornerRadius; private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() { @@ -132,6 +129,7 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) { setOnLightBackground(true); } + mIsRtl = Utilities.isRtl(context.getResources()); mColorExtractor = LocalColorExtractor.newInstance(getContext()); mColorExtractor.setListener(this); @@ -321,12 +319,13 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView mIsScrollable = checkScrollableRecursively(this); if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) { + mCurrentWidgetSize.left = left; + mCurrentWidgetSize.top = top; + mCurrentWidgetSize.right = right; + mCurrentWidgetSize.bottom = bottom; LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag(); - getBoundsForViewInDragLayer(mLauncher.getDragLayer(), this, mCurrentWidgetSize, true, - mTempRectF); - setRect(mTempRectF, mCurrentWidgetSize); - updateColorExtraction(mCurrentWidgetSize, - mWorkspace.getPageIndexForScreenId(info.screenId)); + int pageId = mWorkspace.getPageIndexForScreenId(info.screenId); + updateColorExtraction(mCurrentWidgetSize, pageId); } enforceRoundedCorners(); @@ -339,8 +338,8 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } /** Handles a drag event occurred on a workspace page, {@code pageId}. */ - public void handleDrag(Rect rectInDragLayer, int pageId) { - mWidgetSizeAtDrag.set(rectInDragLayer); + public void handleDrag(Rect rect, int pageId) { + mWidgetSizeAtDrag.set(rect); updateColorExtraction(mWidgetSizeAtDrag, pageId); } @@ -352,14 +351,53 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView requestLayout(); } - /** - * @param rectInDragLayer Rect of widget in drag layer coordinates. - * @param pageId The workspace page the widget is on. - */ - private void updateColorExtraction(Rect rectInDragLayer, int pageId) { - getColorExtractionRect(mLauncher, pageId, rectInDragLayer, mTempRectF); - - if (mTempRectF.isEmpty()) { + private void updateColorExtraction(Rect widgetLocation, int pageId) { + // If the widget hasn't been measured and laid out, we cannot do this. + if (widgetLocation.isEmpty()) { + return; + } + int screenWidth = mLauncher.getDeviceProfile().widthPx; + int screenHeight = mLauncher.getDeviceProfile().heightPx; + int numScreens = mWorkspace.getNumPagesForWallpaperParallax(); + pageId = mIsRtl ? numScreens - pageId - 1 : pageId; + float relativeScreenWidth = 1f / numScreens; + float absoluteTop = widgetLocation.top; + float absoluteBottom = widgetLocation.bottom; + View v = this; + while (v.getParent() instanceof View) { + v = (View) v.getParent(); + if (v.getId() != R.id.launcher) { + break; + } + absoluteBottom += v.getTop(); + absoluteTop += v.getTop(); + } + float xOffset = 0; + View parentView = (View) getParent(); + // The layout depends on the orientation. + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + int parentViewWidth = parentView == null ? 0 : parentView.getWidth(); + xOffset = screenWidth - mWorkspace.getPaddingRight() - parentViewWidth; + } else { + int parentViewPaddingLeft = parentView == null ? 0 : parentView.getPaddingLeft(); + xOffset = mWorkspace.getPaddingLeft() + parentViewPaddingLeft; + } + // This is the position of the widget relative to the wallpaper, as expected by the + // local color extraction of the WallpaperManager. + // The coordinate system is such that, on the horizontal axis, each screen has a + // distinct range on the [0,1] segment. So if there are 3 screens, they will have the + // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be + // the position of the widget relative to the screen. For the vertical axis, this is + // simply the location of the widget relative to the screen. + mTempRectF.left = ((widgetLocation.left + xOffset) / screenWidth + pageId) + * relativeScreenWidth; + mTempRectF.right = ((widgetLocation.right + xOffset) / screenWidth + pageId) + * relativeScreenWidth; + mTempRectF.top = absoluteTop / screenHeight; + mTempRectF.bottom = absoluteBottom / screenHeight; + if (mTempRectF.left < 0 || mTempRectF.right > 1 || mTempRectF.top < 0 + || mTempRectF.bottom > 1) { + Log.e(LOG_TAG, " Error, invalid relative position"); return; } if (!mTempRectF.equals(mLastLocationRegistered)) { diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java index 2121bc288b..097158b072 100644 --- a/src/com/android/launcher3/widget/LocalColorExtractor.java +++ b/src/com/android/launcher3/widget/LocalColorExtractor.java @@ -43,10 +43,7 @@ public class LocalColorExtractor implements ResourceBasedOverride { void onColorsChanged(RectF rect, SparseIntArray extractedColors); } - /** - * Returns a new instance of the LocalColorExtractor. - */ - public static LocalColorExtractor newInstance(Context context) { + static LocalColorExtractor newInstance(Context context) { return Overrides.getObject(LocalColorExtractor.class, context.getApplicationContext(), R.string.local_colors_extraction_class); }