Snap for 7929330 from 39aceb6dc7 to sc-v2-release

Change-Id: I1a9d23ddd153acd0e939b9730cb65d7594f4ba17
This commit is contained in:
Android Build Coastguard Worker
2021-11-19 00:08:01 +00:00
35 changed files with 608 additions and 215 deletions
+1
View File
@@ -204,6 +204,7 @@ android_library {
],
static_libs: [
"Launcher3ResLib",
"lottie",
"SystemUISharedLib",
"SystemUI-statsd",
],
+2
View File
@@ -163,6 +163,8 @@ dependencies {
androidTestImplementation 'com.android.support.test:rules:1.0.0'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
androidTestImplementation "androidx.annotation:annotation:${ANDROID_X_VERSION}"
api 'com.airbnb.android:lottie:3.3.0'
}
protobuf {
+86 -68
View File
@@ -25,82 +25,100 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/allset_page_margin_horizontal"
android:layout_marginEnd="@dimen/allset_page_margin_horizontal"
android:layoutDirection="locale"
android:textDirection="locale"
android:id="@+id/content_view"
android:forceHasOverlappingRendering="false"
android:fitsSystemWindows="true" >
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_title_icon_margin_top"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:src="@drawable/ic_all_set"/>
<TextView
android:id="@+id/title"
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animated_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_title_margin_top"
app:layout_constraintTop_toBottomOf="@id/icon"
app:layout_constraintStart_toStartOf="parent"
android:gravity="start"
android:text="@string/allset_title"/>
android:layout_height="match_parent"
android:gravity="center"
android:scaleType="centerCrop"
<TextView
android:id="@+id/subtitle"
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_subtitle_margin_top"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_max="@dimen/allset_subtitle_width_max"
android:gravity="start"
android:text="@string/allset_description"/>
app:lottie_rawRes="@raw/all_set_page_bg"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/navigation_settings_guideline_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.83" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/allset_page_margin_horizontal"
android:layout_marginEnd="@dimen/allset_page_margin_horizontal"
android:layoutDirection="locale"
android:textDirection="locale"
android:forceHasOverlappingRendering="false"
android:fitsSystemWindows="true" >
<TextView
android:id="@+id/navigation_settings"
style="@style/TextAppearance.GestureTutorial.LinkText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/navigation_settings_guideline_bottom"
android:minHeight="48dp"
android:background="?android:attr/selectableItemBackground"
android:text="@string/allset_navigation_settings" />
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_title_icon_margin_top"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:src="@drawable/ic_all_set"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/hint_guideline_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.94" />
<TextView
android:id="@+id/title"
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_title_margin_top"
app:layout_constraintTop_toBottomOf="@id/icon"
app:layout_constraintStart_toStartOf="parent"
android:gravity="start"
android:text="@string/allset_title"/>
<TextView
android:id="@+id/subtitle"
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/allset_subtitle_margin_top"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_max="@dimen/allset_subtitle_width_max"
android:gravity="start"
android:text="@string/allset_description"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/navigation_settings_guideline_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.83" />
<TextView
android:id="@+id/navigation_settings"
style="@style/TextAppearance.GestureTutorial.LinkText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/navigation_settings_guideline_bottom"
android:minHeight="48dp"
android:background="?android:attr/selectableItemBackground"
android:text="@string/allset_navigation_settings" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/hint_guideline_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.94" />
<TextView
android:id="@+id/hint"
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/hint_guideline_bottom"
android:text="@string/allset_hint"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/hint"
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/hint_guideline_bottom"
android:text="@string/allset_hint"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
+1
View File
@@ -28,6 +28,7 @@
<dimen name="task_menu_item_corner_radius">4dp</dimen>
<dimen name="task_menu_spacing">2dp</dimen>
<dimen name="task_menu_width_grid">234dp</dimen>
<dimen name="task_menu_horizontal_padding">8dp</dimen>
<dimen name="overview_proactive_row_height">48dp</dimen>
<dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
@@ -143,8 +143,7 @@ public class TaskbarDragLayerController {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mControllers.navbarButtonsViewController.isImeVisible()) {
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_CONTENT);
insetsIsTouchableRegion = false;
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (!mControllers.uiController.isTaskbarTouchable()) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
@@ -30,6 +30,7 @@ public class KtR {
public static final class dimen {
public static int task_menu_spacing = R.dimen.task_menu_spacing;
public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
}
public static final class layout {
@@ -208,13 +208,6 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
}
}
/**
* Called when the current task's thumbnail has changed.
*/
public void refreshActionVisibility(ThumbnailData thumbnail) {
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
}
/**
* End rendering live tile in Overview.
*
@@ -134,7 +134,8 @@ public class TaskThumbnailCache {
Preconditions.assertUIThread();
boolean lowResolution = !mHighResLoadingState.isEnabled();
if (task.thumbnail != null && (!task.thumbnail.reducedResolution || lowResolution)) {
if (task.thumbnail != null && task.thumbnail.thumbnail != null
&& (!task.thumbnail.reducedResolution || lowResolution)) {
// Nothing to load, the thumbnail is already high-resolution or matches what the
// request, so just callback
callback.accept(task.thumbnail);
@@ -152,7 +153,8 @@ public class TaskThumbnailCache {
Preconditions.assertUIThread();
ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
if (cachedThumbnail != null && (!cachedThumbnail.reducedResolution || lowResolution)) {
if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
&& (!cachedThumbnail.reducedResolution || lowResolution)) {
// Already cached, lets use that thumbnail
callback.accept(cachedThumbnail);
return null;
@@ -32,7 +32,6 @@ import static com.android.launcher3.QuickstepTransitionManager.SPLIT_LAUNCH_DURA
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
@@ -193,7 +192,6 @@ public final class TaskViewUtils {
boolean showAsGrid = dp.overviewShowAsGrid;
boolean parallaxCenterAndAdjacentTask =
taskIndex != recentsView.getCurrentPage() && !showAsGrid;
float gridTranslationSecondary = recentsView.getGridTranslationSecondary(taskIndex);
int startScroll = recentsView.getScrollOffset(taskIndex);
RemoteTargetHandle[] topMostSimulators = null;
@@ -211,11 +209,9 @@ public final class TaskViewUtils {
tvsLocal.fullScreenProgress.value = 0;
tvsLocal.recentsViewScale.value = 1;
if (showAsGrid) {
tvsLocal.taskSecondaryTranslation.value = gridTranslationSecondary;
}
tvsLocal.setScroll(startScroll);
tvsLocal.setIsGridTask(v.isGridTask());
tvsLocal.setGridTranslationY(v.getGridTranslationY());
// Fade in the task during the initial 20% of the animation
out.addFloat(targetHandle.getTransformParams(), TransformParams.TARGET_ALPHA, 0, 1,
@@ -230,10 +226,6 @@ public final class TaskViewUtils {
out.setFloat(tvsLocal.recentsViewScale,
AnimatedFloat.VALUE, tvsLocal.getFullScreenScale(),
TOUCH_RESPONSE_INTERPOLATOR);
if (showAsGrid) {
out.setFloat(tvsLocal.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL);
}
out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0,
TOUCH_RESPONSE_INTERPOLATOR);
@@ -16,6 +16,7 @@
package com.android.quickstep.fallback;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.ViewUtils.postFrameDrawn;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
@@ -218,8 +219,14 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
@Override
public void onStateTransitionComplete(RecentsState finalState) {
setOverlayEnabled(finalState == DEFAULT || finalState == MODAL_TASK);
boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
setOverlayEnabled(isOverlayEnabled);
setFreezeViewVisibility(false);
if (isOverlayEnabled) {
postFrameDrawn(this, () -> runActionOnRemoteHandles(remoteTargetHandle ->
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true)));
}
}
@Override
@@ -19,6 +19,7 @@ import static com.android.launcher3.Utilities.mapBoundToRange;
import static com.android.launcher3.Utilities.mapRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.Animator;
import android.app.Activity;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -38,6 +39,8 @@ import android.graphics.Rect;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -56,6 +59,8 @@ import com.android.quickstep.GestureState;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.util.TISBindHelper;
import com.airbnb.lottie.LottieAnimationView;
import java.net.URISyntaxException;
/**
@@ -80,6 +85,10 @@ public class AllSetActivity extends Activity {
private View mContentView;
private float mSwipeUpShift;
@Nullable private Vibrator mVibrator;
private LottieAnimationView mAnimatedBackground;
private Animator.AnimatorListener mBackgroundAnimatorListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -115,6 +124,52 @@ public class AllSetActivity extends Activity {
findViewById(R.id.hint).setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
mVibrator = getSystemService(Vibrator.class);
mAnimatedBackground = findViewById(R.id.animated_background);
startBackgroundAnimation();
}
private void startBackgroundAnimation() {
if (Utilities.ATLEAST_S && mVibrator != null && mVibrator.areAllPrimitivesSupported(
VibrationEffect.Composition.PRIMITIVE_THUD)) {
if (mBackgroundAnimatorListener == null) {
mBackgroundAnimatorListener =
new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mVibrator.vibrate(getVibrationEffect());
}
@Override
public void onAnimationRepeat(Animator animation) {
mVibrator.vibrate(getVibrationEffect());
}
@Override
public void onAnimationEnd(Animator animation) {
mVibrator.cancel();
}
@Override
public void onAnimationCancel(Animator animation) {
mVibrator.cancel();
}
};
}
mAnimatedBackground.addAnimatorListener(mBackgroundAnimatorListener);
}
mAnimatedBackground.playAnimation();
}
/**
* Sets up the vibration effect for the next round of animation. The parameters vary between
* different illustrations.
*/
private VibrationEffect getVibrationEffect() {
return VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 1.0f, 50)
.compose();
}
@Override
@@ -153,6 +208,9 @@ public class AllSetActivity extends Activity {
super.onDestroy();
mTISBindHelper.onDestroy();
clearBinderOverride();
if (mBackgroundAnimatorListener != null) {
mAnimatedBackground.removeAnimatorListener(mBackgroundAnimatorListener);
}
}
private AnimatedFloat createSwipeUpProxy(GestureState state) {
@@ -173,6 +231,12 @@ public class AllSetActivity extends Activity {
1, 0, LINEAR);
mContentView.setAlpha(alpha);
mContentView.setTranslationY((alpha - 1) * mSwipeUpShift);
if (alpha == 0f) {
mAnimatedBackground.pauseAnimation();
} else if (!mAnimatedBackground.isAnimating()) {
mAnimatedBackground.resumeAnimation();
}
}
/**
@@ -102,6 +102,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
private StagedSplitBounds mStagedSplitBounds;
private boolean mDrawsBelowRecents;
private boolean mIsGridTask;
private float mGridTranslationY;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
mContext = context;
@@ -156,9 +157,15 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
fullTaskSize = new Rect(mTaskRect);
mOrientationState.getOrientationHandler()
.setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
if (mIsGridTask) {
mTaskRect.offset(0, (int) mGridTranslationY);
}
} else {
fullTaskSize = mTaskRect;
}
if (mIsGridTask) {
fullTaskSize.offset(0, (int) mGridTranslationY);
}
return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
}
@@ -217,6 +224,13 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mIsGridTask = isGridTask;
}
/**
* Sets the y-translation when overview is in grid.
*/
public void setGridTranslationY(float gridTranslationY) {
mGridTranslationY = gridTranslationY;
}
/**
* Adds animation for all the components corresponding to transition from an app to overview.
*/
@@ -320,14 +334,12 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
// Apply TaskView matrix: translate, scroll
// Apply TaskView matrix: taskRect, translate
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
taskPrimaryTranslation.value);
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
taskSecondaryTranslation.value);
mOrientationState.getOrientationHandler().set(
mMatrix, MATRIX_POST_TRANSLATE, recentsViewScroll.value);
// Apply RecentsView matrix
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
@@ -335,6 +347,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
recentsViewSecondaryTranslation.value);
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
recentsViewPrimaryTranslation.value);
mOrientationState.getOrientationHandler().set(
mMatrix, MATRIX_POST_TRANSLATE, recentsViewScroll.value);
applyWindowToHomeRotation(mMatrix);
// Crop rect is the inverse of thumbnail matrix
@@ -4,7 +4,6 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -50,8 +49,6 @@ public class GroupedTaskView extends TaskView {
private final float[] mIcon2CenterCoords = new float[2];
private TransformingTouchDelegate mIcon2TouchDelegate;
@Nullable private StagedSplitBounds mSplitBoundsConfig;
private final Rect mPrimaryTempRect = new Rect();
private final Rect mSecondaryTempRect = new Rect();
public GroupedTaskView(Context context) {
super(context);
@@ -239,10 +236,8 @@ public class GroupedTaskView extends TaskView {
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
mSnapshotView.getBoundsOnScreen(mPrimaryTempRect);
mSnapshotView2.getBoundsOnScreen(mSecondaryTempRect);
getPagedOrientationHandler().setSplitIconParams(mIconView, mIconView2,
taskIconHeight, mPrimaryTempRect, mSecondaryTempRect,
taskIconHeight, mSnapshotView.getWidth(), mSnapshotView.getHeight(),
isRtl, deviceProfile, mSplitBoundsConfig);
}
@@ -21,6 +21,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.quickstep.ViewUtils.postFrameDrawn;
import android.annotation.TargetApi;
import android.content.Context;
@@ -104,8 +105,14 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
@Override
public void onStateTransitionComplete(LauncherState finalState) {
setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK);
boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
setOverlayEnabled(isOverlayEnabled);
setFreezeViewVisibility(false);
if (isOverlayEnabled) {
postFrameDrawn(this, () -> runActionOnRemoteHandles(remoteTargetHandle ->
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true)));
}
}
@Override
@@ -1508,17 +1508,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
// to reset the params after it settles in Overview from swipe up so that we don't
// render with obsolete param values.
runActionOnRemoteHandles(remoteTargetHandle -> {
TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator();
simulator.taskPrimaryTranslation.value = 0;
simulator.taskSecondaryTranslation.value = 0;
simulator.fullScreenProgress.value = 0;
simulator.recentsViewScale.value = 1;
});
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
// null.
if (!mRunningTaskShowScreenshot) {
@@ -1906,7 +1895,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
setEnableDrawingLiveTile(false);
runActionOnRemoteHandles(remoteTargetHandle -> {
remoteTargetHandle.getTransformParams().setTargetSet(null);
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true);
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false);
});
mSplitSelectStateController.resetState();
@@ -4389,7 +4378,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
tvs.setOrientationState(mOrientationState);
tvs.setDp(mActivity.getDeviceProfile());
tvs.setDrawsBelowRecents(true);
tvs.recentsViewScale.value = 1;
}
}
@@ -4691,20 +4679,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId());
}
/**
* Returns how many pixels the task is offset on the currently laid out secondary axis
* according to {@link #mGridProgress}.
*/
public float getGridTranslationSecondary(int pageIndex) {
TaskView taskView = getTaskViewAt(pageIndex);
if (taskView == null) {
return 0;
}
return mOrientationHandler.getSecondaryValue(taskView.getGridTranslationX(),
taskView.getGridTranslationY());
}
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
float degreesRotated;
if (navbarRotation == 0) {
@@ -23,14 +23,18 @@ import android.graphics.Rect
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RectShape
import android.util.AttributeSet
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.android.launcher3.BaseDraggingActivity
import com.android.launcher3.DeviceProfile
import com.android.launcher3.InsettableFrameLayout
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.popup.SystemShortcut
import com.android.launcher3.util.Themes
import com.android.quickstep.KtR
@@ -43,9 +47,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean {
val activity = BaseDraggingActivity
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
val taskMenuViewWithArrow = activity.layoutInflater
.inflate(KtR.layout.task_menu_with_arrow, activity.dragLayer, false) as TaskMenuViewWithArrow<*>
.inflate(
KtR.layout.task_menu_with_arrow,
activity.dragLayer,
false
) as TaskMenuViewWithArrow<*>
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer)
}
@@ -53,10 +61,21 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
init {
clipToOutline = true
shouldScaleArrow = true
// This synchronizes the arrow and menu to open at the same time
OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY
CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
}
private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
@@ -65,6 +84,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
private lateinit var optionLayout: LinearLayout
private lateinit var taskContainer: TaskIdAttributeContainer
private var optionMeasuredHeight = 0
private val arrowHorizontalPadding: Int
get() = if (taskView.isFocusedTask)
resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding)
else
0
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
override fun getTargetObjectLocation(outPos: Rect?) {
@@ -147,7 +173,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
}
override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) {
assignMarginsAndBackgrounds(this, Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface))
assignMarginsAndBackgrounds(
this,
Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
)
}
override fun onCreateOpenAnimation(anim: AnimatorSet) {
@@ -164,4 +193,90 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f)
)
}
/**
* Orients this container to the left or right of the given icon, aligning with the first option
* or second.
*
* These are the preferred orientations, in order (RTL prefers right-aligned over left):
* - Right and first option aligned
* - Right and second option aligned
* - Left and first option aligned
* - Left and second option aligned
*
* So we always align right if there is enough horizontal space
*/
override fun orientAboutObject() {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
// Needed for offsets later
optionMeasuredHeight = optionLayout.getChildAt(0).measuredHeight
val extraHorizontalSpace = (mArrowHeight + mArrowOffsetVertical + arrowHorizontalPadding)
val widthWithArrow = measuredWidth + paddingLeft + paddingRight + extraHorizontalSpace
getTargetObjectLocation(mTempRect)
val dragLayer: InsettableFrameLayout = popupContainer
val insets = dragLayer.insets
// Put to the right of the icon if there is space, which means left aligned with the menu
val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
mIsLeftAligned = if (mIsRtl) {
rightAlignedMenuStartX + insets.left < 0
} else {
leftAlignedMenuStartX + (widthWithArrow - extraHorizontalSpace) + insets.left <
dragLayer.width - insets.right
}
var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
// Offset y so that the arrow and first row are center-aligned with the original icon.
val iconHeight = mTempRect.height()
val optionHeight = optionMeasuredHeight
val yOffset = (optionHeight - iconHeight) / 2
var menuStartY = mTempRect.top - yOffset
// Insets are added later, so subtract them now.
menuStartX -= insets.left
menuStartY -= insets.top
setX(menuStartX.toFloat())
setY(menuStartY.toFloat())
val lp = layoutParams as FrameLayout.LayoutParams
val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
lp.gravity = Gravity.TOP
arrowLp.gravity = lp.gravity
}
override fun addArrow() {
popupContainer.addView(mArrow)
mArrow.x = getArrowX()
mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2)
updateArrowColor()
// This is inverted (x = height, y = width) because the arrow is rotated
mArrow.pivotX = if (mIsLeftAligned) 0f else mArrowHeight.toFloat()
mArrow.pivotY = 0f
}
private fun getArrowX(): Float {
return if (mIsLeftAligned)
x - mArrowHeight
else
x + measuredWidth + mArrowOffsetVertical
}
override fun updateArrowColor() {
mArrow.background = RoundedArrowDrawable(
mArrowWidth.toFloat(),
mArrowHeight.toFloat(),
mArrowPointRadius.toFloat(),
mIsLeftAligned,
mArrowColor
)
elevation = mElevation
mArrow.elevation = mElevation
}
}
@@ -148,10 +148,11 @@ public class TaskThumbnailView extends View {
public void setThumbnail(@Nullable Task task, @Nullable ThumbnailData thumbnailData,
boolean refreshNow) {
mTask = task;
boolean thumbnailWasNull = mThumbnailData == null;
mThumbnailData =
(thumbnailData != null && thumbnailData.thumbnail != null) ? thumbnailData : null;
if (refreshNow) {
refresh();
refresh(thumbnailWasNull && mThumbnailData != null);
}
}
@@ -162,14 +163,22 @@ public class TaskThumbnailView extends View {
/** Updates the shader, paint, matrix to redraw. */
public void refresh() {
refresh(false);
}
/**
* Updates the shader, paint, matrix to redraw.
* @param shouldRefreshOverlay whether to re-initialize overlay
*/
private void refresh(boolean shouldRefreshOverlay) {
if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
Bitmap bm = mThumbnailData.thumbnail;
bm.prepareToDraw();
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
updateThumbnailMatrix();
if (mOverlayEnabled) {
getTaskOverlay().refreshActionVisibility(mThumbnailData);
if (shouldRefreshOverlay) {
refreshOverlay();
}
} else {
mBitmapShader = null;
@@ -648,7 +648,7 @@ public class TaskView extends FrameLayout implements Reusable {
recentsView.getDepthController());
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
public void onAnimationStart(Animator animation) {
recentsView.runActionOnRemoteHandles(
(Consumer<RemoteTargetHandle>) remoteTargetHandle ->
remoteTargetHandle
@@ -658,11 +658,6 @@ public class TaskView extends FrameLayout implements Reusable {
@Override
public void onAnimationEnd(Animator animator) {
recentsView.runActionOnRemoteHandles(
(Consumer<RemoteTargetHandle>) remoteTargetHandle ->
remoteTargetHandle
.getTaskViewSimulator()
.setDrawsBelowRecents(true));
mIsClickableAsLiveTile = true;
}
});
+8
View File
@@ -33,6 +33,14 @@
android:layout_height="match_parent"
android:importantForAccessibility="no"
android:layout_gravity="fill"/>
<ImageView
android:id="@+id/widget_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/profile_badge_margin"/>
</com.android.launcher3.widget.WidgetCellPreview>
<!-- The name of the widget. -->
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -36,8 +36,8 @@
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
<string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> aggiunto alla schermata Home"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}other{# scorciatoie}}"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widget}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}one{# scorciatoia}other{# scorciatoie}}"</string>
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cerca"</string>
@@ -86,7 +86,7 @@
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Modifica nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"App <xliff:g id="APP_NAME">%1$s</xliff:g> disattivata"</string>
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}one{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d di %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nuova pagina Schermata Home"</string>
+3 -3
View File
@@ -36,8 +36,8 @@
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
<string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> adicionado ao ecrã principal"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}other{# atalhos}}"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget(s)}other{# widgets}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}one{# atalho(s)}other{# atalhos}}"</string>
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pesquisar"</string>
@@ -86,7 +86,7 @@
<string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma app de sistema e não pode ser desinstalada."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Edite o nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}other{A app {app_name} tem # notificações}}"</string>
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}one{A app {app_name} tem # notificação(ões)}other{A app {app_name} tem # notificações}}"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova página do ecrã principal"</string>
+104 -15
View File
@@ -19,6 +19,8 @@ package com.android.launcher3;
import static android.animation.ValueAnimator.areAnimatorsEnabled;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -37,7 +39,6 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -61,6 +62,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.CellAndSpan;
@@ -442,18 +444,43 @@ public class CellLayout extends ViewGroup {
}
if (DEBUG_VISUALIZE_OCCUPIED) {
int[] pt = new int[2];
ColorDrawable cd = new ColorDrawable(Color.RED);
cd.setBounds(0, 0, mCellWidth, mCellHeight);
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
if (mOccupied.cells[i][j]) {
cellToPoint(i, j, pt);
canvas.save();
canvas.translate(pt[0], pt[1]);
cd.draw(canvas);
canvas.restore();
Rect cellBounds = new Rect();
// Will contain the bounds of the cell including spacing between cells.
Rect cellBoundsWithSpacing = new Rect();
int[] targetCell = new int[2];
int[] cellCenter = new int[2];
Paint debugPaint = new Paint();
debugPaint.setStrokeWidth(Utilities.dpToPx(1));
for (int x = 0; x < mCountX; x++) {
for (int y = 0; y < mCountY; y++) {
if (!mOccupied.cells[x][y]) {
continue;
}
targetCell[0] = x;
targetCell[1] = y;
boolean canCreateFolder = canCreateFolder(getChildAt(x, y));
cellToRect(x, y, 1, 1, cellBounds);
cellBoundsWithSpacing.set(cellBounds);
cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
getWorkspaceCellVisualCenter(x, y, cellCenter);
canvas.save();
canvas.clipRect(cellBoundsWithSpacing);
// Draw reorder drag target.
debugPaint.setColor(Color.RED);
canvas.drawCircle(cellCenter[0], cellCenter[1], getReorderRadius(targetCell),
debugPaint);
// Draw folder creation drag target.
if (canCreateFolder) {
debugPaint.setColor(Color.GREEN);
canvas.drawCircle(cellCenter[0], cellCenter[1],
getFolderCreationRadius(targetCell), debugPaint);
}
canvas.restore();
}
}
}
@@ -481,6 +508,14 @@ public class CellLayout extends ViewGroup {
}
}
/**
* Returns whether dropping an icon on the given View can create (or add to) a folder.
*/
private boolean canCreateFolder(View child) {
return child instanceof DraggableView
&& ((DraggableView) child).getViewType() == DRAGGABLE_ICON;
}
/**
* Indicates the progress of the Workspace entering the SpringLoaded state; allows the
* CellLayout to update various visuals for this state.
@@ -817,7 +852,7 @@ public class CellLayout extends ViewGroup {
}
/**
* Given a cell coordinate and span return the point that represents the center of the regio
* Given a cell coordinate and span return the point that represents the center of the region
*
* @param cellX X coordinate of the cell
* @param cellY Y coordinate of the cell
@@ -830,11 +865,65 @@ public class CellLayout extends ViewGroup {
result[1] = mTempRect.centerY();
}
public float getDistanceFromCell(float x, float y, int[] cell) {
cellToCenterPoint(cell[0], cell[1], mTmpPoint);
/**
* Returns the distance between the given coordinate and the visual center of the given cell.
*/
public float getDistanceFromWorkspaceCellVisualCenter(float x, float y, int[] cell) {
getWorkspaceCellVisualCenter(cell[0], cell[1], mTmpPoint);
return (float) Math.hypot(x - mTmpPoint[0], y - mTmpPoint[1]);
}
private void getWorkspaceCellVisualCenter(int cellX, int cellY, int[] outPoint) {
View child = getChildAt(cellX, cellY);
if (child instanceof DraggableView) {
DraggableView draggableChild = (DraggableView) child;
if (draggableChild.getViewType() == DRAGGABLE_ICON) {
cellToPoint(cellX, cellY, outPoint);
draggableChild.getWorkspaceVisualDragBounds(mTempRect);
mTempRect.offset(outPoint[0], outPoint[1]);
outPoint[0] = mTempRect.centerX();
outPoint[1] = mTempRect.centerY();
return;
}
}
cellToCenterPoint(cellX, cellY, outPoint);
}
/**
* Returns the max distance from the center of a cell that can accept a drop to create a folder.
*/
public float getFolderCreationRadius(int[] targetCell) {
DeviceProfile grid = mActivity.getDeviceProfile();
float iconVisibleRadius = ICON_VISIBLE_AREA_FACTOR * grid.iconSizePx / 2;
// Halfway between reorder radius and icon.
return (getReorderRadius(targetCell) + iconVisibleRadius) / 2;
}
/**
* Returns the max distance from the center of a cell that will start to reorder on drag over.
*/
public float getReorderRadius(int[] targetCell) {
int[] centerPoint = mTmpPoint;
getWorkspaceCellVisualCenter(targetCell[0], targetCell[1], centerPoint);
Rect cellBoundsWithSpacing = mTempRect;
cellToRect(targetCell[0], targetCell[1], 1, 1, cellBoundsWithSpacing);
cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
if (canCreateFolder(getChildAt(targetCell[0], targetCell[1]))) {
// Take only the circle in the smaller dimension, to ensure we don't start reordering
// too soon before accepting a folder drop.
int minRadius = centerPoint[0] - cellBoundsWithSpacing.left;
minRadius = Math.min(minRadius, centerPoint[1] - cellBoundsWithSpacing.top);
minRadius = Math.min(minRadius, cellBoundsWithSpacing.right - centerPoint[0]);
minRadius = Math.min(minRadius, cellBoundsWithSpacing.bottom - centerPoint[1]);
return minRadius;
}
// Take up the entire cell, including space between this cell and the adjacent ones.
return (float) Math.hypot(cellBoundsWithSpacing.width() / 2f,
cellBoundsWithSpacing.height() / 2f);
}
public int getCellWidth() {
return mCellWidth;
}
+17 -19
View File
@@ -220,7 +220,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
private FolderIcon mDragOverFolderIcon = null;
private boolean mCreateUserFolderOnDrop = false;
private boolean mAddToExistingFolderOnDrop = false;
private float mMaxDistanceForFolderCreation;
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
@@ -308,8 +307,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
public void setInsets(Rect insets) {
DeviceProfile grid = mLauncher.getDeviceProfile();
mMaxDistanceForFolderCreation = grid.isTablet
? 0.75f * grid.iconSizePx : 0.55f * grid.iconSizePx;
mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
Rect padding = grid.workspacePadding;
@@ -1774,8 +1771,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, dropTargetLayout,
mTargetCell);
float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
mDragViewVisualCenter[1], mTargetCell);
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (mCreateUserFolderOnDrop && willCreateUserFolder(d.dragInfo,
dropTargetLayout, mTargetCell, distance, true)) {
return true;
@@ -1809,7 +1806,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
float distance, boolean considerTimeout) {
if (distance > mMaxDistanceForFolderCreation) return false;
if (distance > target.getFolderCreationRadius(targetCell)) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
return willCreateUserFolder(info, dropOverView, considerTimeout);
}
@@ -1844,7 +1841,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
boolean willAddToExistingUserFolder(ItemInfo dragInfo, CellLayout target, int[] targetCell,
float distance) {
if (distance > mMaxDistanceForFolderCreation) return false;
if (distance > target.getFolderCreationRadius(targetCell)) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
return willAddToExistingUserFolder(dragInfo, dropOverView);
@@ -1868,7 +1865,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
boolean createUserFolderIfNecessary(View newView, int container, CellLayout target,
int[] targetCell, float distance, boolean external, DragObject d) {
if (distance > mMaxDistanceForFolderCreation) return false;
if (distance > target.getFolderCreationRadius(targetCell)) return false;
View v = target.getChildAt(targetCell[0], targetCell[1]);
boolean hasntMoved = false;
@@ -1925,7 +1922,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
boolean addToExistingFolderIfNecessary(View newView, CellLayout target, int[] targetCell,
float distance, DragObject d, boolean external) {
if (distance > mMaxDistanceForFolderCreation) return false;
if (distance > target.getFolderCreationRadius(targetCell)) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
if (!mAddToExistingFolderOnDrop) return false;
@@ -1989,8 +1986,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int)
mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
mDragViewVisualCenter[1], mTargetCell);
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
// If the item being dropped is a shortcut and the nearest drop
// cell also contains a shortcut, then create a folder with the two shortcuts.
@@ -2418,7 +2415,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]);
float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
float targetCellDistance = mDragTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
manageFolderFeedback(targetCellDistance, d);
@@ -2431,8 +2428,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
item.spanX, item.spanY, d);
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
&& !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
mLastReorderY != reorderY)) {
&& !mReorderAlarm.alarmPending()
&& (mLastReorderX != reorderX || mLastReorderY != reorderY)
&& targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell)) {
int[] resultSpan = new int[2];
mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
@@ -2529,7 +2527,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
}
private void manageFolderFeedback(float distance, DragObject dragObject) {
if (distance > mMaxDistanceForFolderCreation) {
if (distance > mDragTargetLayout.getFolderCreationRadius(mTargetCell)) {
if ((mDragMode == DRAG_MODE_ADD_TO_FOLDER
|| mDragMode == DRAG_MODE_CREATE_FOLDER)) {
setDragMode(DRAG_MODE_NONE);
@@ -2674,8 +2672,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
cellLayout, mTargetCell);
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
mDragViewVisualCenter[1], mTargetCell);
float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (willCreateUserFolder(d.dragInfo, cellLayout, mTargetCell, distance, true)
|| willAddToExistingUserFolder(
d.dragInfo, cellLayout, mTargetCell, distance)) {
@@ -2774,8 +2772,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
if (touchXY != null) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
cellLayout, mTargetCell);
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
mDragViewVisualCenter[1], mTargetCell);
float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, distance,
true, d)) {
return;
@@ -72,6 +72,7 @@ public final class FeatureFlags {
"PROMISE_APPS_NEW_INSTALLS", true,
"Adds a promise icon to the home screen for new install sessions.");
// TODO: b/206508141: Long pressing on some icons on home screen cause launcher to crash.
public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
"ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
+30 -21
View File
@@ -77,44 +77,45 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
extends AbstractFloatingView {
// Duration values (ms) for popup open and close animations.
private static final int OPEN_DURATION = 276;
private static final int OPEN_FADE_START_DELAY = 0;
private static final int OPEN_FADE_DURATION = 38;
private static final int OPEN_CHILD_FADE_START_DELAY = 38;
private static final int OPEN_CHILD_FADE_DURATION = 76;
protected int OPEN_DURATION = 276;
protected int OPEN_FADE_START_DELAY = 0;
protected int OPEN_FADE_DURATION = 38;
protected int OPEN_CHILD_FADE_START_DELAY = 38;
protected int OPEN_CHILD_FADE_DURATION = 76;
private static final int CLOSE_DURATION = 200;
private static final int CLOSE_FADE_START_DELAY = 140;
private static final int CLOSE_FADE_DURATION = 50;
private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
private static final int CLOSE_CHILD_FADE_DURATION = 140;
protected int CLOSE_DURATION = 200;
protected int CLOSE_FADE_START_DELAY = 140;
protected int CLOSE_FADE_DURATION = 50;
protected int CLOSE_CHILD_FADE_START_DELAY = 0;
protected int CLOSE_CHILD_FADE_DURATION = 140;
// Index used to get background color when using local wallpaper color extraction,
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_800;
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
private final Rect mTempRect = new Rect();
protected final Rect mTempRect = new Rect();
protected final LayoutInflater mInflater;
private final float mOutlineRadius;
protected final float mOutlineRadius;
protected final T mActivityContext;
protected final boolean mIsRtl;
private final int mArrowOffsetVertical;
private final int mArrowOffsetHorizontal;
private final int mArrowWidth;
private final int mArrowHeight;
private final int mArrowPointRadius;
private final View mArrow;
protected final int mArrowOffsetVertical;
protected final int mArrowOffsetHorizontal;
protected final int mArrowWidth;
protected final int mArrowHeight;
protected final int mArrowPointRadius;
protected final View mArrow;
private final int mMargin;
protected boolean mIsLeftAligned;
protected boolean mIsAboveIcon;
private int mGravity;
protected int mGravity;
protected AnimatorSet mOpenCloseAnimator;
protected boolean mDeferContainerRemoval;
protected boolean shouldScaleArrow = false;
private final GradientDrawable mRoundedTop;
private final GradientDrawable mRoundedBottom;
@@ -122,10 +123,10 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
private Runnable mOnCloseCallback = () -> { };
// The rect string of the view that the arrow is attached to, in screen reference frame.
private int mArrowColor;
protected int mArrowColor;
protected final List<LocalColorExtractor> mColorExtractors;
private final float mElevation;
protected final float mElevation;
private final int mBackgroundColor;
private final String mIterateChildrenTag;
@@ -729,6 +730,14 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
scale.setInterpolator(interpolator);
animatorSet.play(scale);
if (shouldScaleArrow) {
Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
scaleValues);
arrowScaleAnimator.setDuration(totalDuration);
arrowScaleAnimator.setInterpolator(interpolator);
animatorSet.play(arrowScaleAnimator);
}
fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
return animatorSet;
@@ -78,6 +78,32 @@ public class RoundedArrowDrawable extends Drawable {
mPath.transform(pathTransform);
}
/**
* Constructor for an arrow that points to the left or right.
*
* @param width of the arrow.
* @param height of the arrow.
* @param radius of the tip of the arrow.
* @param isPointingLeft or not.
* @param color to draw the triangle.
*/
public RoundedArrowDrawable(float width, float height, float radius, boolean isPointingLeft,
int color) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
// Make the drawable with the triangle pointing down...
addDownPointingRoundedTriangleToPath(width, height, radius, mPath);
// ... then rotate it to the side it needs to point.
Matrix pathTransform = new Matrix();
pathTransform.setRotate(isPointingLeft ? 90 : -90, width * 0.5f, height * 0.5f);
mPath.transform(pathTransform);
}
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
@@ -429,7 +429,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
@@ -439,13 +439,12 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
splitConfig.visualDividerBounds.height() :
splitConfig.visualDividerBounds.width());
int primaryHeight = primarySnapshotBounds.height();
primaryIconParams.gravity = (isRtl ? START : END) | TOP;
primaryIconView.setTranslationY(primaryHeight - primaryIconView.getHeight() / 2f);
primaryIconView.setTranslationY(primarySnapshotHeight - primaryIconView.getHeight() / 2f);
primaryIconView.setTranslationX(0);
secondaryIconParams.gravity = (isRtl ? START : END) | TOP;
secondaryIconView.setTranslationY(primaryHeight + taskIconHeight + dividerBar);
secondaryIconView.setTranslationY(primarySnapshotHeight + taskIconHeight + dividerBar);
secondaryIconView.setTranslationX(0);
primaryIconView.setLayoutParams(primaryIconParams);
secondaryIconView.setLayoutParams(secondaryIconParams);
@@ -152,7 +152,7 @@ public interface PagedOrientationHandler {
void setIconAndSnapshotParams(View iconView, int taskIconMargin, int taskIconHeight,
FrameLayout.LayoutParams snapshotParams, boolean isRtl);
void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
/*
@@ -523,7 +523,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
@@ -533,15 +533,12 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
splitConfig.visualDividerBounds.height() :
splitConfig.visualDividerBounds.width());
int primaryWidth = primarySnapshotBounds.width();
if (deviceProfile.isLandscape) {
primaryIconParams.gravity = TOP | START;
primaryIconView.setTranslationX(primaryWidth - primaryIconView.getWidth());
primaryIconView.setTranslationX(primarySnapshotWidth - primaryIconView.getWidth());
primaryIconView.setTranslationY(0);
secondaryIconParams.gravity = TOP | START;
secondaryIconView.setTranslationX(primaryWidth + dividerBar);
secondaryIconView.setTranslationY(0);
secondaryIconView.setTranslationX(primarySnapshotWidth + dividerBar);
} else {
primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
primaryIconView.setTranslationX(-(primaryIconView.getWidth()) / 2f);
@@ -549,8 +546,8 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
secondaryIconView.setTranslationX(secondaryIconView.getWidth() / 2f);
secondaryIconView.setTranslationY(0);
}
secondaryIconView.setTranslationY(0);
primaryIconView.setLayoutParams(primaryIconParams);
secondaryIconView.setLayoutParams(secondaryIconParams);
}
@@ -132,10 +132,10 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
super.setSplitIconParams(primaryIconView, secondaryIconView, taskIconHeight,
primarySnapshotBounds, secondarySnapshotBounds, isRtl, deviceProfile, splitConfig);
primarySnapshotWidth, primarySnapshotHeight, isRtl, deviceProfile, splitConfig);
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
FrameLayout.LayoutParams secondaryIconParams =
@@ -25,11 +25,15 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Size;
@@ -40,6 +44,7 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -60,6 +65,9 @@ public class DatabaseWidgetPreviewLoader {
private final Context mContext;
private final float mPreviewBoxCornerRadius;
private final UserHandle mMyUser = Process.myUserHandle();
private final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
public DatabaseWidgetPreviewLoader(Context context) {
mContext = context;
float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
@@ -100,6 +108,52 @@ public class DatabaseWidgetPreviewLoader {
}
}
/**
* Returns a drawable that can be used as a badge for the user or null.
*/
// @UiThread
public Drawable getBadgeForUser(UserHandle user, int badgeSize) {
if (mMyUser.equals(user)) {
return null;
}
Bitmap badgeBitmap = getUserBadge(user, badgeSize);
FastBitmapDrawable d = new FastBitmapDrawable(badgeBitmap);
d.setFilterBitmap(true);
d.setBounds(0, 0, badgeBitmap.getWidth(), badgeBitmap.getHeight());
return d;
}
private Bitmap getUserBadge(UserHandle user, int badgeSize) {
synchronized (mUserBadges) {
Bitmap badgeBitmap = mUserBadges.get(user);
if (badgeBitmap != null) {
return badgeBitmap;
}
final Resources res = mContext.getResources();
badgeBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888);
Drawable drawable = mContext.getPackageManager().getUserBadgedDrawableForDensity(
new BitmapDrawable(res, badgeBitmap), user,
new Rect(0, 0, badgeSize, badgeSize),
0);
if (drawable instanceof BitmapDrawable) {
badgeBitmap = ((BitmapDrawable) drawable).getBitmap();
} else {
badgeBitmap.eraseColor(Color.TRANSPARENT);
Canvas c = new Canvas(badgeBitmap);
drawable.setBounds(0, 0, badgeSize, badgeSize);
drawable.draw(c);
c.setBitmap(null);
}
mUserBadges.put(user, badgeBitmap);
return badgeBitmap;
}
}
/**
* Generates the widget preview from either the {@link WidgetManagerHelper} or cache
* and add badge at the bottom right corner.
@@ -36,6 +36,7 @@ import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
@@ -47,6 +48,7 @@ import com.android.launcher3.CheckLongPressHelper;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.RoundDrawableWrapper;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -111,6 +113,7 @@ public class WidgetCell extends LinearLayout {
private FrameLayout mWidgetImageContainer;
private WidgetImageView mWidgetImage;
private ImageView mWidgetBadge;
private TextView mWidgetName;
private TextView mWidgetDims;
private TextView mWidgetDescription;
@@ -166,6 +169,7 @@ public class WidgetCell extends LinearLayout {
mWidgetImageContainer = findViewById(R.id.widget_preview_container);
mWidgetImage = findViewById(R.id.widget_preview);
mWidgetBadge = findViewById(R.id.widget_badge);
mWidgetName = findViewById(R.id.widget_name);
mWidgetDims = findViewById(R.id.widget_dims);
mWidgetDescription = findViewById(R.id.widget_description);
@@ -195,6 +199,8 @@ public class WidgetCell extends LinearLayout {
mWidgetImage.animate().cancel();
mWidgetImage.setDrawable(null);
mWidgetImage.setVisibility(View.VISIBLE);
mWidgetBadge.setImageDrawable(null);
mWidgetBadge.setVisibility(View.GONE);
mWidgetName.setText(null);
mWidgetDims.setText(null);
mWidgetDescription.setText(null);
@@ -349,6 +355,7 @@ public class WidgetCell extends LinearLayout {
mAppWidgetHostViewPreview = null;
}
}
if (mAnimatePreview) {
mWidgetImageContainer.setAlpha(0f);
ViewPropertyAnimator anim = mWidgetImageContainer.animate();
@@ -362,6 +369,20 @@ public class WidgetCell extends LinearLayout {
}
}
/** Used to show the badge when the widget is in the recommended section
*/
public void showBadge() {
Drawable badge = mWidgetPreviewLoader.getBadgeForUser(mItem.user,
BaseIconFactory.getBadgeSizeForIconSize(
mActivity.getDeviceProfile().allAppsIconSizePx));
if (badge == null) {
mWidgetBadge.setVisibility(View.GONE);
} else {
mWidgetBadge.setVisibility(View.VISIBLE);
mWidgetBadge.setImageDrawable(badge);
}
}
private void setContainerSize(int width, int height) {
LayoutParams layoutParams = (LayoutParams) mWidgetImageContainer.getLayoutParams();
layoutParams.width = width;
@@ -109,6 +109,7 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
for (WidgetItem widgetItem : widgetItems) {
WidgetCell widgetCell = addItemCell(tableRow);
widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
widgetCell.showBadge();
}
addView(tableRow);
}
@@ -41,7 +41,7 @@ public class TestStabilityRule implements TestRule {
Pattern.compile("^("
+ "(?<local>(BuildFromAndroidStudio|"
+ "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|"
+ "(?<platform>[A-Z]([a-z]|[0-9])*)"
+ "(?<platform>([A-Z][a-z]*[0-9]*|[0-9]+)*)"
+ ")$");
private static final Pattern PLATFORM_BUILD =
Pattern.compile("^("