Snap for 12680993 from 9163f54158 to 25Q1-release

Change-Id: Ic9e296991f9ad86fbe9c94f3a8e4b6763068b242
This commit is contained in:
Android Build Coastguard Worker
2024-11-20 00:18:19 +00:00
31 changed files with 233 additions and 138 deletions
+6 -3
View File
@@ -501,10 +501,13 @@ flag {
}
flag {
name: "enforce_system_radius_for_app_widgets"
name: "use_system_radius_for_app_widgets"
namespace: "launcher"
description: "Enforce system radius for widget corners instead of a separate 16.dp value"
bug: "370950552"
description: "Use system radius for enforced widget corners instead of a separate 16.dp value"
bug: "373351337"
metadata {
purpose: PURPOSE_BUGFIX
}
}
flag {
-5
View File
@@ -362,11 +362,6 @@
<dimen name="taskbar_running_app_indicator_width">12dp</dimen>
<dimen name="taskbar_running_app_indicator_top_margin">4dp</dimen>
<dimen name="taskbar_minimized_app_indicator_width">6dp</dimen>
<dimen name="taskbar_overflow_item_icon_size_default">22dp</dimen>
<dimen name="taskbar_overflow_item_icon_size_scaled_down">15dp</dimen>
<dimen name="taskbar_overflow_item_icon_stroke_width_default">2dp</dimen>
<dimen name="taskbar_overflow_leave_behind_size_default">18dp</dimen>
<dimen name="taskbar_overflow_leave_behind_size_scaled_down">15dp</dimen>
<!-- Transient taskbar -->
<dimen name="transient_taskbar_padding">12dp</dimen>
+1
View File
@@ -211,6 +211,7 @@
<item name="android:enforceNavigationBarContrast">false</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowShowWallpaper">false</item>
</style>
<!--
@@ -448,14 +448,16 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
flags -> (flags & FLAG_IME_VISIBLE) != 0,
ROTATION_DRAWABLE_PERCENT, 1f, 0f));
// Translate back button to be at end/start of other buttons for keyguard
// Translate back button to be at end/start of other buttons for keyguard (only after SUW
// since it is laid to align with SUW actions while in that state)
int navButtonSize = mContext.getResources().getDimensionPixelSize(
R.dimen.taskbar_nav_buttons_size);
boolean isRtl = Utilities.isRtl(mContext.getResources());
if (!mContext.isPhoneMode()) {
mPropertyHolders.add(new StatePropertyHolder(
mBackButton, flags -> (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0
|| (flags & FLAG_KEYGUARD_VISIBLE) != 0,
mBackButton, flags -> mContext.isUserSetupComplete()
&& ((flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0
|| (flags & FLAG_KEYGUARD_VISIBLE) != 0),
VIEW_TRANSLATE_X, navButtonSize * (isRtl ? -2 : 2), 0));
}
@@ -1293,7 +1295,10 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
boolean isNavbarOnRight = location.isOnLeft(mNavButtonsView.isLayoutRtl());
DeviceProfile dp = mContext.getDeviceProfile();
float navBarTargetStartX;
if (mContext.shouldStartAlignTaskbar()) {
if (!mContext.isUserSetupComplete()) {
// Skip additional translations on the nav bar container while in SUW layout
return 0;
} else if (mContext.shouldStartAlignTaskbar()) {
int navBarSpacing = dp.inlineNavButtonsEndSpacingPx;
// If the taskbar is start aligned the navigation bar is aligned to the start or end of
// the container, depending on the bubble bar location
@@ -23,7 +23,6 @@ import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import com.android.app.animation.Interpolators
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.Utilities.mapRange
@@ -98,12 +97,9 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
shadowAlpha = LIGHT_THEME_SHADOW_ALPHA
}
if (context.areDesktopTasksVisible()) {
fullCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
cornerRadius = fullCornerRadius
} else {
fullCornerRadius = context.cornerRadius.toFloat()
cornerRadius = fullCornerRadius
fullCornerRadius = context.cornerRadius.toFloat()
cornerRadius = fullCornerRadius
if (!context.areDesktopTasksVisible()) {
setCornerRoundness(MAX_ROUNDNESS)
}
}
@@ -749,4 +749,9 @@ public class TaskbarManager {
private final DeviceProfile.OnDeviceProfileChangeListener mDebugActivityDeviceProfileChanged =
dp -> debugWhyTaskbarNotDestroyed("mActivity onDeviceProfileChanged");
@VisibleForTesting
public Context getWindowContext() {
return mContext;
}
}
@@ -41,6 +41,7 @@ import com.android.app.animation.Interpolators;
import com.android.launcher3.R;
import com.android.launcher3.Reorderable;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.Themes;
import com.android.systemui.shared.recents.model.Task;
@@ -68,8 +69,15 @@ public class TaskbarOverflowView extends FrameLayout implements Reorderable {
private static final long LEAVE_BEHIND_ANIMATIONS_DELAY = 500L;
private static final long LEAVE_BEHIND_OPACITY_ANIMATION_DURATION = 100L;
private static final long LEAVE_BEHIND_SIZE_ANIMATION_DURATION = 500L;
private static final float LEAVE_BEHIND_SIZE_SCALE_DOWN_MULTIPLIER = 0.83f;
private static final int MAX_ITEMS_IN_PREVIEW = 4;
// The height divided by the width of the horizontal box containing two overlapping app icons.
// According to the spec, this ratio is constant for different sizes of taskbar app icons.
// Assuming the width of this box = taskbar app icon size - 2 paddings - 2 stroke widths, and
// the height = width * 0.61, which is also equal to the height of a single item in the preview.
private static final float TWO_ITEM_ICONS_BOX_ASPECT_RATIO = 0.61f;
private static final FloatProperty<TaskbarOverflowView> ITEM_ICON_CENTER_OFFSET =
new FloatProperty<>("itemIconCenterOffset") {
@Override
@@ -208,9 +216,24 @@ public class TaskbarOverflowView extends FrameLayout implements Reorderable {
icon.mIconSize = iconSize;
icon.mPadding = padding;
final float radius = iconSize / 2f - padding;
final float size = radius + icon.mItemIconStrokeWidth;
icon.mItemIconCenterOffsetDefault = radius - size / 2 - icon.mItemIconStrokeWidth;
final float taskbarIconRadius =
iconSize * IconNormalizer.ICON_VISIBLE_AREA_FACTOR / 2f - padding;
icon.mLeaveBehindSizeDefault = taskbarIconRadius; // 1/2 of taskbar app icon size
icon.mLeaveBehindSizeScaledDown =
icon.mLeaveBehindSizeDefault * LEAVE_BEHIND_SIZE_SCALE_DOWN_MULTIPLIER;
icon.mLeaveBehindSize = icon.mLeaveBehindSizeScaledDown;
icon.mItemIconStrokeWidthDefault = taskbarIconRadius / 5f; // 1/10 of taskbar app icon size
icon.mItemIconStrokeWidth = icon.mItemIconStrokeWidthDefault;
icon.mItemIconSizeDefault = 2 * (taskbarIconRadius - icon.mItemIconStrokeWidthDefault)
* TWO_ITEM_ICONS_BOX_ASPECT_RATIO;
icon.mItemIconSizeScaledDown = icon.mLeaveBehindSizeScaledDown;
icon.mItemIconSize = icon.mItemIconSizeDefault;
icon.mItemIconCenterOffsetDefault = taskbarIconRadius - icon.mItemIconSizeDefault / 2f
- icon.mItemIconStrokeWidthDefault;
icon.mItemIconCenterOffset = icon.mItemIconCenterOffsetDefault;
return icon;
@@ -222,22 +245,6 @@ public class TaskbarOverflowView extends FrameLayout implements Reorderable {
mItemBackgroundColor = getContext().getColor(R.color.taskbar_background);
mLeaveBehindColor = Themes.getAttrColor(getContext(), android.R.attr.textColorTertiary);
mItemIconSizeDefault = getResources().getDimension(
R.dimen.taskbar_overflow_item_icon_size_default);
mItemIconSizeScaledDown = getResources().getDimension(
R.dimen.taskbar_overflow_item_icon_size_scaled_down);
mItemIconSize = mItemIconSizeDefault;
mItemIconStrokeWidthDefault = getResources().getDimension(
R.dimen.taskbar_overflow_item_icon_stroke_width_default);
mItemIconStrokeWidth = mItemIconStrokeWidthDefault;
mLeaveBehindSizeDefault = getResources().getDimension(
R.dimen.taskbar_overflow_leave_behind_size_default);
mLeaveBehindSizeScaledDown = getResources().getDimension(
R.dimen.taskbar_overflow_leave_behind_size_scaled_down);
mLeaveBehindSize = mLeaveBehindSizeScaledDown;
setWillNotDraw(false);
}
@@ -997,10 +997,9 @@ public class BubbleBarViewController {
}
}
/** Marks as should show education and shows the bubble bar in a collapsed state */
/** Marks as should show education. */
public void prepareToShowEducation() {
mShouldShowEducation = true;
mBubbleStashController.showBubbleBar(false /* expand the bubbles */);
}
/**
@@ -304,7 +304,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
mDepthController = new DepthController(this);
if (DesktopModeStatus.canEnterDesktopMode(this)) {
if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(this)) {
mSplitSelectStateController.initSplitFromDesktopController(this,
overviewComponentObserver);
}
@@ -37,6 +37,7 @@ import com.android.launcher3.util.TestUtil
import com.android.quickstep.AllAppsActionManager
import java.lang.reflect.Field
import java.lang.reflect.ParameterizedType
import java.util.Locale
import java.util.Optional
import org.junit.Assume.assumeTrue
import org.junit.rules.TestRule
@@ -119,6 +120,15 @@ class TaskbarUnitTestRule(
}
}
if (description.getAnnotation(ForceRtl::class.java) != null) {
// Needs to be set on window context instead of sandbox context, because it does
// does not propagate between them. However, this change will impact created
// TaskbarActivityContext instances, since they wrap the window context.
taskbarManager.windowContext.resources.configuration.setLayoutDirection(
RTL_LOCALE
)
}
try {
TaskbarViewController.enableModelLoadingForTests(false)
@@ -191,4 +201,11 @@ class TaskbarUnitTestRule(
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class NavBarKidsMode
/** Forces RTL UI for tests. */
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class ForceRtl
}
private val RTL_LOCALE = Locale.of("ar", "XB")
@@ -19,11 +19,13 @@ package com.android.launcher3.taskbar.rules
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.launcher3.taskbar.TaskbarKeyguardController
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.taskbar.TaskbarStashController
import com.android.launcher3.taskbar.bubbles.BubbleBarController
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.ForceRtl
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.NavBarKidsMode
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.UserSetupMode
@@ -197,6 +199,14 @@ class TaskbarUnitTestRuleTest {
}
}
@Test
fun testForceRtlAnnotation_setsActivityContextLayoutDirection() {
@ForceRtl class Rtl
onSetup(description = Description.createSuiteDescription(Rtl::class.java)) {
assertThat(Utilities.isRtl(activityContext.resources)).isTrue()
}
}
/**
* Executes [runTest] after the [testRule] setup phase completes.
*
@@ -15,10 +15,10 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="@dimen/all_apps_tabs_focus_width"
android:end="@dimen/all_apps_tabs_focus_width"
android:start="@dimen/all_apps_tabs_focus_width"
android:top="@dimen/all_apps_tabs_focus_width">
android:bottom="@dimen/all_apps_tabs_focus_vertical_inset"
android:end="@dimen/all_apps_tabs_focus_horizontal_inset"
android:start="@dimen/all_apps_tabs_focus_horizontal_inset"
android:top="@dimen/all_apps_tabs_focus_vertical_inset">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorPrimary" />
@@ -15,10 +15,10 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="@dimen/all_apps_tabs_focus_width"
android:end="@dimen/all_apps_tabs_focus_width"
android:start="@dimen/all_apps_tabs_focus_width"
android:top="@dimen/all_apps_tabs_focus_width">
android:bottom="@dimen/all_apps_tabs_focus_vertical_inset"
android:end="@dimen/all_apps_tabs_focus_horizontal_inset"
android:start="@dimen/all_apps_tabs_focus_horizontal_inset"
android:top="@dimen/all_apps_tabs_focus_vertical_inset">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="?attr/materialColorSurfaceBright" />
@@ -71,7 +71,8 @@
android:id="@+id/widget_preview_scroll_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginVertical="16dp"
android:layout_margin="16dp"
android:background="@drawable/widgets_surface_background"
android:layout_weight="1">
<include
@@ -21,8 +21,6 @@
android:layout_width="match_parent"
android:layout_height="@dimen/all_apps_header_pill_height"
android:layout_gravity="center_horizontal"
android:paddingTop="@dimen/all_apps_tabs_vertical_padding_focus"
android:paddingBottom="@dimen/all_apps_tabs_vertical_padding_focus"
android:layout_marginTop="@dimen/all_apps_tabs_margin_top"
android:orientation="horizontal"
style="@style/TextHeadline"
+2 -2
View File
@@ -210,10 +210,10 @@
<attr name="layout_sticky" format="boolean" />
</declare-styleable>
<declare-styleable name="NumRows">
<declare-styleable name="GridDimension">
<attr name="minDeviceWidthPx" format="float"/>
<attr name="minDeviceHeightPx" format="float"/>
<attr name="numRowsNew" format="integer"/>
<attr name="numGridDimension" format="integer"/>
<attr name="dbFile" />
<attr name="defaultLayoutId"/>
<attr name="demoModeLayoutId"/>
+2 -3
View File
@@ -125,9 +125,8 @@
<dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_bottom_padding">20dp</dimen>
<dimen name="all_apps_tabs_button_horizontal_padding">4dp</dimen>
<dimen name="all_apps_tabs_vertical_padding">6dp</dimen>
<dimen name="all_apps_tabs_vertical_padding_focus">1dp</dimen>
<dimen name="all_apps_tabs_focus_width">5dp</dimen>
<dimen name="all_apps_tabs_focus_horizontal_inset">5dp</dimen>
<dimen name="all_apps_tabs_focus_vertical_inset">6dp</dimen>
<dimen name="all_apps_tabs_focus_border">3dp</dimen>
<dimen name="all_apps_tabs_focus_padding">2dp</dimen>
<dimen name="all_apps_tabs_margin_top">8dp</dimen>
@@ -41,8 +41,11 @@ import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.MSDLPlayerWrapper;
import com.android.launcher3.views.ActivityContext;
import com.google.android.msdl.data.model.MSDLToken;
/**
* Implements a DropTarget.
*/
@@ -62,6 +65,7 @@ public abstract class ButtonDropTarget extends TextView
protected final ActivityContext mActivityContext;
protected final DropTargetHandler mDropTargetHandler;
protected DropTargetBar mDropTargetBar;
private final MSDLPlayerWrapper mMSDLPlayerWrapper;
/** Whether this drop target is active for the current drag */
protected boolean mActive;
@@ -94,6 +98,7 @@ public abstract class ButtonDropTarget extends TextView
super(context, attrs, defStyle);
mActivityContext = ActivityContext.lookupContext(context);
mDropTargetHandler = mActivityContext.getDropTargetHandler();
mMSDLPlayerWrapper = MSDLPlayerWrapper.INSTANCE.get(context);
Resources resources = getResources();
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
@@ -142,6 +147,10 @@ public abstract class ButtonDropTarget extends TextView
@Override
public final void onDragEnter(DragObject d) {
// Perform Haptic feedback
if (Flags.msdlFeedback()) {
mMSDLPlayerWrapper.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR);
}
if (!mAccessibleDrag && !mTextVisible) {
// Show tooltip
hideTooltip();
@@ -651,14 +651,14 @@ public class InvariantDeviceProfile implements SafeCloseable {
}
/**
* Parses through the xml to find NumRows specs. Then calls findBestRowCount to get the correct
* row count for this GridOption.
* Parses through the xml to find GridDimension specs. Then calls findBestRowCount to get the
* correct row count for this GridOption.
*
* @return the result of {@link #findBestRowCount(List, Info)}.
*/
public static NumRows getRowCount(ResourceHelper resourceHelper, Context context,
public static GridDimension getRowCount(ResourceHelper resourceHelper, Context context,
Info displayInfo) {
ArrayList<NumRows> rowCounts = new ArrayList<>();
ArrayList<GridDimension> rowCounts = new ArrayList<>();
try (XmlResourceParser parser = resourceHelper.getXml()) {
final int depth = parser.getDepth();
@@ -666,8 +666,8 @@ public class InvariantDeviceProfile implements SafeCloseable {
while (((type = parser.next()) != XmlPullParser.END_TAG
|| parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& "NumRows".equals(parser.getName())) {
rowCounts.add(new NumRows(context, Xml.asAttributeSet(parser)));
&& "GridDimension".equals(parser.getName())) {
rowCounts.add(new GridDimension(context, Xml.asAttributeSet(parser)));
}
}
} catch (IOException | XmlPullParserException e) {
@@ -678,10 +678,10 @@ public class InvariantDeviceProfile implements SafeCloseable {
}
/**
* @return the biggest row count that fits the display dimensions spec using NumRows to
* @return the biggest row count that fits the display dimensions spec using GridDimension to
* determine that. If no best row count is found, return -1.
*/
public static NumRows findBestRowCount(List<NumRows> list, Info displayInfo) {
public static GridDimension findBestRowCount(List<GridDimension> list, Info displayInfo) {
int minWidthPx = Integer.MAX_VALUE;
int minHeightPx = Integer.MAX_VALUE;
for (WindowBounds bounds : displayInfo.supportedBounds) {
@@ -700,10 +700,10 @@ public class InvariantDeviceProfile implements SafeCloseable {
}
}
NumRows selectedRow = null;
for (NumRows item: list) {
GridDimension selectedRow = null;
for (GridDimension item: list) {
if (minWidthPx >= item.mMinDeviceWidthPx && minHeightPx >= item.mMinDeviceHeightPx) {
if (selectedRow == null || selectedRow.mNumRowsNew < item.mNumRowsNew) {
if (selectedRow == null || selectedRow.mNumGridDimension < item.mNumGridDimension) {
selectedRow = item;
}
}
@@ -1045,8 +1045,8 @@ public class InvariantDeviceProfile implements SafeCloseable {
mIsDualGrid = a.getBoolean(R.styleable.GridDisplayOption_isDualGrid, false);
if (mRowCountSpecsId != INVALID_RESOURCE_HANDLE) {
ResourceHelper resourceHelper = new ResourceHelper(context, mRowCountSpecsId);
NumRows numR = getRowCount(resourceHelper, context, displayInfo);
numRows = numR.mNumRowsNew;
GridDimension numR = getRowCount(resourceHelper, context, displayInfo);
numRows = numR.mNumGridDimension;
dbFile = numR.mDbFile;
defaultLayoutId = numR.mDefaultLayoutId;
demoModeLayoutId = numR.mDemoModeLayoutId;
@@ -1235,8 +1235,8 @@ public class InvariantDeviceProfile implements SafeCloseable {
}
}
public static final class NumRows {
final int mNumRowsNew;
public static final class GridDimension {
final int mNumGridDimension;
final float mMinDeviceWidthPx;
final float mMinDeviceHeightPx;
final String mDbFile;
@@ -1244,17 +1244,17 @@ public class InvariantDeviceProfile implements SafeCloseable {
final int mDemoModeLayoutId;
NumRows(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumRows);
GridDimension(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridDimension);
mNumRowsNew = (int) a.getFloat(R.styleable.NumRows_numRowsNew, 0);
mMinDeviceWidthPx = a.getFloat(R.styleable.NumRows_minDeviceWidthPx, 0);
mMinDeviceHeightPx = a.getFloat(R.styleable.NumRows_minDeviceHeightPx, 0);
mDbFile = a.getString(R.styleable.NumRows_dbFile);
mNumGridDimension = (int) a.getFloat(R.styleable.GridDimension_numGridDimension, 0);
mMinDeviceWidthPx = a.getFloat(R.styleable.GridDimension_minDeviceWidthPx, 0);
mMinDeviceHeightPx = a.getFloat(R.styleable.GridDimension_minDeviceHeightPx, 0);
mDbFile = a.getString(R.styleable.GridDimension_dbFile);
mDefaultLayoutId = a.getResourceId(
R.styleable.NumRows_defaultLayoutId, 0);
R.styleable.GridDimension_defaultLayoutId, 0);
mDemoModeLayoutId = a.getResourceId(
R.styleable.NumRows_demoModeLayoutId, mDefaultLayoutId);
R.styleable.GridDimension_demoModeLayoutId, mDefaultLayoutId);
a.recycle();
}
@@ -28,6 +28,9 @@ import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.google.android.msdl.data.model.MSDLToken;
import com.google.android.msdl.domain.InteractionProperties;
import com.google.android.msdl.domain.MSDLPlayer;
import com.google.android.msdl.logging.MSDLEvent;
import java.util.List;
import javax.inject.Inject;
@@ -58,4 +61,8 @@ public class MSDLPlayerWrapper {
public void playToken(MSDLToken token) {
mMSDLPlayer.playToken(token, null);
}
public List<MSDLEvent> getHistory() {
return mMSDLPlayer.getHistory();
}
}
@@ -16,7 +16,7 @@
package com.android.launcher3.widget;
import static com.android.launcher3.Flags.enforceSystemRadiusForAppWidgets;
import static com.android.launcher3.Flags.useSystemRadiusForAppWidgets;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
@@ -99,7 +99,7 @@ public class RoundedCornerEnforcement {
public static float computeEnforcedRadius(@NonNull Context context) {
Resources res = context.getResources();
float systemRadius = res.getDimension(android.R.dimen.system_app_widget_background_radius);
if (enforceSystemRadiusForAppWidgets()) {
if (useSystemRadiusForAppWidgets()) {
return systemRadius;
}
@@ -168,7 +168,6 @@ abstract class AbstractDeviceProfileTest {
isLandscape: Boolean = false,
isGestureMode: Boolean = true,
isFolded: Boolean = false,
isFixedLandscape: Boolean = false,
) {
val (unfoldedNaturalX, unfoldedNaturalY) = deviceSpecUnfolded.naturalSize
val unfoldedWindowsBounds =
@@ -195,7 +194,6 @@ abstract class AbstractDeviceProfileTest {
rotation = if (isLandscape) Surface.ROTATION_90 else Surface.ROTATION_0,
isGestureMode = isGestureMode,
densityDpi = deviceSpecFolded.densityDpi,
isFixedLandscape = isFixedLandscape,
)
} else {
initializeCommonVars(
@@ -204,7 +202,6 @@ abstract class AbstractDeviceProfileTest {
rotation = if (isLandscape) Surface.ROTATION_0 else Surface.ROTATION_90,
isGestureMode = isGestureMode,
densityDpi = deviceSpecUnfolded.densityDpi,
isFixedLandscape = isFixedLandscape,
)
}
}
@@ -1,20 +1,29 @@
package com.android.launcher3
import android.content.Context
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.Utilities.*
import com.android.launcher3.dragndrop.DragView
import com.android.launcher3.util.ActivityContextWrapper
import com.android.launcher3.util.MSDLPlayerWrapper
import com.google.android.msdl.data.model.MSDLToken
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeleteDropTargetTest {
@get:Rule val mSetFlagsRule = SetFlagsRule()
private var mContext: Context = ActivityContextWrapper(getApplicationContext())
// Use a non-abstract class implementation
@@ -37,4 +46,17 @@ class DeleteDropTargetTest {
// A lot of space for text so the text should not be clipped
assertThat(buttonDropTarget.isTextClippedVertically(1000)).isFalse()
}
@Test
@EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
fun onDragEnter_performsMSDLSwipeThresholdFeedback() {
val target = DropTarget.DragObject(mContext)
target.dragView = mock<DragView<*>>()
buttonDropTarget.onDragEnter(target)
val wrapper = MSDLPlayerWrapper.INSTANCE.get(mContext)
val history = wrapper.history
assertThat(history.size).isEqualTo(1)
assertThat(history[0].tokenName).isEqualTo(MSDLToken.SWIPE_THRESHOLD_INDICATOR.name)
}
}
@@ -71,6 +71,7 @@ import com.android.launcher3.util.PackageUserKey;
import com.google.common.truth.Truth;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -99,6 +100,11 @@ public class IconCacheTest {
new LauncherIconProvider(mContext));
}
@After
public void tearDown() {
mIconCache.close();
}
@Test
public void getShortcutInfoBadge_nullComponent_overrideAllowed() throws Exception {
String overridePackage = "com.android.settings";
@@ -1,5 +1,6 @@
package com.android.launcher3.model
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -11,8 +12,10 @@ import com.android.launcher3.LauncherSettings.Favorites.addTableToDb
import com.android.launcher3.pm.UserCache
import com.android.launcher3.provider.LauncherDbUtils
import java.util.function.ToLongFunction
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -24,6 +27,19 @@ private const val ICON_RESOURCE = "iconResource"
@SmallTest
@RunWith(AndroidJUnit4::class)
class DatabaseHelperTest {
val context: Context = InstrumentationRegistry.getInstrumentation().targetContext
// v30 - 21 columns
lateinit var db: SQLiteDatabase
@Before
fun setUp() {
db = FactitiousDbController(context, INSERTION_SQL).inMemoryDb
}
@After
fun tearDown() {
db.close()
}
/**
* b/304687723 occurred when a return was accidentally added to a case statement in
@@ -33,13 +49,11 @@ class DatabaseHelperTest {
*/
@Test
fun onUpgrade_to_version_32_from_30() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val userSerialProvider =
ToLongFunction<UserHandle> {
UserCache.INSTANCE.get(context).getSerialNumberForUser(it)
}
val dbHelper = DatabaseHelper(context, null, userSerialProvider) {}
val db = FactitiousDbController(context, INSERTION_SQL).inMemoryDb
dbHelper.onUpgrade(db, 30, 32)
@@ -54,9 +68,6 @@ class DatabaseHelperTest {
*/
@Test
fun after_migrating_from_db_v30_to_v32_copy_table() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val db = FactitiousDbController(context, INSERTION_SQL).inMemoryDb // v30 - 21 columns
addTableToDb(db, 1, true, TMP_TABLE)
LauncherDbUtils.copyTable(db, TABLE_NAME, db, TMP_TABLE, context)
@@ -82,6 +82,7 @@ class GridSizeMigrationTest {
@After
fun tearDown() {
db.close()
modelHelper.destroy()
}
@@ -109,6 +109,7 @@ public class LoaderCursorTest {
@After
public void tearDown() {
mCursor.close();
mModelHelper.destroy();
}
@@ -92,6 +92,7 @@ public class RestoreDbTaskTest {
private Cursor mMockCursor;
private LauncherPrefs mPrefs;
private LauncherRestoreEventLogger mMockRestoreEventLogger;
private SQLiteDatabase mDb;
@Before
public void setup() {
@@ -107,57 +108,60 @@ public class RestoreDbTaskTest {
@After
public void teardown() {
if (mDb != null) {
mDb.close();
}
mModelHelper.destroy();
LauncherPrefs.get(mContext).removeSync(RESTORE_DEVICE);
}
@Test
public void testGetProfileId() throws Exception {
SQLiteDatabase db = new MyModelDbController(23).getDb();
assertEquals(23, new RestoreDbTask().getDefaultProfileId(db));
mDb = new MyModelDbController(23).getDb();
assertEquals(23, new RestoreDbTask().getDefaultProfileId(mDb));
}
@Test
public void testMigrateProfileId() throws Exception {
SQLiteDatabase db = new MyModelDbController(42).getDb();
mDb = new MyModelDbController(42).getDb();
// Add some mock data
for (int i = 0; i < 5; i++) {
ContentValues values = new ContentValues();
values.put(Favorites._ID, i);
values.put(Favorites.TITLE, "item " + i);
db.insert(Favorites.TABLE_NAME, null, values);
mDb.insert(Favorites.TABLE_NAME, null, values);
}
// Verify item add
assertEquals(5, getCount(db, "select * from favorites where profileId = 42"));
assertEquals(5, getCount(mDb, "select * from favorites where profileId = 42"));
new RestoreDbTask().migrateProfileId(db, 42, 33);
new RestoreDbTask().migrateProfileId(mDb, 42, 33);
// verify data migrated
assertEquals(0, getCount(db, "select * from favorites where profileId = 42"));
assertEquals(5, getCount(db, "select * from favorites where profileId = 33"));
assertEquals(0, getCount(mDb, "select * from favorites where profileId = 42"));
assertEquals(5, getCount(mDb, "select * from favorites where profileId = 33"));
}
@Test
public void testChangeDefaultColumn() throws Exception {
SQLiteDatabase db = new MyModelDbController(42).getDb();
mDb = new MyModelDbController(42).getDb();
// Add some mock data
for (int i = 0; i < 5; i++) {
ContentValues values = new ContentValues();
values.put(Favorites._ID, i);
values.put(Favorites.TITLE, "item " + i);
db.insert(Favorites.TABLE_NAME, null, values);
mDb.insert(Favorites.TABLE_NAME, null, values);
}
// Verify default column is 42
assertEquals(5, getCount(db, "select * from favorites where profileId = 42"));
assertEquals(5, getCount(mDb, "select * from favorites where profileId = 42"));
new RestoreDbTask().changeDefaultColumn(db, 33);
new RestoreDbTask().changeDefaultColumn(mDb, 33);
// Verify default value changed
ContentValues values = new ContentValues();
values.put(Favorites._ID, 100);
values.put(Favorites.TITLE, "item 100");
db.insert(Favorites.TABLE_NAME, null, values);
assertEquals(1, getCount(db, "select * from favorites where profileId = 33"));
mDb.insert(Favorites.TABLE_NAME, null, values);
assertEquals(1, getCount(mDb, "select * from favorites where profileId = 33"));
}
@Test
@@ -170,7 +174,7 @@ public class RestoreDbTaskTest {
long workProfileId_old = myProfileId + 3;
MyModelDbController controller = new MyModelDbController(myProfileId);
SQLiteDatabase db = controller.getDb();
mDb = controller.getDb();
BackupManager bm = spy(new BackupManager(mContext));
doReturn(myUserHandle()).when(bm).getUserForAncestralSerialNumber(eq(myProfileId_old));
doReturn(mWorkUser).when(bm).getUserForAncestralSerialNumber(eq(workProfileId_old));
@@ -178,16 +182,16 @@ public class RestoreDbTaskTest {
addIconsBulk(controller, 10, 1, myProfileId_old);
addIconsBulk(controller, 6, 2, workProfileId_old);
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
assertEquals(10, getItemCountForProfile(mDb, myProfileId_old));
assertEquals(6, getItemCountForProfile(mDb, workProfileId_old));
mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
assertEquals(0, getItemCountForProfile(db, workProfileId_old));
assertEquals(10, getItemCountForProfile(db, myProfileId));
assertEquals(6, getItemCountForProfile(db, workProfileId));
assertEquals(0, getItemCountForProfile(mDb, myProfileId_old));
assertEquals(0, getItemCountForProfile(mDb, workProfileId_old));
assertEquals(10, getItemCountForProfile(mDb, myProfileId));
assertEquals(6, getItemCountForProfile(mDb, workProfileId));
}
@Test
@@ -199,7 +203,7 @@ public class RestoreDbTaskTest {
long workProfileId_old = myProfileId + 3;
MyModelDbController controller = new MyModelDbController(myProfileId);
SQLiteDatabase db = controller.getDb();
mDb = controller.getDb();
BackupManager bm = spy(new BackupManager(mContext));
doReturn(myUserHandle()).when(bm).getUserForAncestralSerialNumber(eq(myProfileId_old));
// Work profile is not migrated
@@ -207,16 +211,16 @@ public class RestoreDbTaskTest {
addIconsBulk(controller, 10, 1, myProfileId_old);
addIconsBulk(controller, 6, 2, workProfileId_old);
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
assertEquals(10, getItemCountForProfile(mDb, myProfileId_old));
assertEquals(6, getItemCountForProfile(mDb, workProfileId_old));
mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
assertEquals(0, getItemCountForProfile(db, workProfileId_old));
assertEquals(10, getItemCountForProfile(db, myProfileId));
assertEquals(10, getCount(db, "select * from favorites"));
assertEquals(0, getItemCountForProfile(mDb, myProfileId_old));
assertEquals(0, getItemCountForProfile(mDb, workProfileId_old));
assertEquals(10, getItemCountForProfile(mDb, myProfileId));
assertEquals(10, getCount(mDb, "select * from favorites"));
}
@Test
@@ -342,24 +346,24 @@ public class RestoreDbTaskTest {
}
private void runRemoveScreenIdGapsTest(int[] screenIds, int[] expectedScreenIds) {
SQLiteDatabase db = new MyModelDbController(42).getDb();
mDb = new MyModelDbController(42).getDb();
// Add some mock data
for (int i = 0; i < screenIds.length; i++) {
ContentValues values = new ContentValues();
values.put(Favorites._ID, i);
values.put(Favorites.SCREEN, screenIds[i]);
values.put(Favorites.CONTAINER, CONTAINER_DESKTOP);
db.insert(Favorites.TABLE_NAME, null, values);
mDb.insert(Favorites.TABLE_NAME, null, values);
}
// Verify items are added
assertEquals(screenIds.length,
getCount(db, "select * from favorites where container = -100"));
getCount(mDb, "select * from favorites where container = -100"));
new RestoreDbTask().removeScreenIdGaps(db);
new RestoreDbTask().removeScreenIdGaps(mDb);
// verify screenId gaps removed
int[] resultScreenIds = new int[screenIds.length];
try (Cursor c = db.rawQuery(
try (Cursor c = mDb.rawQuery(
"select screen from favorites where container = -100 order by screen", null)) {
int i = 0;
while (c.moveToNext()) {
@@ -26,6 +26,7 @@ import com.android.launcher3.model.WidgetItem
import com.android.launcher3.util.ActivityContextWrapper
import com.android.launcher3.util.Executors
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -38,7 +39,7 @@ class GeneratedPreviewTest {
@get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
private val providerName =
ComponentName(
getInstrumentation().getContext().getPackageName(),
getInstrumentation().context.packageName,
"com.android.launcher3.testcomponent.AppWidgetNoConfig",
)
private val generatedPreviewLayout =
@@ -51,6 +52,7 @@ class GeneratedPreviewTest {
private lateinit var helper: WidgetManagerHelper
private lateinit var appWidgetProviderInfo: LauncherAppWidgetProviderInfo
private lateinit var widgetItem: WidgetItem
private lateinit var iconCache: IconCache
@Before
fun setup() {
@@ -88,17 +90,17 @@ class GeneratedPreviewTest {
createWidgetItem()
}
@After
fun tearDown() {
iconCache.close()
}
private fun createWidgetItem() {
Executors.MODEL_EXECUTOR.submit {
val idp = InvariantDeviceProfile()
widgetItem =
WidgetItem(
appWidgetProviderInfo,
idp,
IconCache(context, idp, null, IconProvider(context)),
context,
helper,
)
if (::iconCache.isInitialized) iconCache.close()
iconCache = IconCache(context, idp, null, IconProvider(context))
widgetItem = WidgetItem(appWidgetProviderInfo, idp, iconCache, context, helper)
}
.get()
}
@@ -86,7 +86,7 @@ class RoundedCornerEnforcementTest {
}
@Test
@DisableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
@DisableFlags(Flags.FLAG_USE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
fun `Compute system radius when smaller`() {
val mockContext = mock(Context::class.java)
val mockRes = mock(Resources::class.java)
@@ -103,7 +103,7 @@ class RoundedCornerEnforcementTest {
}
@Test
@DisableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
@DisableFlags(Flags.FLAG_USE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
fun `Compute launcher radius when smaller`() {
val mockContext = mock(Context::class.java)
val mockRes = mock(Resources::class.java)
@@ -120,7 +120,7 @@ class RoundedCornerEnforcementTest {
}
@Test
@EnableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
@EnableFlags(Flags.FLAG_USE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
fun `Compute system radius ignoring launcher radius`() {
val mockContext = mock(Context::class.java)
val mockRes = mock(Resources::class.java)
@@ -124,9 +124,10 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> {
@JvmOverloads
protected fun injectKeyEvent(keyCode: Int, actionDown: Boolean, metaState: Int = 0) {
uiDevice.waitForIdle()
val eventTime = SystemClock.uptimeMillis()
val event =
KeyEvent.obtain(
KeyEvent(
eventTime,
eventTime,
if (actionDown) KeyEvent.ACTION_DOWN else MotionEvent.ACTION_UP,
@@ -137,10 +138,8 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> {
/* scancode= */ 0,
/* flags= */ 0,
InputDevice.SOURCE_KEYBOARD,
/* characters =*/ null,
)
executeOnLauncher { it.dispatchKeyEvent(event) }
event.recycle()
}
@JvmOverloads