Snap for 9712227 from 19c08777459a4a301411ead33cac328199cf82ee to tm-qpr3-release
Change-Id: Iafe21462f49ef9aa6c2d3d61e7ea2d0107b2e03c
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index c638ba9..b1064f7 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -128,10 +128,17 @@
// Bit encoded value to capture pinned and predicted taskbar positions.
optional int32 cardinality = 2;
+
+ // Container where taskbar was invoked.
+ oneof ParentContainer {
+ TaskSwitcherContainer task_switcher_container = 3;
+ }
}
// Next value 44
enum Attribute {
+ option allow_alias = true;
+
UNKNOWN = 0;
DEFAULT_LAYOUT = 1; // icon automatically placed in workspace, folder, hotseat
BACKUP_RESTORE = 2; // icon layout restored from backup
@@ -166,7 +173,8 @@
ALL_APPS_SEARCH_RESULT_SLICE = 19;
ALL_APPS_SEARCH_RESULT_WIDGETS = 20;
ALL_APPS_SEARCH_RESULT_PLAY = 21;
- ALL_APPS_SEARCH_RESULT_SUGGEST = 22;
+ ALL_APPS_SEARCH_RESULT_FALLBACK = 22;
+ ALL_APPS_SEARCH_RESULT_SUGGEST = 22 [deprecated = true];
ALL_APPS_SEARCH_RESULT_ASSISTANT = 23;
ALL_APPS_SEARCH_RESULT_CHROMETAB = 24;
ALL_APPS_SEARCH_RESULT_NAVVYSITE = 25;
diff --git a/quickstep/res/drawable/ic_desktop.xml b/quickstep/res/drawable/ic_desktop.xml
index dfaf8b8..8de275d 100644
--- a/quickstep/res/drawable/ic_desktop.xml
+++ b/quickstep/res/drawable/ic_desktop.xml
@@ -25,7 +25,7 @@
android:translateX="6.0"
android:translateY="6.0">
<path
- android:fillColor="?android:attr/textColorPrimary"
+ android:fillColor="@android:color/black"
android:pathData="M5.958,37.708Q4.458,37.708 3.354,36.604Q2.25,35.5 2.25,34V18.292Q2.25,16.792 3.354,15.688Q4.458,14.583 5.958,14.583H9.5V5.958Q9.5,4.458 10.625,3.354Q11.75,2.25 13.208,2.25H34Q35.542,2.25 36.646,3.354Q37.75,4.458 37.75,5.958V21.667Q37.75,23.167 36.646,24.271Q35.542,25.375 34,25.375H30.5V34Q30.5,35.5 29.396,36.604Q28.292,37.708 26.792,37.708ZM5.958,34H26.792Q26.792,34 26.792,34Q26.792,34 26.792,34V21.542H5.958V34Q5.958,34 5.958,34Q5.958,34 5.958,34ZM30.5,21.667H34Q34,21.667 34,21.667Q34,21.667 34,21.667V9.208H13.208V14.583H26.833Q28.375,14.583 29.438,15.667Q30.5,16.75 30.5,18.25Z"/>
</group>
</vector>
diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml
index f08cabe..7ea92b5 100644
--- a/quickstep/res/layout/activity_allset.xml
+++ b/quickstep/res/layout/activity_allset.xml
@@ -38,6 +38,7 @@
app:lottie_loop="true" />
<androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/text_content_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/allset_page_margin_horizontal"
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 793c68e..95fea3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -341,6 +341,11 @@
}
@Override
+ protected boolean isInOverview() {
+ return mTaskbarLauncherStateController.isInOverview();
+ }
+
+ @Override
public RecentsView getRecentsView() {
return mLauncher.getOverviewPanel();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 2864ac7..81389ab 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -432,11 +432,16 @@
}
LauncherAtom.ContainerInfo oldContainer = itemInfoBuilder.getContainerInfo();
+ LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
+ LauncherAtom.TaskBarContainer.newBuilder();
+ if (mControllers.uiController.isInOverview()) {
+ taskbarBuilder.setTaskSwitcherContainer(
+ LauncherAtom.TaskSwitcherContainer.newBuilder());
+ }
+
if (oldContainer.hasPredictedHotseatContainer()) {
LauncherAtom.PredictedHotseatContainer predictedHotseat =
oldContainer.getPredictedHotseatContainer();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
if (predictedHotseat.hasIndex()) {
taskbarBuilder.setIndex(predictedHotseat.getIndex());
@@ -449,8 +454,6 @@
.setTaskBarContainer(taskbarBuilder));
} else if (oldContainer.hasHotseat()) {
LauncherAtom.HotseatContainer hotseat = oldContainer.getHotseat();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
if (hotseat.hasIndex()) {
taskbarBuilder.setIndex(hotseat.getIndex());
@@ -462,8 +465,6 @@
LauncherAtom.FolderContainer.Builder folderBuilder = oldContainer.getFolder()
.toBuilder();
LauncherAtom.HotseatContainer hotseat = folderBuilder.getHotseat();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
if (hotseat.hasIndex()) {
taskbarBuilder.setIndex(hotseat.getIndex());
@@ -476,11 +477,11 @@
} else if (oldContainer.hasAllAppsContainer()) {
itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setAllAppsContainer(oldContainer.getAllAppsContainer().toBuilder()
- .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
+ .setTaskbarContainer(taskbarBuilder)));
} else if (oldContainer.hasPredictionContainer()) {
itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setPredictionContainer(oldContainer.getPredictionContainer().toBuilder()
- .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
+ .setTaskbarContainer(taskbarBuilder)));
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 5ac0570..4d163aa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -406,6 +406,10 @@
return mLauncherState != LauncherState.ALL_APPS;
}
+ boolean isInOverview() {
+ return mLauncherState == LauncherState.OVERVIEW;
+ }
+
private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
boolean committed) {
boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index b552e9b..033b075 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -166,6 +166,11 @@
return true;
}
+ /** Returns {@code true} if Taskbar is currently within overview. */
+ protected boolean isInOverview() {
+ return false;
+ }
+
@CallSuper
protected void dumpLogs(String prefix, PrintWriter pw) {
pw.println(String.format(
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index a53f08a..e268d1b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -40,6 +40,9 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
+import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
+import static com.android.launcher3.popup.SystemShortcut.INSTALL;
+import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
@@ -186,6 +189,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
@@ -385,22 +390,30 @@
@Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
- Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
- if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
- RecentsView recentsView = getOverviewPanel();
- // TODO(b/266482558): Pull it out of PagedOrentationHandler for split from workspace.
- List<SplitPositionOption> positions =
- recentsView.getPagedOrientationHandler().getSplitPositionOptions(
- mDeviceProfile);
- List<SystemShortcut.Factory<QuickstepLauncher>> splitShortcuts = new ArrayList<>();
- for (SplitPositionOption position : positions) {
- splitShortcuts.add(getSplitSelectShortcutByPosition(position));
- }
- base = Stream.concat(base, splitShortcuts.stream());
+ // Order matters as it affects order of appearance in popup container
+ List<SystemShortcut.Factory> shortcuts = new ArrayList(Arrays.asList(
+ APP_INFO, WellbeingModel.SHORTCUT_FACTORY, mHotseatPredictionController));
+ shortcuts.addAll(getSplitShortcuts());
+ shortcuts.add(WIDGETS);
+ shortcuts.add(INSTALL);
+ return shortcuts.stream();
+ }
+
+ private List<SystemShortcut.Factory<QuickstepLauncher>> getSplitShortcuts() {
+
+ if (!ENABLE_SPLIT_FROM_WORKSPACE.get() || !mDeviceProfile.isTablet) {
+ return Collections.emptyList();
}
- return Stream.concat(
- Stream.of(mHotseatPredictionController),
- Stream.concat(base, super.getSupportedShortcuts()));
+ RecentsView recentsView = getOverviewPanel();
+ // TODO(b/266482558): Pull it out of PagedOrentationHandler for split from workspace.
+ List<SplitPositionOption> positions =
+ recentsView.getPagedOrientationHandler().getSplitPositionOptions(
+ mDeviceProfile);
+ List<SystemShortcut.Factory<QuickstepLauncher>> splitShortcuts = new ArrayList<>();
+ for (SplitPositionOption position : positions) {
+ splitShortcuts.add(getSplitSelectShortcutByPosition(position));
+ }
+ return splitShortcuts;
}
/**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
index 177a399..d4944d0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
@@ -24,8 +24,6 @@
public final boolean defaultValue;
- boolean mHasBeenChangedAtLeastOnce;
-
public DebugFlag(String key, String description, boolean defaultValue, boolean currentValue) {
super(currentValue);
this.key = key;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
index 4ca7e31..b7fb2ed 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
@@ -35,6 +35,9 @@
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
+import java.util.List;
+import java.util.Set;
+
/**
* Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
*/
@@ -50,31 +53,15 @@
@Override
public void putBoolean(String key, boolean value) {
- for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
- if (flag.key.equals(key)) {
- SharedPreferences prefs = mContext.getSharedPreferences(
- FLAGS_PREF_NAME, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = prefs.edit();
- // We keep the key in the prefs even if it has the default value, because it's a
- // signal that it has been changed at one point.
- if (!prefs.contains(key) && value == flag.defaultValue) {
- editor.remove(key).apply();
- flag.mHasBeenChangedAtLeastOnce = false;
- } else {
- editor.putBoolean(key, value).apply();
- flag.mHasBeenChangedAtLeastOnce = true;
- }
- updateMenu();
- }
- }
+ mSharedPreferences.edit().putBoolean(key, value).apply();
+ updateMenu();
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
if (flag.key.equals(key)) {
- return mContext.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
- .getBoolean(key, flag.defaultValue);
+ return mSharedPreferences.getBoolean(key, flag.defaultValue);
}
}
return defaultValue;
@@ -89,11 +76,22 @@
}
public void applyTo(PreferenceGroup parent) {
+ Set<String> modifiedPrefs = mSharedPreferences.getAll().keySet();
+ List<DebugFlag> flags = FlagsFactory.getDebugFlags();
+ flags.sort((f1, f2) -> {
+ // Sort first by any prefs that the user has changed, then alphabetically.
+ int changeComparison = Boolean.compare(
+ modifiedPrefs.contains(f2.key), modifiedPrefs.contains(f1.key));
+ return changeComparison != 0
+ ? changeComparison
+ : f1.key.compareToIgnoreCase(f2.key);
+ });
+
// For flag overrides we only want to store when the engineer chose to override the
// flag with a different value than the default. That way, when we flip flags in
// future, engineers will pick up the new value immediately. To accomplish this, we use a
// custom preference data store.
- for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
+ for (DebugFlag flag : flags) {
SwitchPreference switchPreference = new SwitchPreference(mContext);
switchPreference.setKey(flag.key);
switchPreference.setDefaultValue(flag.defaultValue);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 84b873d..888cc9d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -53,7 +53,6 @@
private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
-
private final Set<String> mKeySet = new HashSet<>();
private boolean mRestartRequested = false;
@@ -75,7 +74,6 @@
.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE);
boolean currentValue = prefs.getBoolean(key, defaultValue);
DebugFlag flag = new DebugFlag(key, description, defaultValue, currentValue);
- flag.mHasBeenChangedAtLeastOnce = prefs.contains(key);
sDebugFlags.add(flag);
return flag;
} else {
@@ -96,7 +94,6 @@
boolean currentValue = prefs.getBoolean(key, defaultValue);
DebugFlag flag = new DeviceFlag(key, description, defaultValue, currentValue,
defaultValueInCode);
- flag.mHasBeenChangedAtLeastOnce = prefs.contains(key);
sDebugFlags.add(flag);
return flag;
} else {
@@ -117,19 +114,9 @@
if (!Utilities.IS_DEBUG_DEVICE) {
return Collections.emptyList();
}
- List<DebugFlag> flags;
synchronized (sDebugFlags) {
- flags = new ArrayList<>(sDebugFlags);
+ return new ArrayList<>(sDebugFlags);
}
- flags.sort((f1, f2) -> {
- // Sort first by any prefs that the user has changed, then alphabetically.
- int changeComparison = Boolean.compare(
- f2.mHasBeenChangedAtLeastOnce, f1.mHasBeenChangedAtLeastOnce);
- return changeComparison != 0
- ? changeComparison
- : f1.key.compareToIgnoreCase(f2.key);
- });
- return flags;
}
/**
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 0389d07..79971de 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -88,6 +88,10 @@
private static final float ANIMATION_PAUSE_ALPHA_THRESHOLD = 0.1f;
+ private final Rect mTempSettingsBounds = new Rect();
+ private final Rect mTempInclusionBounds = new Rect();
+ private final Rect mTempExclusionBounds = new Rect();
+
private TISBindHelper mTISBindHelper;
private TISBinder mBinder;
@@ -131,9 +135,9 @@
!TextUtils.isEmpty(suwDeviceName)
? suwDeviceName : getString(R.string.default_device_name)));
- TextView tv = findViewById(R.id.navigation_settings);
- tv.setTextColor(accentColor);
- tv.setOnClickListener(v -> {
+ TextView settings = findViewById(R.id.navigation_settings);
+ settings.setTextColor(accentColor);
+ settings.setOnClickListener(v -> {
try {
startActivityForResult(
Intent.parseUri(URI_SYSTEM_NAVIGATION_SETTING, 0), 0);
@@ -142,12 +146,41 @@
}
});
- TextView hintTextView = findViewById(R.id.hint);
+ TextView hint = findViewById(R.id.hint);
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
if (!dp.isGestureMode) {
- hintTextView.setText(R.string.allset_button_hint);
+ hint.setText(R.string.allset_button_hint);
}
- hintTextView.setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
+ hint.setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
+
+ View textContent = findViewById(R.id.text_content_view);
+ textContent.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ mTempSettingsBounds.set(
+ settings.getLeft(),
+ settings.getTop(),
+ settings.getRight(),
+ settings.getBottom());
+ mTempInclusionBounds.set(
+ 0,
+ // Do not allow overlapping with the subtitle text
+ subtitle.getBottom(),
+ textContent.getWidth(),
+ textContent.getHeight());
+ mTempExclusionBounds.set(
+ hint.getLeft(),
+ hint.getTop(),
+ hint.getRight(),
+ hint.getBottom());
+
+ Utilities.translateOverlappingView(
+ settings,
+ mTempSettingsBounds,
+ mTempInclusionBounds,
+ mTempExclusionBounds,
+ Utilities.TRANSLATE_UP);
+ });
+
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
mVibrator = getSystemService(Vibrator.class);
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index bd0ce34..b508484 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.Insets;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -34,6 +35,10 @@
/** Root layout that TutorialFragment uses to intercept motion events. */
public class RootSandboxLayout extends RelativeLayout {
+ private final Rect mTempStepIndicatorBounds = new Rect();
+ private final Rect mTempInclusionBounds = new Rect();
+ private final Rect mTempExclusionBounds = new Rect();
+
private View mFeedbackView;
private View mTutorialStepView;
private View mSkipButton;
@@ -98,18 +103,23 @@
private void updateTutorialStepViewTranslation(
@NonNull View anchorView, boolean translateToRight) {
- mTutorialStepView.setTranslationX(translateToRight
- ? Math.min(
- // Translate to the right if the views are overlapping on large fonts and
- // display sizes.
- Math.max(0, anchorView.getRight() - mTutorialStepView.getLeft()),
- // Do not translate beyond the bounds of the container view.
- mFeedbackView.getWidth() - mTutorialStepView.getRight())
- : Math.max(
- // Translate to the left if the views are overlapping on large fonts and
- // display sizes.
- Math.min(0, anchorView.getLeft() - mTutorialStepView.getRight()),
- // Do not translate beyond the bounds of the container view.
- -mTutorialStepView.getLeft()));
+ mTempStepIndicatorBounds.set(
+ mTutorialStepView.getLeft(),
+ mTutorialStepView.getTop(),
+ mTutorialStepView.getRight(),
+ mTutorialStepView.getBottom());
+ mTempInclusionBounds.set(0, 0, mFeedbackView.getWidth(), mFeedbackView.getHeight());
+ mTempExclusionBounds.set(
+ anchorView.getLeft(),
+ anchorView.getTop(),
+ anchorView.getRight(),
+ anchorView.getBottom());
+
+ Utilities.translateOverlappingView(
+ mTutorialStepView,
+ mTempStepIndicatorBounds,
+ mTempInclusionBounds,
+ mTempExclusionBounds,
+ translateToRight ? Utilities.TRANSLATE_RIGHT : Utilities.TRANSLATE_LEFT);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index adea1a4..4ea7753 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -27,8 +27,10 @@
import android.view.ViewOutlineProvider;
import android.widget.RemoteViews.RemoteViewOutlineProvider;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.R;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.RoundedCornerEnforcement;
@@ -65,14 +67,20 @@
setClipToOutline(true);
}
- void init(LauncherAppWidgetHostView hostView, View backgroundView, float finalRadius,
- int fallbackBackgroundColor) {
+ void init(LauncherAppWidgetHostView hostView, @NonNull View backgroundView,
+ float finalRadius, int fallbackBackgroundColor) {
mFinalRadius = finalRadius;
mSourceView = backgroundView;
mInitialOutlineRadius = getOutlineRadius(hostView, backgroundView);
mIsUsingFallback = false;
if (isSupportedDrawable(backgroundView.getForeground())) {
- mOriginalForeground = backgroundView.getForeground();
+ if (backgroundView.getTag(R.id.saved_floating_widget_foreground) == null) {
+ mOriginalForeground = backgroundView.getForeground();
+ backgroundView.setTag(R.id.saved_floating_widget_foreground, mOriginalForeground);
+ } else {
+ mOriginalForeground = (Drawable) backgroundView.getTag(
+ R.id.saved_floating_widget_foreground);
+ }
mForegroundProperties.init(
mOriginalForeground.getConstantState().newDrawable().mutate());
setForeground(mForegroundProperties.mDrawable);
@@ -82,7 +90,13 @@
mSourceView.setForeground(clipPlaceholder);
}
if (isSupportedDrawable(backgroundView.getBackground())) {
- mOriginalBackground = backgroundView.getBackground();
+ if (backgroundView.getTag(R.id.saved_floating_widget_background) == null) {
+ mOriginalBackground = backgroundView.getBackground();
+ backgroundView.setTag(R.id.saved_floating_widget_background, mOriginalBackground);
+ } else {
+ mOriginalBackground = (Drawable) backgroundView.getTag(
+ R.id.saved_floating_widget_background);
+ }
mBackgroundProperties.init(
mOriginalBackground.getConstantState().newDrawable().mutate());
setBackground(mBackgroundProperties.mDrawable);
@@ -115,6 +129,10 @@
}
void recycle() {
+ if (mSourceView != null) {
+ mSourceView.setTag(R.id.saved_floating_widget_foreground, null);
+ mSourceView.setTag(R.id.saved_floating_widget_background, null);
+ }
mSourceView = null;
mOriginalForeground = null;
mOriginalBackground = null;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ac59403..659de37 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -147,8 +147,6 @@
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource;
@@ -4493,7 +4491,6 @@
* Attempts to initiate split with an existing taskView, if one exists
*/
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "enterSplitSelect");
mSplitSelectSource = splitSelectSource;
mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
deleted file mode 100644
index f10b917..0000000
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2023 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.quickstep;
-
-import android.content.Intent;
-
-import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.rule.TestStabilityRule;
-import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
-
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TaplTestsSplitscreen extends AbstractQuickStepTest {
- private static final String CALCULATOR_APP_NAME = "Calculator";
- private static final String CALCULATOR_APP_PACKAGE =
- resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- TaplTestsLauncher3.initialize(this);
-
- mLauncher.getWorkspace()
- .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
- .switchToAllApps()
- .getAppIcon(CALCULATOR_APP_NAME)
- .dragToHotseat(0);
-
- startAppFast(CALCULATOR_APP_PACKAGE);
- mLauncher.enableBlockTimeout(true);
- mLauncher.showTaskbarIfHidden();
- }
-
- @After
- public void tearDown() {
- mLauncher.enableBlockTimeout(false);
- }
-
- @Test
- // TODO (b/270201357): When this test is proven stable, remove this TestStabilityRule and
- // introduce into presubmit as well.
- @TestStabilityRule.Stability(
- flavors = TestStabilityRule.LOCAL | TestStabilityRule.PLATFORM_POSTSUBMIT)
- @PortraitLandscape
- @TaskbarModeSwitch
- public void testSplitAppFromHomeWithItself() throws Exception {
- Assume.assumeTrue(mLauncher.isTablet());
-
- mLauncher.goHome()
- .switchToAllApps()
- .getAppIcon(CALCULATOR_APP_NAME)
- .openMenu()
- .getSplitScreenMenuItem()
- .click();
-
- mLauncher.getLaunchedAppState()
- .getTaskbar()
- .getAppIcon(CALCULATOR_APP_NAME)
- .launchIntoSplitScreen();
- }
-}
diff --git a/res/drawable/ic_split_horizontal.xml b/res/drawable/ic_split_horizontal.xml
index ee710d0..2efd2b9 100644
--- a/res/drawable/ic_split_horizontal.xml
+++ b/res/drawable/ic_split_horizontal.xml
@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="16dp"
- android:viewportWidth="20"
- android:viewportHeight="16">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:pathData="M18,14L13,14L13,2L18,2L18,14ZM20,14L20,2C20,0.9 19.1,-0 18,-0L13,-0C11.9,-0 11,0.9 11,2L11,14C11,15.1 11.9,16 13,16L18,16C19.1,16 20,15.1 20,14ZM7,14L2,14L2,2L7,2L7,14ZM9,14L9,2C9,0.9 8.1,-0 7,-0L2,-0C0.9,-0 -0,0.9 -0,2L-0,14C-0,15.1 0.9,16 2,16L7,16C8.1,16 9,15.1 9,14Z"
+ android:pathData="M4,6L9,6L9,18L4,18L4,6ZM2,6L2,18C2,19.1 2.9,20 4,20L9,20C10.1,20 11,19.1 11,18L11,6C11,4.9 10.1,4 9,4L4,4C2.9,4 2,4.9 2,6ZM15,6L20,6L20,18L15,18L15,6ZM13,6L13,18C13,19.1 13.9,20 15,20L20,20C21.1,20 22,19.1 22,18L22,6C22,4.9 21.1,4 20,4L15,4C13.9,4 13,4.9 13,6Z"
android:fillColor="#000000"/>
</vector>
diff --git a/res/layout/system_shortcut_icons_container.xml b/res/layout/system_shortcut_icons_container.xml
index ee104d9..dc4fdb3 100644
--- a/res/layout/system_shortcut_icons_container.xml
+++ b/res/layout/system_shortcut_icons_container.xml
@@ -22,11 +22,4 @@
android:orientation="horizontal"
android:gravity="end|center_vertical"
android:background="@drawable/single_item_primary"
- android:elevation="@dimen/deep_shortcuts_elevation"
- android:clipToPadding="true">
-
- <Space android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:id="@+id/separator"/>
-</LinearLayout>
+ android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_icons_container_material_u.xml b/res/layout/system_shortcut_icons_container_material_u.xml
index afd11e6..70950ba 100644
--- a/res/layout/system_shortcut_icons_container_material_u.xml
+++ b/res/layout/system_shortcut_icons_container_material_u.xml
@@ -23,10 +23,4 @@
android:orientation="horizontal"
android:gravity="end|center_vertical"
android:background="@drawable/popup_background_material_u"
- android:elevation="@dimen/deep_shortcuts_elevation">
-
- <Space android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:id="@+id/separator"/>
-</LinearLayout>
+ android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_rows_container_material_u.xml b/res/layout/system_shortcut_rows_container.xml
similarity index 100%
rename from res/layout/system_shortcut_rows_container_material_u.xml
rename to res/layout/system_shortcut_rows_container.xml
diff --git a/res/layout/system_shortcut_spacer.xml b/res/layout/system_shortcut_spacer.xml
new file mode 100644
index 0000000..60ea9ec
--- /dev/null
+++ b/res/layout/system_shortcut_spacer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<Space
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:id="@+id/shortcut_spacer"/>
\ No newline at end of file
diff --git a/res/values/id.xml b/res/values/id.xml
index 375750f..dc81944 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -38,4 +38,7 @@
<item type="id" name="cache_entry_tag_id" />
<item type="id" name="saved_clip_children_tag_id" />
+
+ <item type="id" name="saved_floating_widget_foreground" />
+ <item type="id" name="saved_floating_widget_background" />
</resources>
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index c7431ed..e3bce87 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1370,8 +1370,14 @@
int velocity = (int) mOrientationHandler.getPrimaryVelocity(velocityTracker,
mActivePointerId);
float delta = primaryDirection - mDownMotionPrimary;
- int pageOrientedSize = (int) (mOrientationHandler.getMeasuredSize(
- getPageAt(mCurrentPage))
+
+ View current = getPageAt(mCurrentPage);
+ if (current == null) {
+ Log.e(TAG, "current page was null. this should not happen.");
+ return true;
+ }
+
+ int pageOrientedSize = (int) (mOrientationHandler.getMeasuredSize(current)
* mOrientationHandler.getPrimaryScale(this));
boolean isSignificantMove = isSignificantMove(Math.abs(delta), pageOrientedSize);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 59327dc..0fbaecb 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -65,6 +65,7 @@
import android.view.animation.Interpolator;
import androidx.annotation.ChecksSdkIntAtLeast;
+import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
@@ -136,6 +137,14 @@
@Deprecated
public static final boolean IS_DEBUG_DEVICE = BuildConfig.IS_DEBUG_DEVICE;
+ public static final int TRANSLATE_UP = 0;
+ public static final int TRANSLATE_DOWN = 1;
+ public static final int TRANSLATE_LEFT = 2;
+ public static final int TRANSLATE_RIGHT = 3;
+
+ @IntDef({TRANSLATE_UP, TRANSLATE_DOWN, TRANSLATE_LEFT, TRANSLATE_RIGHT})
+ public @interface AdjustmentDirection{}
+
/**
* Returns true if theme is dark.
*/
@@ -731,4 +740,63 @@
matrixValues[Matrix.MTRANS_X], matrixValues[Matrix.MTRANS_Y]
));
}
+
+ /**
+ * Translates the {@code targetView} so that it overlaps with {@code exclusionBounds} as little
+ * as possible, while remaining within {@code inclusionBounds}.
+ * <p>
+ * {@code inclusionBounds} will always take precedence over {@code exclusionBounds}, so if
+ * {@code targetView} needs to be translated outside of {@code inclusionBounds} to fully fix an
+ * overlap with {@code exclusionBounds}, then {@code targetView} will only be translated up to
+ * the border of {@code inclusionBounds}.
+ * <p>
+ * Note: {@code targetViewBounds}, {@code inclusionBounds} and {@code exclusionBounds} must all
+ * be in relation to the same reference point on screen.
+ * <p>
+ * @param targetView the view being translated
+ * @param targetViewBounds the bounds of the {@code targetView}
+ * @param inclusionBounds the bounds the {@code targetView} absolutely must stay within
+ * @param exclusionBounds the bounds to try to move the {@code targetView} away from
+ * @param adjustmentDirection the translation direction that should be attempted to fix an
+ * overlap
+ */
+ public static void translateOverlappingView(
+ @NonNull View targetView,
+ @NonNull Rect targetViewBounds,
+ @NonNull Rect inclusionBounds,
+ @NonNull Rect exclusionBounds,
+ @AdjustmentDirection int adjustmentDirection) {
+ switch (adjustmentDirection) {
+ case TRANSLATE_RIGHT:
+ targetView.setTranslationX(Math.min(
+ // Translate to the right if the view is overlapping on the left.
+ Math.max(0, exclusionBounds.right - targetViewBounds.left),
+ // Do not translate beyond the inclusion bounds.
+ inclusionBounds.right - targetViewBounds.right));
+ break;
+ case TRANSLATE_LEFT:
+ targetView.setTranslationX(Math.max(
+ // Translate to the left if the view is overlapping on the right.
+ Math.min(0, exclusionBounds.left - targetViewBounds.right),
+ // Do not translate beyond the inclusion bounds.
+ inclusionBounds.left - targetViewBounds.left));
+ break;
+ case TRANSLATE_DOWN:
+ targetView.setTranslationY(Math.min(
+ // Translate downwards if the view is overlapping on the top.
+ Math.max(0, exclusionBounds.bottom - targetViewBounds.top),
+ // Do not translate beyond the inclusion bounds.
+ inclusionBounds.bottom - targetViewBounds.bottom));
+ break;
+ case TRANSLATE_UP:
+ targetView.setTranslationY(Math.max(
+ // Translate upwards if the view is overlapping on the bottom.
+ Math.min(0, exclusionBounds.top - targetViewBounds.bottom),
+ // Do not translate beyond the inclusion bounds.
+ inclusionBounds.top - targetViewBounds.top));
+ break;
+ default:
+ // No-Op
+ }
+ }
}
diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java
index e983a30..be995bc 100644
--- a/src/com/android/launcher3/graphics/SysUiScrim.java
+++ b/src/com/android/launcher3/graphics/SysUiScrim.java
@@ -126,8 +126,14 @@
mMaskHeight = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_DP,
view.getResources().getDisplayMetrics());
mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
- mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
- mHideSysUiScrim = mTopScrim == null;
+ if (mTopScrim != null) {
+ mTopScrim.setDither(true);
+ mBottomMask = createDitheredAlphaMask();
+ mHideSysUiScrim = false;
+ } else {
+ mBottomMask = null;
+ mHideSysUiScrim = true;
+ }
mDrawWallpaperScrim = FeatureFlags.ENABLE_WALLPAPER_SCRIM.get()
&& !Themes.getAttrBoolean(view.getContext(), R.attr.isMainColorDark)
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index a0f21dc..be3a09b 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -60,9 +60,7 @@
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
/**
* A container for shortcuts to deep links and notifications associated with an app.
@@ -337,23 +335,6 @@
}
/**
- * Shows the popup at the desired location, optionally reversing the children.
- * @param viewsToFlip number of views from the top to to flip in case of reverse order
- */
- protected void reorderAndShow(int viewsToFlip) {
- setupForDisplay();
- boolean reverseOrder = !ENABLE_MATERIAL_U_POPUP.get() && mIsAboveIcon;
- if (reverseOrder) {
- reverseOrder(viewsToFlip);
- }
- assignMarginsAndBackgrounds(this);
- if (shouldAddArrow()) {
- addArrow();
- }
- animateOpen();
- }
-
- /**
* Shows the popup at the desired location.
*/
public void show() {
@@ -372,22 +353,6 @@
orientAboutObject();
}
- private void reverseOrder(int viewsToFlip) {
- int count = getChildCount();
- ArrayList<View> allViews = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- if (i == viewsToFlip) {
- Collections.reverse(allViews);
- }
- allViews.add(getChildAt(i));
- }
- Collections.reverse(allViews);
- removeAllViews();
- for (int i = 0; i < count; i++) {
- addView(allViews.get(i));
- }
- }
-
private int getArrowLeft() {
if (mIsLeftAligned) {
return mArrowOffsetHorizontal;
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 8fef5c6..c20ac17 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -227,17 +227,18 @@
if (ENABLE_MATERIAL_U_POPUP.get()) {
container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
R.layout.popup_container_material_u, launcher.getDragLayer(), false);
+ container.configureForLauncher(launcher);
container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
} else {
container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
R.layout.popup_container, launcher.getDragLayer(), false);
+ container.configureForLauncher(launcher);
container.populateAndShow(
icon,
deepShortcutCount,
popupDataProvider.getNotificationKeysForItem(item),
systemShortcuts);
}
- container.configureForLauncher(launcher);
launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
container.requestFocus();
return container;
@@ -257,14 +258,19 @@
}
// If there is only 1 shortcut, add it to its own container so it can show text and icon
if (shortcuts.size() == 1) {
- initializeSystemShortcut(R.layout.system_shortcut, this, shortcuts.get(0));
+ mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
+ this, 0);
+ initializeSystemShortcut(R.layout.system_shortcut, mSystemShortcutContainer,
+ shortcuts.get(0), false);
return;
}
- mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this);
- for (SystemShortcut shortcut : shortcuts) {
+ mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
+ for (int i = 0; i < shortcuts.size(); i++) {
initializeSystemShortcut(
- R.layout.system_shortcut_icon_only, mSystemShortcutContainer,
- shortcut);
+ R.layout.system_shortcut_icon_only,
+ mSystemShortcutContainer,
+ shortcuts.get(i),
+ i < shortcuts.size() - 1);
}
}
@@ -289,7 +295,6 @@
}
updateNotificationHeader();
}
- int viewsToFlip = getChildCount();
mSystemShortcutContainer = this;
if (mDeepShortcutContainer == null) {
mDeepShortcutContainer = findViewById(R.id.deep_shortcuts_container);
@@ -314,8 +319,7 @@
Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(shortcuts);
if (widgetShortcutOpt.isPresent()) {
if (mWidgetContainer == null) {
- mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
- this);
+ mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container, this, 0);
}
initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
}
@@ -324,14 +328,17 @@
} else {
mDeepShortcutContainer.setVisibility(View.GONE);
if (!shortcuts.isEmpty()) {
- for (SystemShortcut shortcut : shortcuts) {
- initializeSystemShortcut(R.layout.system_shortcut, this, shortcut);
+ for (int i = 0; i < shortcuts.size(); i++) {
+ initializeSystemShortcut(
+ R.layout.system_shortcut,
+ this,
+ shortcuts.get(i),
+ i < shortcuts.size() - 1);
}
}
}
-
- reorderAndShow(viewsToFlip);
- showPopupContainer((ItemInfo) originalIcon.getTag(), notificationKeys);
+ show();
+ loadAppShortcuts((ItemInfo) originalIcon.getTag(), notificationKeys);
}
/**
@@ -351,19 +358,17 @@
addAllShortcutsMaterialU(deepShortcutCount, systemShortcuts);
} else if (!systemShortcuts.isEmpty()) {
addSystemShortcutsMaterialU(systemShortcuts,
- R.layout.system_shortcut_rows_container_material_u,
+ R.layout.system_shortcut_rows_container,
R.layout.system_shortcut);
}
-
- // no reversing needed for U design
- reorderAndShow(0);
- showPopupContainer((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
+ show();
+ loadAppShortcuts((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
}
/**
* Animates and loads shortcuts on background thread for this popup container
*/
- private void showPopupContainer(ItemInfo originalItemInfo,
+ private void loadAppShortcuts(ItemInfo originalItemInfo,
List<NotificationKeyData> notificationKeys) {
if (ATLEAST_P) {
@@ -390,7 +395,7 @@
if (deepShortcutCount + systemShortcuts.size() <= SHORTCUT_COLLAPSE_THRESHOLD) {
// add all system shortcuts including widgets shortcut to same container
addSystemShortcutsMaterialU(systemShortcuts,
- R.layout.system_shortcut_rows_container_material_u,
+ R.layout.system_shortcut_rows_container,
R.layout.system_shortcut);
addDeepShortcutsMaterialU(deepShortcutCount);
return;
@@ -458,8 +463,12 @@
return;
}
mSystemShortcutContainer = inflateAndAdd(systemShortcutContainerLayout, this);
- for (SystemShortcut shortcut : systemShortcuts) {
- initializeSystemShortcut(systemShortcutLayout, mSystemShortcutContainer, shortcut);
+ for (int i = 0; i < systemShortcuts.size(); i++) {
+ initializeSystemShortcut(
+ systemShortcutLayout,
+ mSystemShortcutContainer,
+ systemShortcuts.get(i),
+ i < systemShortcuts.size() - 1);
}
}
@@ -533,20 +542,31 @@
}
protected void initializeWidgetShortcut(ViewGroup container, SystemShortcut info) {
- View view = initializeSystemShortcut(R.layout.system_shortcut, container, info);
+ View view = initializeSystemShortcut(R.layout.system_shortcut, container, info, false);
view.getLayoutParams().width = mContainerWidth;
}
- protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
- View view = inflateAndAdd(
- resId, container, getInsertIndexForSystemShortcut(container, info));
+ /**
+ * Initializes and adds View for given SystemShortcut to a container.
+ * @param resId Resource id to use for SystemShortcut View.
+ * @param container ViewGroup to add the shortcut View to as a parent
+ * @param info The SystemShortcut instance to create a View for.
+ * @param shouldAddSpacer If True, will add a spacer after the shortcut, when showing the
+ * SystemShortcut as an icon only. Used to space the shortcut icons
+ * evenly.
+ * @return The view inflated for the SystemShortcut
+ */
+ protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info,
+ boolean shouldAddSpacer) {
+ View view = inflateAndAdd(resId, container);
if (view instanceof DeepShortcutView) {
- // Expanded system shortcut, with both icon and text shown on white background.
+ // System shortcut takes entire row with icon and text
final DeepShortcutView shortcutView = (DeepShortcutView) view;
info.setIconAndLabelFor(shortcutView.getIconView(), shortcutView.getBubbleText());
} else if (view instanceof ImageView) {
- // Only the system shortcut icon shows on a gray background header.
+ // System shortcut is just an icon
info.setIconAndContentDescriptionFor((ImageView) view);
+ if (shouldAddSpacer) inflateAndAdd(R.layout.system_shortcut_spacer, container);
view.setTooltipText(view.getContentDescription());
}
view.setTag(info);
@@ -555,17 +575,6 @@
}
/**
- * Returns an index for inserting a shortcut into a container.
- */
- private int getInsertIndexForSystemShortcut(ViewGroup container, SystemShortcut shortcut) {
- final View separator = container.findViewById(R.id.separator);
-
- return separator != null && shortcut.isLeftGroup() ?
- container.indexOfChild(separator) :
- container.getChildCount();
- }
-
- /**
* Determines when the deferred drag should be started.
*
* Current behavior:
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index 9669010..bf9eb5a 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -42,6 +42,7 @@
import com.android.launcher3.testcomponent.AppWidgetWithConfig;
import com.android.launcher3.testcomponent.RequestPinItemActivity;
import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.Wait.Condition;
@@ -75,6 +76,7 @@
super.setUp();
mCallbackAction = UUID.randomUUID().toString();
mShortcutId = UUID.randomUUID().toString();
+ TaplTestsLauncher3.initialize(this);
}
@Test
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 667290f..82d9630 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -54,14 +54,5 @@
return createMenuItem(menuItem);
}
- /**
- * Returns a menu item that matches the text "Split screen". Fails if it doesn't exist.
- */
- public SplitScreenMenuItem getSplitScreenMenuItem() {
- final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
- AppIcon.getAppIconSelector("Split screen", mLauncher));
- return new SplitScreenMenuItem(mLauncher, menuItem);
- }
-
protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 48e327f..3dcb437 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -76,27 +76,6 @@
}
}
- /**
- * Clicks a launcher object to initiate splitscreen, where the selected app will be one of two
- * apps running on the screen. Should be called when Launcher is in a "split staging" state
- * and is waiting for the user's selection of a second app. Expects a SPLIT_START_EVENT to be
- * fired when the click is executed.
- */
- public LaunchedAppState launchIntoSplitScreen() {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to launch split tasks from " + launchableType())) {
- LauncherInstrumentation.log("Launchable.launch before click "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
- mLauncher.clickLauncherObject(mObject);
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
- return new LaunchedAppState(mLauncher);
- }
- }
- }
-
protected LaunchedAppState assertAppLaunched(BySelector selector) {
mLauncher.assertTrue(
"App didn't start: (" + selector + ")",
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 90f3d13..adc993d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -37,9 +37,10 @@
public final class OverviewTask {
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
- static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
- static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
- static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
+ static final Pattern TASK_START_EVENT =
+ Pattern.compile("startActivityFromRecentsAsync");
+ static final Pattern SPLIT_START_EVENT =
+ Pattern.compile("launchSplitTasks");
private final LauncherInstrumentation mLauncher;
private final UiObject2 mTask;
private final BaseOverview mOverview;
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
deleted file mode 100644
index 47cf20b..0000000
--- a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2023 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.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-import com.android.launcher3.testing.shared.TestProtocol;
-
-/**
- * A class representing the "Split screen" menu item in the app long-press menu. Used for TAPL
- * testing in a similar way as other menu items {@link AppIconMenuItem}, but unlike AppIconMenuItem,
- * the split screen command does not trigger an app launch. Instead, it causes Launcher to shift to
- * a different state (OverviewSplitSelect).
- */
-public final class SplitScreenMenuItem {
- private final LauncherInstrumentation mLauncher;
- private final UiObject2 mObject;
-
- SplitScreenMenuItem(LauncherInstrumentation launcher, UiObject2 object) {
- mLauncher = launcher;
- mObject = object;
- }
-
- /**
- * Executes a click command on this menu item. Expects a SPLIT_SELECT_EVENT to be fired.
- */
- public void click() {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to enter split select from app long-press menu")) {
- LauncherInstrumentation.log("clicking on split screen menu item "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
- mLauncher.clickLauncherObject(mObject);
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_SELECT_EVENT);
- mLauncher.waitForLauncherObject("split_placeholder");
- }
- }
- }
-}