Merge "Using xml override instead of code swap for predicted icon" into main
diff --git a/quickstep/res/drawable/keyboard_quick_switch_thumbnail_background.xml b/quickstep/res/drawable/keyboard_quick_switch_thumbnail_background.xml
new file mode 100644
index 0000000..961f5aa
--- /dev/null
+++ b/quickstep/res/drawable/keyboard_quick_switch_thumbnail_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@android:color/white" />
+ <corners android:radius="@dimen/keyboard_quick_switch_task_view_radius" />
+</shape>
diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview_thumbnail.xml b/quickstep/res/layout/keyboard_quick_switch_taskview_thumbnail.xml
index dde9cac..8cd8560 100644
--- a/quickstep/res/layout/keyboard_quick_switch_taskview_thumbnail.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_taskview_thumbnail.xml
@@ -18,6 +18,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
- android:background="@drawable/keyboard_quick_switch_task_view_background"
+ android:background="@drawable/keyboard_quick_switch_thumbnail_background"
android:clipToOutline="true"
android:importantForAccessibility="no"/>
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index a931f36..a621259 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -41,6 +41,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP;
import static com.android.launcher3.model.PredictionHelper.isTrackedForHotseatPrediction;
import static com.android.launcher3.model.PredictionHelper.isTrackedForWidgetPrediction;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -184,6 +185,10 @@
sendEvent(target, atomInfo, ACTION_LAUNCH, CONTAINER_PREDICTION);
} else if (event == LAUNCHER_DISMISS_PREDICTION_UNDO) {
sendEvent(atomInfo, ACTION_UNDISMISS, CONTAINER_HOTSEAT_PREDICTION);
+ } else if (event == LAUNCHER_WIDGET_ADD_BUTTON_TAP) {
+ if (isTrackedForWidgetPrediction(atomInfo)) {
+ sendEvent(atomInfo, ACTION_PIN, CONTAINER_WIDGETS_PREDICTION);
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index 0bcf2d1..bed85d7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -97,7 +97,11 @@
private void openQuickSwitchView(int currentFocusedIndex) {
if (mQuickSwitchViewController != null) {
- return;
+ if (!mQuickSwitchViewController.isCloseAnimationRunning()) {
+ return;
+ }
+ // Allow the KQS to be reopened during the close animation to make it more responsive
+ closeQuickSwitchView(false);
}
TaskbarOverlayContext overlayContext =
mControllers.taskbarOverlayController.requestWindow();
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 5b407f0..48fc7d1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -23,6 +23,7 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
@@ -174,21 +175,23 @@
return;
}
if (updateFunction == null) {
- applyThumbnail(thumbnailView, task.thumbnail);
+ applyThumbnail(thumbnailView, task.colorBackground, task.thumbnail);
return;
}
- updateFunction.updateThumbnailInBackground(
- task, thumbnailData -> applyThumbnail(thumbnailView, thumbnailData));
+ updateFunction.updateThumbnailInBackground(task, thumbnailData ->
+ applyThumbnail(thumbnailView, task.colorBackground, thumbnailData));
}
private void applyThumbnail(
@NonNull ImageView thumbnailView,
- ThumbnailData thumbnailData) {
+ @ColorInt int backgroundColor,
+ @Nullable ThumbnailData thumbnailData) {
Bitmap bm = thumbnailData == null ? null : thumbnailData.thumbnail;
if (thumbnailView.getVisibility() != VISIBLE) {
thumbnailView.setVisibility(VISIBLE);
}
+ thumbnailView.getBackground().setTint(bm == null ? backgroundColor : Color.TRANSPARENT);
thumbnailView.setImageDrawable(new BlurredBitmapDrawable(bm, THUMBNAIL_BLUR_RADIUS));
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index 5f53cc3..25a97d4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -94,8 +94,12 @@
mViewCallbacks);
}
+ boolean isCloseAnimationRunning() {
+ return mCloseAnimation != null;
+ }
+
protected void closeQuickSwitchView(boolean animate) {
- if (mCloseAnimation != null) {
+ if (isCloseAnimationRunning()) {
// Let currently-running animation finish.
if (!animate) {
mCloseAnimation.end();
@@ -130,7 +134,7 @@
}
private int launchTaskAt(int index) {
- if (mCloseAnimation != null) {
+ if (isCloseAnimationRunning()) {
// Ignore taps on task views and alt key unpresses while the close animation is running.
return -1;
}
@@ -186,7 +190,7 @@
pw.println(prefix + "KeyboardQuickSwitchViewController:");
pw.println(prefix + "\thasFocus=" + mKeyboardQuickSwitchView.hasFocus());
- pw.println(prefix + "\tcloseAnimationRunning=" + (mCloseAnimation != null));
+ pw.println(prefix + "\tisCloseAnimationRunning=" + isCloseAnimationRunning());
pw.println(prefix + "\tmCurrentFocusIndex=" + mCurrentFocusIndex);
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 077ca60..e4d8e92 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
+import static com.android.launcher3.testing.shared.TestProtocol.UPDATE_OVERVIEW_TARGETS_RUNNING_LATE;
import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_ACTIVITY_TIMEOUT;
import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_BROADCAST_TIMEOUT_SECS;
import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT;
@@ -44,6 +45,7 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
+import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -59,6 +61,7 @@
import com.android.launcher3.testcomponent.TestCommandReceiver;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.ExtendedLongPressTimeoutRule;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
@@ -105,6 +108,9 @@
@Rule
public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
+ @Rule
+ public ExtendedLongPressTimeoutRule mLongPressTimeoutRule = new ExtendedLongPressTimeoutRule();
+
public FallbackRecentsTest() throws RemoteException {
Instrumentation instrumentation = getInstrumentation();
Context context = instrumentation.getContext();
@@ -129,6 +135,13 @@
getLauncherCommand(mOtherLauncherActivity));
updateHandler.mChangeCounter
.await(DEFAULT_BROADCAST_TIMEOUT_SECS, TimeUnit.SECONDS);
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "AFTER AWAIT: mObserver home intent package name="
+ + updateHandler.mObserver.getHomeIntent()
+ .getComponent().getPackageName());
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "AFTER AWAIT: mOtherLauncherActivity package name="
+ + mOtherLauncherActivity.packageName);
try {
base.evaluate();
} finally {
@@ -340,12 +353,25 @@
mRads = new RecentsAnimationDeviceState(ctx);
mObserver = new OverviewComponentObserver(ctx, mRads);
mChangeCounter = new CountDownLatch(1);
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "OverviewUpdateHandler(Constructor): mObserver home intent package name="
+ + mObserver.getHomeIntent().getComponent().getPackageName());
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "OverviewUpdateHandler(Constructor): mOtherLauncherActivity package name="
+ + mOtherLauncherActivity.packageName);
if (mObserver.getHomeIntent().getComponent()
.getPackageName().equals(mOtherLauncherActivity.packageName)) {
// Home already same
mChangeCounter.countDown();
} else {
- mObserver.setOverviewChangeListener(b -> mChangeCounter.countDown());
+ mObserver.setOverviewChangeListener(b -> {
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "OverviewChangeListener(Callback): isHomeAndOverviewSame=" + b);
+ Log.d(UPDATE_OVERVIEW_TARGETS_RUNNING_LATE,
+ "OverviewChangeListener(Callback): mObserver home intent package name="
+ + mObserver.getHomeIntent().getComponent().getPackageName());
+ mChangeCounter.countDown();
+ });
}
}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 5266448..76ffbbd 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -164,11 +164,11 @@
* Click handler for tap to add button.
*/
public void addWidget(PendingAddItemInfo info) {
- mActivityContext.getStatsLogManager().logger().withItemInfo(info).log(
- StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP);
handleClose(true);
Launcher.getLauncher(mActivityContext).getAccessibilityDelegate()
.addToWorkspace(info, /*accessibility=*/ false, /*finishCallback=*/ null);
+ mActivityContext.getStatsLogManager().logger().withItemInfo(info).log(
+ StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP);
}
@Override
diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index e0fafcc..fea0330 100644
--- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -180,6 +180,7 @@
public static final String TEST_TAPL_OVERVIEW_ACTIONS_MENU_FAILURE = "b/326073471";
public static final String WIDGET_CONFIG_NULL_EXTRA_INTENT = "b/324419890";
public static final String ACTIVITY_NOT_RESUMED_AFTER_BACK = "b/322823209";
+ public static final String UPDATE_OVERVIEW_TARGETS_RUNNING_LATE = "b/321775748";
public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 972be80..d8635f9 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -66,6 +66,7 @@
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.ExtendedLongPressTimeoutRule;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
@@ -219,6 +220,9 @@
@Rule
public SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+ @Rule
+ public ExtendedLongPressTimeoutRule mLongPressTimeoutRule = new ExtendedLongPressTimeoutRule();
+
public static void initialize(AbstractLauncherUiTest test) throws Exception {
test.reinitializeLauncherData();
test.mDevice.pressHome();
diff --git a/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java b/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java
new file mode 100644
index 0000000..702988c
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/ExtendedLongPressTimeoutRule.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util.rule;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.ViewConfiguration;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class ExtendedLongPressTimeoutRule implements TestRule {
+
+ private static final String TAG = "ExtendedLongPressTimeoutRule";
+
+ private static final float LONG_PRESS_TIMEOUT_MULTIPLIER = 10f;
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ ContentResolver contentResolver = InstrumentationRegistry.getInstrumentation()
+ .getContext()
+ .getContentResolver();
+ int prevLongPressTimeout = Settings.Secure.getInt(
+ contentResolver,
+ Settings.Secure.LONG_PRESS_TIMEOUT,
+ ViewConfiguration.getLongPressTimeout());
+ int newLongPressTimeout =
+ (int) (prevLongPressTimeout * LONG_PRESS_TIMEOUT_MULTIPLIER);
+
+ try {
+ Log.d(TAG, "In try-block: Setting long press timeout from "
+ + prevLongPressTimeout + "ms to " + newLongPressTimeout + "ms");
+ Settings.Secure.putInt(
+ contentResolver,
+ Settings.Secure.LONG_PRESS_TIMEOUT,
+ (int) (prevLongPressTimeout * LONG_PRESS_TIMEOUT_MULTIPLIER));
+
+ base.evaluate();
+ } catch (Exception e) {
+ Log.e(TAG, "Error", e);
+ throw e;
+ } finally {
+ Log.d(TAG, "In finally-block: resetting long press timeout to "
+ + prevLongPressTimeout + "ms");
+ Settings.Secure.putInt(
+ contentResolver,
+ Settings.Secure.LONG_PRESS_TIMEOUT,
+ prevLongPressTimeout);
+ }
+ }
+ };
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 0e523c3..c7d3754 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1919,17 +1919,21 @@
}
private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
- float x, float y, int source) {
+ float x, float y, int source, int toolType) {
return MotionEvent.obtain(downTime, eventTime, action, 1,
- new MotionEvent.PointerProperties[]{getPointerProperties(0)},
+ new MotionEvent.PointerProperties[]{getPointerProperties(0, toolType)},
new MotionEvent.PointerCoords[]{getPointerCoords(x, y)},
0, 0, 1.0f, 1.0f, 0, 0, source, 0);
}
private static MotionEvent.PointerProperties getPointerProperties(int pointerId) {
+ return getPointerProperties(pointerId, Configurator.getInstance().getToolType());
+ }
+
+ private static MotionEvent.PointerProperties getPointerProperties(int pointerId, int toolType) {
MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
properties.id = pointerId;
- properties.toolType = Configurator.getInstance().getToolType();
+ properties.toolType = toolType;
return properties;
}
@@ -1975,6 +1979,19 @@
public void sendPointer(long downTime, long currentTime, int action, Point point,
GestureScope gestureScope, int source, boolean isRightClick) {
+ sendPointer(
+ downTime,
+ currentTime,
+ action,
+ point,
+ gestureScope,
+ source,
+ isRightClick,
+ Configurator.getInstance().getToolType());
+ }
+
+ public void sendPointer(long downTime, long currentTime, int action, Point point,
+ GestureScope gestureScope, int source, boolean isRightClick, int toolType) {
final boolean hasTIS = hasTIS();
int pointerCount = mPointerCount;
@@ -2009,13 +2026,13 @@
? getTrackpadMotionEvent(
downTime, currentTime, action, point.x, point.y, pointerCount,
mTrackpadGestureType)
- : getMotionEvent(downTime, currentTime, action, point.x, point.y, source);
+ : getMotionEvent(downTime, currentTime, action, point.x, point.y, source, toolType);
if (action == MotionEvent.ACTION_BUTTON_PRESS
|| action == MotionEvent.ACTION_BUTTON_RELEASE) {
event.setActionButton(MotionEvent.BUTTON_PRIMARY);
}
if (isRightClick) {
- event.setButtonState(event.getButtonState() & MotionEvent.BUTTON_SECONDARY);
+ event.setButtonState(event.getButtonState() | MotionEvent.BUTTON_SECONDARY);
}
injectEvent(event);
}
@@ -2114,15 +2131,19 @@
@NonNull final UiObject2 target, @NonNull String resName, Pattern longClickEvent) {
final Point targetCenter = target.getVisibleCenter();
final long downTime = SystemClock.uptimeMillis();
+ // Use stylus secondary button press to prevent using the exteded long press timeout rule
+ // unnecessarily
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter,
- GestureScope.DONT_EXPECT_PILFER);
+ GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_TOUCHSCREEN,
+ /* isRightClick= */ true, MotionEvent.TOOL_TYPE_STYLUS);
try {
expectEvent(TestProtocol.SEQUENCE_MAIN, longClickEvent);
final UiObject2 result = waitForLauncherObject(resName);
return result;
} finally {
sendPointer(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, targetCenter,
- GestureScope.DONT_EXPECT_PILFER);
+ GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_TOUCHSCREEN,
+ /* isRightClick= */ true, MotionEvent.TOOL_TYPE_STYLUS);
}
}