diff --git a/go/quickstep/res/drawable/round_rect_dialog.xml b/go/quickstep/res/drawable/round_rect_dialog.xml
new file mode 100644
index 0000000000..bbb7c5b545
--- /dev/null
+++ b/go/quickstep/res/drawable/round_rect_dialog.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml b/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml
new file mode 100644
index 0000000000..db1531ac58
--- /dev/null
+++ b/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/go/quickstep/res/values-land/dimens.xml b/go/quickstep/res/values-land/dimens.xml
new file mode 100644
index 0000000000..50970162cd
--- /dev/null
+++ b/go/quickstep/res/values-land/dimens.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ 360dp
+ 168dp
+
diff --git a/go/quickstep/res/values/attrs.xml b/go/quickstep/res/values/attrs.xml
index 03eab50d32..cdbdc2afe7 100644
--- a/go/quickstep/res/values/attrs.xml
+++ b/go/quickstep/res/values/attrs.xml
@@ -19,4 +19,6 @@
+
+
\ No newline at end of file
diff --git a/go/quickstep/res/values/colors.xml b/go/quickstep/res/values/colors.xml
index ae72ef63dc..8034be217d 100644
--- a/go/quickstep/res/values/colors.xml
+++ b/go/quickstep/res/values/colors.xml
@@ -20,4 +20,7 @@
#F8F9FA
#70FFFFFF
#474747
+
+ #FFFFFF
+ #424242
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
index 55cd138f12..0a7ac4563d 100644
--- a/go/quickstep/res/values/dimens.xml
+++ b/go/quickstep/res/values/dimens.xml
@@ -28,4 +28,12 @@
0dp
24dp
28dp
+
+
+ 288dp
+ 24dp
+ 8dp
+ 12dp
+ 8dp
+ 216dp
diff --git a/go/quickstep/res/values/strings.xml b/go/quickstep/res/values/strings.xml
index 61c8cd9343..6e9e63e3c2 100644
--- a/go/quickstep/res/values/strings.xml
+++ b/go/quickstep/res/values/strings.xml
@@ -11,4 +11,13 @@
Translate
Lens
+
+
+ Translate or listen to text on screen
+
+ Information such as text on your screen, web addresses, and screenshots may be shared with Google.\n\nTo change what information you share, go to Settings > Apps > Default apps > Digital assistant app.
+
+ CANCEL
+
+ GOT IT
diff --git a/go/quickstep/res/values/styles.xml b/go/quickstep/res/values/styles.xml
index ffe8f4607d..561531b623 100644
--- a/go/quickstep/res/values/styles.xml
+++ b/go/quickstep/res/values/styles.xml
@@ -20,12 +20,14 @@
- @color/go_overview_text_color
- @color/go_overview_text_color
- @color/go_overview_button_color
+ - @color/go_modal_dialog_background
@@ -56,4 +58,33 @@
- wrap_content
- vertical
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index b823c36501..37f535200a 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -20,20 +20,31 @@ import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBN
import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED;
import android.annotation.SuppressLint;
+import android.app.AlertDialog;
import android.app.assist.AssistContent;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
import android.graphics.Matrix;
+import android.graphics.drawable.ColorDrawable;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.quickstep.util.AssistContentRequester;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.TaskThumbnailView;
@@ -53,6 +64,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code";
public static final int ERROR_PERMISSIONS_STRUCTURE = 1;
public static final int ERROR_PERMISSIONS_SCREENSHOT = 2;
+ private static final String NIU_ACTIONS_CONFIRMED = "launcher_go.niu_actions_confirmed";
private static final String TAG = "TaskOverlayFactoryGo";
private AssistContentRequester mContentRequester;
@@ -79,6 +91,9 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
private boolean mAssistStructurePermitted;
private boolean mAssistScreenshotPermitted;
private AssistContentRequester mFactoryContentRequester;
+ private SharedPreferences mSharedPreferences;
+ private String mPreviousAction;
+ private AlertDialog mConfirmationDialog;
private TaskOverlayGo(TaskThumbnailView taskThumbnailView,
AssistContentRequester assistContentRequester) {
@@ -92,6 +107,12 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
@Override
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix,
boolean rotated) {
+ if (mConfirmationDialog != null && mConfirmationDialog.isShowing()) {
+ // Redraw the dialog in case the layout changed
+ mConfirmationDialog.dismiss();
+ showConfirmationDialog();
+ }
+
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
checkSettings();
if (thumbnail == null || TextUtils.isEmpty(mNIUPackageName)) {
@@ -105,6 +126,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot() && !isManagedProfileTask;
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
mTaskPackageName = task.key.getPackageName();
+ mSharedPreferences = Utilities.getPrefs(mApplicationContext);
if (!mAssistStructurePermitted || !mAssistScreenshotPermitted) {
return;
@@ -131,6 +153,12 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
* Creates and sends an Intent corresponding to the button that was clicked
*/
private void sendNIUIntent(String actionType) {
+ if (!mSharedPreferences.getBoolean(NIU_ACTIONS_CONFIRMED, false)) {
+ mPreviousAction = actionType;
+ showConfirmationDialog();
+ return;
+ }
+
Intent intent = createNIUIntent(actionType);
// Only add and send the image if the appropriate permissions are held
if (mAssistStructurePermitted && mAssistScreenshotPermitted) {
@@ -218,6 +246,35 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
public void setImageActionsAPI(ImageActionsApi imageActionsApi) {
mImageApi = imageActionsApi;
}
+
+ private void showConfirmationDialog() {
+ BaseDraggingActivity activity = BaseActivity.fromContext(getActionsView().getContext());
+ LayoutInflater inflater = LayoutInflater.from(activity);
+ View view = inflater.inflate(R.layout.niu_actions_confirmation_dialog, /* root */ null);
+
+ Button acceptButton = view.findViewById(R.id.niu_actions_confirmation_accept);
+ acceptButton.setOnClickListener(this::onNiuActionsConfirmationAccept);
+
+ Button rejectButton = view.findViewById(R.id.niu_actions_confirmation_reject);
+ rejectButton.setOnClickListener(this::onNiuActionsConfirmationReject);
+
+ mConfirmationDialog = new AlertDialog.Builder(activity)
+ .setView(view)
+ .create();
+ mConfirmationDialog.getWindow()
+ .setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ mConfirmationDialog.show();
+ }
+
+ private void onNiuActionsConfirmationAccept(View v) {
+ mConfirmationDialog.dismiss();
+ mSharedPreferences.edit().putBoolean(NIU_ACTIONS_CONFIRMED, true).apply();
+ sendNIUIntent(mPreviousAction);
+ }
+
+ private void onNiuActionsConfirmationReject(View v) {
+ mConfirmationDialog.cancel();
+ }
}
/**
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 475b5bead0..6d49d75953 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -141,6 +141,9 @@ enum Attribute {
ALL_APPS_SEARCH_RESULT_NAVVYSITE = 25;
ALL_APPS_SEARCH_RESULT_TIPS = 26;
ALL_APPS_SEARCH_RESULT_PEOPLE_TILE = 27;
+
+ WIDGETS_BOTTOM_TRAY = 28;
+ WIDGETS_TRAY_PREDICTION = 29;
}
// Main app icons
diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml
index 656c59669c..f718b8b64b 100644
--- a/quickstep/res/drawable/ic_all_set.xml
+++ b/quickstep/res/drawable/ic_all_set.xml
@@ -14,10 +14,10 @@
limitations under the License.
-->
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index a2c0a7dee9..9b402e3cb5 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -114,8 +114,8 @@
40dp
- 28dp
- 80dp
+ 24dp
+ 32dp
52dp
24dp
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index f8cfe173ec..ebf8fb79d7 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -725,7 +725,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
floatingIconBounds.bottom += offsetY;
if (initOnly) {
- floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f,
+ // For the init pass, we want full alpha since the window is not yet ready.
+ floatingView.update(1f, 255, floatingIconBounds, percent, 0f,
mWindowRadius.value * scale, true /* isOpening */);
return;
}
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index 22a8c9b1d0..3d891e8748 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.model;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
+
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.text.TextUtils;
@@ -73,7 +75,9 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask {
if (notAddedWidgets.size() > 0) {
// Even an apps have more than one widgets, we only include one widget.
fixedContainerItems.items.add(
- new PendingAddWidgetInfo(notAddedWidgets.get(0).widgetInfo));
+ new PendingAddWidgetInfo(
+ notAddedWidgets.get(0).widgetInfo,
+ CONTAINER_WIDGETS_PREDICTION));
}
}
}
@@ -90,7 +94,9 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask {
new ComponentName(app.getPackageName(), app.getClassName()), app.getUser());
if (widgetItems.containsKey(targetWidget)) {
fixedContainerItems.items.add(
- new PendingAddWidgetInfo(widgetItems.get(targetWidget).widgetInfo));
+ new PendingAddWidgetInfo(widgetItems.get(
+ targetWidget).widgetInfo,
+ CONTAINER_WIDGETS_PREDICTION));
}
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 99ad8c0b9d..6d81bcf31b 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -61,6 +61,7 @@ import android.content.Intent;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
@@ -383,10 +384,10 @@ public abstract class AbsSwipeUpHandler,
// Set up a entire animation lifecycle callback to notify the current recents view when
// the animation is canceled
mGestureState.runOnceAtState(STATE_RECENTS_ANIMATION_CANCELED, () -> {
- ThumbnailData snapshot = mGestureState.getRecentsAnimationCanceledSnapshot();
+ ThumbnailData snapshot = mGestureState.consumeRecentsAnimationCanceledSnapshot();
if (snapshot != null) {
- RecentsModel.INSTANCE.get(mContext).onTaskSnapshotChanged(
- mRecentsView.getRunningTaskId(), snapshot);
+ mRecentsView.switchToScreenshot(snapshot,
+ () -> mRecentsAnimationController.cleanupScreenshot());
mRecentsView.onRecentsAnimationComplete();
}
});
@@ -1234,30 +1235,40 @@ public abstract class AbsSwipeUpHandler,
final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState();
final int windowRotation = orientationState.getDisplayRotation();
final int homeRotation = orientationState.getRecentsActivityRotation();
+
+ final Matrix homeToWindowPositionMap = new Matrix();
+ final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
+ // Move the startRect to Launcher space as floatingIconView runs in Launcher
+ final Matrix windowToHomePositionMap = new Matrix();
+ homeToWindowPositionMap.invert(windowToHomePositionMap);
+ windowToHomePositionMap.mapRect(startRect);
+
final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
.startSwipePipToHome(taskInfo.topActivity,
TaskInfoCompat.getTopActivityInfo(taskInfo),
runningTaskTarget.taskInfo.pictureInPictureParams,
homeRotation,
mDp.hotseatBarSizePx);
- final SwipePipToHomeAnimator swipePipToHomeAnimator = new SwipePipToHomeAnimator(
- mContext,
- runningTaskTarget.taskId,
- taskInfo.topActivity,
- runningTaskTarget.leash.getSurfaceControl(),
- TaskInfoCompat.getPipSourceRectHint(
- runningTaskTarget.taskInfo.pictureInPictureParams),
- TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
- updateProgressForStartRect(new Matrix(), startProgress),
- destinationBounds,
- mRecentsView.getPipCornerRadius(),
- mRecentsView);
+ final SwipePipToHomeAnimator.Builder builder = new SwipePipToHomeAnimator.Builder()
+ .setContext(mContext)
+ .setTaskId(runningTaskTarget.taskId)
+ .setComponentName(taskInfo.topActivity)
+ .setLeash(runningTaskTarget.leash.getSurfaceControl())
+ .setSourceRectHint(TaskInfoCompat.getPipSourceRectHint(
+ runningTaskTarget.taskInfo.pictureInPictureParams))
+ .setAppBounds(TaskInfoCompat.getWindowConfigurationBounds(taskInfo))
+ .setHomeToWindowPositionMap(homeToWindowPositionMap)
+ .setStartBounds(startRect)
+ .setDestinationBounds(destinationBounds)
+ .setCornerRadius(mRecentsView.getPipCornerRadius())
+ .setAttachedView(mRecentsView);
// We would assume home and app window always in the same rotation While homeRotation
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
if (homeRotation == ROTATION_0
&& (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
- swipePipToHomeAnimator.setFromRotation(mTaskViewSimulator, windowRotation);
+ builder.setFromRotation(mTaskViewSimulator, windowRotation);
}
+ final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
AnimatorPlaybackController activityAnimationToHome =
homeAnimFactory.createActivityAnimationToHome();
swipePipToHomeAnimator.addAnimatorListener(new AnimatorListenerAdapter() {
@@ -1284,6 +1295,7 @@ public abstract class AbsSwipeUpHandler,
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
}
});
+ setupWindowAnimation(swipePipToHomeAnimator);
return swipePipToHomeAnimator;
}
@@ -1314,6 +1326,11 @@ public abstract class AbsSwipeUpHandler,
HomeAnimationFactory homeAnimationFactory) {
RectFSpringAnim anim =
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
+ setupWindowAnimation(anim);
+ return anim;
+ }
+
+ private void setupWindowAnimation(RectFSpringAnim anim) {
anim.addOnUpdateListener((v, r, p) -> {
updateSysUiFlags(Math.max(p, mCurrentShift.value));
});
@@ -1331,7 +1348,6 @@ public abstract class AbsSwipeUpHandler,
if (mRecentsAnimationTargets != null) {
mRecentsAnimationTargets.addReleaseCheck(anim);
}
- return anim;
}
public void onConsumerAboutToBeSwitched() {
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index a302a07bca..015002f0e1 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -376,11 +376,14 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
}
/**
- * Returns the canceled animation thumbnail data. This call only returns a value while
- * STATE_RECENTS_ANIMATION_CANCELED state is being set.
+ * Returns and clears the canceled animation thumbnail data. This call only returns a value
+ * while STATE_RECENTS_ANIMATION_CANCELED state is being set, and the caller is responsible for
+ * calling {@link RecentsAnimationController#cleanupScreenshot()}.
*/
- ThumbnailData getRecentsAnimationCanceledSnapshot() {
- return mRecentsAnimationCanceledSnapshot;
+ ThumbnailData consumeRecentsAnimationCanceledSnapshot() {
+ ThumbnailData data = mRecentsAnimationCanceledSnapshot;
+ mRecentsAnimationCanceledSnapshot = null;
+ return data;
}
void setSwipeUpStartTimeMs(long uptimeMs) {
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index bb5e493cde..ae2328e643 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -95,7 +95,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
@UiThread
public RecentsAnimationCallbacks startRecentsAnimation(GestureState gestureState,
Intent intent, RecentsAnimationCallbacks.RecentsAnimationListener listener) {
- Log.d("b/186444448", "startRecentsAnimation");
// Notify if recents animation is still running
if (mController != null) {
String msg = "New recents animation started before old animation completed";
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index b1c9ed0361..6575996d69 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -130,7 +130,8 @@ public class StatsLogCompatManager extends StatsLogManager {
info.getAttribute().getNumber() /* origin */,
getCardinality(info) /* cardinality */,
info.getWidget().getSpanX(),
- info.getWidget().getSpanY());
+ info.getWidget().getSpanY(),
+ getFeatures(info));
}
/**
@@ -365,15 +366,12 @@ public class StatsLogCompatManager extends StatsLogManager {
atomInfo.getFolderIcon().getFromLabelState().getNumber() /* fromState */,
atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */,
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
- getCardinality(atomInfo) /* cardinality */);
+ getCardinality(atomInfo) /* cardinality */,
+ getFeatures(atomInfo) /* features */);
}
}
private static int getCardinality(LauncherAtom.ItemInfo info) {
- // TODO(b/187734511): Implement a unified solution for 1x1 widgets in folders/hotseat.
- if (info.getItemCase().equals(LauncherAtom.ItemInfo.ItemCase.WIDGET)) {
- return info.getWidget().getWidgetFeatures();
- }
switch (info.getContainerInfo().getContainerCase()) {
case PREDICTED_HOTSEAT_CONTAINER:
return info.getContainerInfo().getPredictedHotseatContainer().getCardinality();
@@ -514,6 +512,13 @@ public class StatsLogCompatManager extends StatsLogManager {
}
}
+ private static int getFeatures(LauncherAtom.ItemInfo info) {
+ if (info.getItemCase().equals(LauncherAtom.ItemInfo.ItemCase.WIDGET)) {
+ return info.getWidget().getWidgetFeatures();
+ }
+ return 0;
+ }
+
/**
* Interface to get stats log while it is dispatched to the system
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index 67a635b70b..7488649eb7 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -56,7 +56,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
private final ComponentName mComponentName;
private final SurfaceControl mLeash;
private final Rect mAppBounds = new Rect();
+ private final Matrix mHomeToWindowPositionMap = new Matrix();
private final Rect mStartBounds = new Rect();
+ private final RectF mCurrentBoundsF = new RectF();
private final Rect mCurrentBounds = new Rect();
private final Rect mDestinationBounds = new Rect();
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
@@ -66,10 +68,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
private final Rect mSourceHintRectInsets;
private final Rect mSourceInsets = new Rect();
- /** for rotation via {@link #setFromRotation(TaskViewSimulator, int)} */
- private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0;
+ /** for rotation calculations */
+ private final @RecentsOrientedState.SurfaceRotation int mFromRotation;
private final Rect mDestinationBoundsTransformed = new Rect();
- private final Rect mDestinationBoundsAnimation = new Rect();
/**
* Flag to avoid the double-end problem since the leash would have been released
@@ -91,31 +92,39 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
* @param leash {@link SurfaceControl} this animator operates on
* @param sourceRectHint See the definition in {@link android.app.PictureInPictureParams}
* @param appBounds Bounds of the application, sourceRectHint is based on this bounds
+ * @param homeToWindowPositionMap {@link Matrix} to map a Rect from home to window space
* @param startBounds Bounds of the application when this animator starts. This can be
* different from the appBounds if user has swiped a certain distance and
* Launcher has performed transform on the leash.
* @param destinationBounds Bounds of the destination this animator ends to
+ * @param fromRotation From rotation if different from final rotation, ROTATION_0 otherwise
+ * @param destinationBoundsTransformed Destination bounds in window space
* @param cornerRadius Corner radius in pixel value for PiP window
+ * @param view Attached view for logging purpose
*/
- public SwipePipToHomeAnimator(@NonNull Context context,
+ private SwipePipToHomeAnimator(@NonNull Context context,
int taskId,
@NonNull ComponentName componentName,
@NonNull SurfaceControl leash,
@Nullable Rect sourceRectHint,
@NonNull Rect appBounds,
+ @NonNull Matrix homeToWindowPositionMap,
@NonNull RectF startBounds,
@NonNull Rect destinationBounds,
+ @RecentsOrientedState.SurfaceRotation int fromRotation,
+ @NonNull Rect destinationBoundsTransformed,
int cornerRadius,
@NonNull View view) {
- super(startBounds, new RectF(destinationBounds), context);
+ super(startBounds, new RectF(destinationBoundsTransformed), context);
mTaskId = taskId;
mComponentName = componentName;
mLeash = leash;
mAppBounds.set(appBounds);
+ mHomeToWindowPositionMap.set(homeToWindowPositionMap);
startBounds.round(mStartBounds);
mDestinationBounds.set(destinationBounds);
- mDestinationBoundsTransformed.set(mDestinationBounds);
- mDestinationBoundsAnimation.set(mDestinationBounds);
+ mFromRotation = fromRotation;
+ mDestinationBoundsTransformed.set(destinationBoundsTransformed);
mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius);
if (sourceRectHint != null && (sourceRectHint.width() < destinationBounds.width()
@@ -191,37 +200,13 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
addOnUpdateListener(this::onAnimationUpdate);
}
- /** sets the from rotation if it's different from the target rotation. */
- public void setFromRotation(TaskViewSimulator taskViewSimulator,
- @RecentsOrientedState.SurfaceRotation int fromRotation) {
- if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) {
- Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation);
- return;
- }
- mFromRotation = fromRotation;
- final Matrix matrix = new Matrix();
- taskViewSimulator.applyWindowToHomeRotation(matrix);
-
- // map the destination bounds into window space. mDestinationBounds is always calculated
- // in the final home space and the animation runs in original window space.
- final RectF transformed = new RectF(mDestinationBounds);
- matrix.mapRect(transformed, new RectF(mDestinationBounds));
- transformed.round(mDestinationBoundsTransformed);
-
- // set the animation destination bounds for RectEvaluator calculation.
- // bounds and insets are calculated as if the transition is from mAppBounds to
- // mDestinationBoundsAnimation, separated from rotate / scale / position.
- mDestinationBoundsAnimation.set(mAppBounds.left, mAppBounds.top,
- mAppBounds.left + mDestinationBounds.width(),
- mAppBounds.top + mDestinationBounds.height());
- }
-
private void onAnimationUpdate(@Nullable AppCloseConfig values, RectF currentRect,
float progress) {
if (mHasAnimationEnded) return;
final SurfaceControl.Transaction tx =
PipSurfaceTransactionHelper.newSurfaceControlTransaction();
- onAnimationUpdate(tx, currentRect, progress);
+ mHomeToWindowPositionMap.mapRect(mCurrentBoundsF, currentRect);
+ onAnimationUpdate(tx, mCurrentBoundsF, progress);
tx.apply();
}
@@ -309,6 +294,108 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
return new RotatedPosition(degree, positionX, positionY);
}
+ /** Builder class for {@link SwipePipToHomeAnimator} */
+ public static class Builder {
+ private Context mContext;
+ private int mTaskId;
+ private ComponentName mComponentName;
+ private SurfaceControl mLeash;
+ private Rect mSourceRectHint;
+ private Rect mAppBounds;
+ private Matrix mHomeToWindowPositionMap;
+ private RectF mStartBounds;
+ private Rect mDestinationBounds;
+ private int mCornerRadius;
+ private View mAttachedView;
+ private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0;
+ private final Rect mDestinationBoundsTransformed = new Rect();
+
+ public Builder setContext(Context context) {
+ mContext = context;
+ return this;
+ }
+
+ public Builder setTaskId(int taskId) {
+ mTaskId = taskId;
+ return this;
+ }
+
+ public Builder setComponentName(ComponentName componentName) {
+ mComponentName = componentName;
+ return this;
+ }
+
+ public Builder setLeash(SurfaceControl leash) {
+ mLeash = leash;
+ return this;
+ }
+
+ public Builder setSourceRectHint(Rect sourceRectHint) {
+ mSourceRectHint = new Rect(sourceRectHint);
+ return this;
+ }
+
+ public Builder setAppBounds(Rect appBounds) {
+ mAppBounds = new Rect(appBounds);
+ return this;
+ }
+
+ public Builder setHomeToWindowPositionMap(Matrix homeToWindowPositionMap) {
+ mHomeToWindowPositionMap = new Matrix(homeToWindowPositionMap);
+ return this;
+ }
+
+ public Builder setStartBounds(RectF startBounds) {
+ mStartBounds = new RectF(startBounds);
+ return this;
+ }
+
+ public Builder setDestinationBounds(Rect destinationBounds) {
+ mDestinationBounds = new Rect(destinationBounds);
+ return this;
+ }
+
+ public Builder setCornerRadius(int cornerRadius) {
+ mCornerRadius = cornerRadius;
+ return this;
+ }
+
+ public Builder setAttachedView(View attachedView) {
+ mAttachedView = attachedView;
+ return this;
+ }
+
+ public Builder setFromRotation(TaskViewSimulator taskViewSimulator,
+ @RecentsOrientedState.SurfaceRotation int fromRotation) {
+ if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) {
+ Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation);
+ return this;
+ }
+ final Matrix matrix = new Matrix();
+ taskViewSimulator.applyWindowToHomeRotation(matrix);
+
+ // map the destination bounds into window space. mDestinationBounds is always calculated
+ // in the final home space and the animation runs in original window space.
+ final RectF transformed = new RectF(mDestinationBounds);
+ matrix.mapRect(transformed, new RectF(mDestinationBounds));
+ transformed.round(mDestinationBoundsTransformed);
+
+ mFromRotation = fromRotation;
+ return this;
+ }
+
+ public SwipePipToHomeAnimator build() {
+ if (mDestinationBoundsTransformed.isEmpty()) {
+ mDestinationBoundsTransformed.set(mDestinationBounds);
+ }
+ return new SwipePipToHomeAnimator(mContext, mTaskId, mComponentName, mLeash,
+ mSourceRectHint, mAppBounds,
+ mHomeToWindowPositionMap, mStartBounds, mDestinationBounds,
+ mFromRotation, mDestinationBoundsTransformed,
+ mCornerRadius, mAttachedView);
+ }
+ }
+
private static class RotatedPosition {
private final float degree;
private final float positionX;
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 0e6ce87042..7eee415315 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -17,7 +17,6 @@ package com.android.quickstep.util;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
-import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
@@ -62,7 +61,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
private final boolean mIsRecentsRtl;
private final Rect mTaskRect = new Rect();
- private boolean mDrawsBelowRecents;
private final PointF mPivot = new PointF();
private DeviceProfile mDp;
@@ -163,10 +161,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
recentsViewScroll.value = scroll;
}
- public void setDrawsBelowRecents(boolean drawsBelowRecents) {
- mDrawsBelowRecents = drawsBelowRecents;
- }
-
/**
* Adds animation for all the components corresponding to transition from an app to overview.
*/
@@ -301,12 +295,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
builder.withMatrix(mMatrix)
.withWindowCrop(mTmpCropRect)
.withCornerRadius(getCurrentCornerRadius());
-
- if (LIVE_TILE.get() && params.getRecentsSurface() != null) {
- // When relativeLayer = 0, it reverts the surfaces back to the original order.
- builder.withRelativeLayerTo(params.getRecentsSurface(),
- mDrawsBelowRecents ? Integer.MIN_VALUE : 0);
- }
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index 22ce9421f7..88b11a0884 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -152,6 +152,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
RectF widgetBackgroundPosition, Size windowSize, float windowCornerRadius,
boolean appTargetIsTranslucent, int fallbackBackgroundColor) {
mAppWidgetView = originalView;
+ // Deferrals must begin before GhostView is created. See b/190818220
mAppWidgetView.beginDeferringUpdates();
mBackgroundPosition = widgetBackgroundPosition;
mAppTargetIsTranslucent = appTargetIsTranslucent;
@@ -240,6 +241,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
((ViewGroup) dragLayer.getParent()).removeView(this);
dragLayer.removeView(mListenerView);
mBackgroundView.finish();
+ // Removing GhostView must occur before ending deferrals. See b/190818220
mAppWidgetView.endDeferringUpdates();
recycle();
mLauncher.getViewCache().recycleView(R.layout.floating_widget_view, this);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index c7924e4da5..a72a205def 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -82,7 +82,6 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -638,7 +637,6 @@ public abstract class RecentsView 0) {
setCurrentPage(indexOfChild(getTaskViewAt(0)));
}
+ } else if (currentTaskId != -1) {
+ currentTaskView = getTaskView(currentTaskId);
+ if (currentTaskView != null) {
+ setCurrentPage(indexOfChild(currentTaskView));
+ }
}
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
@@ -1206,6 +1215,8 @@ public abstract class RecentsView {
setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
mActivity.getDragLayer().recreateControllers();
- updateChildTaskOrientations();
setRecentsChangedOrientation(false).start();
}));
pa.start();
@@ -1742,7 +1750,6 @@ public abstract class RecentsView {
- if (LIVE_TILE.get()) {
- RecentsView recentsView = mTaskView.getRecentsView();
- recentsView.switchToScreenshot(null,
- () -> recentsView.finishRecentsAnimation(true /* toRecents */,
- false /* shouldPip */,
- () -> menuOption.onClick(view)));
- } else {
- menuOption.onClick(view);
- }
- });
+ menuOptionView.setOnClickListener(menuOption::onClick);
mOptionLayout.addView(menuOptionView);
}
private void orientAroundTaskView(TaskView taskView) {
PagedOrientationHandler orientationHandler = taskView.getPagedOrientationHandler();
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
- float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
- orientationHandler.setTaskMenuAroundTaskView(this, taskInsetMargin);
+ orientationHandler.setTaskMenuAroundTaskView(this, mTaskInsetMargin);
mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
@@ -243,9 +239,6 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
setScaleY(taskView.getScaleY());
orientationHandler.setTaskOptionsMenuLayoutOrientation(
mActivity.getDeviceProfile(), mOptionLayout);
- PointF additionalInset = orientationHandler.getAdditionalInsetForTaskMenu(taskInsetMargin);
- insets.left += additionalInset.x;
- insets.top += additionalInset.y;
setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index df195d75b1..ee6b94b4f6 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -84,7 +84,6 @@ public class TaskThumbnailView extends View implements PluginListener showTaskMenu());
+ mIconView.setOnClickListener(v -> {
+ if (LIVE_TILE.get() && isRunningTask()) {
+ RecentsView recentsView = getRecentsView();
+ recentsView.switchToScreenshot(
+ () -> recentsView.finishRecentsAnimation(true /* toRecents */,
+ this::showTaskMenu));
+ } else {
+ showTaskMenu();
+ }
+ });
mIconView.setOnLongClickListener(v -> {
requestDisallowInterceptTouchEvent(true);
return showTaskMenu();
@@ -812,8 +815,6 @@ public class TaskView extends FrameLayout implements Reusable {
}
public void animateIconScaleAndDimIntoView() {
- Log.d("b/186444448", "animateIconScaleAndDimIntoView: startProgress="
- + mIconScaleAnimStartProgress);
if (mIconAndDimAnimator != null) {
mIconAndDimAnimator.cancel();
}
@@ -823,7 +824,6 @@ public class TaskView extends FrameLayout implements Reusable {
mIconAndDimAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- Log.d("b/186444448", "animateIconScaleAndDimIntoView: end");
mIconAndDimAnimator = null;
}
});
diff --git a/res/drawable/work_card.xml b/res/drawable/work_card.xml
index 0e4b05407e..7048955b74 100644
--- a/res/drawable/work_card.xml
+++ b/res/drawable/work_card.xml
@@ -20,8 +20,5 @@
android:shape="rectangle">
-
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 919f1b27cf..84fdfdf3cd 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -22,7 +22,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="@dimen/work_edu_card_margin"
+ android:paddingHorizontal="@dimen/work_card_padding_horizontal"
+ android:paddingVertical="@dimen/work_card_padding_vertical"
android:background="@drawable/work_card"
android:layout_gravity="center_horizontal"
android:gravity="center"
@@ -34,8 +35,7 @@
android:id="@+id/work_apps_paused_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginBottom="@dimen/work_card_padding_vertical"
android:text="@string/work_profile_edu_work_apps"
android:textAlignment="center"
android:textSize="20sp" />
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 02a50cad98..841734c2fc 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -28,18 +28,18 @@
android:layout_marginTop="40dp"
android:text="@string/work_apps_paused_title"
android:textAlignment="center"
- android:textSize="20sp" />
+ android:textSize="22sp" />
+ android:textSize="14sp" />
\ No newline at end of file
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 7183817ed3..04faa15271 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -25,7 +25,7 @@
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp"
android:background="@drawable/work_apps_toggle_background"
- android:drawablePadding="16dp"
+ android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_corp_off"
android:layout_marginBottom="@dimen/work_fab_margin"
android:layout_marginEnd="@dimen/work_fab_margin"
diff --git a/res/raw/downgrade_schema.json b/res/raw/downgrade_schema.json
index 8f1780e5f7..bc25cece2d 100644
--- a/res/raw/downgrade_schema.json
+++ b/res/raw/downgrade_schema.json
@@ -2,8 +2,14 @@
// Note: Comments are not supported in JSON schema, but android parser is lenient.
// Maximum DB version supported by this schema
- "version" : 28,
+ "version" : 29,
+ "downgrade_to_28" : [
+ "ALTER TABLE favorites RENAME TO temp_favorites;",
+ "CREATE TABLE favorites(_id INTEGER PRIMARY KEY, title TEXT, intent TEXT, container INTEGER, screen INTEGER, cellX INTEGER, cellY INTEGER, spanX INTEGER, spanY INTEGER, itemType INTEGER, appWidgetId INTEGER NOT NULL DEFAULT - 1, iconPackage TEXT, iconResource TEXT, icon BLOB, appWidgetProvider TEXT, modified INTEGER NOT NULL DEFAULT 0, restored INTEGER NOT NULL DEFAULT 0, profileId INTEGER DEFAULT 0, rank INTEGER NOT NULL DEFAULT 0, options INTEGER NOT NULL DEFAULT 0);",
+ "INSERT INTO favorites SELECT _id, title, intent, container, screen, cellX, cellY, spanX, spanY, itemType, appWidgetId, iconPackage, iconResource, icon, appWidgetProvider, modified, restored, profileId, rank, options FROM temp_favorites;",
+ "DROP TABLE temp_favorites;"
+ ],
"downgrade_to_27" : [
"CREATE TABLE workspaceScreens (_id INTEGER PRIMARY KEY,screenRank INTEGER,modified INTEGER NOT NULL DEFAULT 0)",
"insert into workspaceScreens (_id, screenRank) select screen as _id, screen as screenRank from favorites where container = -100 group by screen order by screen"
diff --git a/res/values-sw340dp/dimens.xml b/res/values-sw340dp/dimens.xml
index c9f2981f70..33b06f588c 100644
--- a/res/values-sw340dp/dimens.xml
+++ b/res/values-sw340dp/dimens.xml
@@ -19,6 +19,5 @@
20dp
- 16sp
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9891ff5200..a891e65a81 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -121,6 +121,8 @@
48dp
24dp
+ 24dp
+ 32dp
16dp
20dp
16sp
@@ -189,8 +191,9 @@
14dp
- 20sp
+ 16sp
2dp
+ 4dp
30dp
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 09c8b9b45c..a926cb5154 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -258,7 +258,7 @@