Snap for 10296703 from a6a71d5ace to udc-qpr1-release

Change-Id: I0602922e4f584b88e59ac81bae0d4b77332939b9
This commit is contained in:
Android Build Coastguard Worker
2023-06-10 04:38:33 +00:00
16 changed files with 349 additions and 117 deletions
@@ -2042,10 +2042,5 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
setCrossWindowBlursEnabled(
CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled());
}
@Override
public void setSurface(SurfaceControl surface) {
super.setSurface(surface);
}
}
}
@@ -158,6 +158,12 @@ public class DepthController extends BaseDepthController implements StateHandler
super.applyDepthAndBlur();
}
@Override
protected void onInvalidSurface() {
// Lets wait for surface to become valid again
mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
}
@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
mIgnoreStateChangesDuringMultiWindowAnimation = true;
@@ -41,8 +41,10 @@ public class TaskbarAutohideSuspendController implements
public static final int FLAG_AUTOHIDE_SUSPEND_TOUCHING = 1 << 2;
// Taskbar EDU overlay is open above the Taskbar. */
public static final int FLAG_AUTOHIDE_SUSPEND_EDU_OPEN = 1 << 3;
// Taskbar in immersive mode in overview
// Taskbar is in immersive mode in overview.
public static final int FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER = 1 << 4;
// Transient Taskbar is temporarily unstashed (pending a timeout).
public static final int FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR = 1 << 5;
@IntDef(flag = true, value = {
FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
@@ -50,6 +52,7 @@ public class TaskbarAutohideSuspendController implements
FLAG_AUTOHIDE_SUSPEND_TOUCHING,
FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER,
FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AutohideSuspendFlag {}
@@ -85,18 +88,21 @@ public class TaskbarAutohideSuspendController implements
boolean isSuspended = isSuspended();
mSystemUiProxy.notifyTaskbarAutohideSuspend(isSuspended);
mActivity.onTransientAutohideSuspendFlagChanged(isSuspended);
mActivity.onTransientAutohideSuspendFlagChanged(isTransientTaskbarStashingSuspended());
}
/**
* Returns true iff taskbar autohide is currently suspended.
* Returns true iff taskbar autohide is currently suspended for immersive mode.
*/
public boolean isSuspended() {
private boolean isSuspended() {
return mAutohideSuspendFlags != 0;
}
public boolean isSuspendedForTransientTaskbarInOverview() {
return (mAutohideSuspendFlags & FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER) != 0;
/**
* Returns whether Transient Taskbar should avoid auto-stashing.
*/
public boolean isTransientTaskbarStashingSuspended() {
return (mAutohideSuspendFlags & ~FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR) != 0;
}
@Override
@@ -115,6 +121,8 @@ public class TaskbarAutohideSuspendController implements
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_EDU_OPEN, "FLAG_AUTOHIDE_SUSPEND_EDU_OPEN");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER,
"FLAG_AUTOHIDE_SUSPEND_IN_LAUNCHER");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR,
"FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR");
return str.toString();
}
}
@@ -519,10 +519,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
return;
}
if (stash && mControllers.taskbarAutohideSuspendController.isSuspended()
&& !mControllers.taskbarAutohideSuspendController
.isSuspendedForTransientTaskbarInOverview()) {
// Avoid stashing if autohide is currently suspended.
if (stash && mControllers.taskbarAutohideSuspendController
.isTransientTaskbarStashingSuspended()) {
return;
}
@@ -1080,6 +1078,9 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
mActivity.getStatsLogManager().logger().log(hasAnyFlag(FLAG_STASHED_IN_APP_AUTO)
? LAUNCHER_TRANSIENT_TASKBAR_HIDE
: LAUNCHER_TRANSIENT_TASKBAR_SHOW);
mControllers.taskbarAutohideSuspendController.updateFlag(
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR,
!hasAnyFlag(FLAG_STASHED_IN_APP_AUTO));
}
}
@@ -1172,7 +1173,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
}
private void onTaskbarTimeout(Alarm alarm) {
if (mControllers.taskbarAutohideSuspendController.isSuspended()) {
if (mControllers.taskbarAutohideSuspendController.isTransientTaskbarStashingSuspended()) {
return;
}
updateAndAnimateTransientTaskbarForTimeout();
@@ -88,6 +88,8 @@ public class BaseDepthController {
*/
protected boolean mInEarlyWakeUp;
private boolean mWaitingOnSurfaceValidity;
public BaseDepthController(Launcher activity) {
mLauncher = activity;
mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius);
@@ -115,6 +117,8 @@ public class BaseDepthController {
}
}
protected void onInvalidSurface() { }
protected void applyDepthAndBlur() {
float depth = mDepth;
IBinder windowToken = mLauncher.getRootView().getWindowToken();
@@ -128,9 +132,15 @@ public class BaseDepthController {
if (!BlurUtils.supportsBlursOnWindows()) {
return;
}
if (mSurface == null || !mSurface.isValid()) {
if (mSurface == null) {
return;
}
if (!mSurface.isValid()) {
mWaitingOnSurfaceValidity = true;
onInvalidSurface();
return;
}
mWaitingOnSurfaceValidity = false;
boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg && !mPauseBlurs;
@@ -174,7 +184,7 @@ public class BaseDepthController {
* Sets the specified app target surface to apply the blur to.
*/
protected void setSurface(SurfaceControl surface) {
if (mSurface != surface) {
if (mSurface != surface || mWaitingOnSurfaceValidity) {
mSurface = surface;
applyDepthAndBlur();
}
+3 -1
View File
@@ -204,6 +204,7 @@
<!-- 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 -->
@@ -251,10 +252,11 @@
<attr name="maxAvailableSize" format="dimension" />
</declare-styleable>
<declare-styleable name="SpecSize">
<declare-styleable name="SizeSpec">
<attr name="fixedSize" format="dimension" />
<attr name="ofAvailableSpace" format="float" />
<attr name="ofRemainderSpace" format="float" />
<attr name="matchWorkspace" format="boolean" />
</declare-styleable>
<declare-styleable name="ProfileDisplayOption">
@@ -0,0 +1,73 @@
package com.android.launcher3.responsive
import android.content.res.TypedArray
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import com.android.launcher3.R
import com.android.launcher3.util.ResourceHelper
data class SizeSpec(
val fixedSize: Float,
val ofAvailableSpace: Float,
val ofRemainderSpace: Float,
val matchWorkspace: Boolean
) {
fun isValid(): Boolean {
// All attributes are empty
if (fixedSize < 0f && ofAvailableSpace <= 0f && ofRemainderSpace <= 0f && !matchWorkspace) {
Log.e(TAG, "SizeSpec#isValid - all attributes are empty")
return false
}
// More than one attribute is filled
val attrCount =
(if (fixedSize > 0) 1 else 0) +
(if (ofAvailableSpace > 0) 1 else 0) +
(if (ofRemainderSpace > 0) 1 else 0) +
(if (matchWorkspace) 1 else 0)
if (attrCount > 1) {
Log.e(TAG, "SizeSpec#isValid - more than one attribute is filled")
return false
}
// Values should be between 0 and 1
if (ofAvailableSpace !in 0f..1f || ofRemainderSpace !in 0f..1f) {
Log.e(TAG, "SizeSpec#isValid - values should be between 0 and 1")
return false
}
// Invalid fixed size
if (fixedSize < 0f) {
Log.e(TAG, "SizeSpec#isValid - values should be bigger or equal to zero.")
return false
}
return true
}
companion object {
private const val TAG = "WorkspaceSpecs::SizeSpec"
private fun getValue(a: TypedArray, index: Int): Float {
return when (a.getType(index)) {
TypedValue.TYPE_DIMENSION -> a.getDimensionPixelSize(index, 0).toFloat()
TypedValue.TYPE_FLOAT -> a.getFloat(index, 0f)
else -> 0f
}
}
fun create(resourceHelper: ResourceHelper, attrs: AttributeSet): SizeSpec {
val styledAttrs = resourceHelper.obtainStyledAttributes(attrs, R.styleable.SizeSpec)
val fixedSize = getValue(styledAttrs, R.styleable.SizeSpec_fixedSize)
val ofAvailableSpace = getValue(styledAttrs, R.styleable.SizeSpec_ofAvailableSpace)
val ofRemainderSpace = getValue(styledAttrs, R.styleable.SizeSpec_ofRemainderSpace)
val matchWorkspace = styledAttrs.getBoolean(R.styleable.SizeSpec_matchWorkspace, false)
styledAttrs.recycle()
return SizeSpec(fixedSize, ofAvailableSpace, ofRemainderSpace, matchWorkspace)
}
}
}
@@ -40,17 +40,14 @@ public class OnboardingPrefs<T extends ActivityContext> {
public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
public static final String SEARCH_KEYBOARD_EDU_SEEN = "launcher.search_edu_seen";
public static final String SEARCH_SNACKBAR_COUNT = "launcher.keyboard_snackbar_count";
public static final String SEARCH_ONBOARDING_COUNT = "launcher.search_onboarding_count";
public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
public static final String QSB_SEARCH_ONBOARDING_CARD_DISMISSED = "launcher.qsb_edu_dismiss";
public static final String TASKBAR_EDU_TOOLTIP_STEP = "launcher.taskbar_edu_tooltip_step";
// When adding a new key, add it here as well, to be able to reset it from Developer Options.
public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
"All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
"Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
HOTSEAT_LONGPRESS_TIP_SEEN },
"Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT,
SEARCH_ONBOARDING_COUNT, QSB_SEARCH_ONBOARDING_CARD_DISMISSED},
"Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT},
"Taskbar Education", new String[] { TASKBAR_EDU_TOOLTIP_STEP },
"All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
);
@@ -62,7 +59,6 @@ public class OnboardingPrefs<T extends ActivityContext> {
HOME_BOUNCE_SEEN,
HOTSEAT_LONGPRESS_TIP_SEEN,
SEARCH_KEYBOARD_EDU_SEEN,
QSB_SEARCH_ONBOARDING_CARD_DISMISSED
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventBoolKey {}
@@ -74,7 +70,6 @@ public class OnboardingPrefs<T extends ActivityContext> {
HOME_BOUNCE_COUNT,
HOTSEAT_DISCOVERY_TIP_COUNT,
SEARCH_SNACKBAR_COUNT,
SEARCH_ONBOARDING_COUNT,
ALL_APPS_VISITED_COUNT,
TASKBAR_EDU_TOOLTIP_STEP,
})
@@ -88,8 +83,6 @@ public class OnboardingPrefs<T extends ActivityContext> {
maxCounts.put(HOME_BOUNCE_COUNT, 3);
maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
maxCounts.put(SEARCH_SNACKBAR_COUNT, 3);
// This is the sum of all onboarding cards. Currently there is only 1 card shown 3 times.
maxCounts.put(SEARCH_ONBOARDING_COUNT, 3);
maxCounts.put(ALL_APPS_VISITED_COUNT, 20);
maxCounts.put(TASKBAR_EDU_TOOLTIP_STEP, 2);
MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
@@ -17,6 +17,7 @@ package com.android.launcher3.util;
import static android.os.VibrationEffect.createPredefined;
import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -68,6 +69,9 @@ public class VibratorWrapper {
@Nullable
private final VibrationEffect mBumpEffect;
@Nullable
private final VibrationEffect mAssistEffect;
private long mLastDragTime;
private final int mThresholdUntilNextDragCallMillis;
@@ -125,12 +129,25 @@ public class VibratorWrapper {
mBumpEffect = null;
mThresholdUntilNextDragCallMillis = 0;
}
if (Utilities.ATLEAST_R && mVibrator.areAllPrimitivesSupported(
VibrationEffect.Composition.PRIMITIVE_QUICK_RISE,
VibrationEffect.Composition.PRIMITIVE_TICK)) {
// quiet ramp, short pause, then sharp tick
mAssistEffect = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f, 50)
.compose();
} else {
// fallback for devices without composition support
mAssistEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
}
}
/**
* This is called when the user swipes to/from all apps. This is meant to be used in between
* long animation progresses so that it gives a dragging texture effect. For a better
* experience, this should be used in combination with vibrateForDragCommit().
* This is called when the user swipes to/from all apps. This is meant to be used in between
* long animation progresses so that it gives a dragging texture effect. For a better
* experience, this should be used in combination with vibrateForDragCommit().
*/
public void vibrateForDragTexture() {
if (mDragEffect == null) {
@@ -145,7 +162,7 @@ public class VibratorWrapper {
}
/**
* This is used when user reaches the commit threshold when swiping to/from from all apps.
* This is used when user reaches the commit threshold when swiping to/from from all apps.
*/
public void vibrateForDragCommit() {
if (mCommitEffect != null) {
@@ -156,9 +173,9 @@ public class VibratorWrapper {
}
/**
* The bump haptic is used to be called at the end of a swipe and only if it the gesture is a
* FLING going to/from all apps. Client can just call this method elsewhere just for the
* effect.
* The bump haptic is used to be called at the end of a swipe and only if it the gesture is a
* FLING going to/from all apps. Client can just call this method elsewhere just for the
* effect.
*/
public void vibrateForDragBump() {
if (mBumpEffect != null) {
@@ -166,6 +183,15 @@ public class VibratorWrapper {
}
}
/**
* The assist haptic is used to be called when an assistant is invoked
*/
public void vibrateForAssist() {
if (mAssistEffect != null) {
vibrate(mAssistEffect);
}
}
/**
* This should be used to cancel a haptic in case where the haptic shouldn't be vibrating. For
* example, when no animation is happening but a vibrator happens to be vibrating still. Need
@@ -176,6 +202,7 @@ public class VibratorWrapper {
// reset dragTexture timestamp to be able to play dragTexture again whenever cancelled
mLastDragTime = 0;
}
private boolean isHapticFeedbackEnabled(ContentResolver resolver) {
return Settings.System.getInt(resolver, HAPTIC_FEEDBACK_ENABLED, 0) == 1;
}
@@ -774,7 +774,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
super.onCloseComplete();
removeCallbacks(mShowEducationTipTask);
if (mLatestEducationalTip != null) {
mLatestEducationalTip.close(false);
mLatestEducationalTip.close(true);
}
AccessibilityManagerCompat.sendStateEventToTest(getContext(), NORMAL_STATE_ORDINAL);
}
@@ -16,13 +16,12 @@
package com.android.launcher3.workspace
import android.content.res.TypedArray
import android.content.res.XmlResourceParser
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.util.Xml
import com.android.launcher3.R
import com.android.launcher3.responsive.SizeSpec
import com.android.launcher3.util.ResourceHelper
import java.io.IOException
import kotlin.math.roundToInt
@@ -95,16 +94,16 @@ class WorkspaceSpecs(resourceHelper: ResourceHelper) {
if (type == XmlPullParser.START_TAG) {
when (parser.name) {
XmlTags.START_PADDING -> {
startPadding = SizeSpec(resourceHelper, attr)
startPadding = SizeSpec.create(resourceHelper, attr)
}
XmlTags.END_PADDING -> {
endPadding = SizeSpec(resourceHelper, attr)
endPadding = SizeSpec.create(resourceHelper, attr)
}
XmlTags.GUTTER -> {
gutter = SizeSpec(resourceHelper, attr)
gutter = SizeSpec.create(resourceHelper, attr)
}
XmlTags.CELL_SIZE -> {
cellSize = SizeSpec(resourceHelper, attr)
cellSize = SizeSpec.create(resourceHelper, attr)
}
}
}
@@ -270,61 +269,12 @@ data class WorkspaceSpec(
}
private fun allSpecsAreValid(): Boolean =
startPadding.isValid() && endPadding.isValid() && gutter.isValid() && cellSize.isValid()
}
class SizeSpec(resourceHelper: ResourceHelper, attrs: AttributeSet) {
val fixedSize: Float
val ofAvailableSpace: Float
val ofRemainderSpace: Float
init {
val styledAttrs = resourceHelper.obtainStyledAttributes(attrs, R.styleable.SpecSize)
fixedSize = getValue(styledAttrs, R.styleable.SpecSize_fixedSize)
ofAvailableSpace = getValue(styledAttrs, R.styleable.SpecSize_ofAvailableSpace)
ofRemainderSpace = getValue(styledAttrs, R.styleable.SpecSize_ofRemainderSpace)
styledAttrs.recycle()
}
private fun getValue(a: TypedArray, index: Int): Float {
if (a.getType(index) == TypedValue.TYPE_DIMENSION) {
return a.getDimensionPixelSize(index, 0).toFloat()
} else if (a.getType(index) == TypedValue.TYPE_FLOAT) {
return a.getFloat(index, 0f)
}
return 0f
}
fun isValid(): Boolean {
// All attributes are empty
if (fixedSize < 0f && ofAvailableSpace <= 0f && ofRemainderSpace <= 0f) {
Log.e(TAG, "SizeSpec#isValid - all attributes are empty")
return false
}
// More than one attribute is filled
val attrCount =
(if (fixedSize > 0) 1 else 0) +
(if (ofAvailableSpace > 0) 1 else 0) +
(if (ofRemainderSpace > 0) 1 else 0)
if (attrCount > 1) {
Log.e(TAG, "SizeSpec#isValid - more than one attribute is filled")
return false
}
// Values should be between 0 and 1
if (ofAvailableSpace !in 0f..1f || ofRemainderSpace !in 0f..1f) {
Log.e(TAG, "SizeSpec#isValid - values should be between 0 and 1")
return false
}
return true
}
override fun toString(): String {
return "SizeSpec(fixedSize=$fixedSize, ofAvailableSpace=$ofAvailableSpace, " +
"ofRemainderSpace=$ofRemainderSpace)"
}
startPadding.isValid() &&
endPadding.isValid() &&
gutter.isValid() &&
cellSize.isValid() &&
!startPadding.matchWorkspace &&
!endPadding.matchWorkspace &&
!gutter.matchWorkspace &&
!cellSize.matchWorkspace
}
+2 -2
View File
@@ -26,10 +26,10 @@
<attr name="maxAvailableSize" format="dimension" />
</declare-styleable>
<declare-styleable name="SpecSize">
<declare-styleable name="SizeSpec">
<attr name="fixedSize" format="dimension" />
<attr name="ofAvailableSpace" format="float" />
<attr name="ofRemainderSpace" format="float" />
<attr name="matchWorkspace" format="boolean" />
</declare-styleable>
</resources>
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<workspaceSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
<workspaceSpec
launcher:specType="height"
launcher:maxAvailableSize="648dp">
<startPadding
launcher:ofAvailableSpace="0.0125" />
<endPadding
launcher:ofAvailableSpace="0.05" />
<!-- value in workspace spec using matchWorkspace -->
<gutter
launcher:matchWorkspace="true" />
<cellSize
launcher:ofRemainderSpace="0.2" />
</workspaceSpec>
<workspaceSpec
launcher:specType="height"
launcher:maxAvailableSize="9999dp">
<startPadding
launcher:ofAvailableSpace="0.0306" />
<endPadding
launcher:ofAvailableSpace="0.068" />
<gutter
launcher:fixedSize="16dp" />
<cellSize
launcher:ofRemainderSpace="0.2" />
</workspaceSpec>
<!-- Width spec is always the same -->
<workspaceSpec
launcher:specType="width"
launcher:maxAvailableSize="9999dp">
<startPadding
launcher:ofRemainderSpace="0.21436227" />
<endPadding
launcher:ofRemainderSpace="0.21436227" />
<gutter
launcher:ofRemainderSpace="0.11425509" />
<cellSize
launcher:fixedSize="120dp" />
</workspaceSpec>
</workspaceSpecs>
@@ -0,0 +1,88 @@
/*
* 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.responsive
import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.AbstractDeviceProfileTest
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class SizeSpecTest : AbstractDeviceProfileTest() {
override val runningContext: Context = InstrumentationRegistry.getInstrumentation().context
@Before
fun setup() {
initializeVarsForPhone(deviceSpecs["phone"]!!)
}
@Test
fun valid_values() {
val combinations =
listOf(
SizeSpec(100f, 0f, 0f, false),
SizeSpec(0f, 1f, 0f, false),
SizeSpec(0f, 0f, 1f, false),
SizeSpec(0f, 0f, 0f, false),
SizeSpec(0f, 0f, 0f, true)
)
for (instance in combinations) {
assertThat(instance.isValid()).isEqualTo(true)
}
}
@Test
fun multiple_values_assigned() {
val combinations =
listOf(
SizeSpec(1f, 1f, 0f, false),
SizeSpec(1f, 0f, 1f, false),
SizeSpec(1f, 0f, 0f, true),
SizeSpec(0f, 1f, 1f, false),
SizeSpec(0f, 1f, 0f, true),
SizeSpec(0f, 0f, 1f, true),
SizeSpec(1f, 1f, 1f, true)
)
for (instance in combinations) {
assertThat(instance.isValid()).isEqualTo(false)
}
}
@Test
fun invalid_values() {
val combinations =
listOf(
SizeSpec(0f, 1.1f, 0f, false),
SizeSpec(0f, -0.1f, 0f, false),
SizeSpec(0f, 0f, 1.1f, false),
SizeSpec(0f, 0f, -0.1f, false),
SizeSpec(-1f, 0f, 0f, false)
)
for (instance in combinations) {
assertThat(instance.isValid()).isEqualTo(false)
}
}
}
@@ -27,7 +27,7 @@ class TestResourceHelper(private val context: Context, private val specsFileId:
ResourceHelper(context, specsFileId) {
override fun obtainStyledAttributes(attrs: AttributeSet, styleId: IntArray): TypedArray {
var clone = styleId.clone()
if (styleId == R.styleable.SpecSize) clone = TestR.styleable.SpecSize
if (styleId == R.styleable.SizeSpec) clone = TestR.styleable.SizeSpec
else if (styleId == R.styleable.WorkspaceSpec) clone = TestR.styleable.WorkspaceSpec
return context.obtainStyledAttributes(attrs, clone)
}
@@ -50,16 +50,20 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"specType=HEIGHT, " +
"startPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"endPadding=SizeSpec(fixedSize=84.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"cellSize=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.15808, " +
"ofRemainderSpace=0.0)" +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
")"
)
assertThat(workspaceSpecs.workspaceHeightSpecList[1].toString())
@@ -69,16 +73,20 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"specType=HEIGHT, " +
"startPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"endPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=1.0), " +
"ofRemainderSpace=1.0, " +
"matchWorkspace=false), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"cellSize=SizeSpec(fixedSize=273.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0)" +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
")"
)
assertThat(workspaceSpecs.workspaceHeightSpecList[2].toString())
@@ -88,16 +96,20 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"specType=HEIGHT, " +
"startPadding=SizeSpec(fixedSize=21.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"endPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=1.0), " +
"ofRemainderSpace=1.0, " +
"matchWorkspace=false), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"cellSize=SizeSpec(fixedSize=273.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0)" +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
")"
)
assertThat(workspaceSpecs.workspaceWidthSpecList.size).isEqualTo(1)
@@ -108,16 +120,20 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"specType=WIDTH, " +
"startPadding=SizeSpec(fixedSize=58.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"endPadding=SizeSpec(fixedSize=58.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0), " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"cellSize=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.25)" +
"ofRemainderSpace=0.25, " +
"matchWorkspace=false)" +
")"
)
}
@@ -136,4 +152,9 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
fun parseInvalidFile_valueBiggerThan1_throwsError() {
WorkspaceSpecs(TestResourceHelper(context!!, TestR.xml.invalid_workspace_file_case_3))
}
@Test(expected = IllegalStateException::class)
fun parseInvalidFile_matchWorkspace_true_throwsError() {
WorkspaceSpecs(TestResourceHelper(context!!, TestR.xml.invalid_workspace_file_case_4))
}
}