Merge "Ignore all launcher3 flaky test so that they come back online" into tm-qpr-dev
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
index 10444f1..d7daea3 100644
--- a/quickstep/res/layout/taskbar_edu.xml
+++ b/quickstep/res/layout/taskbar_edu.xml
@@ -46,7 +46,7 @@
android:id="@+id/edu_start_button"
android:layout_width="wrap_content"
android:layout_height="36dp"
- android:layout_marginBottom="92dp"
+ android:layout_marginBottom="18dp"
android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="@id/content"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 311f37d..1eff992 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -78,10 +78,8 @@
<string name="allset_title" msgid="5021126669778966707">"എല്ലാം സജ്ജീകരിച്ചു!"</string>
<string name="allset_hint" msgid="2384632994739392447">"ഹോമിലേക്ക് പോകാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"നിങ്ങളുടെ ഹോം സ്ക്രീനിലേക്ക് പോകാൻ ഹോം ബട്ടൺ ടാപ്പ് ചെയ്യുക"</string>
- <!-- no translation found for allset_description_generic (5385500062202019855) -->
- <skip />
- <!-- no translation found for default_device_name (6660656727127422487) -->
- <skip />
+ <string name="allset_description_generic" msgid="5385500062202019855">"നിങ്ങൾക്ക് <xliff:g id="DEVICE">%1$s</xliff:g> ഉപയോഗിച്ചു തുടങ്ങാം"</string>
+ <string name="default_device_name" msgid="6660656727127422487">"ഉപകരണം"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"സിസ്റ്റം നാവിഗേഷൻ ക്രമീകരണം"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"പങ്കിടുക"</string>
<string name="action_screenshot" msgid="8171125848358142917">"സ്ക്രീൻഷോട്ട്"</string>
@@ -94,8 +92,7 @@
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"റദ്ദാക്കുക"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ഒഴിവാക്കുക"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"സ്ക്രീൻ റൊട്ടേറ്റ് ചെയ്യുക"</string>
- <!-- no translation found for taskbar_edu_a11y_title (5417986057866415355) -->
- <skip />
+ <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ടാസ്ക്ബാർ മാർഗ്ഗനിർദ്ദേശ വിൻഡോ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ടാസ്ക്ക്ബാർ വിവര പാനൽ ദൃശ്യമായി"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ടാസ്ക്ക്ബാർ വിവര പാനൽ അടച്ചു"</string>
<string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ആപ്പുകൾ മാറാൻ ടാസ്ക്ക്ബാർ ഉപയോഗിക്കുക"</string>
@@ -112,10 +109,8 @@
<string name="taskbar_button_recents" msgid="7273376136216613134">"അടുത്തിടെയുള്ളവ"</string>
<string name="taskbar_button_notifications" msgid="7471740351507357318">"അറിയിപ്പുകൾ"</string>
<string name="taskbar_button_quick_settings" msgid="227662894293189391">"ദ്രുത ക്രമീകരണം"</string>
- <!-- no translation found for taskbar_a11y_title (6432169809852243110) -->
- <skip />
- <!-- no translation found for taskbar_phone_a11y_title (4933360237131229395) -->
- <skip />
+ <string name="taskbar_a11y_title" msgid="6432169809852243110">"ടാസ്ക്ബാർ"</string>
+ <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"നാവിഗേഷൻ ബാർ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"താഴേക്കോ വലത്തേക്കോ നീക്കുക"</string>
</resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index cb3f69a..b17d415 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -78,10 +78,8 @@
<string name="allset_title" msgid="5021126669778966707">"அனைத்தையும் அமைத்துவிட்டீர்கள்!"</string>
<string name="allset_hint" msgid="2384632994739392447">"முகப்புத் திரைக்குச் செல்ல மேல்நோக்கி ஸ்வைப் செய்யுங்கள்"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"முகப்புத் திரைக்குச் செல்வதற்கு முகப்பு பட்டனைத் தட்டவும்"</string>
- <!-- no translation found for allset_description_generic (5385500062202019855) -->
- <skip />
- <!-- no translation found for default_device_name (6660656727127422487) -->
- <skip />
+ <string name="allset_description_generic" msgid="5385500062202019855">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்"</string>
+ <string name="default_device_name" msgid="6660656727127422487">"சாதனம்"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"சிஸ்டம் வழிசெலுத்தல் அமைப்புகள்"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"பகிர்"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ஸ்கிரீன்ஷாட்"</string>
@@ -94,8 +92,7 @@
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ரத்துசெய்"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"தவிர்"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"திரையைச் சுழற்றும்"</string>
- <!-- no translation found for taskbar_edu_a11y_title (5417986057866415355) -->
- <skip />
+ <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"செயல் பட்டியைப் பயன்படுத்தும் விதம்"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் காட்டப்படுகிறது"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் மூடப்பட்டது"</string>
<string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ஆப்ஸிற்கு இடையே மாற பணிப்பட்டியைப் பயன்படுத்தவும்"</string>
@@ -112,10 +109,8 @@
<string name="taskbar_button_recents" msgid="7273376136216613134">"சமீபத்தியவை"</string>
<string name="taskbar_button_notifications" msgid="7471740351507357318">"அறிவிப்புகள்"</string>
<string name="taskbar_button_quick_settings" msgid="227662894293189391">"விரைவு அமைப்புகள்"</string>
- <!-- no translation found for taskbar_a11y_title (6432169809852243110) -->
- <skip />
- <!-- no translation found for taskbar_phone_a11y_title (4933360237131229395) -->
- <skip />
+ <string name="taskbar_a11y_title" msgid="6432169809852243110">"செயல் பட்டி"</string>
+ <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"வழிசெலுத்தல் பட்டி"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"மேலே/இடதுபுறம் நகர்த்தும்"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"கீழே/வலதுபுறம் நகர்த்தும்"</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index c54d119..4fbe8cf 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -30,7 +30,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -51,7 +50,7 @@
import java.util.stream.Collectors;
@TargetApi(Build.VERSION_CODES.P)
-public class PredictionRowView<T extends Context & ActivityContext & DeviceProfileListenable>
+public class PredictionRowView<T extends Context & ActivityContext>
extends LinearLayout implements OnDeviceProfileChangeListener, FloatingHeaderRow {
private final T mActivityContext;
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index 0c8952d..a205d19 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -42,7 +42,8 @@
* Whether desktop mode is supported.
*/
private boolean isDesktopModeSupported() {
- return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false);
+ return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false)
+ || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
index b4052e3..82d1830 100644
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -19,18 +19,16 @@
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.AppLauncher;
+import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.List;
// TODO(b/218912746): Share more behavior to avoid all apps context depending directly on taskbar.
/** Base for common behavior between taskbar window contexts. */
-public abstract class BaseTaskbarContext extends ContextThemeWrapper implements AppLauncher,
- DeviceProfileListenable {
+public abstract class BaseTaskbarContext extends ContextThemeWrapper implements ActivityContext {
protected final LayoutInflater mLayoutInflater;
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 02206ce..22f7f13 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -38,6 +38,7 @@
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
@@ -45,7 +46,6 @@
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.views.RecentsView;
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 2435236..cbee58b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -81,6 +81,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter;
@@ -89,7 +90,6 @@
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.AnimatedFloat;
import com.android.systemui.shared.rotation.FloatingRotationButton;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index af46df4..74e7375 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -28,13 +28,13 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
-import com.android.quickstep.AnimatedFloat;
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 01ec5f3..83b8d83 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -877,6 +877,16 @@
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
}
+ /** Called when we want to hide the overlay window when user performs swipe up gesture. */
+ public void onSwipeToHideOverlay() {
+ mControllers.taskbarOverlayController.hideWindow();
+ }
+
+ /** Returns {@code true} if taskbar is stashed. */
+ public boolean isTaskbarStashed() {
+ return mControllers.taskbarStashController.isStashed();
+ }
+
/**
* Called to start the taskbar translation spring to its settled translation (0).
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 0328df9..bc41c2b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -21,9 +21,9 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
-import com.android.quickstep.AnimatedFloat;
import com.android.systemui.shared.rotation.RotationButtonController;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index e54fc00..cd27a46 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -23,11 +23,11 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DimensionUtils;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.TouchController;
-import com.android.quickstep.AnimatedFloat;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
index 2cb05ff..d3f1b2f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
@@ -15,11 +15,11 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_EDU;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
@@ -62,20 +62,21 @@
: R.layout.taskbar_edu_pages_persistent,
mPagedView,
true);
+
+ // Provide enough room for taskbar.
+ View startButton = mTaskbarEduView.findViewById(R.id.edu_start_button);
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) startButton.getLayoutParams();
+ DeviceProfile dp = overlayContext.getDeviceProfile();
+ layoutParams.bottomMargin += DisplayController.isTransientTaskbar(overlayContext)
+ ? dp.taskbarSize + dp.transientTaskbarMargin
+ : dp.taskbarSize;
+
mTaskbarEduView.init(new TaskbarEduCallbacks());
mControllers.navbarButtonsViewController.setSlideInViewVisible(true);
- TaskbarStashController stashController = mControllers.taskbarStashController;
- stashController.updateStateForFlag(FLAG_STASHED_IN_APP_EDU, true);
- stashController.applyState(overlayController.getOpenDuration());
-
- mTaskbarEduView.setOnCloseBeginListener(() -> {
- mControllers.navbarButtonsViewController.setSlideInViewVisible(false);
- // Post in case view is closing due to gesture navigation. If a gesture is in progress,
- // wait to unstash until after the gesture is finished.
- MAIN_EXECUTOR.post(() -> stashController.resetFlagIfNoGestureInProgress(
- FLAG_STASHED_IN_APP_EDU));
- });
+ mTaskbarEduView.setOnCloseBeginListener(
+ () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false));
mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null);
mTaskbarEduView.show();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
index f7aafe0..ffaee45 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
@@ -30,10 +30,10 @@
import android.view.MotionEvent;
import android.view.View;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.TouchController;
-import com.android.quickstep.AnimatedFloat;
/**
* Controller for taskbar when force visible in immersive mode is set.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index b74dd21..4ad3858 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -35,12 +35,12 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.views.RecentsView;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index ce191b7..88767dd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -22,7 +22,7 @@
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
-import com.android.quickstep.AnimatedFloat;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 3d98f6e..95337ce 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -52,11 +52,11 @@
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
import java.io.PrintWriter;
@@ -82,7 +82,6 @@
public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard
public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed
public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 10; // Autohide (transient taskbar).
- public static final int FLAG_STASHED_IN_APP_EDU = 1 << 11; // EDU is visible.
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -91,7 +90,7 @@
private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
| FLAG_STASHED_IN_SYSUI_STATE | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
| FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS
- | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO | FLAG_STASHED_IN_APP_EDU;
+ | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO;
private static final int FLAGS_STASHED_IN_APP_IGNORING_IME =
FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME;
@@ -101,8 +100,7 @@
// Currently any flag that causes us to stash in an app is included, except for IME or All Apps
// since those cover the underlying app anyway and thus the app shouldn't change insets.
private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
- & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS
- & ~FLAG_STASHED_IN_APP_EDU;
+ & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS;
/**
* How long to stash/unstash when manually invoked via long press.
@@ -728,7 +726,6 @@
// Only update the following flags when system gesture is not in progress.
boolean shouldStashForIme = shouldStashForIme();
updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
- updateStateForFlag(FLAG_STASHED_IN_APP_EDU, false);
if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != shouldStashForIme) {
updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme);
applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme());
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
index 1a7ec13..5dba444 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
@@ -15,8 +15,8 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.anim.AnimatedFloat.VALUE;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
-import static com.android.quickstep.AnimatedFloat.VALUE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -26,10 +26,10 @@
import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.SpringForce;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.AnimatedFloat;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index a059295..b3b53c2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -25,6 +25,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -84,7 +85,9 @@
* Manually closes the overlay window.
*/
public void hideOverlayWindow() {
- mControllers.taskbarOverlayController.hideWindow();
+ if (!DisplayController.isTransientTaskbar(mControllers.taskbarActivityContext)) {
+ mControllers.taskbarOverlayController.hideWindow();
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index d14eeab..5c9b51a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -19,13 +19,13 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.Utilities.squaredHypot;
+import static com.android.launcher3.anim.AnimatedFloat.VALUE;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_NEGATIVE;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
-import static com.android.quickstep.AnimatedFloat.VALUE;
import android.annotation.NonNull;
import android.graphics.Rect;
@@ -45,6 +45,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
@@ -59,7 +60,6 @@
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
-import com.android.quickstep.AnimatedFloat;
import java.io.PrintWriter;
import java.util.function.Predicate;
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 4165486..721f816 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar.allapps;
import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_AUTO;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
@@ -28,6 +29,7 @@
import com.android.launcher3.taskbar.TaskbarStashController;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
+import com.android.launcher3.util.DisplayController;
/**
* Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
@@ -88,18 +90,25 @@
}
private void setUpTaskbarStashing() {
- mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
+ mTaskbarStashController.updateStateForFlag(
+ DisplayController.isTransientTaskbar(mContext)
+ ? FLAG_STASHED_IN_APP_AUTO
+ : FLAG_STASHED_IN_TASKBAR_ALL_APPS,
+ true);
mTaskbarStashController.applyState(
ALL_APPS.getTransitionDuration(mContext, true /* isToState */));
+
mNavbarButtonsViewController.setSlideInViewVisible(true);
mSlideInView.setOnCloseBeginListener(() -> {
mNavbarButtonsViewController.setSlideInViewVisible(false);
AbstractFloatingView.closeOpenContainer(
mContext, AbstractFloatingView.TYPE_ACTION_POPUP);
- // Post in case view is closing due to gesture navigation. If a gesture is in progress,
- // wait to unstash until after the gesture is finished.
- MAIN_EXECUTOR.post(() -> mTaskbarStashController.resetFlagIfNoGestureInProgress(
- FLAG_STASHED_IN_TASKBAR_ALL_APPS));
+ if (!DisplayController.isTransientTaskbar(mContext)) {
+ // Post in case view is closing due to gesture navigation. If a gesture is in
+ // progress, wait to unstash until after the gesture is finished.
+ MAIN_EXECUTOR.post(() -> mTaskbarStashController.resetFlagIfNoGestureInProgress(
+ FLAG_STASHED_IN_TASKBAR_ALL_APPS));
+ }
});
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index fd184c6..2a42175 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,12 +20,11 @@
import android.content.Context;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ActivityContext;
/**
* Definition for AllApps state
@@ -40,7 +39,7 @@
}
@Override
- public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ public <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
return isToState
? context.getDeviceProfile().allAppsOpenDuration
@@ -78,7 +77,7 @@
}
@Override
- protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ protected <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
if (context.getDeviceProfile().isTablet) {
return context.getDeviceProfile().bottomSheetDepth;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 922679b..2c7e46c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -62,6 +62,7 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.states.StateAnimationConfig;
@@ -69,7 +70,6 @@
import com.android.launcher3.touch.BothAxesSwipeDetector;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.TouchController;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index 374b839..d4bebea 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -58,6 +58,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringAnimationBuilder;
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 8e07376..83f2a0a 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -34,6 +34,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.util.Log;
import android.util.SparseIntArray;
import androidx.annotation.NonNull;
@@ -54,6 +55,8 @@
* and provide callers the relevant classes.
*/
public final class OverviewComponentObserver {
+ private static final String TAG = "OverviewComponentObserver";
+
private final BroadcastReceiver mUserPreferenceChangeReceiver =
new SimpleBroadcastReceiver(this::updateOverviewTargets);
private final BroadcastReceiver mOtherHomeAppUpdateReceiver =
@@ -146,7 +149,12 @@
}
}
- if (!mDeviceState.isHomeDisabled() && (defaultHome == null || mIsDefaultHome)) {
+ // TODO(b/258022658): Remove temporary logging.
+ Log.i(TAG, "updateOverviewTargets: mIsHomeDisabled=" + mIsHomeDisabled
+ + ", isDefaultHomeNull=" + (defaultHome == null)
+ + ", mIsDefaultHome=" + mIsDefaultHome);
+
+ if (!mIsHomeDisabled && (defaultHome == null || mIsDefaultHome)) {
// User default home is same as out home app. Use Overview integrated in Launcher.
mActivityInterface = LauncherActivityInterface.INSTANCE;
mIsHomeAndOverviewSame = true;
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index fdde45a..291f835 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -31,6 +31,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index eae79df..663525d 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -303,7 +303,8 @@
private boolean isAvailable(BaseDraggingActivity activity, int displayId) {
return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity)
- && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false);
+ && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false)
+ && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
}
};
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index e8722e2..b7252bc 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -60,6 +60,7 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index af6a45a..2565697 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -73,6 +73,7 @@
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index db7e087..5374ff0 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -41,11 +41,11 @@
import android.view.VelocityTracker;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.MultiStateCallback;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index 2462394..45ffa1c 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -28,12 +28,12 @@
import android.graphics.Point;
import android.view.MotionEvent;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.MultiStateCallback;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
index 3a09490..c8326c4 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
@@ -53,8 +53,11 @@
private final float mUnstashArea;
private final float mScreenWidth;
- private final int mTaskbarThresholdY;
- private boolean mHasPassedTaskbarThreshold;
+ private final int mTaskbarNavThresholdY;
+ private final int mTaskbarAppWindowThresholdY;
+ private final boolean mTaskbarAlreadyOpen;
+ private boolean mHasPassedTaskbarNavThreshold;
+ private boolean mHasPassedTaskbarAppWindowThreshold;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
@@ -73,11 +76,18 @@
Resources res = context.getResources();
mUnstashArea = res.getDimensionPixelSize(R.dimen.taskbar_unstash_input_area);
- int taskbarThreshold = res.getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get()
+ int taskbarNavThreshold = res.getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get()
? R.dimen.taskbar_nav_threshold_v2
: R.dimen.taskbar_nav_threshold);
+ int taskbarAppWindowThreshold = res.getDimensionPixelSize(
+ ENABLE_TASKBAR_REVISED_THRESHOLDS.get()
+ ? R.dimen.taskbar_app_window_threshold_v2
+ : R.dimen.taskbar_app_window_threshold);
int screenHeight = taskbarActivityContext.getDeviceProfile().heightPx;
- mTaskbarThresholdY = screenHeight - taskbarThreshold;
+ mTaskbarNavThresholdY = screenHeight - taskbarNavThreshold;
+ mTaskbarAppWindowThresholdY = screenHeight - taskbarAppWindowThreshold;
+ mTaskbarAlreadyOpen = mTaskbarActivityContext != null
+ && !mTaskbarActivityContext.isTaskbarStashed();
mIsTransientTaskbar = DisplayController.isTransientTaskbar(context);
@@ -113,7 +123,8 @@
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
- mHasPassedTaskbarThreshold = false;
+ mHasPassedTaskbarNavThreshold = false;
+ mHasPassedTaskbarAppWindowThreshold = false;
mTaskbarActivityContext.setAutohideSuspendFlag(
FLAG_AUTOHIDE_SUSPEND_TOUCHING, true);
if (isInArea(x)) {
@@ -156,18 +167,23 @@
if (mIsTransientTaskbar) {
float dY = mLastPos.y - mDownPos.y;
- boolean passedTaskbarThreshold = dY < 0
- && mLastPos.y < mTaskbarThresholdY;
+ boolean passedTaskbarNavThreshold = dY < 0
+ && mLastPos.y < mTaskbarNavThresholdY;
+ boolean passedTaskbarAppWindowThreshold = dY < 0
+ && mLastPos.y < mTaskbarAppWindowThresholdY;
- if (!mHasPassedTaskbarThreshold
- && passedTaskbarThreshold) {
- mHasPassedTaskbarThreshold = true;
-
+ if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) {
+ mHasPassedTaskbarNavThreshold = true;
mTaskbarActivityContext.onSwipeToUnstashTaskbar();
}
+ if (mTaskbarAlreadyOpen || (!mHasPassedTaskbarAppWindowThreshold
+ && passedTaskbarAppWindowThreshold)) {
+ mHasPassedTaskbarAppWindowThreshold = true;
+ mTaskbarActivityContext.onSwipeToHideOverlay();
+ }
if (dY < 0) {
- dY = -OverScroll.dampedScroll(-dY, mTaskbarThresholdY);
+ dY = -OverScroll.dampedScroll(-dY, mTaskbarNavThresholdY);
if (mTransitionCallback != null) {
mTransitionCallback.onActionMove(dY);
}
@@ -185,7 +201,8 @@
if (mTransitionCallback != null) {
mTransitionCallback.onActionEnd();
}
- mHasPassedTaskbarThreshold = false;
+ mHasPassedTaskbarNavThreshold = false;
+ mHasPassedTaskbarAppWindowThreshold = false;
break;
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 036ddcc..e0262d0 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -58,9 +58,9 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.Executors;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.util.TISBindHelper;
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 6b016ce..05b246b 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -24,8 +24,8 @@
import android.os.Build;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SwipeUpAnimationLogic;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index d7ff0be..670ee9b 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -42,10 +42,10 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewComponentObserver;
import com.android.quickstep.RecentsAnimationDeviceState;
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 1515c5b..44ad889 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -41,10 +41,10 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
import com.android.launcher3.util.TraceHelper;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 8c43fd1..308249c 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -59,9 +59,10 @@
// TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks.
public class DesktopTaskView extends TaskView {
- /** Flag to indicate whether desktop mode is available on the device */
- public static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean(
- "persist.wm.debug.desktop_mode", false);
+ /** Flags to indicate whether desktop mode is available on the device */
+ public static final boolean DESKTOP_MODE_SUPPORTED =
+ SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false)
+ || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
private static final String TAG = DesktopTaskView.class.getSimpleName();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8b406ec..0e49769 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -135,6 +135,7 @@
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
@@ -159,7 +160,6 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TranslateEdgeEffect;
import com.android.launcher3.util.ViewPool;
-import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.RecentsAnimationController;
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6b4d129..d79c022 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -40,8 +40,8 @@
<string name="add_item_request_drag_hint" msgid="8730547755622776606">"לוחצים לחיצה ארוכה על הווידג\'ט כדי להזיז אותו במסך הבית"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"הוספה למסך הבית"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"הווידג\'ט <xliff:g id="WIDGET_NAME">%1$s</xliff:g> נוסף למסך הבית"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ווידג\'ט אחד}two{# ווידג\'טים}many{# ווידג\'טים}other{# ווידג\'טים}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{קיצור דרך אחד}two{# קיצורי דרך}many{# קיצורי דרך}other{# קיצורי דרך}}"</string>
+ <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ווידג\'ט אחד}one{# ווידג\'טים}two{# ווידג\'טים}other{# ווידג\'טים}}"</string>
+ <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{קיצור דרך אחד}one{# קיצורי דרך}two{# קיצורי דרך}other{# קיצורי דרך}}"</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">"ווידג\'טים"</string>
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"חיפוש"</string>
@@ -89,7 +89,7 @@
<string name="uninstall_system_app_text" msgid="4172046090762920660">"זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"עריכת השם"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> מושבתת"</string>
- <string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{לאפליקציה {app_name} יש התראה אחת}two{לאפליקציה {app_name} יש # התראות}many{לאפליקציה {app_name} יש # התראות}other{לאפליקציה {app_name} יש # התראות}}"</string>
+ <string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{לאפליקציה {app_name} יש התראה אחת}one{לאפליקציה {app_name} יש # התראות}two{לאפליקציה {app_name} יש # התראות}other{לאפליקציה {app_name} יש # התראות}}"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"דף %1$d מתוך %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"מסך הבית %1$d מתוך %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"מסך הבית חדש"</string>
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 9bdc822..61707df 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -30,14 +30,13 @@
import androidx.annotation.IntDef;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
-import com.android.launcher3.views.AppLauncher;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimView;
import java.io.PrintWriter;
@@ -48,8 +47,7 @@
/**
* Launcher BaseActivity
*/
-public abstract class BaseActivity extends Activity implements AppLauncher,
- DeviceProfileListenable {
+public abstract class BaseActivity extends Activity implements ActivityContext {
private static final String TAG = "BaseActivity";
diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java
index ec29b29..3e4e96b 100644
--- a/src/com/android/launcher3/CheckLongPressHelper.java
+++ b/src/com/android/launcher3/CheckLongPressHelper.java
@@ -17,11 +17,12 @@
package com.android.launcher3;
import android.os.Handler;
-import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import com.android.launcher3.util.TouchUtil;
+
/**
* Utility class to handle tripper long press or right click on a view with custom timeout and
* stylus event
@@ -64,7 +65,7 @@
cancelLongPress();
// Mouse right click should immediately trigger a long press
- if (isMouseRightClickDownOrMove(ev)) {
+ if (TouchUtil.isMouseRightClickDownOrMove(ev)) {
mIsInMouseRightClick = true;
triggerLongPress();
final Handler handler = mView.getHandler();
@@ -176,14 +177,4 @@
return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
&& event.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
}
-
- /**
- * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect
- * ACTION_UP from mouse's right button because, in that case,
- * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right).
- */
- private static boolean isMouseRightClickDownOrMove(MotionEvent event) {
- return event.isFromSource(InputDevice.SOURCE_MOUSE)
- && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0);
- }
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 828066a..ce78fce 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -55,7 +55,6 @@
import com.android.launcher3.util.WindowBounds;
import java.io.PrintWriter;
-import java.util.List;
import java.util.Locale;
@SuppressLint("NewApi")
@@ -1631,35 +1630,6 @@
void onDeviceProfileChanged(DeviceProfile dp);
}
- /** Allows registering listeners for {@link DeviceProfile} changes. */
- public interface DeviceProfileListenable {
-
- /** The current device profile. */
- DeviceProfile getDeviceProfile();
-
- /** Registered {@link OnDeviceProfileChangeListener} instances. */
- List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners();
-
- /** Notifies listeners of a {@link DeviceProfile} change. */
- default void dispatchDeviceProfileChanged() {
- DeviceProfile deviceProfile = getDeviceProfile();
- List<OnDeviceProfileChangeListener> listeners = getOnDeviceProfileChangeListeners();
- for (int i = listeners.size() - 1; i >= 0; i--) {
- listeners.get(i).onDeviceProfileChanged(deviceProfile);
- }
- }
-
- /** Register listener for {@link DeviceProfile} changes. */
- default void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
- getOnDeviceProfileChangeListeners().add(listener);
- }
-
- /** Unregister listener for {@link DeviceProfile} changes. */
- default void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
- getOnDeviceProfileChangeListeners().remove(listener);
- }
- }
-
/**
* Handler that deals with ItemInfo of the views for the DeviceProfile
*/
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1a6c68d..18ed0fc 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -43,7 +43,6 @@
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
-import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION;
import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION;
import static com.android.launcher3.logging.StatsLogManager.EventEnum;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
@@ -1280,8 +1279,7 @@
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
- if ((SHOW_DOT_PAGINATION.get() || SHOW_DELIGHTFUL_PAGINATION.get())
- && WorkspacePageIndicator.class.getName().equals(name)) {
+ if ((SHOW_DOT_PAGINATION.get()) && WorkspacePageIndicator.class.getName().equals(name)) {
return LayoutInflater.from(context).inflate(R.layout.page_indicator_dots,
(ViewGroup) parent, false);
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 31a7d18..5dddc6f 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -41,6 +41,7 @@
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.uioverrides.states.AllAppsState;
import com.android.launcher3.uioverrides.states.OverviewState;
+import com.android.launcher3.views.ActivityContext;
import java.util.Arrays;
@@ -261,7 +262,7 @@
*
* 0 means completely zoomed in, without blurs. 1 is zoomed out, with blurs.
*/
- public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ public final <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
float getDepth(DEVICE_PROFILE_CONTEXT context) {
return getDepth(context,
BaseDraggingActivity.fromContext(context).getDeviceProfile().isMultiWindowMode);
@@ -272,7 +273,7 @@
*
* @see #getDepth(Context).
*/
- public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ public final <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
float getDepth(DEVICE_PROFILE_CONTEXT context, boolean isMultiWindowMode) {
if (isMultiWindowMode) {
return 0;
@@ -280,7 +281,7 @@
return getDepthUnchecked(context);
}
- protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ protected <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
return 0f;
}
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 5c55b53..5296df1 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -27,13 +27,12 @@
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.views.AppLauncher;
+import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
@@ -42,8 +41,8 @@
*
* @param <T> Type of context inflating all apps.
*/
-public class ActivityAllAppsContainerView<T extends Context & AppLauncher
- & DeviceProfileListenable> extends BaseAllAppsContainerView<T> {
+public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
+ extends BaseAllAppsContainerView<T> {
private static final long DEFAULT_SEARCH_TRANSITION_DURATION_MS = 300;
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index f308a25..65b4661 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -48,7 +48,6 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget.DragObject;
@@ -81,8 +80,8 @@
*
* @param <T> Type of context inflating all apps.
*/
-public abstract class BaseAllAppsContainerView<T extends Context & ActivityContext
- & DeviceProfileListenable> extends SpringRelativeLayout implements DragSource, Insettable,
+public abstract class BaseAllAppsContainerView<T extends Context & ActivityContext>
+ extends SpringRelativeLayout implements DragSource, Insettable,
OnDeviceProfileChangeListener, OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index 4fb732d..20edf8a 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -26,17 +26,17 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.views.AppLauncher;
+import com.android.launcher3.views.ActivityContext;
/**
* Provides views for local search results.
*/
-public class DefaultSearchAdapterProvider extends SearchAdapterProvider<AppLauncher> {
+public class DefaultSearchAdapterProvider extends SearchAdapterProvider<ActivityContext> {
private final RecyclerView.ItemDecoration mDecoration;
private View mHighlightedView;
- public DefaultSearchAdapterProvider(AppLauncher launcher) {
+ public DefaultSearchAdapterProvider(ActivityContext launcher) {
super(launcher);
mDecoration = new RecyclerView.ItemDecoration() {
@Override
diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/src/com/android/launcher3/anim/AnimatedFloat.java
similarity index 95%
rename from quickstep/src/com/android/quickstep/AnimatedFloat.java
rename to src/com/android/launcher3/anim/AnimatedFloat.java
index 5ab3c58..b73621d 100644
--- a/quickstep/src/com/android/quickstep/AnimatedFloat.java
+++ b/src/com/android/launcher3/anim/AnimatedFloat.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.quickstep;
+package com.android.launcher3.anim;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -98,12 +98,18 @@
}
}
+ /**
+ * Cancels the animation.
+ */
public void cancelAnimation() {
if (mValueAnimator != null) {
mValueAnimator.cancel();
}
}
+ /**
+ * Ends the animation.
+ */
public void finishAnimation() {
if (mValueAnimator != null && mValueAnimator.isRunning()) {
mValueAnimator.end();
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 5cab817..77c920c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -307,10 +307,6 @@
"SCROLL_TOP_TO_RESET", false, "Bring up IME and focus on "
+ "input when scroll to top if 'Always show keyboard' is enabled or in prefix state");
- public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION = getDebugFlag(
- "SHOW_DELIGHTFUL_PAGINATION", false,
- "Enable showing the new 'delightful pagination' which is a brand"
- + " new animation for folder pagination and workspace pagination");
public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag(
"POPUP_MATERIAL_U", false, "Switch popup UX to use material U");
@@ -335,7 +331,7 @@
+ " nav mode and when transient taskbar is enabled.");
public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(
- "ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar.");
+ "ENABLE_TRANSIENT_TASKBAR", true, "Enables transient taskbar.");
public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(
"SECONDARY_DRAG_N_DROP_TO_PIN", false,
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 772913d..e7b0446 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -63,6 +63,7 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Hotseat;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.InvariantDeviceProfile;
@@ -174,6 +175,7 @@
}
}
+ private final List<OnDeviceProfileChangeListener> mDpChangeListeners = new ArrayList<>();
private final Handler mUiHandler;
private final Context mContext;
private final InvariantDeviceProfile mIdp;
@@ -331,6 +333,11 @@
}
@Override
+ public List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
+ return mDpChangeListeners;
+ }
+
+ @Override
public Hotseat getHotseat() {
return mHotseat;
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index e9b6606..c324ce3 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -16,7 +16,6 @@
package com.android.launcher3.pageindicators;
-import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION;
import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION;
import android.animation.Animator;
@@ -32,7 +31,6 @@
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
@@ -48,7 +46,6 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.util.Themes;
/**
@@ -70,7 +67,6 @@
private static final int PAGE_INDICATOR_ALPHA = 255;
private static final int DOT_ALPHA = 128;
private static final int DOT_GAP_FACTOR = 3;
- private static final float DOT_GAP_FACTOR_FLOAT = 3.8f;
private static final int VISIBLE_ALPHA = 1;
private static final int INVISIBLE_ALPHA = 0;
private Paint mPaginationPaint;
@@ -78,8 +74,6 @@
// This value approximately overshoots to 1.5 times the original size.
private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
- private static final float INDICATOR_ROTATION = 180f;
-
private static final RectF sTempRect = new RectF();
private static final FloatProperty<PageIndicatorDots> CURRENT_POSITION =
@@ -112,11 +106,8 @@
};
private final Handler mDelayedPaginationFadeHandler = new Handler(Looper.getMainLooper());
- private final Drawable mPageIndicatorDrawable;
private final float mDotRadius;
private final float mCircleGap;
- private final float mPageIndicatorSize;
- private final float mPageIndicatorRadius;
private final boolean mIsRtl;
private int mNumPages;
@@ -159,31 +150,14 @@
mPaginationPaint.setStyle(Style.FILL);
mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
-
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- mPageIndicatorSize = getResources().getDimension(
- R.dimen.page_indicator_size);
- mPageIndicatorRadius = mPageIndicatorSize / 2;
- mPageIndicatorDrawable = context.getDrawable(R.drawable.page_indicator);
- mPageIndicatorDrawable.setBounds(0, 0, (int) mPageIndicatorSize,
- (int) mPageIndicatorSize);
- mCircleGap = DOT_GAP_FACTOR_FLOAT * mDotRadius;
-
- } else {
- mPageIndicatorSize = 0;
- mPageIndicatorRadius = 0;
- mPageIndicatorDrawable = null;
- mCircleGap = DOT_GAP_FACTOR * mDotRadius;
- }
- if (!SHOW_DELIGHTFUL_PAGINATION.get()) {
- setOutlineProvider(new MyOutlineProver());
- }
+ mCircleGap = DOT_GAP_FACTOR * mDotRadius;
+ setOutlineProvider(new MyOutlineProver());
mIsRtl = Utilities.isRtl(getResources());
}
@Override
public void setScroll(int currentScroll, int totalScroll) {
- if (SHOW_DELIGHTFUL_PAGINATION.get() || SHOW_DOT_PAGINATION.get()) {
+ if (SHOW_DOT_PAGINATION.get()) {
animatePaginationToAlpha(VISIBLE_ALPHA);
}
@@ -197,16 +171,6 @@
}
mTotalScroll = totalScroll;
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- mCurrentScroll = currentScroll;
- invalidate();
-
- if (mShouldAutoHide
- && (getScrollPerPage() == 0 || mCurrentScroll % getScrollPerPage() == 0)) {
- hideAfterDelay();
- }
- return;
- }
int scrollPerPage = totalScroll / (mNumPages - 1);
int pageToLeft = currentScroll / scrollPerPage;
@@ -404,122 +368,45 @@
}
for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) {
mPaginationPaint.setAlpha(i == mActivePage ? PAGE_INDICATOR_ALPHA : DOT_ALPHA);
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- if (i != mActivePage) {
- canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i],
- mPaginationPaint);
- } else {
- drawPageIndicator(canvas, mEntryAnimationRadiusFactors[i]);
- }
- } else {
- canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i],
- mPaginationPaint);
- }
+ canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i],
+ mPaginationPaint);
x += circleGap;
}
} else {
// Here we draw the dots
mPaginationPaint.setAlpha(DOT_ALPHA);
for (int i = 0; i < mNumPages; i++) {
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- canvas.drawCircle(x, y, getRadius(x), mPaginationPaint);
- } else {
- canvas.drawCircle(x, y, mDotRadius, mPaginationPaint);
- }
+ canvas.drawCircle(x, y, mDotRadius, mPaginationPaint);
x += circleGap;
}
// Here we draw the current page indicator
mPaginationPaint.setAlpha(PAGE_INDICATOR_ALPHA);
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- drawPageIndicator(canvas, 1);
- } else {
- canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint);
- }
+ canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint);
}
}
- /**
- * Draws the page indicator, denoting the currently selected page
- *
- * @param canvas is used to draw the page indicator and to rotate it as we scroll
- * @param scale is used to set the scale of our canvas
- */
- private void drawPageIndicator(Canvas canvas, float scale) {
- RectF currRect = getActiveRect();
-
- // saves the canvas so we can later restore it to its original scale
- canvas.save();
-
- // Moves the canvas to start at the top left corner of the page indicator
- canvas.translate(currRect.left, currRect.top);
-
- // Scales the canvas in place to animate the indicator on entry
- canvas.scale(scale, scale, mPageIndicatorRadius, mPageIndicatorRadius);
-
- int scrollPerPage = getScrollPerPage();
- // This IF is to avoid division by 0
- if (scrollPerPage != 0) {
- int delta = mCurrentScroll % scrollPerPage;
- canvas.rotate((INDICATOR_ROTATION * delta) / scrollPerPage,
- mPageIndicatorRadius, mPageIndicatorRadius);
- }
-
- mPageIndicatorDrawable.draw(canvas);
- canvas.restore();
- }
-
- /**
- * Returns the radius of the circle based on how close the page indicator is to it
- *
- * @param dotPositionX is the position the dot is located at in the x-axis
- */
- private float getRadius(float dotPositionX) {
-
- float startXIndicator =
- ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset();
- float indicatorPosition = startXIndicator + getIndicatorScrollDistance()
- + mPageIndicatorRadius;
-
- // If the indicator gets close enough to a dot then we change the radius
- // of the dot based on how close the indicator is to it.
- float dotDistance = Math.abs(indicatorPosition - dotPositionX);
- if (dotDistance <= mCircleGap) {
- return Utilities.mapToRange(dotDistance, 0, mCircleGap, 0f, mDotRadius,
- Interpolators.LINEAR);
- }
- return mDotRadius;
- }
-
private RectF getActiveRect() {
float startCircle = (int) mCurrentPosition;
float delta = mCurrentPosition - startCircle;
float diameter = 2 * mDotRadius;
float startX;
- if (SHOW_DELIGHTFUL_PAGINATION.get()) {
- startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset();
- sTempRect.top = (getHeight() - mPageIndicatorSize) * 0.5f;
- sTempRect.bottom = (getHeight() + mPageIndicatorSize) * 0.5f;
- sTempRect.left = startX + getIndicatorScrollDistance();
- sTempRect.right = sTempRect.left + mPageIndicatorSize;
+ startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2);
+ sTempRect.top = (getHeight() * 0.5f) - mDotRadius;
+ sTempRect.bottom = (getHeight() * 0.5f) + mDotRadius;
+ sTempRect.left = startX + (startCircle * mCircleGap);
+ sTempRect.right = sTempRect.left + diameter;
+
+ if (delta < SHIFT_PER_ANIMATION) {
+ // dot is capturing the right circle.
+ sTempRect.right += delta * mCircleGap * 2;
} else {
- startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2);
- sTempRect.top = (getHeight() * 0.5f) - mDotRadius;
- sTempRect.bottom = (getHeight() * 0.5f) + mDotRadius;
- sTempRect.left = startX + (startCircle * mCircleGap);
- sTempRect.right = sTempRect.left + diameter;
+ // Dot is leaving the left circle.
+ sTempRect.right += mCircleGap;
- if (delta < SHIFT_PER_ANIMATION) {
- // dot is capturing the right circle.
- sTempRect.right += delta * mCircleGap * 2;
- } else {
- // Dot is leaving the left circle.
- sTempRect.right += mCircleGap;
-
- delta -= SHIFT_PER_ANIMATION;
- sTempRect.left += delta * mCircleGap * 2;
- }
+ delta -= SHIFT_PER_ANIMATION;
+ sTempRect.left += delta * mCircleGap * 2;
}
if (mIsRtl) {
@@ -531,29 +418,6 @@
return sTempRect;
}
- /**
- * The offset between the radius of the dot and the midpoint of the indicator so that
- * the indicator is centered in with the indicator circles
- */
- private float getOffset() {
- return mPageIndicatorRadius - mDotRadius;
- }
-
- /**
- * Returns an int that is the amount we need to scroll per page
- */
- private int getScrollPerPage() {
- return mNumPages > 1 ? mTotalScroll / (mNumPages - 1) : 0;
- }
-
- /**
- * The current scroll adjusted for the distance the indicator needs to travel on the screen
- */
- private float getIndicatorScrollDistance() {
- int scrollPerPage = getScrollPerPage();
- return scrollPerPage != 0 ? ((float) mCurrentScroll / scrollPerPage) * mCircleGap : 0;
- }
-
private class MyOutlineProver extends ViewOutlineProvider {
@Override
diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java
index 32378b8..2390425 100644
--- a/src/com/android/launcher3/statemanager/BaseState.java
+++ b/src/com/android/launcher3/statemanager/BaseState.java
@@ -18,7 +18,7 @@
import android.content.Context;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
+import com.android.launcher3.views.ActivityContext;
/**
* Interface representing a state of a StatefulActivity
@@ -37,7 +37,7 @@
/**
* @return How long the animation to this state should take (or from this state to NORMAL).
*/
- <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState);
/**
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index 6cb021b..96ae4a3 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -44,6 +44,7 @@
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.util.TouchUtil;
/**
* Helper class to handle touch on empty space in workspace and show options popup on long press
@@ -105,6 +106,11 @@
if (handleLongPress) {
mLongPressState = STATE_REQUESTED;
mTouchDownPoint.set(ev.getX(), ev.getY());
+ // Mouse right button's ACTION_DOWN should immediately show menu
+ if (TouchUtil.isMouseRightClickDownOrMove(ev)) {
+ maybeShowMenu();
+ return true;
+ }
}
mWorkspace.onTouchEvent(ev);
@@ -185,6 +191,10 @@
@Override
public void onLongPress(MotionEvent event) {
+ maybeShowMenu();
+ }
+
+ private void maybeShowMenu() {
if (mLongPressState == STATE_REQUESTED) {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Workspace.longPress");
if (canHandleLongPress()) {
diff --git a/src/com/android/launcher3/util/TouchUtil.java b/src/com/android/launcher3/util/TouchUtil.java
new file mode 100644
index 0000000..b18a2ef
--- /dev/null
+++ b/src/com/android/launcher3/util/TouchUtil.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+
+/** Util class for touch event. */
+public final class TouchUtil {
+
+ private TouchUtil() {}
+
+ /**
+ * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect
+ * ACTION_UP from mouse's right button because, in that case,
+ * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right).
+ */
+ public static boolean isMouseRightClickDownOrMove(@NonNull MotionEvent event) {
+ return event.isFromSource(InputDevice.SOURCE_MOUSE)
+ && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0);
+ }
+}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index dd5b22e..28085e1 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -17,23 +17,41 @@
import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_KEYBOARD_CLOSED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.Process;
+import android.os.StrictMode;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.inputmethod.InputMethodManager;
+import android.widget.Toast;
import androidx.annotation.Nullable;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
@@ -41,20 +59,30 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.OnboardingPrefs;
+import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.ViewCache;
+import java.util.List;
+
/**
* An interface to be used along with a context for various activities in Launcher. This allows a
* generic class to depend on Context subclass instead of an Activity.
*/
public interface ActivityContext {
+ String TAG = "ActivityContext";
+
default boolean finishAutoCancelActionMode() {
return false;
}
@@ -117,6 +145,28 @@
DeviceProfile getDeviceProfile();
+ /** Registered {@link OnDeviceProfileChangeListener} instances. */
+ List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners();
+
+ /** Notifies listeners of a {@link DeviceProfile} change. */
+ default void dispatchDeviceProfileChanged() {
+ DeviceProfile deviceProfile = getDeviceProfile();
+ List<OnDeviceProfileChangeListener> listeners = getOnDeviceProfileChangeListeners();
+ for (int i = listeners.size() - 1; i >= 0; i--) {
+ listeners.get(i).onDeviceProfileChanged(deviceProfile);
+ }
+ }
+
+ /** Register listener for {@link DeviceProfile} changes. */
+ default void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
+ getOnDeviceProfileChangeListeners().add(listener);
+ }
+
+ /** Unregister listener for {@link DeviceProfile} changes. */
+ default void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
+ getOnDeviceProfileChangeListeners().remove(listener);
+ }
+
default ViewCache getViewCache() {
return new ViewCache();
}
@@ -162,32 +212,6 @@
return false;
}
- /**
- * Returns the ActivityContext associated with the given Context, or throws an exception if
- * the Context is not associated with any ActivityContext.
- */
- static <T extends Context & ActivityContext> T lookupContext(Context context) {
- T activityContext = lookupContextNoThrow(context);
- if (activityContext == null) {
- throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
- }
- return activityContext;
- }
-
- /**
- * Returns the ActivityContext associated with the given Context, or null if
- * the Context is not associated with any ActivityContext.
- */
- static <T extends Context & ActivityContext> T lookupContextNoThrow(Context context) {
- if (context instanceof ActivityContext) {
- return (T) context;
- } else if (context instanceof ContextWrapper) {
- return lookupContextNoThrow(((ContextWrapper) context).getBaseContext());
- } else {
- return null;
- }
- }
-
default View.OnClickListener getItemOnClickListener() {
return v -> {
// No op.
@@ -256,4 +280,187 @@
});
}
}
+
+ /**
+ * Safely starts an activity.
+ *
+ * @param v View starting the activity.
+ * @param intent Base intent being launched.
+ * @param item Item associated with the view.
+ * @return {@code true} if the activity starts successfully.
+ */
+ default boolean startActivitySafely(
+ View v, Intent intent, @Nullable ItemInfo item) {
+
+ Context context = (Context) this;
+ if (isAppBlockedForSafeMode() && !PackageManagerHelper.isSystemApp(context, intent)) {
+ Toast.makeText(context, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
+ UserHandle user = item == null ? null : item.user;
+
+ // Prepare intent
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (v != null) {
+ intent.setSourceBounds(Utilities.getViewBounds(v));
+ }
+ try {
+ boolean isShortcut = (item instanceof WorkspaceItemInfo)
+ && (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
+ || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
+ && !((WorkspaceItemInfo) item).isPromise();
+ if (isShortcut) {
+ // Shortcuts need some special checks due to legacy reasons.
+ startShortcutIntentSafely(intent, optsBundle, item);
+ } else if (user == null || user.equals(Process.myUserHandle())) {
+ // Could be launching some bookkeeping activity
+ context.startActivity(intent, optsBundle);
+ } else {
+ context.getSystemService(LauncherApps.class).startMainActivity(
+ intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
+ }
+ if (item != null) {
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ logAppLaunch(getStatsLogManager(), item, instanceId);
+ }
+ return true;
+ } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
+ Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
+ }
+ return false;
+ }
+
+ /** Returns {@code true} if an app launch is blocked due to safe mode. */
+ default boolean isAppBlockedForSafeMode() {
+ return false;
+ }
+
+ /**
+ * Creates and logs a new app launch event.
+ */
+ default void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
+ InstanceId instanceId) {
+ statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
+ .log(LAUNCHER_APP_LAUNCH_TAP);
+ }
+
+ /**
+ * Returns launch options for an Activity.
+ *
+ * @param v View initiating a launch.
+ * @param item Item associated with the view.
+ */
+ default ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
+ int left = 0, top = 0;
+ int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+ if (v instanceof BubbleTextView) {
+ // Launch from center of icon, not entire view
+ Drawable icon = ((BubbleTextView) v).getIcon();
+ if (icon != null) {
+ Rect bounds = icon.getBounds();
+ left = (width - bounds.width()) / 2;
+ top = v.getPaddingTop();
+ width = bounds.width();
+ height = bounds.height();
+ }
+ }
+ ActivityOptions options =
+ ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
+
+ options.setLaunchDisplayId(
+ (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
+ : Display.DEFAULT_DISPLAY);
+ RunnableList callback = new RunnableList();
+ return new ActivityOptionsWrapper(options, callback);
+ }
+
+ /**
+ * Safely launches an intent for a shortcut.
+ *
+ * @param intent Intent to start.
+ * @param optsBundle Optional launch arguments.
+ * @param info Shortcut information.
+ */
+ default void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
+ try {
+ StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
+ try {
+ // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
+ // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
+ // is enabled by default on NYC.
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
+ .penaltyLog().build());
+
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
+ String packageName = intent.getPackage();
+ startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
+ } else {
+ // Could be launching some bookkeeping activity
+ ((Context) this).startActivity(intent, optsBundle);
+ }
+ } finally {
+ StrictMode.setVmPolicy(oldPolicy);
+ }
+ } catch (SecurityException e) {
+ if (!onErrorStartingShortcut(intent, info)) {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * A wrapper around the platform method with Launcher specific checks.
+ */
+ default void startShortcut(String packageName, String id, Rect sourceBounds,
+ Bundle startActivityOptions, UserHandle user) {
+ if (GO_DISABLE_WIDGETS) {
+ return;
+ }
+ try {
+ ((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id,
+ sourceBounds, startActivityOptions, user);
+ } catch (SecurityException | IllegalStateException e) {
+ Log.e(TAG, "Failed to start shortcut", e);
+ }
+ }
+
+ /**
+ * Invoked when a shortcut fails to launch.
+ * @param intent Shortcut intent that failed to start.
+ * @param info Shortcut information.
+ * @return {@code true} if the error is handled by this callback.
+ */
+ default boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
+ return false;
+ }
+
+ /**
+ * Returns the ActivityContext associated with the given Context, or throws an exception if
+ * the Context is not associated with any ActivityContext.
+ */
+ static <T extends Context & ActivityContext> T lookupContext(Context context) {
+ T activityContext = lookupContextNoThrow(context);
+ if (activityContext == null) {
+ throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
+ }
+ return activityContext;
+ }
+
+ /**
+ * Returns the ActivityContext associated with the given Context, or null if
+ * the Context is not associated with any ActivityContext.
+ */
+ static <T extends Context & ActivityContext> T lookupContextNoThrow(Context context) {
+ if (context instanceof ActivityContext) {
+ return (T) context;
+ } else if (context instanceof ContextWrapper) {
+ return lookupContextNoThrow(((ContextWrapper) context).getBaseContext());
+ } else {
+ return null;
+ }
+ }
}
diff --git a/src/com/android/launcher3/views/AppLauncher.java b/src/com/android/launcher3/views/AppLauncher.java
deleted file mode 100644
index 19e66ab..0000000
--- a/src/com/android/launcher3/views/AppLauncher.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2022 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.views;
-
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
-
-import android.app.ActivityOptions;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.StrictMode;
-import android.os.UserHandle;
-import android.util.Log;
-import android.view.Display;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.InstanceIdSequence;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.RunnableList;
-
-/** An {@link ActivityContext} that can also launch app activities and shortcuts safely. */
-public interface AppLauncher extends ActivityContext {
-
- String TAG = "AppLauncher";
-
- /**
- * Safely starts an activity.
- *
- * @param v View starting the activity.
- * @param intent Base intent being launched.
- * @param item Item associated with the view.
- * @return {@code true} if the activity starts successfully.
- */
- default boolean startActivitySafely(
- View v, Intent intent, @Nullable ItemInfo item) {
-
- Context context = (Context) this;
- if (isAppBlockedForSafeMode() && !PackageManagerHelper.isSystemApp(context, intent)) {
- Toast.makeText(context, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
- return false;
- }
-
- Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
- UserHandle user = item == null ? null : item.user;
-
- // Prepare intent
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (v != null) {
- intent.setSourceBounds(Utilities.getViewBounds(v));
- }
- try {
- boolean isShortcut = (item instanceof WorkspaceItemInfo)
- && (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
- || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
- && !((WorkspaceItemInfo) item).isPromise();
- if (isShortcut) {
- // Shortcuts need some special checks due to legacy reasons.
- startShortcutIntentSafely(intent, optsBundle, item);
- } else if (user == null || user.equals(Process.myUserHandle())) {
- // Could be launching some bookkeeping activity
- context.startActivity(intent, optsBundle);
- } else {
- context.getSystemService(LauncherApps.class).startMainActivity(
- intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
- }
- if (item != null) {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- logAppLaunch(getStatsLogManager(), item, instanceId);
- }
- return true;
- } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
- Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
- }
- return false;
- }
-
- /** Returns {@code true} if an app launch is blocked due to safe mode. */
- default boolean isAppBlockedForSafeMode() {
- return false;
- }
-
- /**
- * Creates and logs a new app launch event.
- */
- default void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
- InstanceId instanceId) {
- statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
- .log(LAUNCHER_APP_LAUNCH_TAP);
- }
-
- /**
- * Returns launch options for an Activity.
- *
- * @param v View initiating a launch.
- * @param item Item associated with the view.
- */
- default ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- int left = 0, top = 0;
- int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof BubbleTextView) {
- // Launch from center of icon, not entire view
- Drawable icon = ((BubbleTextView) v).getIcon();
- if (icon != null) {
- Rect bounds = icon.getBounds();
- left = (width - bounds.width()) / 2;
- top = v.getPaddingTop();
- width = bounds.width();
- height = bounds.height();
- }
- }
- ActivityOptions options =
- ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
-
- options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
- RunnableList callback = new RunnableList();
- return new ActivityOptionsWrapper(options, callback);
- }
-
- /**
- * Safely launches an intent for a shortcut.
- *
- * @param intent Intent to start.
- * @param optsBundle Optional launch arguments.
- * @param info Shortcut information.
- */
- default void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
- try {
- StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
- try {
- // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
- // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
- // is enabled by default on NYC.
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
- .penaltyLog().build());
-
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
- String packageName = intent.getPackage();
- startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
- } else {
- // Could be launching some bookkeeping activity
- ((Context) this).startActivity(intent, optsBundle);
- }
- } finally {
- StrictMode.setVmPolicy(oldPolicy);
- }
- } catch (SecurityException e) {
- if (!onErrorStartingShortcut(intent, info)) {
- throw e;
- }
- }
- }
-
- /**
- * A wrapper around the platform method with Launcher specific checks.
- */
- default void startShortcut(String packageName, String id, Rect sourceBounds,
- Bundle startActivityOptions, UserHandle user) {
- if (GO_DISABLE_WIDGETS) {
- return;
- }
- try {
- ((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id,
- sourceBounds, startActivityOptions, user);
- } catch (SecurityException | IllegalStateException e) {
- Log.e(TAG, "Failed to start shortcut", e);
- }
- }
-
- /**
- * Invoked when a shortcut fails to launch.
- * @param intent Shortcut intent that failed to start.
- * @param info Shortcut information.
- * @return {@code true} if the error is handled by this callback.
- */
- default boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
- return false;
- }
-}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 622516f..5b57e22 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -139,12 +139,12 @@
mTargetRect.roundOut(outPos);
}
- public static OptionsPopupView show(AppLauncher launcher, RectF targetRect,
+ public static OptionsPopupView show(ActivityContext launcher, RectF targetRect,
List<OptionItem> items, boolean shouldAddArrow) {
return show(launcher, targetRect, items, shouldAddArrow, 0 /* width */);
}
- public static OptionsPopupView show(AppLauncher launcher, RectF targetRect,
+ public static OptionsPopupView show(ActivityContext launcher, RectF targetRect,
List<OptionItem> items, boolean shouldAddArrow, int width) {
OptionsPopupView popup = (OptionsPopupView) launcher.getLayoutInflater()
.inflate(R.layout.longpress_options_menu, launcher.getDragLayer(), false);
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index a581f91..772a995 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,11 +20,11 @@
import android.content.Context;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ActivityContext;
/**
* Definition for AllApps state
@@ -40,7 +40,7 @@
}
@Override
- public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ public <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
return isToState
? context.getDeviceProfile().allAppsOpenDuration
diff --git a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
index 2618a2e..191d284 100644
--- a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
+++ b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
@@ -20,15 +20,21 @@
import android.view.ContextThemeWrapper;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* {@link ContextWrapper} with internal Launcher interface for testing
*/
public class ActivityContextWrapper extends ContextThemeWrapper implements ActivityContext {
+ private final List<OnDeviceProfileChangeListener> mDpChangeListeners = new ArrayList<>();
+
private final DeviceProfile mProfile;
private final MyDragLayer mMyDragLayer;
@@ -44,6 +50,11 @@
}
@Override
+ public List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
+ return mDpChangeListeners;
+ }
+
+ @Override
public DeviceProfile getDeviceProfile() {
return mProfile;
}
diff --git a/tests/src/com/android/launcher3/util/TouchUtilTest.kt b/tests/src/com/android/launcher3/util/TouchUtilTest.kt
new file mode 100644
index 0000000..d6c6e91
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/TouchUtilTest.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util
+
+import android.view.InputDevice
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Unit tests for [TouchUtil] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TouchUtilTest {
+
+ @Test
+ fun isMouseRightClickDownOrMove_onMouseRightButton_returnsTrue() {
+ val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
+ ev.source = InputDevice.SOURCE_MOUSE
+ ev.buttonState = MotionEvent.BUTTON_SECONDARY
+
+ assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isTrue()
+ }
+
+ @Test
+ fun isMouseRightClickDownOrMove_onMouseLeftButton_returnsFalse() {
+ val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
+ ev.source = InputDevice.SOURCE_MOUSE
+ ev.buttonState = MotionEvent.BUTTON_PRIMARY
+
+ assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
+ }
+
+ @Test
+ fun isMouseRightClickDownOrMove_onMouseTertiaryButton_returnsFalse() {
+ val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
+ ev.source = InputDevice.SOURCE_MOUSE
+ ev.buttonState = MotionEvent.BUTTON_TERTIARY
+
+ assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
+ }
+
+ @Test
+ fun isMouseRightClickDownOrMove_onDpadRightButton_returnsFalse() {
+ val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
+ ev.source = InputDevice.SOURCE_DPAD
+ ev.buttonState = MotionEvent.BUTTON_SECONDARY
+
+ assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
+ }
+}