Snap for 7333400 from c71f134ec6 to sc-release
Change-Id: I26ed3bea37899660ab6ad2ac7b37632a42d1cc61
This commit is contained in:
@@ -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<T extends OverviewActionsView> 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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<Intent, ActivityOptions> 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);
|
||||
}
|
||||
|
||||
@@ -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<IBinder> 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]),
|
||||
|
||||
@@ -2481,6 +2481,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
if (LIVE_TILE.get() && mRunningTaskId != -1) {
|
||||
switchToScreenshot(
|
||||
() -> 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<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* capturing the snapshot at the same time.
|
||||
*/
|
||||
public void switchToScreenshot(Runnable onFinishRunnable) {
|
||||
switchToScreenshot(mRunningTaskId == -1 ? null
|
||||
switchToScreenshot(mRecentsAnimationController == null || mRunningTaskId == -1 ? null
|
||||
: mRecentsAnimationController.screenshotTask(mRunningTaskId), onFinishRunnable);
|
||||
}
|
||||
|
||||
|
||||
@@ -777,8 +777,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
float upperClamp = invert ? 1 : iconScalePercentage;
|
||||
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
|
||||
.getInterpolation(progress);
|
||||
mIconView.setScaleX(scale);
|
||||
mIconView.setScaleY(scale);
|
||||
mIconView.setAlpha(scale);
|
||||
if (mContextualChipWrapper != null && mContextualChipWrapper != null) {
|
||||
mContextualChipWrapper.setAlpha(scale);
|
||||
mContextualChipWrapper.setScaleX(Math.min(scale, comp(mModalness)));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:alpha="0.4"
|
||||
<item android:alpha="0.3"
|
||||
android:color="?android:attr/colorAccent"/>
|
||||
</selector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:alpha="0.3"
|
||||
<item android:alpha="0.25"
|
||||
android:color="?android:attr/colorAccent"/>
|
||||
</selector>
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- Workspace -->
|
||||
<!-- The duration (in ms) of the fade animation on the object outlines, used when
|
||||
we are dragging objects around on the home screen. -->
|
||||
<integer name="config_dragOutlineFadeTime">900</integer>
|
||||
<integer name="config_dragOutlineFadeTime">500</integer>
|
||||
|
||||
<!-- The alpha value at which to show the most recent drop visualization outline. -->
|
||||
<integer name="config_dragOutlineMaxAlpha">255</integer>
|
||||
|
||||
@@ -293,7 +293,7 @@
|
||||
<dimen name="overview_task_margin">0dp</dimen>
|
||||
|
||||
<!-- Workspace grid visualization parameters -->
|
||||
<dimen name="grid_visualization_rounding_radius">28dp</dimen>
|
||||
<dimen name="grid_visualization_rounding_radius">22dp</dimen>
|
||||
<dimen name="grid_visualization_cell_spacing">6dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
// +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<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
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<String, View> 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<T extends StatefulActivity<LauncherState>>
|
||||
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<T extends StatefulActivity<LauncherState>>
|
||||
mColors[i] =
|
||||
(int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor);
|
||||
}
|
||||
|
||||
if (Utilities.ATLEAST_S) {
|
||||
setupColorExtraction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,15 +342,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
// 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<T extends StatefulActivity<LauncherState>>
|
||||
mArrowColor));
|
||||
mArrow.setElevation(getElevation());
|
||||
}
|
||||
|
||||
mArrow.setPivotX(mArrowWidth / 2.0f);
|
||||
mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -699,11 +671,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
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<T extends StatefulActivity<LauncherState>>
|
||||
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<RectF> 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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user