Snap for 10106040 from 4d17468f88 to udc-release

Change-Id: I5d24fe1c0dc961081331092c43d2be016c2f0424
This commit is contained in:
Android Build Coastguard Worker
2023-05-10 23:28:54 +00:00
12 changed files with 309 additions and 39 deletions
@@ -43,7 +43,8 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun
private var shadowBlur = 0f
private var keyShadowDistance = 0f
private var arrowPositionX: Float = 0f
var arrowPositionX: Float = 0f
private set
private var showingArrow: Boolean = false
private var arrowDrawable: ShapeDrawable
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar.bubbles;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
@@ -41,14 +42,14 @@ import java.util.List;
* - stashed as a handle
* - unstashed but collapsed, in this state the bar is showing but the bubbles are stacked within it
* - unstashed and expanded, in this state the bar is showing and the bubbles are shown in a row
* with one of the bubbles being selected. Additionally, WMShell will display the expanded bubble
* view above the bar.
* with one of the bubbles being selected. Additionally, WMShell will display the expanded bubble
* view above the bar.
* <p>
* The bubble bar has some behavior related to taskbar:
* - When taskbar is unstashed, bubble bar will also become unstashed (but in its "collapsed"
* state)
* state)
* - When taskbar is stashed, bubble bar will also become stashed (unless bubble bar is in its
* "expanded" state)
* "expanded" state)
* - When bubble bar is in its "expanded" state, taskbar becomes stashed
* <p>
* If there are no bubbles, the bubble bar and bubble stashed handle are not shown. Additionally
@@ -64,6 +65,7 @@ public class BubbleBarView extends FrameLayout {
// TODO: (b/273594744) calculate the amount of space we have and base the max on that
// if it's smaller than 5.
private static final int MAX_BUBBLES = 5;
private static final int ARROW_POSITION_ANIMATION_DURATION_MS = 200;
private final TaskbarActivityContext mActivityContext;
private final BubbleBarBackground mBubbleBarBackground;
@@ -209,14 +211,18 @@ public class BubbleBarView extends FrameLayout {
/**
* Sets which bubble view should be shown as selected.
*/
// TODO: (b/273592694) animate it
public void setSelectedBubble(BubbleView view) {
mSelectedBubbleView = view;
updateArrowForSelected();
invalidate();
updateArrowForSelected(/* shouldAnimate= */ true);
}
private void updateArrowForSelected() {
/**
* Update the arrow position to match the selected bubble.
*
* @param shouldAnimate whether or not to animate the arrow. If the bar was just expanded, this
* should be set to {@code false}. Otherwise set this to {@code true}.
*/
private void updateArrowForSelected(boolean shouldAnimate) {
if (mSelectedBubbleView == null) {
Log.w(TAG, "trying to update selection arrow without a selected view!");
return;
@@ -224,7 +230,21 @@ public class BubbleBarView extends FrameLayout {
final int index = indexOfChild(mSelectedBubbleView);
// Find the center of the bubble when it's expanded, set the arrow position to it.
final float tx = getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f;
mBubbleBarBackground.setArrowPosition(tx);
if (shouldAnimate) {
final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX();
ValueAnimator animator = ValueAnimator.ofFloat(currentArrowPosition, tx);
animator.setDuration(ARROW_POSITION_ANIMATION_DURATION_MS);
animator.addUpdateListener(animation -> {
float x = (float) animation.getAnimatedValue();
mBubbleBarBackground.setArrowPosition(x);
invalidate();
});
animator.start();
} else {
mBubbleBarBackground.setArrowPosition(tx);
invalidate();
}
}
@Override
@@ -248,7 +268,7 @@ public class BubbleBarView extends FrameLayout {
public void setExpanded(boolean isBarExpanded) {
if (mIsBarExpanded != isBarExpanded) {
mIsBarExpanded = isBarExpanded;
updateArrowForSelected();
updateArrowForSelected(/* shouldAnimate= */ false);
setOrUnsetClickListener();
if (!isBarExpanded && mReorderRunnable != null) {
mReorderRunnable.run();
@@ -17,11 +17,9 @@ package com.android.quickstep.util;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import android.util.FloatProperty;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
@@ -61,7 +59,6 @@ public class TransformParams {
private float mCornerRadius;
private RemoteAnimationTargets mTargetSet;
private SurfaceTransactionApplier mSyncTransactionApplier;
private SurfaceControl mRecentsSurface;
private BuilderProxy mHomeBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
private BuilderProxy mBaseBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
@@ -141,8 +138,9 @@ public class TransformParams {
public SurfaceTransaction createSurfaceParams(BuilderProxy proxy) {
RemoteAnimationTargets targets = mTargetSet;
SurfaceTransaction transaction = new SurfaceTransaction();
mRecentsSurface = getRecentsSurface(targets);
if (targets == null) {
return transaction;
}
for (int i = 0; i < targets.unfilteredApps.length; i++) {
RemoteAnimationTarget app = targets.unfilteredApps[i];
SurfaceProperties builder = transaction.forSurface(app.leash);
@@ -176,20 +174,6 @@ public class TransformParams {
return transaction;
}
private static SurfaceControl getRecentsSurface(RemoteAnimationTargets targets) {
for (int i = 0; i < targets.unfilteredApps.length; i++) {
RemoteAnimationTarget app = targets.unfilteredApps[i];
if (app.mode == targets.targetMode) {
if (app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_RECENTS) {
return app.leash;
}
} else {
return app.leash;
}
}
return null;
}
// Pubic getters so outside packages can read the values.
public float getProgress() {
@@ -204,10 +188,6 @@ public class TransformParams {
return mCornerRadius;
}
public SurfaceControl getRecentsSurface() {
return mRecentsSurface;
}
public RemoteAnimationTargets getTargetSet() {
return mTargetSet;
}
+3
View File
@@ -199,6 +199,9 @@
<attr name="demoModeLayoutId" format="reference" />
<attr name="isScalable" format="boolean" />
<attr name="devicePaddingId" format="reference" />
<!-- File that contains the specs for the workspace.
Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
<attr name="workspaceSpecsId" format="reference" />
<!-- By default all categories are enabled -->
<attr name="deviceCategory" format="integer">
<!-- Enable on phone only -->
+1 -1
View File
@@ -26,6 +26,6 @@
launcher:category="1"
launcher:sectionDrawable="@drawable/ic_note_taking_widget_category"
launcher:sectionTitle="@string/widget_category_note_taking">
<widget launcher:provider="com.android.settings/com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity" />
<widget launcher:provider="com.android.systemui/.notetask.shortcut.CreateNoteTaskShortcutActivity" />
</section>
</widget-sections>
@@ -101,6 +101,7 @@ public class DeviceProfile {
public final float aspectRatio;
public final boolean isScalableGrid;
public final boolean isResponsiveGrid;
private final int mTypeIndex;
/**
@@ -293,6 +294,10 @@ public class DeviceProfile {
this.rotationHint = windowBounds.rotationHint;
mInsets.set(windowBounds.insets);
// TODO(b/241386436):
// for testing that the flag works only, shouldn't change any launcher behaviour
isResponsiveGrid = inv.workspaceSpecsId != INVALID_RESOURCE_HANDLE;
isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
// Determine device posture.
mInfo = info;
@@ -1577,6 +1582,7 @@ public class DeviceProfile {
writer.println(prefix + "\taspectRatio:" + aspectRatio);
writer.println(prefix + "\tisResponsiveGrid:" + isResponsiveGrid);
writer.println(prefix + "\tisScalableGrid:" + isScalableGrid);
writer.println(prefix + "\tinv.numRows: " + inv.numRows);
@@ -48,6 +48,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.annotation.XmlRes;
import androidx.core.content.res.ResourcesCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.provider.RestoreDbTask;
@@ -105,7 +106,7 @@ public class InvariantDeviceProfile {
static final int INDEX_TWO_PANEL_PORTRAIT = 2;
static final int INDEX_TWO_PANEL_LANDSCAPE = 3;
/** These resources are used to override the device profile */
/** These resources are used to override the device profile */
private static final String RES_GRID_NUM_ROWS = "grid_num_rows";
private static final String RES_GRID_NUM_COLUMNS = "grid_num_columns";
private static final String RES_GRID_ICON_SIZE_DP = "grid_icon_size_dp";
@@ -177,6 +178,8 @@ public class InvariantDeviceProfile {
protected boolean isScalable;
@XmlRes
public int devicePaddingId = INVALID_RESOURCE_HANDLE;
@XmlRes
public int workspaceSpecsId = INVALID_RESOURCE_HANDLE;
public String dbFile;
public int defaultLayoutId;
@@ -350,6 +353,7 @@ public class InvariantDeviceProfile {
isScalable = closestProfile.isScalable;
devicePaddingId = closestProfile.devicePaddingId;
workspaceSpecsId = closestProfile.mWorkspaceSpecsId;
this.deviceType = deviceType;
inlineNavButtonsEndSpacing = closestProfile.inlineNavButtonsEndSpacing;
@@ -795,6 +799,7 @@ public class InvariantDeviceProfile {
private final boolean isScalable;
private final int devicePaddingId;
private final int mWorkspaceSpecsId;
public GridOption(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(
@@ -836,7 +841,7 @@ public class InvariantDeviceProfile {
inlineNavButtonsEndSpacing =
a.getResourceId(R.styleable.GridDisplayOption_inlineNavButtonsEndSpacing,
R.dimen.taskbar_button_margin_default);
R.dimen.taskbar_button_margin_default);
numFolderRows = a.getInt(
R.styleable.GridDisplayOption_numFolderRows, numRows);
@@ -856,6 +861,13 @@ public class InvariantDeviceProfile {
deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
DEVICE_CATEGORY_ALL);
if (FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE.get()) {
mWorkspaceSpecsId = a.getResourceId(
R.styleable.GridDisplayOption_workspaceSpecsId, INVALID_RESOURCE_HANDLE);
} else {
mWorkspaceSpecsId = INVALID_RESOURCE_HANDLE;
}
int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
DONT_INLINE_QSB);
inlineQsb[INDEX_DEFAULT] =
+3
View File
@@ -214,6 +214,7 @@ import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ComposeInitializer;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingSurfaceView;
import com.android.launcher3.views.OptionsPopupView;
@@ -553,6 +554,8 @@ public class Launcher extends StatefulActivity<LauncherState>
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(getRootView());
ComposeInitializer.initCompose(this);
if (mOnInitialBindListener != null) {
getRootView().getViewTreeObserver().addOnPreDrawListener(mOnInitialBindListener);
}
@@ -416,6 +416,10 @@ public final class FeatureFlags {
// TODO(Block 32): Empty block
public static final BooleanFlag ENABLE_RESPONSIVE_WORKSPACE = getDebugFlag(241386436,
"ENABLE_RESPONSIVE_WORKSPACE", DISABLED,
"Enables new workspace grid calculations method.");
public static class BooleanFlag {
private final boolean mCurrentValue;
@@ -0,0 +1,229 @@
/*
* 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.views;
import android.os.Build;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.ViewTreeLifecycleOwner;
import androidx.savedstate.SavedStateRegistry;
import androidx.savedstate.SavedStateRegistryController;
import androidx.savedstate.SavedStateRegistryOwner;
import androidx.savedstate.ViewTreeSavedStateRegistryOwner;
import com.android.launcher3.Utilities;
/**
* An initializer to use Compose for classes implementing {@code ActivityContext}. This allows
* adding ComposeView to ViewTree outside a {@link androidx.activity.ComponentActivity}.
*/
public final class ComposeInitializer {
/**
* Performs the initialization to use Compose in the ViewTree of {@code target}.
*/
public static void initCompose(ActivityContext target) {
getContentChild(target).addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
ComposeInitializer.onAttachedToWindow(v);
}
@Override
public void onViewDetachedFromWindow(View v) {
ComposeInitializer.onDetachedFromWindow(v);
}
});
}
/**
* Find the "content child" for {@code target}.
*
* @see "WindowRecomposer.android.kt: [View.contentChild]"
*/
private static View getContentChild(ActivityContext target) {
View self = target.getDragLayer();
ViewParent parent = self.getParent();
while (parent instanceof View parentView) {
if (parentView.getId() == android.R.id.content) return self;
self = parentView;
parent = self.getParent();
}
return self;
}
/**
* Function to be called on your window root view's [View.onAttachedToWindow] function.
*/
private static void onAttachedToWindow(View root) {
if (ViewTreeLifecycleOwner.get(root) != null) {
throw new IllegalStateException(
"View " + root + " already has a LifecycleOwner");
}
ViewParent parent = root.getParent();
if (parent instanceof View && ((View) parent).getId() != android.R.id.content) {
throw new IllegalStateException(
"ComposeInitializer.onContentChildAttachedToWindow(View) must be called on "
+ "the content child. Outside of activities and dialogs, this is "
+ "usually the top-most View of a window.");
}
// The lifecycle owner, which is STARTED when [root] is visible and RESUMED when [root]
// is both visible and focused.
ViewLifecycleOwner lifecycleOwner = new ViewLifecycleOwner(root);
// We must call [ViewLifecycleOwner.onCreate] after creating the
// [SavedStateRegistryOwner] because `onCreate` might move the lifecycle state to STARTED
// which will make [SavedStateRegistryController.performRestore] throw.
lifecycleOwner.onCreate();
// Set the owners on the root. They will be reused by any ComposeView inside the root
// hierarchy.
ViewTreeLifecycleOwner.set(root, lifecycleOwner);
ViewTreeSavedStateRegistryOwner.set(root, lifecycleOwner);
}
/**
* Function to be called on your window root view's [View.onDetachedFromWindow] function.
*/
private static void onDetachedFromWindow(View root) {
final LifecycleOwner lifecycleOwner = ViewTreeLifecycleOwner.get(root);
if (lifecycleOwner != null) {
((ViewLifecycleOwner) lifecycleOwner).onDestroy();
}
ViewTreeLifecycleOwner.set(root, null);
ViewTreeSavedStateRegistryOwner.set(root, null);
}
/**
* A [LifecycleOwner] for a [View] that updates lifecycle state based on window state.
*
* Also a trivial implementation of [SavedStateRegistryOwner] that does not do any save or
* restore. This works for processes similar to the SystemUI process, which is always running
* and top-level windows using this initialization are created once, when the process is
* started.
*
* The implementation requires the caller to call [onCreate] and [onDestroy] when the view is
* attached to or detached from a view hierarchy. After [onCreate] and before [onDestroy] is
* called, the implementation monitors window state in the following way
* * If the window is not visible, we are in the [Lifecycle.State.CREATED] state
* * If the window is visible but not focused, we are in the [Lifecycle.State.STARTED] state
* * If the window is visible and focused, we are in the [Lifecycle.State.RESUMED] state
*
* Or in table format:
* ```
* ┌───────────────┬───────────────────┬──────────────┬─────────────────┐
* │ View attached │ Window Visibility │ Window Focus │ Lifecycle State │
* ├───────────────┼───────────────────┴──────────────┼─────────────────┤
* │ Not attached │ Any │ N/A │
* ├───────────────┼───────────────────┬──────────────┼─────────────────┤
* │ │ Not visible │ Any │ CREATED │
* │ ├───────────────────┼──────────────┼─────────────────┤
* │ Attached │ │ No focus │ STARTED │
* │ │ Visible ├──────────────┼─────────────────┤
* │ │ │ Has focus │ RESUMED │
* └───────────────┴───────────────────┴──────────────┴─────────────────┘
* ```
*/
private static class ViewLifecycleOwner implements SavedStateRegistryOwner {
private final ViewTreeObserver.OnWindowFocusChangeListener mWindowFocusListener =
hasFocus -> updateState();
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
private final SavedStateRegistryController mSavedStateRegistryController =
SavedStateRegistryController.create(this);
private final View mView;
private final Api34Impl mApi34Impl;
ViewLifecycleOwner(View view) {
mView = view;
if (Utilities.ATLEAST_U) {
mApi34Impl = new Api34Impl();
} else {
mApi34Impl = null;
}
mSavedStateRegistryController.performRestore(null);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
@NonNull
@Override
public SavedStateRegistry getSavedStateRegistry() {
return mSavedStateRegistryController.getSavedStateRegistry();
}
void onCreate() {
mLifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
if (Utilities.ATLEAST_U) {
mApi34Impl.addOnWindowVisibilityChangeListener();
}
mView.getViewTreeObserver().addOnWindowFocusChangeListener(
mWindowFocusListener);
updateState();
}
void onDestroy() {
if (Utilities.ATLEAST_U) {
mApi34Impl.removeOnWindowVisibilityChangeListener();
}
mView.getViewTreeObserver().removeOnWindowFocusChangeListener(
mWindowFocusListener);
mLifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
}
private void updateState() {
Lifecycle.State state =
mView.getWindowVisibility() != View.VISIBLE ? Lifecycle.State.CREATED
: (!mView.hasWindowFocus() ? Lifecycle.State.STARTED
: Lifecycle.State.RESUMED);
mLifecycleRegistry.setCurrentState(state);
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
private class Api34Impl {
private final ViewTreeObserver.OnWindowVisibilityChangeListener
mWindowVisibilityListener =
visibility -> updateState();
void addOnWindowVisibilityChangeListener() {
mView.getViewTreeObserver().addOnWindowVisibilityChangeListener(
mWindowVisibilityListener);
}
void removeOnWindowVisibilityChangeListener() {
mView.getViewTreeObserver().removeOnWindowVisibilityChangeListener(
mWindowVisibilityListener);
}
}
}
}
@@ -50,7 +50,7 @@ abstract class AbstractDeviceProfileTest {
private lateinit var originalWindowManagerProxy: WindowManagerProxy
@Before
fun setUp() {
open fun setUp() {
val appContext: Context = ApplicationProvider.getApplicationContext()
originalWindowManagerProxy = WindowManagerProxy.INSTANCE.get(appContext)
originalDisplayController = DisplayController.INSTANCE.get(appContext)
@@ -59,7 +59,7 @@ abstract class AbstractDeviceProfileTest {
}
@After
fun tearDown() {
open fun tearDown() {
WindowManagerProxy.INSTANCE.initializeForTesting(originalWindowManagerProxy)
DisplayController.INSTANCE.initializeForTesting(originalDisplayController)
}
@@ -58,6 +58,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 126.0px (48.0dp)\n" +
"\taspectRatio:2.2222223\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 5\n" +
@@ -193,6 +194,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 63.0px (24.0dp)\n" +
"\taspectRatio:2.2222223\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 5\n" +
@@ -328,6 +330,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 126.0px (48.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:2.2222223\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 5\n" +
@@ -463,6 +466,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 63.0px (24.0dp)\n" +
"\taspectRatio:2.2222223\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 5\n" +
@@ -599,6 +603,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.6\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:true\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 6\n" +
@@ -735,6 +740,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.6\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:true\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 6\n" +
@@ -871,6 +877,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.6\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:true\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 6\n" +
@@ -1007,6 +1014,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.6\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:true\n" +
"\tinv.numRows: 5\n" +
"\tinv.numColumns: 6\n" +
@@ -1148,6 +1156,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.2\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 4\n" +
"\tinv.numColumns: 4\n" +
@@ -1288,6 +1297,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.2\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 4\n" +
"\tinv.numColumns: 4\n" +
@@ -1428,6 +1438,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.2\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 4\n" +
"\tinv.numColumns: 4\n" +
@@ -1564,6 +1575,7 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
"\tmInsets.right: 0.0px (0.0dp)\n" +
"\tmInsets.bottom: 0.0px (0.0dp)\n" +
"\taspectRatio:1.2\n" +
"\tisResponsiveGrid:false\n" +
"\tisScalableGrid:false\n" +
"\tinv.numRows: 4\n" +
"\tinv.numColumns: 4\n" +