Merge "Adding support for listening to end callbacks when launching an intent from Launcher" into udc-dev
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 0eef70e..a8b7698 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -57,7 +57,6 @@
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.views.ActivityContext;
@@ -183,7 +182,16 @@
: null;
super.applyFromWorkspaceItem(info, animate, staggerIndex);
int oldPlateColor = mPlateColor;
- int newPlateColor = ColorUtils.setAlphaComponent(mDotParams.appColor, 200);
+
+ int newPlateColor;
+ if (getIcon().isThemed()) {
+ newPlateColor = getResources().getColor(android.R.color.system_accent1_300);
+ } else {
+ float[] hctPlateColor = new float[3];
+ ColorUtils.colorToM3HCT(mDotParams.appColor, hctPlateColor);
+ newPlateColor = ColorUtils.M3HCTtoColor(hctPlateColor[0], 36, 85);
+ }
+
if (!animate) {
mPlateColor = newPlateColor;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 40dfd82..8cbd6e8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -41,11 +41,9 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TaskUtils;
-import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.OverviewToHomeAnim;
import com.android.quickstep.views.RecentsView;
@@ -108,11 +106,6 @@
if (AbstractFloatingView.getTopOpenViewWithType(mLauncher, typeToClose) != null) {
return true;
}
- if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
- && TopTaskTracker.INSTANCE.get(mLauncher).getCachedTopTask(false)
- .isExcludedAssistant()) {
- return true;
- }
return false;
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 99a57a2..cf68c91 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -24,7 +24,6 @@
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
-import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
@@ -1089,22 +1088,17 @@
boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
boolean isPreviousGestureAnimatingToLauncher =
previousGestureState.isRunningAnimationToLauncher();
- boolean forcingOverviewInputConsumer =
- ASSISTANT_GIVES_LAUNCHER_FOCUS.get() && forceOverviewInputConsumer;
boolean isInLiveTileMode = gestureState.getActivityInterface().isInLiveTileMode();
reasonString.append(SUBSTRING_PREFIX)
.append(hasWindowFocus
? "activity has window focus"
: (isPreviousGestureAnimatingToLauncher
? "previous gesture is still animating to launcher"
- : (forcingOverviewInputConsumer
- ? "assistant gives launcher focus and forcing focus"
- : (isInLiveTileMode
- ? "device is in live mode"
- : "all overview focus conditions failed"))));
+ : isInLiveTileMode
+ ? "device is in live mode"
+ : "all overview focus conditions failed"));
if (hasWindowFocus
|| isPreviousGestureAnimatingToLauncher
- || forcingOverviewInputConsumer
|| isInLiveTileMode) {
reasonString.append(SUBSTRING_PREFIX)
.append("overview should have focus, using OverviewInputConsumer");
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 64165b6..3388642 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -51,6 +51,7 @@
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
+ private boolean mHasSetTouchModeForFirstDPadEvent;
public OverviewInputConsumer(GestureState gestureState, T activity,
@Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
@@ -95,6 +96,9 @@
mInputMonitor.pilferPointers();
}
}
+ if (mHasSetTouchModeForFirstDPadEvent) {
+ mActivity.getRootView().clearFocus();
+ }
}
@Override
@@ -112,6 +116,19 @@
mgr.dispatchVolumeKeyEventAsSystemService(ev,
AudioManager.USE_DEFAULT_STREAM_TYPE);
break;
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (!mHasSetTouchModeForFirstDPadEvent) {
+ // When Overview is launched via meta+tab or swipe up from an app, the touch
+ // mode somehow is not changed to false by the Android framework. The subsequent
+ // key events (e.g. DPAD_LEFT, DPAD_RIGHT) can only be dispatched to focused
+ // views, while focus can only be requested in
+ // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To
+ // note, here we launch overview with live tile.
+ mHasSetTouchModeForFirstDPadEvent = true;
+ mActivity.getRootView().getViewRootImpl().touchModeChanged(false);
+ }
+ break;
default:
break;
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 62d46d3..97e34c5 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -62,6 +62,7 @@
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.TestStabilityRule;
+import com.android.launcher3.util.rule.ViewCaptureRule;
import com.android.quickstep.views.RecentsView;
import org.junit.After;
@@ -115,10 +116,12 @@
Utilities.enableRunningInTestHarnessForTests();
}
+ final ViewCaptureRule viewCaptureRule = new ViewCaptureRule();
mOrderSensitiveRules = RuleChain
.outerRule(new SamplerRule())
.around(new NavigationModeSwitchRule(mLauncher))
- .around(new FailureWatcher(mDevice, mLauncher));
+ .around(viewCaptureRule)
+ .around(new FailureWatcher(mDevice, mLauncher, viewCaptureRule.getViewCapture()));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
getHomeIntentInPackage(context),
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 985fe77..0c036ff 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -28,6 +28,9 @@
<color name="popup_notification_dot_light">@android:color/system_accent1_100</color>
<color name="popup_notification_dot_dark">@android:color/system_accent2_600</color>
+ <color name="notification_dot_color_light">@android:color/system_accent3_200</color>
+ <color name="notification_dot_color_dark">@android:color/system_accent3_100</color>
+
<color name="workspace_text_color_light">@android:color/system_neutral1_0</color>
<color name="workspace_text_color_dark">@android:color/system_neutral1_1000</color>
@@ -40,7 +43,6 @@
<color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
- <color name="folder_dot_color">@android:color/system_accent3_100</color>
<color name="folder_pagination_color_light">@android:color/system_accent1_600</color>
<color name="folder_pagination_color_dark">@android:color/system_accent2_100</color>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 8136534..418f5a7 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -40,8 +40,8 @@
<attr name="eduHalfSheetBGColor" format="color" />
<attr name="overviewScrimColor" format="color" />
<attr name="popupNotificationDotColor" format="color" />
+ <attr name="notificationDotColor" format="color" />
- <attr name="folderDotColor" format="color" />
<attr name="folderPaginationColor" format="color" />
<attr name="folderPreviewColor" format="color" />
<attr name="folderBackgroundColor" format="color" />
@@ -90,7 +90,6 @@
<declare-styleable name="FolderIconPreview">
<attr name="folderPreviewColor" />
<attr name="folderIconBorderColor" />
- <attr name="folderDotColor" />
</declare-styleable>
<declare-styleable name="SearchResultSuggestion">
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9e73453..b1bff18 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -54,6 +54,9 @@
<color name="popup_notification_dot_light">#FFF</color>
<color name="popup_notification_dot_dark">#757575</color>
+ <color name="notification_dot_color_light">#6DD58C</color>
+ <color name="notification_dot_color_dark">#C4EED0</color>
+
<color name="workspace_text_color_light">#FFF</color>
<color name="workspace_text_color_dark">#FF000000</color>
@@ -66,7 +69,6 @@
<color name="folder_preview_light">#F9F9F9</color>
<color name="folder_preview_dark">#464746</color>
- <color name="folder_dot_color">?attr/colorPrimary</color>
<color name="folder_pagination_color_light">#ff006c5f</color>
<color name="folder_pagination_color_dark">#ffbfebe3</color>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 11861b9..8f75550 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -41,6 +41,7 @@
<item name="popupShadeSecond">@color/popup_shade_second_light</item>
<item name="popupShadeThird">@color/popup_shade_third_light</item>
<item name="popupNotificationDotColor">@color/popup_notification_dot_light</item>
+ <item name="notificationDotColor">@color/notification_dot_color_light</item>
<item name="isMainColorDark">false</item>
<item name="isWorkspaceDarkText">false</item>
<item name="workspaceTextColor">@color/workspace_text_color_light</item>
@@ -49,7 +50,6 @@
<item name="workspaceKeyShadowColor">#89000000</item>
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
- <item name="folderDotColor">@color/folder_dot_color</item>
<item name="folderPaginationColor">@color/folder_pagination_color_light</item>
<item name="folderPreviewColor">@color/folder_preview_light</item>
<item name="folderBackgroundColor">@color/folder_background_light</item>
@@ -109,8 +109,8 @@
<item name="popupShadeFirst">@color/popup_shade_first_dark</item>
<item name="popupShadeSecond">@color/popup_shade_second_dark</item>
<item name="popupShadeThird">@color/popup_shade_third_dark</item>
+ <item name="notificationDotColor">@color/notification_dot_color_dark</item>
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
- <item name="folderDotColor">@color/folder_dot_color</item>
<item name="folderPaginationColor">@color/folder_pagination_color_dark</item>
<item name="folderPreviewColor">@color/folder_preview_dark</item>
<item name="folderBackgroundColor">@color/folder_background_dark</item>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 450a9f0..f920d75 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -77,6 +77,7 @@
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ShortcutUtil;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.IconLabelDotView;
@@ -387,8 +388,7 @@
}
FastBitmapDrawable iconDrawable = info.newIcon(getContext(), flags);
mDotParams.appColor = iconDrawable.getIconColor();
- mDotParams.dotColor = getContext().getResources()
- .getColor(android.R.color.system_accent3_200, getContext().getTheme());
+ mDotParams.dotColor = Themes.getAttrColor(getContext(), R.attr.notificationDotColor);
setIcon(iconDrawable);
applyLabel(info);
}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 1a86009..108e557 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -115,6 +115,12 @@
setContentDescription(mText);
}
+ protected void updateText(CharSequence text) {
+ setText(text);
+ mText = getText();
+ setContentDescription(mText);
+ }
+
protected void setDrawable(int resId) {
// We do not set the drawable in the xml as that inflates two drawables corresponding to
// drawableLeft and drawableStart.
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 65870d3..617afcb 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -92,6 +92,15 @@
static final String TAG = "Launcher.Model";
+ // Broadcast intent to track when the profile gets locked:
+ // ACTION_MANAGED_PROFILE_UNAVAILABLE can be used until Android U where profile no longer gets
+ // locked when paused.
+ // ACTION_PROFILE_INACCESSIBLE always means that the profile is getting locked but it only
+ // appeared in Android S.
+ private static final String ACTION_PROFILE_LOCKED = Utilities.ATLEAST_U
+ ? Intent.ACTION_PROFILE_INACCESSIBLE
+ : Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE;
+
@NonNull
private final LauncherAppState mApp;
@NonNull
@@ -290,9 +299,9 @@
// If we have changed locale we need to clear out the labels in all apps/workspace.
forceReload();
} else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
- || Intent.ACTION_PROFILE_INACCESSIBLE.equals(action)
|| Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)
- || Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
+ || Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)
+ || Intent.ACTION_PROFILE_INACCESSIBLE.equals(action)) {
UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.WORK_TAB_MISSING, "onBroadcastIntent intentAction: " + action +
@@ -305,9 +314,7 @@
PackageUpdatedTask.OP_USER_AVAILABILITY_CHANGE, user));
}
- // ACTION_PROFILE_INACCESSIBLE sends the profile back to locked mode, so
- // we need to run the state change task again.
- if (Intent.ACTION_PROFILE_INACCESSIBLE.equals(action)
+ if (ACTION_PROFILE_LOCKED.equals(action)
|| Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
enqueueModelUpdateTask(new UserLockStateChangedTask(
user, Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)));
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 8dc1204..f27ad7b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -142,10 +142,6 @@
"Enables haptics opening/closing All apps");
// TODO(Block 6): Clean up flags
- public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag(270393268,
- "WIDGETS_IN_LAUNCHER_PREVIEW", ENABLED,
- "Enables widgets in Launcher preview for the Wallpaper app.");
-
public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
"ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", DISABLED,
"Enables Search box in Taskbar All Apps.");
@@ -211,17 +207,9 @@
"Allows on device search in all apps logging");
// TODO(Block 14): Cleanup flags
- public static final BooleanFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = getDebugFlag(270391641,
- "ASSISTANT_GIVES_LAUNCHER_FOCUS", DISABLED,
- "Allow Launcher to handle nav bar gestures while Assistant is running over it");
-
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag(270393108, "NOTIFY_CRASHES",
DISABLED, "Sends a notification whenever launcher encounters an uncaught exception.");
- public static final BooleanFlag FORCE_PERSISTENT_TASKBAR = getDebugFlag(270395077,
- "FORCE_PERSISTENT_TASKBAR", DISABLED, "Forces taskbar to be persistent, even in gesture"
- + " nav mode and when transient taskbar is enabled.");
-
public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798,
"ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar.");
@@ -394,7 +382,7 @@
"Enable initiating split screen from workspace to workspace.");
public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
- "ENABLE_TRACKPAD_GESTURE", ENABLED, "Enables trackpad gesture.");
+ "ENABLE_TRACKPAD_GESTURE", DISABLED, "Enables trackpad gesture.");
// TODO(Block 29): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(270393897,
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 2465745..406955c 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -43,6 +43,7 @@
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
/**
@@ -150,7 +151,7 @@
mInvalidateDelegate = invalidateDelegate;
TypedArray ta = context.getTheme().obtainStyledAttributes(R.styleable.FolderIconPreview);
- mDotColor = ta.getColor(R.styleable.FolderIconPreview_folderDotColor, 0);
+ mDotColor = Themes.getAttrColor(context, R.attr.notificationDotColor);
mStrokeColor = ta.getColor(R.styleable.FolderIconPreview_folderIconBorderColor, 0);
mBgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0);
ta.recycle();
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index b438e86..47677ea 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -105,7 +105,6 @@
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.LauncherWidgetHolder;
import com.android.launcher3.widget.LocalColorExtractor;
-import com.android.launcher3.widget.NavigableAppWidgetHostView;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import com.android.launcher3.widget.util.WidgetSizes;
@@ -281,9 +280,7 @@
} else {
mWallpaperColorResources = null;
}
- mAppWidgetHost = FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()
- ? new LauncherPreviewAppWidgetHost(context)
- : null;
+ mAppWidgetHost = new LauncherPreviewAppWidgetHost(context);
}
/** Populate preview and render it. */
@@ -416,19 +413,8 @@
private void inflateAndAddWidgets(
LauncherAppWidgetInfo info, LauncherAppWidgetProviderInfo providerInfo) {
- AppWidgetHostView view;
- if (FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()) {
- view = mAppWidgetHost.createView(mContext, info.appWidgetId, providerInfo);
- } else {
- view = new NavigableAppWidgetHostView(this) {
- @Override
- protected boolean shouldAllowDirectClick() {
- return false;
- }
- };
- view.setAppWidget(-1, providerInfo);
- view.updateAppWidget(null);
- }
+ AppWidgetHostView view = mAppWidgetHost.createView(
+ mContext, info.appWidgetId, providerInfo);
if (mWallpaperColorResources != null) {
view.setColorResources(mWallpaperColorResources);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 050e88f..6a972eb 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -589,17 +589,17 @@
float scaledDividerHeight = dividerHeight * scale;
if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- if (splitInfo.appsStackedVertically) {
- outRect.bottom = Math.round(outRect.top + scaledTopTaskHeight);
- } else {
+ if (dp.isLandscape) {
outRect.right = outRect.left + Math.round(outRect.width() * topLeftTaskPercent);
+ } else {
+ outRect.bottom = Math.round(outRect.top + scaledTopTaskHeight);
}
} else {
- if (splitInfo.appsStackedVertically) {
- outRect.top += Math.round(scaledTopTaskHeight + scaledDividerHeight);
- } else {
+ if (dp.isLandscape) {
outRect.left += Math.round(outRect.width()
* (topLeftTaskPercent + dividerBarPercent));
+ } else {
+ outRect.top += Math.round(scaledTopTaskHeight + scaledDividerHeight);
}
}
}
@@ -610,9 +610,9 @@
DeviceProfile dp, boolean isRtl) {
int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
- int dividerBar = Math.round(splitBoundsConfig.appsStackedVertically
- ? splitBoundsConfig.dividerHeightPercent * dp.availableHeightPx
- : splitBoundsConfig.dividerWidthPercent * parentWidth);
+ float dividerScale = splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.dividerHeightPercent
+ : splitBoundsConfig.dividerWidthPercent;
int primarySnapshotHeight;
int primarySnapshotWidth;
int secondarySnapshotHeight;
@@ -620,12 +620,13 @@
float taskPercent = splitBoundsConfig.appsStackedVertically ?
splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
if (dp.isLandscape) {
+ int scaledDividerBar = Math.round(parentWidth * dividerScale);
primarySnapshotHeight = totalThumbnailHeight;
primarySnapshotWidth = Math.round(parentWidth * taskPercent);
secondarySnapshotHeight = totalThumbnailHeight;
- secondarySnapshotWidth = parentWidth - primarySnapshotWidth - dividerBar;
- int translationX = primarySnapshotWidth + dividerBar;
+ secondarySnapshotWidth = parentWidth - primarySnapshotWidth - scaledDividerBar;
+ int translationX = primarySnapshotWidth + scaledDividerBar;
if (isRtl) {
primarySnapshot.setTranslationX(-translationX);
secondarySnapshot.setTranslationX(0);
@@ -640,7 +641,7 @@
} else {
float scale = (float) totalThumbnailHeight / dp.availableHeightPx;
float topTaskHeight = dp.availableHeightPx * taskPercent;
- float finalDividerHeight = dividerBar * scale;
+ float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
float scaledTopTaskHeight = topTaskHeight * scale;
primarySnapshotWidth = parentWidth;
primarySnapshotHeight = Math.round(scaledTopTaskHeight);
diff --git a/tests/Android.bp b/tests/Android.bp
index fa0cdf2..e7f4084 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -51,6 +51,7 @@
"src/com/android/launcher3/util/WidgetUtils.java",
"src/com/android/launcher3/util/rule/FailureWatcher.java",
"src/com/android/launcher3/util/rule/LauncherActivityRule.java",
+ "src/com/android/launcher3/util/rule/ViewCaptureRule.kt",
"src/com/android/launcher3/util/rule/SamplerRule.java",
"src/com/android/launcher3/util/rule/ScreenRecordRule.java",
"src/com/android/launcher3/util/rule/ShellCommandRule.java",
@@ -132,4 +133,4 @@
manifest: "shared/AndroidManifest.xml",
sdk_version: "current",
min_sdk_version: min_launcher3_sdk_version,
- }
\ No newline at end of file
+ }
diff --git a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
index 84c617c..bcfb90b 100644
--- a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
+++ b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
@@ -8,7 +8,6 @@
import com.android.launcher3.util.ActivityContextWrapper
import com.google.common.truth.Truth.assertThat
import org.junit.Before
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@@ -26,19 +25,15 @@
enableRunningInTestHarnessForTests()
}
- // Needs mText, mTempRect, getPaddingTop, getPaddingBottom
- // availableHeight as a parameter
- @Ignore("TODO(b/279464742)")
@Test
fun isTextClippedVerticallyTest() {
- buttonDropTarget.mText = "My Test"
+ buttonDropTarget.updateText("My Test")
+ buttonDropTarget.setPadding(0, 0, 0, 0)
+ buttonDropTarget.setTextMultiLine(false)
// No space for text
assertThat(buttonDropTarget.isTextClippedVertically(30)).isTrue()
- // Some space for text, and just enough that the text should not be clipped
- assertThat(buttonDropTarget.isTextClippedVertically(50)).isFalse()
-
// A lot of space for text so the text should not be clipped
assertThat(buttonDropTarget.isTextClippedVertically(100)).isFalse()
}
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderAlgorithmUnitTest.java b/tests/src/com/android/launcher3/celllayout/ReorderAlgorithmUnitTest.java
index e3de500..ee05fe6 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderAlgorithmUnitTest.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderAlgorithmUnitTest.java
@@ -87,15 +87,13 @@
// modify the device profile.
dp.inv.numColumns = width;
dp.inv.numRows = height;
+ dp.cellLayoutBorderSpacePx = new Point(0, 0);
CellLayout cl = new CellLayout(getWrappedContext(c, dp));
// I put a very large number for width and height so that all the items can fit, it doesn't
// need to be exact, just bigger than the sum of cell border
cl.measure(View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.EXACTLY));
-
- cl.measure(View.MeasureSpec.makeMeasureSpec(cl.getDesiredWidth(), View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(cl.getDesiredHeight(), View.MeasureSpec.EXACTLY));
return cl;
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 3141c7b..d7c4ae3 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -72,6 +72,7 @@
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.util.rule.TestStabilityRule;
+import com.android.launcher3.util.rule.ViewCaptureRule;
import org.junit.After;
import org.junit.Assert;
@@ -215,14 +216,15 @@
}
protected TestRule getRulesInsideActivityMonitor() {
+ final ViewCaptureRule viewCaptureRule = new ViewCaptureRule();
final RuleChain inner = RuleChain
.outerRule(new PortraitLandscapeRunner(this))
- .around(new FailureWatcher(mDevice, mLauncher));
+ .around(viewCaptureRule)
+ .around(new FailureWatcher(mDevice, mLauncher, viewCaptureRule.getViewCapture()));
return TestHelpers.isInLauncherProcess()
- ? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher())
- .around(inner) :
- inner;
+ ? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner)
+ : inner;
}
@Rule
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index 51facf4..19e7b13 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -7,8 +7,12 @@
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.uiautomator.UiDevice;
+import com.android.app.viewcapture.ViewCapture;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.ui.AbstractLauncherUiTest;
@@ -29,10 +33,14 @@
private static boolean sSavedBugreport = false;
final private UiDevice mDevice;
private final LauncherInstrumentation mLauncher;
+ @NonNull
+ private final ViewCapture mViewCapture;
- public FailureWatcher(UiDevice device, LauncherInstrumentation launcher) {
+ public FailureWatcher(UiDevice device, LauncherInstrumentation launcher,
+ @NonNull ViewCapture viewCapture) {
mDevice = device;
mLauncher = launcher;
+ mViewCapture = viewCapture;
}
@Override
@@ -82,7 +90,7 @@
@Override
protected void failed(Throwable e, Description description) {
- onError(mLauncher, description, e);
+ onError(mLauncher, description, e, mViewCapture);
}
static File diagFile(Description description, String prefix, String ext) {
@@ -93,8 +101,12 @@
public static void onError(LauncherInstrumentation launcher, Description description,
Throwable e) {
- final UiDevice device = launcher.getDevice();
- if (device == null) return;
+ onError(launcher, description, e, null);
+ }
+
+ private static void onError(LauncherInstrumentation launcher, Description description,
+ Throwable e, @Nullable ViewCapture viewCapture) {
+
final File sceenshot = diagFile(description, "TestScreenshot", "png");
final File hierarchy = diagFile(description, "Hierarchy", "zip");
@@ -109,13 +121,20 @@
out.putNextEntry(new ZipEntry("visible_windows.zip"));
dumpCommand("cmd window dump-visible-window-views", out);
out.closeEntry();
- } catch (IOException ex) {
+
+ if (viewCapture != null) {
+ out.putNextEntry(new ZipEntry("FS/data/misc/wmtrace/failed_test.vc"));
+ viewCapture.dumpTo(out, ApplicationProvider.getApplicationContext());
+ out.closeEntry();
+ }
+ } catch (Exception ignored) {
}
Log.e(TAG, "Failed test " + description.getMethodName()
+ ",\nscreenshot will be saved to " + sceenshot
+ ",\nUI dump at: " + hierarchy
+ " (use go/web-hv to open the dump file)", e);
+ final UiDevice device = launcher.getDevice();
device.takeScreenshot(sceenshot);
// Dump accessibility hierarchy
diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
index 2093682..e9a52f8 100644
--- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
@@ -56,4 +56,4 @@
return launcher.getWorkspace().getFirstMatch(op) != null;
};
}
-}
+}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java b/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java
index 1dbba6a..2eedec3 100644
--- a/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java
@@ -102,4 +102,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
new file mode 100644
index 0000000..e4713b2
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.util.rule
+
+import android.app.Activity
+import android.app.Application
+import android.media.permission.SafeCloseable
+import android.os.Bundle
+import androidx.test.core.app.ApplicationProvider
+import com.android.app.viewcapture.SimpleViewCapture
+import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * This JUnit TestRule registers a listener for activity lifecycle events to attach a ViewCapture
+ * instance that other test rules use to dump the timelapse hierarchy upon an error during a test.
+ *
+ * This rule will not work in OOP tests that don't have access to the activity under test.
+ */
+class ViewCaptureRule : TestRule {
+ val viewCapture = SimpleViewCapture("test-view-capture")
+
+ override fun apply(base: Statement, description: Description): Statement {
+ return object : Statement() {
+ override fun evaluate() {
+ val windowListenerCloseables = mutableListOf<SafeCloseable>()
+
+ val lifecycleCallbacks =
+ object : ActivityLifecycleCallbacksAdapter {
+ override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
+ super.onActivityCreated(activity, bundle)
+ windowListenerCloseables.add(
+ viewCapture.startCapture(
+ activity.window.decorView,
+ "${description.testClass?.simpleName}.${description.methodName}"
+ )
+ )
+ }
+
+ override fun onActivityDestroyed(activity: Activity) {
+ super.onActivityDestroyed(activity)
+ viewCapture.stopCapture(activity.window.decorView)
+ }
+ }
+
+ val application = ApplicationProvider.getApplicationContext<Application>()
+ application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
+
+ try {
+ base.evaluate()
+ } finally {
+ application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)
+
+ // Clean up ViewCapture references here rather than in onActivityDestroyed so
+ // test code can access view hierarchy capture. onActivityDestroyed would delete
+ // view capture data before FailureWatcher could output it as a test artifact.
+ windowListenerCloseables.onEach(SafeCloseable::close)
+ }
+ }
+ }
+ }
+}