Snap for 7514518 from e54f789de9e5aa9d9a158bc7339adb3d6e4e543c to sc-release
Change-Id: I79d6876f65628f815896d798db915d21f3474fa5
diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml
index 656c596..f718b8b 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="42dp"
- android:height="42dp"
- android:viewportWidth="42"
- android:viewportHeight="42">
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"
android:fillColor="#FFFFFF"/>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 28262a8..1f86d62 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -114,8 +114,8 @@
<!-- All Set page -->
<dimen name="allset_page_margin_horizontal">40dp</dimen>
- <dimen name="allset_title_margin_top">28dp</dimen>
- <dimen name="allset_title_icon_margin_top">80dp</dimen>
+ <dimen name="allset_title_margin_top">24dp</dimen>
+ <dimen name="allset_title_icon_margin_top">32dp</dimen>
<dimen name="allset_hint_margin_bottom">52dp</dimen>
<dimen name="allset_subtitle_margin_top">24dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 310e178..5bb76d6 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -725,7 +725,8 @@
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/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 6e7db55..ea4b08d 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -384,10 +384,10 @@
// 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();
}
});
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index a302a07..015002f 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -376,11 +376,14 @@
}
/**
- * 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/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index c1c85de..2bcc229 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -88,6 +88,7 @@
SystemShortcut screenshotShortcut = TaskShortcutFactory.SCREENSHOT
.getShortcut(activity, taskView);
if (screenshotShortcut != null) {
+ screenshotShortcut.setHasFinishRecentsInAction(true);
shortcuts.add(screenshotShortcut);
}
@@ -96,6 +97,7 @@
SystemShortcut modalShortcut = TaskShortcutFactory.MODAL
.getShortcut(activity, taskView);
if (modalShortcut != null) {
+ modalShortcut.setHasFinishRecentsInAction(true);
shortcuts.add(modalShortcut);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index d663635..b5ab400 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -220,7 +220,7 @@
menuOptionView.setEnabled(menuOption.isEnabled());
menuOptionView.setAlpha(menuOption.isEnabled() ? 1 : 0.5f);
menuOptionView.setOnClickListener(view -> {
- if (LIVE_TILE.get()) {
+ if (LIVE_TILE.get() && !menuOption.hasFinishRecentsInAction()) {
RecentsView recentsView = mTaskView.getRecentsView();
recentsView.switchToScreenshot(null,
() -> recentsView.finishRecentsAnimation(true /* toRecents */,
diff --git a/res/drawable/work_card.xml b/res/drawable/work_card.xml
index 0e4b054..7048955 100644
--- a/res/drawable/work_card.xml
+++ b/res/drawable/work_card.xml
@@ -20,8 +20,5 @@
android:shape="rectangle">
<solid android:color="?androidprv:attr/colorSurface" />
<corners android:radius="@dimen/work_edu_card_margin" />
- <padding
- android:left="@dimen/work_fab_radius"
- android:right="@dimen/work_fab_radius" />
</shape>
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 919f1b2..84fdfdf 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 02a50ca..841734c 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" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/work_apps_paused_content"
- android:textColor="?attr/workProfileOverlayTextColor"
+ android:textColor="?android:attr/textColorSecondary"
android:text="@string/work_apps_paused_body"
android:textAlignment="center"
android:layout_marginTop="16dp"
android:layout_marginBottom="24dp"
- android:textSize="16sp" />
+ android:textSize="14sp" />
<Button
android:layout_width="wrap_content"
@@ -49,5 +49,7 @@
android:text="@string/work_apps_enable_btn_text"
android:textAlignment="center"
android:background="@drawable/rounded_action_button"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
android:textSize="14sp" />
</com.android.launcher3.allapps.WorkPausedCard>
\ No newline at end of file
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 7183817..04faa15 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/values-sw340dp/dimens.xml b/res/values-sw340dp/dimens.xml
index c9f2981..33b06f5 100644
--- a/res/values-sw340dp/dimens.xml
+++ b/res/values-sw340dp/dimens.xml
@@ -19,6 +19,5 @@
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">20dp</dimen>
- <dimen name="drop_target_text_size">16sp</dimen>
</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 270c92e..ee2304c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -121,6 +121,8 @@
<!-- Floating action button inside work tab to toggle work profile -->
<dimen name="work_fab_height">48dp</dimen>
<dimen name="work_fab_radius">24dp</dimen>
+ <dimen name="work_card_padding_horizontal">24dp</dimen>
+ <dimen name="work_card_padding_vertical">32dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
<dimen name="work_profile_footer_padding">20dp</dimen>
<dimen name="work_profile_footer_text_size">16sp</dimen>
@@ -189,8 +191,9 @@
<!-- Dragging -->
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">14dp</dimen>
- <dimen name="drop_target_text_size">20sp</dimen>
+ <dimen name="drop_target_text_size">16sp</dimen>
<dimen name="drop_target_shadow_elevation">2dp</dimen>
+ <dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
<!-- the distance an icon must be dragged before button drop targets accept it -->
<dimen name="drag_distanceThreshold">30dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 416c711..24851f2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -258,7 +258,7 @@
<!-- Drop targets -->
<style name="DropTargetButtonBase" parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:drawablePadding">8dp</item>
- <item name="android:padding">16dp</item>
+ <item name="android:padding">14dp</item>
<item name="android:textColor">@color/drop_target_text</item>
<item name="android:textSize">@dimen/drop_target_text_size</item>
<item name="android:singleLine">true</item>
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 23dd3bb..61b5564 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -20,15 +20,12 @@
import static com.android.launcher3.LauncherState.NORMAL;
-import android.animation.AnimatorSet;
import android.content.Context;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Property;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -40,6 +37,7 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.model.data.ItemInfo;
/**
@@ -212,18 +210,23 @@
return;
}
final DragLayer dragLayer = mLauncher.getDragLayer();
+ final DragView dragView = d.dragView;
final Rect from = new Rect();
dragLayer.getViewRectRelativeToSelf(d.dragView, from);
final Rect to = getIconRect(d);
final float scale = (float) to.width() / from.width();
- d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
+ dragView.disableColorExtraction();
+ dragView.detachContentView(/* reattachToPreviousParent= */ true);
mDropTargetBar.deferOnDragEnd();
Runnable onAnimationEndRunnable = () -> {
completeDrop(d);
mDropTargetBar.onDragEnd();
mLauncher.getStateManager().goToState(NORMAL);
+ // Only re-enable updates once the workspace is back to normal, which will be after the
+ // current frame.
+ post(dragView::resumeColorExtraction);
};
dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index 4a1b084..88f6c49 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -105,7 +105,8 @@
/ (2 * (grid.inv.numColumns + 1)))
+ grid.edgeMarginPx;
} else {
- gap = grid.desiredWorkspaceLeftRightMarginPx - grid.inv.defaultWidgetPadding.right;
+ gap = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
}
lp.width = grid.availableWidthPx - 2 * gap;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f28f54a..5bdc402 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1786,8 +1786,11 @@
onDropExternal(touchXY, dropTargetLayout, d);
} else {
final View cell = mDragInfo.cell;
+ final DragView dragView = d.dragView;
boolean droppedOnOriginalCellDuringTransition = false;
- Runnable onCompleteRunnable = null;
+ Runnable onCompleteRunnable = dragView::resumeColorExtraction;
+
+ dragView.disableColorExtraction();
if (dropTargetLayout != null && !d.cancelled) {
// Move internally
@@ -1898,7 +1901,9 @@
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE
&& !options.isAccessibleDrag) {
+ final Runnable previousRunnable = onCompleteRunnable;
onCompleteRunnable = () -> {
+ previousRunnable.run();
if (!isPageInTransition()) {
AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
@@ -1967,7 +1972,7 @@
parent.onDropChild(cell);
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY,
- onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable));
+ forSuccessCallback(onCompleteRunnable));
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 1664980..3fdb256 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -66,6 +66,7 @@
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
/** A custom view for rendering an icon, folder, shortcut or widget during drag-n-drop. */
public class DragView extends FrameLayout implements StateListener<LauncherState> {
@@ -471,12 +472,12 @@
mContent.draw(picture.beginRecording(mWidth, mHeight));
picture.endRecording();
View view = new View(mLauncher);
- view.setClipToOutline(mContent.getClipToOutline());
- view.setOutlineProvider(mContent.getOutlineProvider());
view.setBackground(new PictureDrawable(picture));
view.measure(makeMeasureSpec(mWidth, EXACTLY), makeMeasureSpec(mHeight, EXACTLY));
view.layout(mContent.getLeft(), mContent.getTop(),
mContent.getRight(), mContent.getBottom());
+ setClipToOutline(mContent.getClipToOutline());
+ setOutlineProvider(mContent.getOutlineProvider());
addViewInLayout(view, indexOfChild(mContent), mContent.getLayoutParams(), true);
removeViewInLayout(mContent);
@@ -491,6 +492,24 @@
}
/**
+ * If the drag view uses color extraction, block it.
+ */
+ public void disableColorExtraction() {
+ if (mContent instanceof LauncherAppWidgetHostView) {
+ ((LauncherAppWidgetHostView) mContent).disableColorExtraction();
+ }
+ }
+
+ /**
+ * If the drag view uses color extraction, restores it.
+ */
+ public void resumeColorExtraction() {
+ if (mContent instanceof LauncherAppWidgetHostView) {
+ ((LauncherAppWidgetHostView) mContent).enableColorExtraction(/* updateColors= */ false);
+ }
+ }
+
+ /**
* Removes this view from the {@link DragLayer}.
*
* <p>If the drag content is a {@link #mContent}, this call doesn't reattach the
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index a6674fc..8bef6ad 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -269,6 +269,9 @@
setDrawable(p, items.get(i));
if (!animate) {
+ if (p.anim != null) {
+ p.anim.cancel();
+ }
computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, p);
if (mReferenceDrawable == null) {
mReferenceDrawable = p.drawable;
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index e5424cf..d3f4909 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -50,6 +50,8 @@
*/
private boolean isEnabled = true;
+ private boolean mHasFinishRecentsInAction = false;
+
public SystemShortcut(int iconResId, int labelResId, T target, ItemInfo itemInfo) {
mIconResId = iconResId;
mLabelResId = labelResId;
@@ -100,6 +102,14 @@
return mAccessibilityActionId == action;
}
+ public void setHasFinishRecentsInAction(boolean hasFinishRecentsInAction) {
+ mHasFinishRecentsInAction = hasFinishRecentsInAction;
+ }
+
+ public boolean hasFinishRecentsInAction() {
+ return mHasFinishRecentsInAction;
+ }
+
public interface Factory<T extends BaseDraggingActivity> {
@Nullable SystemShortcut<T> getShortcut(T activity, ItemInfo itemInfo);
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index ea08a25..63bc416 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -57,7 +57,6 @@
import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener;
import java.util.List;
-import java.util.Optional;
/**
* {@inheritDoc}
@@ -118,7 +117,9 @@
private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper;
private long mDeferUpdatesUntilMillis = 0;
private RemoteViews mDeferredRemoteViews;
- private Optional<SparseIntArray> mDeferredColorChange = Optional.empty();
+ private boolean mHasDeferredColorChange = false;
+ private @Nullable SparseIntArray mDeferredColorChange = null;
+ private boolean mEnableColorExtraction = true;
public LauncherAppWidgetHostView(Context context) {
super(context);
@@ -243,18 +244,23 @@
*/
public void endDeferringUpdates() {
RemoteViews remoteViews;
- Optional<SparseIntArray> deferredColors;
+ SparseIntArray deferredColors;
+ boolean hasDeferredColors;
synchronized (mUpdateLock) {
mDeferUpdatesUntilMillis = 0;
remoteViews = mDeferredRemoteViews;
mDeferredRemoteViews = null;
deferredColors = mDeferredColorChange;
- mDeferredColorChange = Optional.empty();
+ hasDeferredColors = mHasDeferredColorChange;
+ mDeferredColorChange = null;
+ mHasDeferredColorChange = false;
}
if (remoteViews != null) {
updateAppWidget(remoteViews);
}
- deferredColors.ifPresent(colors -> onColorsChanged(null /* rectF */, colors));
+ if (hasDeferredColors) {
+ onColorsChanged(null /* rectF */, deferredColors);
+ }
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
@@ -342,13 +348,7 @@
}
mIsScrollable = checkScrollableRecursively(this);
- if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
-
- LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
- mDragLayerRelativeCoordinateHelper.viewToRect(this, mCurrentWidgetSize);
- updateColorExtraction(mCurrentWidgetSize,
- mWorkspace.getPageIndexForScreenId(info.screenId));
- }
+ updateColorExtraction();
enforceRoundedCorners();
}
@@ -377,6 +377,7 @@
* @param pageId The workspace page the widget is on.
*/
private void updateColorExtraction(Rect rectInDragLayer, int pageId) {
+ if (!mEnableColorExtraction) return;
mColorExtractor.getExtractedRectForViewRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
if (mTempRectF.isEmpty()) {
@@ -391,6 +392,38 @@
}
}
+ /**
+ * Update the color extraction, using the current position of the app widget.
+ */
+ private void updateColorExtraction() {
+ if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
+ LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
+ mDragLayerRelativeCoordinateHelper.viewToRect(this, mCurrentWidgetSize);
+ updateColorExtraction(mCurrentWidgetSize,
+ mWorkspace.getPageIndexForScreenId(info.screenId));
+ }
+ }
+
+ /**
+ * Enables the local color extraction.
+ *
+ * @param updateColors If true, this will update the color extraction using the current location
+ * of the App Widget.
+ */
+ public void enableColorExtraction(boolean updateColors) {
+ mEnableColorExtraction = true;
+ if (updateColors) {
+ updateColorExtraction();
+ }
+ }
+
+ /**
+ * Disables the local color extraction.
+ */
+ public void disableColorExtraction() {
+ mEnableColorExtraction = false;
+ }
+
// Compare two location rectangles. Locations are always in the [0;1] range.
private static boolean isSameLocation(@NonNull RectF rect1, @Nullable RectF rect2,
float epsilon) {
@@ -409,10 +442,12 @@
public void onColorsChanged(RectF rectF, SparseIntArray colors) {
synchronized (mUpdateLock) {
if (isDeferringUpdates()) {
- mDeferredColorChange = Optional.ofNullable(colors);
+ mDeferredColorChange = colors;
+ mHasDeferredColorChange = true;
return;
}
- mDeferredColorChange = Optional.empty();
+ mDeferredColorChange = null;
+ mHasDeferredColorChange = false;
}
// setColorResources will reapply the view, which must happen in the UI thread.
diff --git a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
index a809e2e..710e3cd 100644
--- a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
+++ b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
@@ -15,6 +15,10 @@
*/
package com.android.launcher3.tapl;
+import static com.android.launcher3.testing.TestProtocol.SEQUENCE_MAIN;
+import static com.android.launcher3.testing.TestProtocol.SEQUENCE_PILFER;
+import static com.android.launcher3.testing.TestProtocol.SEQUENCE_TIS;
+
import android.os.SystemClock;
import com.android.launcher3.testing.TestProtocol;
@@ -87,6 +91,24 @@
final ListMap<String> actualEvents = finishSync(waitForExpectedCountMs);
if (actualEvents == null) return "null event sequences because launcher likely died";
+ final String lowLevelDiags = lowLevelMismatchDiagnostics(actualEvents);
+ // If we have a sequence mismatch for a successful gesture, we want to provide all low-level
+ // details.
+ if (successfulGesture) {
+ return lowLevelDiags;
+ }
+
+ final String sequenceMismatchInEnglish = highLevelMismatchDiagnostics(actualEvents);
+
+ if (sequenceMismatchInEnglish != null) {
+ LauncherInstrumentation.log(lowLevelDiags);
+ return "Hint: " + sequenceMismatchInEnglish;
+ } else {
+ return lowLevelDiags;
+ }
+ }
+
+ private String lowLevelMismatchDiagnostics(ListMap<String> actualEvents) {
final StringBuilder sb = new StringBuilder();
boolean hasMismatches = false;
for (Map.Entry<String, List<Pattern>> expectedEvents : mExpectedEvents.entrySet()) {
@@ -118,6 +140,42 @@
return hasMismatches ? "Mismatching events: " + sb.toString() : null;
}
+ private String highLevelMismatchDiagnostics(ListMap<String> actualEvents) {
+ if (!mExpectedEvents.getNonNull(SEQUENCE_TIS).isEmpty()
+ && actualEvents.getNonNull(SEQUENCE_TIS).isEmpty()) {
+ return "TouchInteractionService didn't receive any of the touch events sent by the "
+ + "test";
+ }
+ if (getMismatchPosition(mExpectedEvents.getNonNull(SEQUENCE_TIS),
+ actualEvents.getNonNull(SEQUENCE_TIS)) != -1) {
+ // If TIS has a mismatch that we can't convert to high-level diags, don't convert
+ // other sequences either.
+ return null;
+ }
+
+ if (mExpectedEvents.getNonNull(SEQUENCE_PILFER).size() == 1
+ && actualEvents.getNonNull(SEQUENCE_PILFER).isEmpty()) {
+ return "Launcher didn't detect the navigation gesture sent by the test";
+ }
+ if (mExpectedEvents.getNonNull(SEQUENCE_PILFER).isEmpty()
+ && actualEvents.getNonNull(SEQUENCE_PILFER).size() == 1) {
+ return "Launcher detected a navigation gesture, but the test didn't send one";
+ }
+ if (getMismatchPosition(mExpectedEvents.getNonNull(SEQUENCE_PILFER),
+ actualEvents.getNonNull(SEQUENCE_PILFER)) != -1) {
+ // If Pilfer has a mismatch that we can't convert to high-level diags, don't analyze
+ // other sequences.
+ return null;
+ }
+
+ if (!mExpectedEvents.getNonNull(SEQUENCE_MAIN).isEmpty()
+ && actualEvents.getNonNull(SEQUENCE_MAIN).isEmpty()) {
+ return "None of the touch or keyboard events sent by the test was received by "
+ + "Launcher's main thread";
+ }
+ return null;
+ }
+
// If the list of actual events matches the list of expected events, returns -1, otherwise
// the position of the mismatch.
private static int getMismatchPosition(List<Pattern> expected, List<String> actual) {