diff options
127 files changed, 2260 insertions, 1515 deletions
diff --git a/core/java/android/os/OomKillRecord.java b/core/java/android/os/OomKillRecord.java index ca1d49a93def..78fbce63b00d 100644 --- a/core/java/android/os/OomKillRecord.java +++ b/core/java/android/os/OomKillRecord.java @@ -25,7 +25,7 @@ import com.android.internal.util.FrameworkStatsLog; * Note that this class fields' should be equivalent to the struct * <b>OomKill</b> inside * <pre> - * system/memory/libmeminfo/libmemevents/include/memevents.h + * system/memory/libmeminfo/libmemevents/include/memevents/bpf_types.h * </pre> * * @hide @@ -36,14 +36,27 @@ public final class OomKillRecord { private int mUid; private String mProcessName; private short mOomScoreAdj; + private long mTotalVmInKb; + private long mAnonRssInKb; + private long mFileRssInKb; + private long mShmemRssInKb; + private long mPgTablesInKb; public OomKillRecord(long timeStampInMillis, int pid, int uid, - String processName, short oomScoreAdj) { + String processName, short oomScoreAdj, + long totalVmInKb, long anonRssInKb, + long fileRssInKb, long shmemRssInKb, + long pgTablesInKb) { this.mTimeStampInMillis = timeStampInMillis; this.mPid = pid; this.mUid = uid; this.mProcessName = processName; this.mOomScoreAdj = oomScoreAdj; + this.mTotalVmInKb = totalVmInKb; + this.mAnonRssInKb = anonRssInKb; + this.mFileRssInKb = fileRssInKb; + this.mShmemRssInKb = shmemRssInKb; + this.mPgTablesInKb = pgTablesInKb; } /** @@ -55,7 +68,8 @@ public final class OomKillRecord { FrameworkStatsLog.write( FrameworkStatsLog.KERNEL_OOM_KILL_OCCURRED, mUid, mPid, mOomScoreAdj, mTimeStampInMillis, - mProcessName); + mProcessName, mTotalVmInKb, mAnonRssInKb, + mFileRssInKb, mShmemRssInKb, mPgTablesInKb); } public long getTimestampMilli() { diff --git a/core/tests/overlaytests/device_non_system/Android.bp b/core/tests/overlaytests/device_non_system/Android.bp new file mode 100644 index 000000000000..dd7786a4e43f --- /dev/null +++ b/core/tests/overlaytests/device_non_system/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2024 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "OverlayDeviceTestsNonSystem", + team: "trendy_team_android_resources", + srcs: ["src/**/*.java"], + platform_apis: true, + certificate: "platform", + static_libs: [ + "androidx.test.rules", + "testng", + "compatibility-device-util-axt", + ], + test_suites: ["device-tests"], + data: [ + ":OverlayDeviceTestsNonSystem_AppOverlay", + ], +} diff --git a/core/tests/overlaytests/device_non_system/AndroidManifest.xml b/core/tests/overlaytests/device_non_system/AndroidManifest.xml new file mode 100644 index 000000000000..a37d1689e80e --- /dev/null +++ b/core/tests/overlaytests/device_non_system/AndroidManifest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.non_system"> + + <uses-sdk android:minSdkVersion="34" /> + + <application> + <uses-library android:name="android.test.runner"/> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.overlaytest.non_system" + android:label="Runtime resource overlay tests for non system app" /> +</manifest> diff --git a/core/tests/overlaytests/device_non_system/AndroidTest.xml b/core/tests/overlaytests/device_non_system/AndroidTest.xml new file mode 100644 index 000000000000..fc47e6a90880 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/AndroidTest.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<configuration description="Test module config for OverlayDeviceTestsNonSystem"> + <option name="test-tag" value="OverlayDeviceTestsNonSystem" /> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="OverlayDeviceTestsNonSystem_AppOverlay.apk" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.RunOnSecondaryUserTargetPreparer"> + <option name="test-package-name" value="com.android.overlaytest.non_system" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="test-user-token" value="%TEST_USER%"/> + <option name="run-command" + value="cmd overlay enable --user %TEST_USER% com.android.overlaytest.non_system.app_overlay" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="OverlayDeviceTestsNonSystem.apk" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.overlaytest.non_system" /> + </test> +</configuration> diff --git a/core/tests/overlaytests/device_non_system/res/layout/layout.xml b/core/tests/overlaytests/device_non_system/res/layout/layout.xml new file mode 100644 index 000000000000..2cb201377d52 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/layout/layout.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:id="@+id/text_view_id" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/test_string" /> +</LinearLayout>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/res/values/overlayable.xml b/core/tests/overlaytests/device_non_system/res/values/overlayable.xml new file mode 100644 index 000000000000..f8017bc35d5d --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/values/overlayable.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> + +<resources> + <overlayable name="TestResources"> + <policy type="public"> + <item type="string" name="test_string" /> + </policy> + </overlayable> +</resources>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/res/values/strings.xml b/core/tests/overlaytests/device_non_system/res/values/strings.xml new file mode 100644 index 000000000000..ff501a0639ff --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="test_string">Original</string> +</resources>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java b/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java new file mode 100644 index 000000000000..2b0fe6cdc559 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 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.overlaytest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import androidx.test.InstrumentationRegistry; + +import com.android.overlaytest.non_system.R; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * This test class is to verify overlay behavior for non-system apps. + */ +@RunWith(JUnit4.class) +public class OverlayTest { + @Test + public void testStringOverlay() throws Throwable { + final LayoutInflater inflater = LayoutInflater.from(InstrumentationRegistry.getContext()); + final View layout = inflater.inflate(R.layout.layout, null); + TextView tv = layout.findViewById(R.id.text_view_id); + assertNotNull(tv); + assertEquals("Overlaid", tv.getText().toString()); + } +} diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp new file mode 100644 index 000000000000..b5e6d9c692bd --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp @@ -0,0 +1,30 @@ +// Copyright (C) 2024 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "OverlayDeviceTestsNonSystem_AppOverlay", + team: "trendy_team_android_resources", + sdk_version: "current", + certificate: "platform", + aaptflags: ["--no-resource-removal"], +} diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..4df80c085602 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.non_system.app_overlay" + android:versionCode="1" + android:versionName="1.0"> + <application android:hasCode="false" /> + <overlay android:targetPackage="com.android.overlaytest.non_system" + android:targetName="TestResources" + android:isStatic="true" + android:resourcesMap="@xml/overlays"/> +</manifest>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml new file mode 100644 index 000000000000..d0d4bfed94ed --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<overlay> + <item target="string/test_string" value="Overlaid"/> +</overlay>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt index e73d8802f0b2..8487e3792993 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt @@ -18,6 +18,7 @@ package com.android.wm.shell.bubbles import android.content.Context import android.content.Intent import android.content.pm.ShortcutInfo +import android.content.res.Resources import android.graphics.Insets import android.graphics.PointF import android.graphics.Rect @@ -43,6 +44,9 @@ class BubblePositionerTest { private lateinit var positioner: BubblePositioner private val context = ApplicationProvider.getApplicationContext<Context>() + private val resources: Resources + get() = context.resources + private val defaultDeviceConfig = DeviceConfig( windowBounds = Rect(0, 0, 1000, 2000), @@ -205,6 +209,58 @@ class BubblePositionerTest { } @Test + fun testBubbleBarExpandedViewHeightAndWidth() { + val deviceConfig = + defaultDeviceConfig.copy( + // portrait orientation + isLandscape = false, + isLargeScreen = true, + insets = Insets.of(10, 20, 5, 15), + windowBounds = Rect(0, 0, 1800, 2600) + ) + val bubbleBarBounds = Rect(1700, 2500, 1780, 2600) + + positioner.setShowingInBubbleBar(true) + positioner.update(deviceConfig) + positioner.bubbleBarBounds = bubbleBarBounds + + val spaceBetweenTopInsetAndBubbleBarInLandscape = 1680 + val expandedViewVerticalSpacing = + resources.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding) + val expectedHeight = + spaceBetweenTopInsetAndBubbleBarInLandscape - 2 * expandedViewVerticalSpacing + val expectedWidth = resources.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width) + + assertThat(positioner.getExpandedViewWidthForBubbleBar(false)).isEqualTo(expectedWidth) + assertThat(positioner.getExpandedViewHeightForBubbleBar(false)).isEqualTo(expectedHeight) + } + + @Test + fun testBubbleBarExpandedViewHeightAndWidth_screenWidthTooSmall() { + val screenWidth = 300 + val deviceConfig = + defaultDeviceConfig.copy( + // portrait orientation + isLandscape = false, + isLargeScreen = true, + insets = Insets.of(10, 20, 5, 15), + windowBounds = Rect(0, 0, screenWidth, 2600) + ) + val bubbleBarBounds = Rect(100, 2500, 280, 2550) + positioner.setShowingInBubbleBar(true) + positioner.update(deviceConfig) + positioner.bubbleBarBounds = bubbleBarBounds + + val spaceBetweenTopInsetAndBubbleBarInLandscape = 180 + val expandedViewSpacing = + resources.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding) + val expectedHeight = spaceBetweenTopInsetAndBubbleBarInLandscape - 2 * expandedViewSpacing + val expectedWidth = screenWidth - 15 /* horizontal insets */ - 2 * expandedViewSpacing + assertThat(positioner.getExpandedViewWidthForBubbleBar(false)).isEqualTo(expectedWidth) + assertThat(positioner.getExpandedViewHeightForBubbleBar(false)).isEqualTo(expectedHeight) + } + + @Test fun testGetExpandedViewHeight_max() { val deviceConfig = defaultDeviceConfig.copy( diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 6d5bf6233366..4ee2c1a1da60 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -254,6 +254,8 @@ <dimen name="bubble_bar_expanded_view_caption_dot_size">4dp</dimen> <!-- The spacing between the dots for the caption menu in the bubble bar expanded view.. --> <dimen name="bubble_bar_expanded_view_caption_dot_spacing">4dp</dimen> + <!-- Width of the expanded bubble bar view shown when the bubble is expanded. --> + <dimen name="bubble_bar_expanded_view_width">412dp</dimen> <!-- Minimum width of the bubble bar manage menu. --> <dimen name="bubble_bar_manage_menu_min_width">200dp</dimen> <!-- Size of the dismiss icon in the bubble bar manage menu. --> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java index 4d5e516f76e5..14c3a0701c83 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java @@ -149,9 +149,10 @@ public class BubblePositioner { mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); if (mShowingInBubbleBar) { - mExpandedViewLargeScreenWidth = isLandscape() - ? (int) (bounds.width() * EXPANDED_VIEW_BUBBLE_BAR_LANDSCAPE_WIDTH_PERCENT) - : (int) (bounds.width() * EXPANDED_VIEW_BUBBLE_BAR_PORTRAIT_WIDTH_PERCENT); + mExpandedViewLargeScreenWidth = Math.min( + res.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width), + mPositionRect.width() - 2 * mExpandedViewPadding + ); } else if (mDeviceConfig.isSmallTablet()) { mExpandedViewLargeScreenWidth = (int) (bounds.width() * EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT); @@ -839,11 +840,42 @@ public class BubblePositioner { * How tall the expanded view should be when showing from the bubble bar. */ public int getExpandedViewHeightForBubbleBar(boolean isOverflow) { - return isOverflow - ? mOverflowHeight - : getExpandedViewBottomForBubbleBar() - mInsets.top - mExpandedViewPadding; + if (isOverflow) { + return mOverflowHeight; + } else { + return getBubbleBarExpandedViewHeightForLandscape(); + } } + /** + * Calculate the height of expanded view in landscape mode regardless current orientation. + * Here is an explanation: + * ------------------------ mScreenRect.top + * | top inset ↕ | + * |----------------------- + * | 16dp spacing ↕ | + * | --------- | --- expanded view top + * | | | | ↑ + * | | | | ↓ expanded view height + * | --------- | --- expanded view bottom + * | 16dp spacing ↕ | ↑ + * | @bubble bar@ | | height of the bubble bar container + * ------------------------ | already includes bottom inset and spacing + * | bottom inset ↕ | ↓ + * |----------------------| --- mScreenRect.bottom + */ + private int getBubbleBarExpandedViewHeightForLandscape() { + int heightOfBubbleBarContainer = + mScreenRect.height() - getExpandedViewBottomForBubbleBar(); + // getting landscape height from screen rect + int expandedViewHeight = Math.min(mScreenRect.width(), mScreenRect.height()); + expandedViewHeight -= heightOfBubbleBarContainer; /* removing bubble container height */ + expandedViewHeight -= mInsets.top; /* removing top inset */ + expandedViewHeight -= mExpandedViewPadding; /* removing spacing */ + return expandedViewHeight; + } + + /** The bottom position of the expanded view when showing above the bubble bar. */ public int getExpandedViewBottomForBubbleBar() { return mBubbleBarBounds.top - mExpandedViewPadding; diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt index 3380adac0b3f..e9eabb4162e3 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt @@ -17,10 +17,10 @@ package com.android.wm.shell.flicker.appcompat import android.content.Context -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.FlickerTestData import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import com.android.server.wm.flicker.helpers.LetterboxAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.wm.shell.flicker.BaseTest diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt index f08eba5a73a3..16c2d47f9db3 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt @@ -18,11 +18,11 @@ package com.android.wm.shell.flicker.appcompat import android.platform.test.annotations.Postsubmit import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt index 826fc541687e..d85b7718aa56 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt @@ -19,11 +19,11 @@ package com.android.wm.shell.flicker.appcompat import android.platform.test.annotations.Postsubmit import android.tools.Rotation import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt index 26e78bf625ba..164534c14d28 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt @@ -16,17 +16,17 @@ package com.android.wm.shell.flicker.appcompat +import android.graphics.Rect import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.RequiresDevice import android.tools.NavBar import android.tools.Rotation -import android.tools.datatypes.Rect import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -260,7 +260,7 @@ class QuickSwitchLauncherToLetterboxAppTest(flicker: LegacyFlickerTest) : BaseAp companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt index 2aa84b4e55b8..034d54b185ed 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt @@ -53,7 +53,7 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) class RepositionFixedPortraitAppTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) { - val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation).bounds + val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation) /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt index 7ffa23345589..22543aa9f773 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt @@ -16,19 +16,19 @@ package com.android.wm.shell.flicker.appcompat +import android.graphics.Rect import android.os.Build import android.platform.test.annotations.Postsubmit import android.system.helpers.CommandsHelper import android.tools.NavBar import android.tools.Rotation -import android.tools.datatypes.Rect import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory import android.tools.helpers.FIND_TIMEOUT +import android.tools.traces.component.ComponentNameMatcher import android.tools.traces.parsers.toFlickerComponent import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice @@ -167,7 +167,7 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo } companion object { - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() const val LAUNCHER_PACKAGE = "com.google.android.apps.nexuslauncher" /** diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt index 521c0d0aaeb7..2a9b1078afe3 100644 --- a/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt @@ -19,11 +19,11 @@ package com.android.wm.shell.flicker.bubble import android.content.Context import android.graphics.Point import android.platform.test.annotations.Presubmit -import android.tools.flicker.subject.layers.LayersTraceSubject -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.flicker.subject.layers.LayersTraceSubject +import android.tools.traces.component.ComponentNameMatcher import android.util.DisplayMetrics import android.view.WindowManager import androidx.test.uiautomator.By diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt index e059ac78dc6b..9ef49c1c9e7e 100644 --- a/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt @@ -17,10 +17,10 @@ package com.android.wm.shell.flicker.bubble import android.platform.test.annotations.Postsubmit -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import android.view.WindowInsets import android.view.WindowManager import androidx.test.filters.FlakyTest diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt index a0edcfb17971..371fee225b34 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt @@ -17,10 +17,10 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -66,9 +66,7 @@ class AutoEnterPipWithSourceRectHintTest(flicker: LegacyFlickerTest) : @Test fun pipOverlayNotShown() { val overlay = ComponentNameMatcher.PIP_CONTENT_OVERLAY - flicker.assertLayers { - this.notContains(overlay) - } + flicker.assertLayers { this.notContains(overlay) } } @Presubmit @Test @@ -83,4 +81,4 @@ class AutoEnterPipWithSourceRectHintTest(flicker: LegacyFlickerTest) : // auto enter and sourceRectHint that causes the app to move outside of the display // bounds during the transition. } -}
\ No newline at end of file +} diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt index 031acf4919eb..1c0820a2b0db 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt @@ -17,10 +17,10 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import com.android.wm.shell.flicker.pip.common.ClosePipTransition import org.junit.FixMethodOrder import org.junit.Test @@ -69,7 +69,8 @@ class ClosePipBySwipingDownTest(flicker: LegacyFlickerTest) : ClosePipTransition wmHelper.currentState.layerState .getLayerWithBuffer(barComponent) ?.visibleRegion - ?.height + ?.bounds + ?.height() ?: error("Couldn't find Nav or Task bar layer") // The dismiss button doesn't appear at the complete bottom of the screen, // it appears above the hot seat but `hotseatBarSize` is not available outside diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt index 9a1bd267ea1f..270ebf5dd29b 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt @@ -21,12 +21,12 @@ import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.tools.Rotation import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory import android.tools.helpers.WindowUtils +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.FlakyTest import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt index 25614ef63ccc..eeff167b1fc4 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt @@ -18,11 +18,11 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import com.android.wm.shell.flicker.pip.common.PipTransition import org.junit.FixMethodOrder import org.junit.Test diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt index 5f25d70acf7c..f81e8490b0eb 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt @@ -191,8 +191,9 @@ class FromSplitScreenEnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic - fun getParams() = LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) + fun getParams() = + LegacyFlickerTestFactory.nonRotationTests( + supportedRotations = listOf(Rotation.ROTATION_0) + ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt index e184cf04e4ae..ad3c69eae06a 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt @@ -19,12 +19,12 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.tools.Rotation import android.tools.flicker.assertions.FlickerTest -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory import android.tools.helpers.WindowUtils +import android.tools.traces.component.ComponentNameMatcher import com.android.server.wm.flicker.helpers.ImeAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.wm.shell.flicker.pip.common.PipTransition diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt index 68417066ac0a..16d08e5e9055 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt @@ -18,11 +18,11 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.flicker.subject.exceptions.IncorrectRegionException import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.flicker.subject.exceptions.IncorrectRegionException import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.pip.common.PipTransition import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt index c9f4a6ca75b1..65b60ce1022b 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt @@ -18,12 +18,12 @@ package com.android.wm.shell.flicker.pip.apps import android.platform.test.annotations.Postsubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.StandardAppHelper import android.tools.flicker.junit.FlickerBuilderProvider import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import com.android.wm.shell.flicker.pip.common.EnterPipTransition import org.junit.Test import org.junit.runners.Parameterized diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt index 88650107e63a..1fc9d9910a15 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt @@ -65,8 +65,8 @@ import org.junit.runners.Parameterized open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) { override val standardAppHelper: MapsAppHelper = MapsAppHelper(instrumentation) - override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS, - Manifest.permission.ACCESS_FINE_LOCATION) + override val permissions: Array<String> = + arrayOf(Manifest.permission.POST_NOTIFICATIONS, Manifest.permission.ACCESS_FINE_LOCATION) val locationManager: LocationManager = instrumentation.context.getSystemService(Context.LOCATION_SERVICE) as LocationManager diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt index e85da30440cf..3a0eeb67995b 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt @@ -19,13 +19,13 @@ package com.android.wm.shell.flicker.pip.apps import android.Manifest import android.platform.test.annotations.Postsubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.NetflixAppHelper import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory import android.tools.helpers.WindowUtils +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.statusBarLayerPositionAtEnd import org.junit.Assume diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt index 3ae5937df4d0..35ed8de3a464 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt @@ -18,11 +18,11 @@ package com.android.wm.shell.flicker.pip.apps import android.Manifest import android.platform.test.annotations.Postsubmit -import android.tools.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.YouTubeAppHelper import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import org.junit.Assume import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt index de8e7c3b35b1..879034f32514 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt @@ -19,13 +19,13 @@ package com.android.wm.shell.flicker.pip.apps import android.Manifest import android.platform.test.annotations.Postsubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.YouTubeAppHelper import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory import android.tools.helpers.WindowUtils +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.statusBarLayerPositionAtEnd import org.junit.Assume diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt index dc122590388f..8cb81b46cf4d 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt @@ -18,10 +18,10 @@ package com.android.wm.shell.flicker.pip.common import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher.Companion.LAUNCHER import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher.Companion.LAUNCHER import com.android.server.wm.flicker.helpers.setRotation import org.junit.Test import org.junit.runners.Parameterized diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt index 3d9eae62b499..6dd3a175da65 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt @@ -18,10 +18,10 @@ package com.android.wm.shell.flicker.pip.common import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import org.junit.Test import org.junit.runners.Parameterized diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt index 7b6839dc123f..0742cf9c5887 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt @@ -18,9 +18,9 @@ package com.android.wm.shell.flicker.pip.common import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import com.android.server.wm.flicker.helpers.SimpleAppHelper import org.junit.Test import org.junit.runners.Parameterized diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt index f4baf5f75928..c4881e7e17a1 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt @@ -18,9 +18,9 @@ package com.android.wm.shell.flicker.pip.common import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.flicker.subject.region.RegionSubject import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.flicker.subject.region.RegionSubject import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper import com.android.wm.shell.flicker.utils.Direction import org.junit.Test diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt index fd467e32e0dc..99c1ad2aaa4e 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt @@ -20,11 +20,11 @@ import android.app.Instrumentation import android.content.Intent import android.platform.test.annotations.Presubmit import android.tools.Rotation -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome import android.tools.helpers.WindowUtils +import android.tools.traces.component.ComponentNameMatcher import com.android.server.wm.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.testapp.ActivityOptions diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt index 9e6a686861c8..bcd0f126daef 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt @@ -24,6 +24,7 @@ import android.tools.traces.parsers.WindowManagerStateHelper import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.server.wm.flicker.helpers.MultiWindowUtils import com.android.wm.shell.flicker.service.common.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After @@ -51,6 +52,10 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { fun setup() { Assume.assumeTrue(tapl.isTablet) + MultiWindowUtils.executeShellCommand( + instrumentation, + "settings put system notification_cooldown_enabled 0" + ) // Send a notification sendNotificationApp.launchViaIntent(wmHelper) sendNotificationApp.postNotification(wmHelper) @@ -74,5 +79,10 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { primaryApp.exit(wmHelper) secondaryApp.exit(wmHelper) sendNotificationApp.exit(wmHelper) + + MultiWindowUtils.executeShellCommand( + instrumentation, + "settings reset system notification_cooldown_enabled" + ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt index 9312c0aebf98..db962e717a3b 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt @@ -141,7 +141,7 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { private fun isLandscape(rotation: Rotation): Boolean { val displayBounds = WindowUtils.getDisplayBounds(rotation) - return displayBounds.width > displayBounds.height + return displayBounds.width() > displayBounds.height() } private fun isTablet(): Boolean { diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt index d74c59ef0879..7f48499b0558 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt @@ -17,12 +17,12 @@ package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Presubmit -import android.tools.traces.component.ComponentNameMatcher -import android.tools.traces.component.EdgeExtensionComponentMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher +import android.tools.traces.component.EdgeExtensionComponentMatcher import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.splitscreen.benchmark.CopyContentInSplitBenchmark diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt index 8724346427f4..a72b3d15eb9e 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt @@ -18,11 +18,11 @@ package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Presubmit import android.tools.NavBar -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.PipAppHelper import com.android.wm.shell.flicker.splitscreen.benchmark.SplitScreenBase diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt index 16d73318bd3a..90453640c91a 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt @@ -19,13 +19,13 @@ package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.tools.NavBar -import android.tools.flicker.subject.layers.LayersTraceSubject -import android.tools.flicker.subject.region.RegionSubject -import android.tools.traces.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.flicker.subject.layers.LayersTraceSubject +import android.tools.flicker.subject.region.RegionSubject +import android.tools.traces.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.splitscreen.benchmark.UnlockKeyguardToSplitScreenBenchmark diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt index 9c5a3fe35bfe..7e8e50843b90 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt @@ -16,11 +16,11 @@ package com.android.wm.shell.flicker.splitscreen.benchmark -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.legacy.LegacyFlickerTestFactory +import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt index 38206c396efb..6a6aa1abc9f3 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt @@ -128,7 +128,7 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy private fun isLandscape(rotation: Rotation): Boolean { val displayBounds = WindowUtils.getDisplayBounds(rotation) - return displayBounds.width > displayBounds.height + return displayBounds.width() > displayBounds.height() } companion object { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt index a19d232c9a2f..90d2635f6a51 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt @@ -17,8 +17,8 @@ package com.android.wm.shell.flicker import android.app.Instrumentation -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.utils.ICommonAssertions diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt index 3df0954da2e9..509f4f202b6b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt @@ -18,13 +18,13 @@ package com.android.wm.shell.flicker.utils +import android.graphics.Region import android.tools.Rotation -import android.tools.datatypes.Region +import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.flicker.subject.layers.LayerTraceEntrySubject import android.tools.flicker.subject.layers.LayersTraceSubject -import android.tools.traces.component.IComponentMatcher -import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.helpers.WindowUtils +import android.tools.traces.component.IComponentMatcher fun LegacyFlickerTest.appPairsDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } @@ -263,41 +263,41 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( val displayBounds = WindowUtils.getDisplayBounds(rotation) return invoke { val dividerRegion = - layer(SPLIT_SCREEN_DIVIDER_COMPONENT)?.visibleRegion?.region + layer(SPLIT_SCREEN_DIVIDER_COMPONENT)?.visibleRegion?.region?.bounds ?: error("$SPLIT_SCREEN_DIVIDER_COMPONENT component not found") visibleRegion(component).isNotEmpty() visibleRegion(component) .coversAtMost( - if (displayBounds.width > displayBounds.height) { + if (displayBounds.width() > displayBounds.height()) { if (landscapePosLeft) { - Region.from( + Region( 0, 0, - (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, - displayBounds.bounds.bottom + (dividerRegion.left + dividerRegion.right) / 2, + displayBounds.bottom ) } else { - Region.from( - (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, + Region( + (dividerRegion.left + dividerRegion.right) / 2, 0, - displayBounds.bounds.right, - displayBounds.bounds.bottom + displayBounds.right, + displayBounds.bottom ) } } else { if (portraitPosTop) { - Region.from( + Region( 0, 0, - displayBounds.bounds.right, - (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2 + displayBounds.right, + (dividerRegion.top + dividerRegion.bottom) / 2 ) } else { - Region.from( + Region( 0, - (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2, - displayBounds.bounds.right, - displayBounds.bounds.bottom + (dividerRegion.top + dividerRegion.bottom) / 2, + displayBounds.right, + displayBounds.bottom ) } } @@ -420,17 +420,17 @@ fun LegacyFlickerTest.dockedStackSecondaryBoundsIsVisibleAtEnd( fun getPrimaryRegion(dividerRegion: Region, rotation: Rotation): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation.isRotated()) { - Region.from( + Region( 0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset, - displayBounds.bounds.bottom + displayBounds.bottom ) } else { - Region.from( + Region( 0, 0, - displayBounds.bounds.right, + displayBounds.right, dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset ) } @@ -439,18 +439,18 @@ fun getPrimaryRegion(dividerRegion: Region, rotation: Rotation): Region { fun getSecondaryRegion(dividerRegion: Region, rotation: Rotation): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation.isRotated()) { - Region.from( + Region( dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0, - displayBounds.bounds.right, - displayBounds.bounds.bottom + displayBounds.right, + displayBounds.bottom ) } else { - Region.from( + Region( 0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset, - displayBounds.bounds.right, - displayBounds.bounds.bottom + displayBounds.right, + displayBounds.bottom ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt index 50c04354528f..4465a16a8e0f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt @@ -17,8 +17,8 @@ package com.android.wm.shell.flicker.utils import android.platform.test.annotations.Presubmit -import android.tools.traces.component.ComponentNameMatcher import android.tools.flicker.legacy.LegacyFlickerTest +import android.tools.traces.component.ComponentNameMatcher import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt index 9cc3a989894e..c4954f90179c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt @@ -20,11 +20,11 @@ import android.app.Instrumentation import android.graphics.Point import android.os.SystemClock import android.tools.Rotation +import android.tools.device.apphelpers.StandardAppHelper +import android.tools.flicker.rules.ChangeDisplayOrientationRule import android.tools.traces.component.ComponentNameMatcher import android.tools.traces.component.IComponentMatcher import android.tools.traces.component.IComponentNameMatcher -import android.tools.device.apphelpers.StandardAppHelper -import android.tools.flicker.rules.ChangeDisplayOrientationRule import android.tools.traces.parsers.WindowManagerStateHelper import android.tools.traces.parsers.toFlickerComponent import android.view.InputDevice @@ -182,13 +182,7 @@ object SplitScreenUtils { val swipeXCoordinate = displayBounds.centerX() / 2 // Pull down the notifications - device.swipe( - swipeXCoordinate, - 5, - swipeXCoordinate, - displayBounds.bottom, - 50 /* steps */ - ) + device.swipe(swipeXCoordinate, 5, swipeXCoordinate, displayBounds.bottom, 50 /* steps */) SystemClock.sleep(TIMEOUT_MS) // Find the target notification @@ -211,7 +205,7 @@ object SplitScreenUtils { // Drag to split val dragStart = notificationContent.visibleCenter val dragMiddle = Point(dragStart.x + 50, dragStart.y) - val dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4) + val dragEnd = Point(displayBounds.width() / 4, displayBounds.width() / 4) val downTime = SystemClock.uptimeMillis() touch(instrumentation, MotionEvent.ACTION_DOWN, downTime, downTime, TIMEOUT_MS, dragStart) @@ -318,7 +312,7 @@ object SplitScreenUtils { wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace ?: error("Display not found") val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - dividerBar.drag(Point(displayBounds.width * 1 / 3, displayBounds.height * 2 / 3), 200) + dividerBar.drag(Point(displayBounds.width() * 1 / 3, displayBounds.height() * 2 / 3), 200) wmHelper .StateSyncBuilder() diff --git a/nfc/Android.bp b/nfc/Android.bp index c186804d2006..13ac2311bde3 100644 --- a/nfc/Android.bp +++ b/nfc/Android.bp @@ -66,6 +66,7 @@ java_sdk_library { ], impl_library_visibility: [ "//frameworks/base:__subpackages__", + "//cts/hostsidetests/multidevices/nfc:__subpackages__", "//cts/tests/tests/nfc", "//packages/apps/Nfc:__subpackages__", ], diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt index 19d3f599ef31..28cd37ea9327 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt @@ -16,13 +16,15 @@ package com.android.systemui.volume.panel.component.volume.ui.composable +import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.getValue @@ -84,27 +86,29 @@ fun VolumeSlider( valueRange = state.valueRange, onValueChange = onValueChange, enabled = state.isEnabled, - icon = { isDragging -> - if (isDragging) { - Text(text = state.valueText, color = LocalContentColor.current) - } else { - state.icon?.let { - SliderIcon( - icon = it, - onIconTapped = onIconTapped, - isTappable = state.isMutable, - ) - } + icon = { + state.icon?.let { + SliderIcon( + icon = it, + onIconTapped = onIconTapped, + isTappable = state.isMutable, + ) } }, colors = sliderColors, - label = { - VolumeSliderContent( - modifier = Modifier, - label = state.label, - isEnabled = state.isEnabled, - disabledMessage = state.disabledMessage, - ) + label = { isDragging -> + AnimatedVisibility( + visible = !isDragging, + enter = fadeIn(tween(150)), + exit = fadeOut(tween(150)), + ) { + VolumeSliderContent( + modifier = Modifier, + label = state.label, + isEnabled = state.isEnabled, + disabledMessage = state.disabledMessage, + ) + } } ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 8bc6a00a3426..6b2a1d59e62d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -66,6 +66,7 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testDispatcher @@ -820,21 +821,37 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test - fun isAuthenticatedIsResetToFalseWhenKeyguardDoneAnimationsFinished() = + fun isAuthenticatedIsResetToFalseWhenFinishedTransitioningToGoneAndStatusBarStateShade() = testScope.runTest { initCollectors() allPreconditionsToRunFaceAuthAreTrue() triggerFaceAuth(false) + keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) authenticationCallback.value.onAuthenticationSucceeded( mock(FaceManager.AuthenticationResult::class.java) ) assertThat(authenticated()).isTrue() - keyguardRepository.keyguardDoneAnimationsFinished() + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + ) + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + ) + ) + assertThat(authenticated()).isTrue() + keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(authenticated()).isFalse() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt index 33a17e8c56dd..70582daf8e9f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt @@ -16,14 +16,13 @@ package com.android.systemui.keyguard.domain.interactor -import android.platform.test.annotations.DisableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardClockSwitch.LARGE import com.android.keyguard.KeyguardClockSwitch.SMALL -import com.android.systemui.Flags as AConfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic @@ -66,7 +65,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { } @Test - @DisableFlags(AConfigFlags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun clockSize_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockSize) @@ -78,7 +77,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { } @Test - @DisableFlags(AConfigFlags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun clockShouldBeCentered_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockShouldBeCentered) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt index f78fbd16daf9..1dd5d073bef3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt @@ -215,14 +215,16 @@ class KeyguardInteractorTest : SysuiTestCase() { ) repository.setStatusBarState(StatusBarState.KEYGUARD) - shadeRepository.setLegacyShadeExpansion(1f) + // User begins to swipe up + shadeRepository.setLegacyShadeExpansion(0.99f) // When not dismissable, no alpha value (null) should emit repository.setKeyguardDismissible(false) assertThat(dismissAlpha).isNull() repository.setKeyguardDismissible(true) - assertThat(dismissAlpha).isGreaterThan(0.95f) + shadeRepository.setLegacyShadeExpansion(0.98f) + assertThat(dismissAlpha).isGreaterThan(0.5f) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt index 973e496f03f1..e3eca6729188 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt @@ -422,4 +422,23 @@ class KeyguardRootViewModelTest : SysuiTestCase() { shadeRepository.setQsExpansion(0.5f) assertThat(alpha).isEqualTo(0f) } + + @Test + fun alpha_idleOnDream_isZero() = + testScope.runTest { + val alpha by collectLastValue(underTest.alpha(viewState)) + assertThat(alpha).isEqualTo(1f) + + // Go to GONE state + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DREAMING, + testScope = testScope, + ) + assertThat(alpha).isEqualTo(0f) + + // Try pulling down shade and ensure the value doesn't change + shadeRepository.setQsExpansion(0.5f) + assertThat(alpha).isEqualTo(0f) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 75e66fb06ce8..ae2fefd7b957 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -20,13 +20,11 @@ package com.android.systemui.scene.domain.startable import android.app.StatusBarManager import android.os.PowerManager -import android.platform.test.annotations.EnableFlags import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey -import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.authenticationInteractor @@ -40,6 +38,7 @@ import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepositor import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository @@ -94,7 +93,7 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) -@EnableFlags(AconfigFlags.FLAG_SCENE_CONTAINER) +@EnableSceneContainer class SceneContainerStartableTest : SysuiTestCase() { @Mock private lateinit var windowController: NotificationShadeWindowController diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt index e590bae3c53c..2938acf293b3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt @@ -16,11 +16,10 @@ package com.android.systemui.scene.shared.flag -import android.platform.test.annotations.DisableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.Kosmos import com.google.common.truth.Truth @@ -32,7 +31,7 @@ import org.junit.runner.RunWith internal class SceneContainerFlagsTest : SysuiTestCase() { @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun isNotEnabled_withoutAconfigFlags() { Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false) Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt index c8062fb4e724..f0498ded64a5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt @@ -16,57 +16,20 @@ package com.android.systemui.statusbar.phone -import android.app.ActivityOptions import android.app.PendingIntent import android.content.Intent -import android.os.Bundle -import android.os.RemoteException -import android.os.UserHandle -import android.view.View -import android.widget.FrameLayout -import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.ActivityIntentHelper import com.android.systemui.SysuiTestCase -import com.android.systemui.animation.ActivityTransitionAnimator -import com.android.systemui.animation.LaunchableView -import com.android.systemui.assist.AssistManager -import com.android.systemui.keyguard.KeyguardViewMediator -import com.android.systemui.keyguard.WakefulnessLifecycle -import com.android.systemui.plugins.ActivityStarter.OnDismissAction -import com.android.systemui.settings.UserTracker -import com.android.systemui.shade.ShadeController -import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.data.repository.ShadeAnimationRepository -import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl -import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.util.concurrency.FakeExecutor -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor -import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.nullable -import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat -import dagger.Lazy -import java.util.Optional import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock -import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.mock -import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -74,177 +37,22 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) class ActivityStarterImplTest : SysuiTestCase() { - @Mock private lateinit var centralSurfaces: CentralSurfaces - @Mock private lateinit var assistManager: AssistManager - @Mock private lateinit var dozeServiceHost: DozeServiceHost - @Mock private lateinit var biometricUnlockController: BiometricUnlockController - @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator - @Mock private lateinit var shadeController: ShadeController - @Mock private lateinit var commandQueue: CommandQueue - @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager - @Mock private lateinit var mActivityTransitionAnimator: ActivityTransitionAnimator - @Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager - @Mock private lateinit var statusBarWindowController: StatusBarWindowController - @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController - @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle - @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var legacyActivityStarterInternal: LegacyActivityStarterInternalImpl + @Mock private lateinit var activityStarterInternal: ActivityStarterInternalImpl @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController - @Mock private lateinit var userTracker: UserTracker - @Mock private lateinit var activityIntentHelper: ActivityIntentHelper private lateinit var underTest: ActivityStarterImpl private val mainExecutor = FakeExecutor(FakeSystemClock()) - private val shadeAnimationInteractor = - ShadeAnimationInteractorLegacyImpl(ShadeAnimationRepository(), FakeShadeRepository()) @Before fun setUp() { MockitoAnnotations.initMocks(this) underTest = ActivityStarterImpl( - Lazy { Optional.of(centralSurfaces) }, - Lazy { assistManager }, - Lazy { dozeServiceHost }, - Lazy { biometricUnlockController }, - Lazy { keyguardViewMediator }, - Lazy { shadeController }, - commandQueue, - shadeAnimationInteractor, - Lazy { statusBarKeyguardViewManager }, - Lazy { notifShadeWindowController }, - mActivityTransitionAnimator, - context, - DISPLAY_ID, - lockScreenUserManager, - statusBarWindowController, - wakefulnessLifecycle, - keyguardStateController, - statusBarStateController, - keyguardUpdateMonitor, - deviceProvisionedController, - userTracker, - activityIntentHelper, - mainExecutor, + statusBarStateController = statusBarStateController, + mainExecutor = mainExecutor, + legacyActivityStarter = { legacyActivityStarterInternal }, + activityStarterInternal = { activityStarterInternal }, ) - whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER) - } - - @Test - fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() { - val pendingIntent = mock(PendingIntent::class.java) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - - underTest.startPendingIntentDismissingKeyguard(pendingIntent) - mainExecutor.runAllReady() - - verify(statusBarKeyguardViewManager) - .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null)) - } - - @Test - fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLs_launchAnimator() { - val pendingIntent = mock(PendingIntent::class.java) - val parent = FrameLayout(context) - val view = - object : View(context), LaunchableView { - override fun setShouldBlockVisibilityChanges(block: Boolean) {} - } - parent.addView(view) - val controller = ActivityTransitionAnimator.Controller.fromView(view) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) - .thenReturn(true) - - underTest.startPendingIntentMaybeDismissingKeyguard( - intent = pendingIntent, - animationController = controller, - intentSentUiThreadCallback = null, - ) - mainExecutor.runAllReady() - - verify(mActivityTransitionAnimator) - .startPendingIntentWithAnimation( - nullable(), - eq(true), - nullable(), - eq(true), - any(), - ) - } - - fun startPendingIntentDismissingKeyguard_fillInIntentAndExtraOptions_sendAndReturnResult() { - val pendingIntent = mock(PendingIntent::class.java) - val fillInIntent = mock(Intent::class.java) - val parent = FrameLayout(context) - val view = - object : View(context), LaunchableView { - override fun setShouldBlockVisibilityChanges(block: Boolean) {} - } - parent.addView(view) - val controller = ActivityTransitionAnimator.Controller.fromView(view) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) - .thenReturn(false) - - // extra activity options to set on pending intent - val activityOptions = mock(ActivityOptions::class.java) - activityOptions.splashScreenStyle = SPLASH_SCREEN_STYLE_SOLID_COLOR - activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission = false - val bundleCaptor = argumentCaptor<Bundle>() - - underTest.startPendingIntentMaybeDismissingKeyguard( - intent = pendingIntent, - animationController = controller, - intentSentUiThreadCallback = null, - fillInIntent = fillInIntent, - extraOptions = activityOptions.toBundle(), - ) - mainExecutor.runAllReady() - - // Fill-in intent is passed and options contain extra values specified - verify(pendingIntent) - .sendAndReturnResult( - eq(context), - eq(0), - eq(fillInIntent), - nullable(), - nullable(), - nullable(), - bundleCaptor.capture() - ) - val options = ActivityOptions.fromBundle(bundleCaptor.value) - assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission).isFalse() - assertThat(options.splashScreenStyle).isEqualTo(SPLASH_SCREEN_STYLE_SOLID_COLOR) - } - - @Test - fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() { - val pendingIntent = mock(PendingIntent::class.java) - val associatedView = mock(ExpandableNotificationRow::class.java) - - underTest.startPendingIntentDismissingKeyguard( - intent = pendingIntent, - intentSentUiThreadCallback = null, - associatedView = associatedView, - ) - - verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView) - } - - @Test - fun startActivity_noUserHandleProvided_getUserHandle() { - val intent = mock(Intent::class.java) - - underTest.startActivity(intent, false) - - verify(userTracker).userHandle } @Test @@ -258,115 +66,9 @@ class ActivityStarterImplTest : SysuiTestCase() { @Test fun postStartActivityDismissingKeyguard_intent_postsOnMain() { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - val intent = mock(Intent::class.java) - - underTest.postStartActivityDismissingKeyguard(intent, 0) + underTest.postStartActivityDismissingKeyguard(mock(Intent::class.java), 0) assertThat(mainExecutor.numPending()).isEqualTo(1) - mainExecutor.runAllReady() - - verify(deviceProvisionedController).isDeviceProvisioned - verify(shadeController).collapseShadeForActivityStart() - } - - @Test - fun postStartActivityDismissingKeyguard_intent_notDeviceProvisioned_doesNotProceed() { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) - val intent = mock(Intent::class.java) - - underTest.postStartActivityDismissingKeyguard(intent, 0) - mainExecutor.runAllReady() - - verify(deviceProvisionedController).isDeviceProvisioned - verify(shadeController, never()).collapseShadeForActivityStart() - } - - @Test - fun dismissKeyguardThenExecute_startWakeAndUnlock() { - whenever(wakefulnessLifecycle.wakefulness) - .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP) - whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true) - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) - whenever(dozeServiceHost.isPulsing).thenReturn(true) - - underTest.dismissKeyguardThenExecute({ true }, {}, false) - - verify(biometricUnlockController) - .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) - } - - @Test - fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() { - val customMessage = "Enter your pin." - whenever(keyguardStateController.isShowing).thenReturn(true) - - underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage) - - verify(statusBarKeyguardViewManager) - .dismissWithAction( - any(OnDismissAction::class.java), - any(Runnable::class.java), - eq(false), - eq(customMessage) - ) - } - - @Test - fun dismissKeyguardThenExecute_awakeDreams() { - val customMessage = "Enter your pin." - var dismissActionExecuted = false - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) - - underTest.dismissKeyguardThenExecute( - { - dismissActionExecuted = true - true - }, - {}, - false, - customMessage - ) - - verify(centralSurfaces).awakenDreams() - assertThat(dismissActionExecuted).isTrue() - } - - @Test - @Throws(RemoteException::class) - fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() { - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardStateController.isOccluded).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) - - underTest.executeRunnableDismissingKeyguard( - runnable = {}, - cancelAction = null, - dismissShade = false, - afterKeyguardGone = false, - deferred = false - ) - - verify(centralSurfaces, times(1)).awakenDreams() - } - - @Test - @Throws(RemoteException::class) - fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() { - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardStateController.isOccluded).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false) - - underTest.executeRunnableDismissingKeyguard( - runnable = {}, - cancelAction = null, - dismissShade = false, - afterKeyguardGone = false, - deferred = false - ) - - verify(centralSurfaces, never()).awakenDreams() } @Test @@ -377,8 +79,4 @@ class ActivityStarterImplTest : SysuiTestCase() { mainExecutor.runAllReady() verify(statusBarStateController).setLeaveOpenOnKeyguardHide(true) } - - private companion object { - private const val DISPLAY_ID = 0 - } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt new file mode 100644 index 000000000000..b443489f98e2 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2024 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.systemui.statusbar.phone + +import android.app.ActivityOptions +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.RemoteException +import android.os.UserHandle +import android.view.View +import android.widget.FrameLayout +import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.animation.LaunchableView +import com.android.systemui.assist.AssistManager +import com.android.systemui.keyguard.KeyguardViewMediator +import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.plugins.ActivityStarter.OnDismissAction +import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.data.repository.FakeShadeRepository +import com.android.systemui.shade.data.repository.ShadeAnimationRepository +import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.NotificationLockscreenUserManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.statusbar.window.StatusBarWindowController +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.nullable +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import java.util.Optional +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidJUnit4::class) +class LegacyActivityStarterInternalImplTest : SysuiTestCase() { + @Mock private lateinit var centralSurfaces: CentralSurfaces + @Mock private lateinit var assistManager: AssistManager + @Mock private lateinit var dozeServiceHost: DozeServiceHost + @Mock private lateinit var biometricUnlockController: BiometricUnlockController + @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator + @Mock private lateinit var shadeController: ShadeController + @Mock private lateinit var commandQueue: CommandQueue + @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager + @Mock private lateinit var activityTransitionAnimator: ActivityTransitionAnimator + @Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager + @Mock private lateinit var statusBarWindowController: StatusBarWindowController + @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController + @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle + @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController + @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController + @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var activityIntentHelper: ActivityIntentHelper + private lateinit var underTest: LegacyActivityStarterInternalImpl + private val mainExecutor = FakeExecutor(FakeSystemClock()) + private val shadeAnimationInteractor = + ShadeAnimationInteractorLegacyImpl(ShadeAnimationRepository(), FakeShadeRepository()) + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + underTest = + LegacyActivityStarterInternalImpl( + centralSurfacesOptLazy = { Optional.of(centralSurfaces) }, + assistManagerLazy = { assistManager }, + dozeServiceHostLazy = { dozeServiceHost }, + biometricUnlockControllerLazy = { biometricUnlockController }, + keyguardViewMediatorLazy = { keyguardViewMediator }, + shadeControllerLazy = { shadeController }, + commandQueue = commandQueue, + shadeAnimationInteractor = shadeAnimationInteractor, + statusBarKeyguardViewManagerLazy = { statusBarKeyguardViewManager }, + notifShadeWindowControllerLazy = { notifShadeWindowController }, + activityTransitionAnimator = activityTransitionAnimator, + context = context, + displayId = DISPLAY_ID, + lockScreenUserManager = lockScreenUserManager, + statusBarWindowController = statusBarWindowController, + wakefulnessLifecycle = wakefulnessLifecycle, + keyguardStateController = keyguardStateController, + statusBarStateController = statusBarStateController, + keyguardUpdateMonitor = keyguardUpdateMonitor, + deviceProvisionedController = deviceProvisionedController, + userTracker = userTracker, + activityIntentHelper = activityIntentHelper, + mainExecutor = mainExecutor, + ) + whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER) + } + + @Test + fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() { + val pendingIntent = mock(PendingIntent::class.java) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + + underTest.startPendingIntentDismissingKeyguard(pendingIntent) + mainExecutor.runAllReady() + + verify(statusBarKeyguardViewManager) + .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null)) + } + + @Test + fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLs_launchAnimator() { + val pendingIntent = mock(PendingIntent::class.java) + val parent = FrameLayout(context) + val view = + object : View(context), LaunchableView { + override fun setShouldBlockVisibilityChanges(block: Boolean) {} + } + parent.addView(view) + val controller = ActivityTransitionAnimator.Controller.fromView(view) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) + .thenReturn(true) + + startPendingIntentMaybeDismissingKeyguard( + intent = pendingIntent, + animationController = controller, + intentSentUiThreadCallback = null, + ) + mainExecutor.runAllReady() + + verify(activityTransitionAnimator) + .startPendingIntentWithAnimation( + nullable(), + eq(true), + nullable(), + eq(true), + any(), + ) + } + + fun startPendingIntentDismissingKeyguard_fillInIntentAndExtraOptions_sendAndReturnResult() { + val pendingIntent = mock(PendingIntent::class.java) + val fillInIntent = mock(Intent::class.java) + val parent = FrameLayout(context) + val view = + object : View(context), LaunchableView { + override fun setShouldBlockVisibilityChanges(block: Boolean) {} + } + parent.addView(view) + val controller = ActivityTransitionAnimator.Controller.fromView(view) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) + .thenReturn(false) + + // extra activity options to set on pending intent + val activityOptions = mock(ActivityOptions::class.java) + activityOptions.splashScreenStyle = SPLASH_SCREEN_STYLE_SOLID_COLOR + activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission = false + val bundleCaptor = argumentCaptor<Bundle>() + + startPendingIntentMaybeDismissingKeyguard( + intent = pendingIntent, + animationController = controller, + intentSentUiThreadCallback = null, + fillInIntent = fillInIntent, + extraOptions = activityOptions.toBundle(), + ) + mainExecutor.runAllReady() + + // Fill-in intent is passed and options contain extra values specified + verify(pendingIntent) + .sendAndReturnResult( + eq(context), + eq(0), + eq(fillInIntent), + nullable(), + nullable(), + nullable(), + bundleCaptor.capture() + ) + val options = ActivityOptions.fromBundle(bundleCaptor.value) + assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission).isFalse() + assertThat(options.splashScreenStyle).isEqualTo(SPLASH_SCREEN_STYLE_SOLID_COLOR) + } + + @Test + fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() { + val pendingIntent = mock(PendingIntent::class.java) + val associatedView = mock(ExpandableNotificationRow::class.java) + + underTest.startPendingIntentDismissingKeyguard( + intent = pendingIntent, + intentSentUiThreadCallback = null, + associatedView = associatedView, + ) + + verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView) + } + + @Test + fun startActivity_noUserHandleProvided_getUserHandle() { + val intent = mock(Intent::class.java) + + underTest.startActivity(intent, false, null, false, null) + + verify(userTracker).userHandle + } + + @Test + fun dismissKeyguardThenExecute_startWakeAndUnlock() { + whenever(wakefulnessLifecycle.wakefulness) + .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP) + whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true) + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + whenever(dozeServiceHost.isPulsing).thenReturn(true) + + underTest.dismissKeyguardThenExecute({ true }, {}, false) + + verify(biometricUnlockController) + .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) + } + + @Test + fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() { + val customMessage = "Enter your pin." + whenever(keyguardStateController.isShowing).thenReturn(true) + + underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage) + + verify(statusBarKeyguardViewManager) + .dismissWithAction( + any(OnDismissAction::class.java), + any(Runnable::class.java), + eq(false), + eq(customMessage) + ) + } + + @Test + fun dismissKeyguardThenExecute_awakeDreams() { + val customMessage = "Enter your pin." + var dismissActionExecuted = false + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) + + underTest.dismissKeyguardThenExecute( + { + dismissActionExecuted = true + true + }, + {}, + false, + customMessage + ) + + verify(centralSurfaces).awakenDreams() + assertThat(dismissActionExecuted).isTrue() + } + + @Test + @Throws(RemoteException::class) + fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() { + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardStateController.isOccluded).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) + + underTest.executeRunnableDismissingKeyguard( + runnable = {}, + cancelAction = null, + dismissShade = false, + afterKeyguardGone = false, + deferred = false + ) + + verify(centralSurfaces, times(1)).awakenDreams() + } + + @Test + @Throws(RemoteException::class) + fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() { + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardStateController.isOccluded).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false) + + underTest.executeRunnableDismissingKeyguard( + runnable = {}, + cancelAction = null, + dismissShade = false, + afterKeyguardGone = false, + deferred = false + ) + + verify(centralSurfaces, never()).awakenDreams() + } + + private fun startPendingIntentMaybeDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + animationController: ActivityTransitionAnimator.Controller?, + fillInIntent: Intent? = null, + extraOptions: Bundle? = null, + ) { + underTest.startPendingIntentDismissingKeyguard( + intent = intent, + intentSentUiThreadCallback = intentSentUiThreadCallback, + animationController = animationController, + showOverLockscreen = true, + fillInIntent = fillInIntent, + extraOptions = extraOptions, + ) + } + + private companion object { + private const val DISPLAY_ID = 0 + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractorTest.kt deleted file mode 100644 index 79d3fe9063b7..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractorTest.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2024 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.systemui.volume.panel.component.volume.domain.interactor - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.google.common.truth.Truth.assertThat -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class VolumeSliderInteractorTest : SysuiTestCase() { - - private val underTest = VolumeSliderInteractor() - - @Test - fun processVolumeToValue_returnsTranslatedVolume() { - assertThat(underTest.processVolumeToValue(2, volumeRange)).isEqualTo(20f) - } - - private companion object { - val volumeRange = 0..10 - } -} diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt index baae986c494d..1eba0662a43d 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt @@ -40,7 +40,6 @@ import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationSta import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.dump.DumpManager -import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.BiometricType import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository @@ -51,6 +50,7 @@ import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger @@ -313,10 +313,16 @@ constructor( // or device starts going to sleep. merge( powerInteractor.isAsleep, - if (KeyguardWmStateRefactor.isEnabled) { - keyguardTransitionInteractor.isInTransitionToState(KeyguardState.GONE) - } else { - keyguardRepository.keyguardDoneAnimationsFinished.map { true } + combine( + keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE), + keyguardInteractor.statusBarState, + ) { isFinishedInGoneState, statusBarState -> + // When the user is dragging the primary bouncer in (up) by manually scrolling + // up on the lockscreen, the device won't be irreversibly transitioned to GONE + // until the statusBarState updates to SHADE, so we check that here. + // Else, we could reset the face auth state too early and end up in a strange + // state. + isFinishedInGoneState && statusBarState == StatusBarState.SHADE }, userRepository.selectedUser.map { it.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index 424bd0a3e23b..9a9e698e0138 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -209,6 +209,15 @@ public class DozeLog implements Dumpable { } /** + * Logs cancelation requests for time ticks + * @param isPending is an unschedule request pending? + * @param isTimeTickScheduled is a time tick request scheduled + */ + public void tracePendingUnscheduleTimeTick(boolean isPending, boolean isTimeTickScheduled) { + mLogger.logPendingUnscheduleTimeTick(isPending, isTimeTickScheduled); + } + + /** * Appends keyguard visibility change event to the logs * @param showing whether the keyguard is now showing */ diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt index 75b8e513c14a..9d6693efffa3 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt @@ -162,6 +162,15 @@ class DozeLogger @Inject constructor( }) } + fun logPendingUnscheduleTimeTick(isPending: Boolean, isTimeTickScheduled: Boolean) { + buffer.log(TAG, INFO, { + bool1 = isPending + bool2 = isTimeTickScheduled + }, { + "Pending unschedule time tick, isPending=$bool1, isTimeTickScheduled:$bool2" + }) + } + fun logDozeStateChanged(state: DozeMachine.State) { buffer.log(TAG, INFO, { str1 = state.name diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 34a80e867153..95012a2643a5 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -26,11 +26,12 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; -import com.android.systemui.DejankUtils; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AlarmTimeout; +import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.wakelock.WakeLock; import java.util.Calendar; @@ -52,14 +53,17 @@ public class DozeUi implements DozeMachine.Part { private final boolean mCanAnimateTransition; private final DozeParameters mDozeParameters; private final DozeLog mDozeLog; - + private final DelayableExecutor mBgExecutor; private long mLastTimeTickElapsed = 0; // If time tick is scheduled and there's not a pending runnable to cancel: - private boolean mTimeTickScheduled; + private volatile boolean mTimeTickScheduled; private final Runnable mCancelTimeTickerRunnable = new Runnable() { @Override public void run() { - mTimeTicker.cancel(); + mDozeLog.tracePendingUnscheduleTimeTick(false, mTimeTickScheduled); + if (!mTimeTickScheduled) { + mTimeTicker.cancel(); + } } }; @@ -67,11 +71,13 @@ public class DozeUi implements DozeMachine.Part { public DozeUi(Context context, AlarmManager alarmManager, WakeLock wakeLock, DozeHost host, @Main Handler handler, DozeParameters params, + @Background DelayableExecutor bgExecutor, DozeLog dozeLog) { mContext = context; mWakeLock = wakeLock; mHost = host; mHandler = handler; + mBgExecutor = bgExecutor; mCanAnimateTransition = !params.getDisplayNeedsBlanking(); mDozeParameters = params; mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler); @@ -166,7 +172,6 @@ public class DozeUi implements DozeMachine.Part { return; } mTimeTickScheduled = true; - DejankUtils.removeCallbacks(mCancelTimeTickerRunnable); long time = System.currentTimeMillis(); long delta = roundToNextMinute(time) - System.currentTimeMillis(); @@ -182,7 +187,8 @@ public class DozeUi implements DozeMachine.Part { return; } mTimeTickScheduled = false; - DejankUtils.postAfterTraversal(mCancelTimeTickerRunnable); + mDozeLog.tracePendingUnscheduleTimeTick(true, mTimeTickScheduled); + mBgExecutor.execute(mCancelTimeTickerRunnable); } private void verifyLastTimeTick() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index e384bfb7a36e..c4769488646d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -49,6 +49,7 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor +import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import com.android.systemui.util.kotlin.sample import javax.inject.Inject import javax.inject.Provider @@ -209,7 +210,8 @@ constructor( keyguardTransitionInteractor .transitionValue(GONE) .map { it == 1f } - .onStart { emit(false) }, + .onStart { emit(false) } + .distinctUntilChanged(), repository.topClippingBounds ) { _, isGone, topClippingBounds -> if (!isGone) { @@ -279,12 +281,16 @@ constructor( * signal should be sent directly to transitions. */ val dismissAlpha: Flow<Float?> = - combine( - shadeRepository.legacyShadeExpansion, + shadeRepository.legacyShadeExpansion + .filter { it < 1f } + .sampleCombine( statusBarState, keyguardTransitionInteractor.currentKeyguardState, isKeyguardDismissible, - ) { legacyShadeExpansion, statusBarState, currentKeyguardState, isKeyguardDismissible -> + ) + .map { + (legacyShadeExpansion, statusBarState, currentKeyguardState, isKeyguardDismissible) + -> if ( statusBarState == StatusBarState.KEYGUARD && isKeyguardDismissible && diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt index 64e15659d08b..ac67f94fa9cf 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt @@ -185,8 +185,12 @@ constructor( .transitionValue(OCCLUDED) .map { it == 1f } .onStart { emit(false) }, - ) { isIdleOnCommunal, isGone, isOccluded -> - isIdleOnCommunal || isGone || isOccluded + keyguardTransitionInteractor + .transitionValue(KeyguardState.DREAMING) + .map { it == 1f } + .onStart { emit(false) }, + ) { isIdleOnCommunal, isGone, isOccluded, isDreaming -> + isIdleOnCommunal || isGone || isOccluded || isDreaming } .distinctUntilChanged() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt index c4d9ab7a47c2..9619acaed441 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt @@ -27,6 +27,7 @@ import android.database.ContentObserver import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler import android.os.PowerManager +import android.provider.Settings import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED import android.provider.Settings.Global.HEADS_UP_OFF import com.android.systemui.dagger.qualifiers.Main @@ -42,6 +43,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock class PeekDisabledSuppressor( @@ -231,6 +233,7 @@ class AlertKeyguardVisibilitySuppressor( class AvalancheSuppressor( private val avalancheProvider: AvalancheProvider, private val systemClock: SystemClock, + private val systemSettings: SystemSettings, ) : VisualInterruptionFilter( types = setOf(PEEK, PULSE), @@ -253,12 +256,23 @@ class AvalancheSuppressor( } override fun shouldSuppress(entry: NotificationEntry): Boolean { - val timeSinceAvalanche = systemClock.currentTimeMillis() - avalancheProvider.startTime - val isActive = timeSinceAvalanche < avalancheProvider.timeoutMs + if (!isCooldownEnabled()) { + reason = "FALSE avalanche cooldown setting DISABLED" + return false + } + val timeSinceAvalancheMs = systemClock.currentTimeMillis() - avalancheProvider.startTime + val timedOut = timeSinceAvalancheMs >= avalancheProvider.timeoutMs + if (timedOut) { + reason = "FALSE avalanche event TIMED OUT. " + + "${timeSinceAvalancheMs/1000} seconds since last avalanche" + return false + } val state = calculateState(entry) - val suppress = isActive && state == State.SUPPRESS - reason = "avalanche suppress=$suppress isActive=$isActive state=$state" - return suppress + if (state != State.SUPPRESS) { + reason = "FALSE avalanche IN ALLOWLIST: $state" + return false + } + return true } private fun calculateState(entry: NotificationEntry): State { @@ -294,4 +308,11 @@ class AvalancheSuppressor( } return State.SUPPRESS } + + private fun isCooldownEnabled(): Boolean { + return systemSettings.getInt( + Settings.System.NOTIFICATION_COOLDOWN_ENABLED, + /* def */ 1 + ) == 1 + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt index 375b6e5cb6a3..e6d97c211dc5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.EventLog import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -61,7 +62,8 @@ constructor( private val systemClock: SystemClock, private val uiEventLogger: UiEventLogger, private val userTracker: UserTracker, - private val avalancheProvider: AvalancheProvider + private val avalancheProvider: AvalancheProvider, + private val systemSettings: SystemSettings ) : VisualInterruptionDecisionProvider { init { @@ -170,7 +172,7 @@ constructor( addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider)) if (NotificationAvalancheSuppression.isEnabled) { - addFilter(AvalancheSuppressor(avalancheProvider, systemClock)) + addFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) avalancheProvider.register() } started = true diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt index 8ab1eca98cc9..9268d1658b80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt @@ -14,51 +14,20 @@ package com.android.systemui.statusbar.phone -import android.app.ActivityManager -import android.app.ActivityOptions -import android.app.ActivityTaskManager import android.app.PendingIntent -import android.app.TaskStackBuilder -import android.content.Context import android.content.Intent import android.os.Bundle -import android.os.RemoteException import android.os.UserHandle -import android.provider.Settings -import android.util.Log -import android.view.RemoteAnimationAdapter import android.view.View -import android.view.WindowManager -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.ActivityIntentHelper import com.android.systemui.animation.ActivityTransitionAnimator -import com.android.systemui.animation.ActivityTransitionAnimator.PendingIntentStarter -import com.android.systemui.animation.DelegateTransitionAnimatorController -import com.android.systemui.assist.AssistManager -import com.android.systemui.camera.CameraIntents.Companion.isInsecureCameraIntent import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.DisplayId import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.keyguard.KeyguardViewMediator -import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter.OnDismissAction -import com.android.systemui.res.R -import com.android.systemui.settings.UserTracker -import com.android.systemui.shade.ShadeController -import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor -import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.SysuiStatusBarStateController -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.util.concurrency.DelayableExecutor -import com.android.systemui.util.kotlin.getOrNull import dagger.Lazy -import java.util.Optional import javax.inject.Inject /** Handles start activity logic in SystemUI. */ @@ -66,38 +35,18 @@ import javax.inject.Inject class ActivityStarterImpl @Inject constructor( - private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>, - private val assistManagerLazy: Lazy<AssistManager>, - private val dozeServiceHostLazy: Lazy<DozeServiceHost>, - private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, - private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>, - private val shadeControllerLazy: Lazy<ShadeController>, - private val commandQueue: CommandQueue, - private val shadeAnimationInteractor: ShadeAnimationInteractor, - private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>, - private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>, - private val activityTransitionAnimator: ActivityTransitionAnimator, - private val context: Context, - @DisplayId private val displayId: Int, - private val lockScreenUserManager: NotificationLockscreenUserManager, - private val statusBarWindowController: StatusBarWindowController, - private val wakefulnessLifecycle: WakefulnessLifecycle, - private val keyguardStateController: KeyguardStateController, private val statusBarStateController: SysuiStatusBarStateController, - private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val deviceProvisionedController: DeviceProvisionedController, - private val userTracker: UserTracker, - private val activityIntentHelper: ActivityIntentHelper, @Main private val mainExecutor: DelayableExecutor, + legacyActivityStarter: Lazy<LegacyActivityStarterInternalImpl>, + activityStarterInternal: Lazy<ActivityStarterInternalImpl>, ) : ActivityStarter { - companion object { - const val TAG = "ActivityStarterImpl" - } - - private val centralSurfaces: CentralSurfaces? - get() = centralSurfacesOptLazy.get().getOrNull() - private val activityStarterInternal = ActivityStarterInternal() + private val activityStarterInternal: ActivityStarterInternal = + if (SceneContainerFlag.isEnabled) { + activityStarterInternal.get() + } else { + legacyActivityStarter.get() + } override fun startPendingIntentDismissingKeyguard(intent: PendingIntent) { activityStarterInternal.startPendingIntentDismissingKeyguard(intent = intent) @@ -401,575 +350,11 @@ constructor( } } - private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { - mainExecutor.executeDelayed(runnable, delay.toLong()) - } - - /** - * Whether we should animate an activity launch. - * - * Note: This method must be called *before* dismissing the keyguard. - */ - private fun shouldAnimateLaunch( - isActivityIntent: Boolean, - showOverLockscreen: Boolean, - ): Boolean { - // TODO(b/294418322): Support launch animations when occluded. - if (keyguardStateController.isOccluded) { - return false - } - - // Always animate if we are not showing the keyguard or if we animate over the lockscreen - // (without unlocking it). - if (showOverLockscreen || !keyguardStateController.isShowing) { - return true - } - - // We don't animate non-activity launches as they can break the animation. - // TODO(b/184121838): Support non activity launches on the lockscreen. - return isActivityIntent - } - override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { - return shouldAnimateLaunch(isActivityIntent, false) + return activityStarterInternal.shouldAnimateLaunch(isActivityIntent) } - /** - * Encapsulates the activity logic for activity starter. - * - * Logic is duplicated in {@link CentralSurfacesImpl} - */ - private inner class ActivityStarterInternal { - /** Starts an activity after dismissing keyguard. */ - fun startActivityDismissingKeyguard( - intent: Intent, - onlyProvisioned: Boolean = false, - dismissShade: Boolean = false, - disallowEnterPictureInPictureWhileLaunching: Boolean = false, - callback: ActivityStarter.Callback? = null, - flags: Int = 0, - animationController: ActivityTransitionAnimator.Controller? = null, - userHandle: UserHandle? = null, - customMessage: String? = null, - ) { - val userHandle: UserHandle = userHandle ?: getActivityUserHandle(intent) - - if (onlyProvisioned && !deviceProvisionedController.isDeviceProvisioned) return - - val willLaunchResolverActivity: Boolean = - activityIntentHelper.wouldLaunchResolverActivity( - intent, - lockScreenUserManager.currentUserId - ) - - val animate = - animationController != null && - !willLaunchResolverActivity && - shouldAnimateLaunch(isActivityIntent = true) - val animController = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = dismissShade, - isLaunchForActivity = true, - ) - - // If we animate, we will dismiss the shade only once the animation is done. This is - // taken care of by the StatusBarLaunchAnimationController. - val dismissShadeDirectly = dismissShade && animController == null - - val runnable = Runnable { - assistManagerLazy.get().hideAssist() - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK - intent.addFlags(flags) - val result = intArrayOf(ActivityManager.START_CANCELED) - activityTransitionAnimator.startIntentWithAnimation( - animController, - animate, - intent.getPackage() - ) { adapter: RemoteAnimationAdapter? -> - val options = - ActivityOptions(CentralSurfaces.getActivityOptions(displayId, adapter)) - - // We know that the intent of the caller is to dismiss the keyguard and - // this runnable is called right after the keyguard is solved, so we tell - // WM that we should dismiss it to avoid flickers when opening an activity - // that can also be shown over the keyguard. - options.setDismissKeyguardIfInsecure() - options.setDisallowEnterPictureInPictureWhileLaunching( - disallowEnterPictureInPictureWhileLaunching - ) - if (isInsecureCameraIntent(intent)) { - // Normally an activity will set it's requested rotation - // animation on its window. However when launching an activity - // causes the orientation to change this is too late. In these cases - // the default animation is used. This doesn't look good for - // the camera (as it rotates the camera contents out of sync - // with physical reality). So, we ask the WindowManager to - // force the cross fade animation if an orientation change - // happens to occur during the launch. - options.rotationAnimationHint = - WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS - } - if (Settings.Panel.ACTION_VOLUME == intent.action) { - // Settings Panel is implemented as activity(not a dialog), so - // underlying app is paused and may enter picture-in-picture mode - // as a result. - // So we need to disable picture-in-picture mode here - // if it is volume panel. - options.setDisallowEnterPictureInPictureWhileLaunching(true) - } - try { - result[0] = - ActivityTaskManager.getService() - .startActivityAsUser( - null, - context.basePackageName, - context.attributionTag, - intent, - intent.resolveTypeIfNeeded(context.contentResolver), - null, - null, - 0, - Intent.FLAG_ACTIVITY_NEW_TASK, - null, - options.toBundle(), - userHandle.identifier, - ) - } catch (e: RemoteException) { - Log.w(TAG, "Unable to start activity", e) - } - result[0] - } - callback?.onActivityStarted(result[0]) - } - val cancelRunnable = Runnable { - callback?.onActivityStarted(ActivityManager.START_CANCELED) - } - // Do not deferKeyguard when occluded because, when keyguard is occluded, - // we do not launch the activity until keyguard is done. - val occluded = (keyguardStateController.isShowing && keyguardStateController.isOccluded) - val deferred = !occluded - executeRunnableDismissingKeyguard( - runnable, - cancelRunnable, - dismissShadeDirectly, - willLaunchResolverActivity, - deferred, - animate, - customMessage, - ) - } - - /** - * Starts a pending intent after dismissing keyguard. - * - * This can be called in a background thread (to prevent calls in [ActivityIntentHelper] in - * the main thread). - */ - fun startPendingIntentDismissingKeyguard( - intent: PendingIntent, - intentSentUiThreadCallback: Runnable? = null, - associatedView: View? = null, - animationController: ActivityTransitionAnimator.Controller? = null, - showOverLockscreen: Boolean = false, - fillInIntent: Intent? = null, - extraOptions: Bundle? = null, - ) { - val animationController = - if (associatedView is ExpandableNotificationRow) { - centralSurfaces?.getAnimatorControllerFromNotification(associatedView) - } else animationController - - val willLaunchResolverActivity = - (intent.isActivity && - activityIntentHelper.wouldPendingLaunchResolverActivity( - intent, - lockScreenUserManager.currentUserId, - )) - - val actuallyShowOverLockscreen = - showOverLockscreen && - intent.isActivity && - activityIntentHelper.wouldPendingShowOverLockscreen( - intent, - lockScreenUserManager.currentUserId - ) - - val animate = - !willLaunchResolverActivity && - animationController != null && - shouldAnimateLaunch(intent.isActivity, actuallyShowOverLockscreen) - - // We wrap animationCallback with a StatusBarLaunchAnimatorController so - // that the shade is collapsed after the animation (or when it is cancelled, - // aborted, etc). - val statusBarController = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = true, - isLaunchForActivity = intent.isActivity, - ) - val controller = - if (actuallyShowOverLockscreen) { - wrapAnimationControllerForLockscreen(statusBarController) - } else { - statusBarController - } - - // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we - // run the animation on the keyguard). The animation will take care of (instantly) - // collapsing the shade and hiding the keyguard once it is done. - val collapse = !animate - val runnable = Runnable { - try { - activityTransitionAnimator.startPendingIntentWithAnimation( - controller, - animate, - intent.creatorPackage, - actuallyShowOverLockscreen, - object : PendingIntentStarter { - override fun startPendingIntent( - animationAdapter: RemoteAnimationAdapter? - ): Int { - val options = - ActivityOptions( - CentralSurfaces.getActivityOptions( - displayId, - animationAdapter - ) - .apply { extraOptions?.let { putAll(it) } } - ) - // TODO b/221255671: restrict this to only be set for - // notifications - options.isEligibleForLegacyPermissionPrompt = true - options.setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED - ) - return intent.sendAndReturnResult( - context, - 0, - fillInIntent, - null, - null, - null, - options.toBundle() - ) - } - }, - ) - } catch (e: PendingIntent.CanceledException) { - // the stack trace isn't very helpful here. - // Just log the exception message. - Log.w(TAG, "Sending intent failed: $e") - if (!collapse) { - // executeRunnableDismissingKeyguard did not collapse for us already. - shadeControllerLazy.get().collapseOnMainThread() - } - // TODO: Dismiss Keyguard. - } - if (intent.isActivity) { - assistManagerLazy.get().hideAssist() - // This activity could have started while the device is dreaming, in which case - // the dream would occlude the activity. In order to show the newly started - // activity, we wake from the dream. - keyguardUpdateMonitor.awakenFromDream() - } - intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) } - } - - if (!actuallyShowOverLockscreen) { - postOnUiThread(delay = 0) { - executeRunnableDismissingKeyguard( - runnable = runnable, - afterKeyguardGone = willLaunchResolverActivity, - dismissShade = collapse, - willAnimateOnKeyguard = animate, - ) - } - } else { - postOnUiThread(delay = 0, runnable) - } - } - - /** Starts an Activity. */ - fun startActivity( - intent: Intent, - dismissShade: Boolean = false, - animationController: ActivityTransitionAnimator.Controller? = null, - showOverLockscreenWhenLocked: Boolean = false, - userHandle: UserHandle? = null, - ) { - val userHandle = userHandle ?: getActivityUserHandle(intent) - // Make sure that we dismiss the keyguard if it is directly dismissible or when we don't - // want to show the activity above it. - if (keyguardStateController.isUnlocked || !showOverLockscreenWhenLocked) { - startActivityDismissingKeyguard( - intent = intent, - onlyProvisioned = false, - dismissShade = dismissShade, - disallowEnterPictureInPictureWhileLaunching = false, - callback = null, - flags = 0, - animationController = animationController, - userHandle = userHandle, - ) - return - } - - val animate = - animationController != null && - shouldAnimateLaunch( - /* isActivityIntent= */ true, - showOverLockscreenWhenLocked - ) == true - - var controller: ActivityTransitionAnimator.Controller? = null - if (animate) { - // Wrap the animation controller to dismiss the shade and set - // mIsLaunchingActivityOverLockscreen during the animation. - val delegate = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = dismissShade, - isLaunchForActivity = true, - ) - controller = wrapAnimationControllerForLockscreen(delegate) - } else if (dismissShade) { - // The animation will take care of dismissing the shade at the end of the animation. - // If we don't animate, collapse it directly. - shadeControllerLazy.get().cancelExpansionAndCollapseShade() - } - - // We should exit the dream to prevent the activity from starting below the - // dream. - if (keyguardUpdateMonitor.isDreaming) { - centralSurfaces?.awakenDreams() - } - - activityTransitionAnimator.startIntentWithAnimation( - controller, - animate, - intent.getPackage(), - showOverLockscreenWhenLocked - ) { adapter: RemoteAnimationAdapter? -> - TaskStackBuilder.create(context) - .addNextIntent(intent) - .startActivities( - CentralSurfaces.getActivityOptions(displayId, adapter), - userHandle - ) - } - } - - /** Executes an action after dismissing keyguard. */ - fun dismissKeyguardThenExecute( - action: OnDismissAction, - cancel: Runnable? = null, - afterKeyguardGone: Boolean = false, - customMessage: String? = null, - ) { - if ( - !action.willRunAnimationOnKeyguard() && - wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP && - keyguardStateController.canDismissLockScreen() && - !statusBarStateController.leaveOpenOnKeyguardHide() && - dozeServiceHostLazy.get().isPulsing - ) { - // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a - // pulse. - // TODO: Factor this transition out of BiometricUnlockController. - biometricUnlockControllerLazy - .get() - .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) - } - if (keyguardStateController.isShowing) { - statusBarKeyguardViewManagerLazy - .get() - .dismissWithAction(action, cancel, afterKeyguardGone, customMessage) - } else { - // If the keyguard isn't showing but the device is dreaming, we should exit the - // dream. - if (keyguardUpdateMonitor.isDreaming) { - centralSurfaces?.awakenDreams() - } - action.onDismiss() - } - } - - /** Executes an action after dismissing keyguard. */ - fun executeRunnableDismissingKeyguard( - runnable: Runnable? = null, - cancelAction: Runnable? = null, - dismissShade: Boolean = false, - afterKeyguardGone: Boolean = false, - deferred: Boolean = false, - willAnimateOnKeyguard: Boolean = false, - customMessage: String? = null, - ) { - val onDismissAction: OnDismissAction = - object : OnDismissAction { - override fun onDismiss(): Boolean { - if (runnable != null) { - if ( - keyguardStateController.isShowing && - keyguardStateController.isOccluded - ) { - statusBarKeyguardViewManagerLazy - .get() - .addAfterKeyguardGoneRunnable(runnable) - } else { - mainExecutor.execute(runnable) - } - } - if (dismissShade) { - shadeControllerLazy.get().collapseShadeForActivityStart() - } - return deferred - } - - override fun willRunAnimationOnKeyguard(): Boolean { - return willAnimateOnKeyguard - } - } - dismissKeyguardThenExecute( - onDismissAction, - cancelAction, - afterKeyguardGone, - customMessage, - ) - } - - /** - * Return a [ActivityTransitionAnimator.Controller] wrapping `animationController` so that: - * - if it launches in the notification shade window and `dismissShade` is true, then the - * shade will be instantly dismissed at the end of the animation. - * - if it launches in status bar window, it will make the status bar window match the - * device size during the animation (that way, the animation won't be clipped by the - * status bar size). - * - * @param animationController the controller that is wrapped and will drive the main - * animation. - * @param dismissShade whether the notification shade will be dismissed at the end of the - * animation. This is ignored if `animationController` is not animating in the shade - * window. - * @param isLaunchForActivity whether the launch is for an activity. - */ - private fun wrapAnimationControllerForShadeOrStatusBar( - animationController: ActivityTransitionAnimator.Controller?, - dismissShade: Boolean, - isLaunchForActivity: Boolean, - ): ActivityTransitionAnimator.Controller? { - if (animationController == null) { - return null - } - val rootView = animationController.transitionContainer.rootView - val controllerFromStatusBar: Optional<ActivityTransitionAnimator.Controller> = - statusBarWindowController.wrapAnimationControllerIfInStatusBar( - rootView, - animationController - ) - if (controllerFromStatusBar.isPresent) { - return controllerFromStatusBar.get() - } - - centralSurfaces?.let { - // If the view is not in the status bar, then we are animating a view in the shade. - // We have to make sure that we collapse it when the animation ends or is cancelled. - if (dismissShade) { - return StatusBarTransitionAnimatorController( - animationController, - shadeAnimationInteractor, - shadeControllerLazy.get(), - notifShadeWindowControllerLazy.get(), - commandQueue, - displayId, - isLaunchForActivity - ) - } - } - - return animationController - } - - /** - * Wraps an animation controller so that if an activity would be launched on top of the - * lockscreen, the correct flags are set for it to be occluded. - */ - private fun wrapAnimationControllerForLockscreen( - animationController: ActivityTransitionAnimator.Controller? - ): ActivityTransitionAnimator.Controller? { - return animationController?.let { - object : DelegateTransitionAnimatorController(it) { - override fun onIntentStarted(willAnimate: Boolean) { - delegate.onIntentStarted(willAnimate) - if (willAnimate) { - centralSurfaces?.setIsLaunchingActivityOverLockscreen(true) - } - } - - override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { - super.onTransitionAnimationStart(isExpandingFullyAbove) - - // Double check that the keyguard is still showing and not going - // away, but if so set the keyguard occluded. Typically, WM will let - // KeyguardViewMediator know directly, but we're overriding that to - // play the custom launch animation, so we need to take care of that - // here. The unocclude animation is not overridden, so WM will call - // KeyguardViewMediator's unocclude animation runner when the - // activity is exited. - if ( - keyguardStateController.isShowing && - !keyguardStateController.isKeyguardGoingAway - ) { - Log.d(TAG, "Setting occluded = true in #startActivity.") - keyguardViewMediatorLazy - .get() - .setOccluded(true /* isOccluded */, true /* animate */) - } - } - - override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { - // Set mIsLaunchingActivityOverLockscreen to false before actually - // finishing the animation so that we can assume that - // mIsLaunchingActivityOverLockscreen being true means that we will - // collapse the shade (or at least run the post collapse runnables) - // later on. - centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) - delegate.onTransitionAnimationEnd(isExpandingFullyAbove) - } - - override fun onTransitionAnimationCancelled( - newKeyguardOccludedState: Boolean? - ) { - if (newKeyguardOccludedState != null) { - keyguardViewMediatorLazy - .get() - .setOccluded(newKeyguardOccludedState, false /* animate */) - } - - // Set mIsLaunchingActivityOverLockscreen to false before actually - // finishing the animation so that we can assume that - // mIsLaunchingActivityOverLockscreen being true means that we will - // collapse the shade (or at least run the // post collapse - // runnables) later on. - centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) - delegate.onTransitionAnimationCancelled(newKeyguardOccludedState) - } - } - } - } - - /** Retrieves the current user handle to start the Activity. */ - private fun getActivityUserHandle(intent: Intent): UserHandle { - val packages: Array<String> = - context.resources.getStringArray(R.array.system_ui_packages) - for (pkg in packages) { - val componentName = intent.component ?: break - if (pkg == componentName.packageName) { - return UserHandle(UserHandle.myUserId()) - } - } - return userTracker.userHandle - } + private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { + mainExecutor.executeDelayed(runnable, delay.toLong()) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt new file mode 100644 index 000000000000..e8443982d560 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2024 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.systemui.statusbar.phone + +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.UserHandle +import android.view.View +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.plugins.ActivityStarter + +interface ActivityStarterInternal { + /** + * Starts a pending intent after dismissing keyguard. + * + * This can be called in a background thread (to prevent calls in [ActivityIntentHelper] in the + * main thread). + */ + fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable? = null, + associatedView: View? = null, + animationController: ActivityTransitionAnimator.Controller? = null, + showOverLockscreen: Boolean = false, + fillInIntent: Intent? = null, + extraOptions: Bundle? = null, + ) + + /** Starts an activity after dismissing keyguard. */ + fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean = false, + callback: ActivityStarter.Callback? = null, + flags: Int = 0, + animationController: ActivityTransitionAnimator.Controller? = null, + customMessage: String? = null, + disallowEnterPictureInPictureWhileLaunching: Boolean = false, + userHandle: UserHandle? = null, + ) + + /** Starts an Activity. */ + fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle? = null, + ) + + /** Executes an action after dismissing keyguard. */ + fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String? = null, + ) + + /** Executes an action after dismissing keyguard. */ + fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable? = null, + dismissShade: Boolean = false, + afterKeyguardGone: Boolean = false, + deferred: Boolean = false, + willAnimateOnKeyguard: Boolean = false, + customMessage: String? = null, + ) + + /** Whether we should animate an activity launch. */ + fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt new file mode 100644 index 000000000000..c101755bcf38 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 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.systemui.statusbar.phone + +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.UserHandle +import android.view.View +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.ActivityStarter +import javax.inject.Inject + +/** + * Encapsulates the activity logic for activity starter when flexiglass is enabled. + * + * TODO: b/308819693 + */ +@SysUISingleton +class ActivityStarterInternalImpl @Inject constructor() : ActivityStarterInternal { + override fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + associatedView: View?, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreen: Boolean, + fillInIntent: Intent?, + extraOptions: Bundle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean, + callback: ActivityStarter.Callback?, + flags: Int, + animationController: ActivityTransitionAnimator.Controller?, + customMessage: String?, + disallowEnterPictureInPictureWhileLaunching: Boolean, + userHandle: UserHandle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable?, + dismissShade: Boolean, + afterKeyguardGone: Boolean, + deferred: Boolean, + willAnimateOnKeyguard: Boolean, + customMessage: String? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { + TODO("Not yet implemented b/308819693") + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt new file mode 100644 index 000000000000..ebaeb39efe31 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt @@ -0,0 +1,639 @@ +/* + * Copyright (C) 2024 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.systemui.statusbar.phone + +import android.app.ActivityManager +import android.app.ActivityOptions +import android.app.ActivityTaskManager +import android.app.PendingIntent +import android.app.TaskStackBuilder +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.RemoteException +import android.os.UserHandle +import android.provider.Settings +import android.util.Log +import android.view.RemoteAnimationAdapter +import android.view.View +import android.view.WindowManager +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.animation.DelegateTransitionAnimatorController +import com.android.systemui.assist.AssistManager +import com.android.systemui.camera.CameraIntents +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.DisplayId +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.keyguard.KeyguardViewMediator +import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.res.R +import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.NotificationLockscreenUserManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.statusbar.window.StatusBarWindowController +import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.kotlin.getOrNull +import dagger.Lazy +import java.util.Optional +import javax.inject.Inject + +/** Encapsulates the activity logic for activity starter. */ +@SysUISingleton +class LegacyActivityStarterInternalImpl +@Inject +constructor( + private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>, + private val keyguardStateController: KeyguardStateController, + private val statusBarStateController: SysuiStatusBarStateController, + private val assistManagerLazy: Lazy<AssistManager>, + private val dozeServiceHostLazy: Lazy<DozeServiceHost>, + private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, + private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>, + private val shadeControllerLazy: Lazy<ShadeController>, + private val commandQueue: CommandQueue, + private val shadeAnimationInteractor: ShadeAnimationInteractor, + private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>, + private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>, + private val activityTransitionAnimator: ActivityTransitionAnimator, + private val context: Context, + @DisplayId private val displayId: Int, + private val lockScreenUserManager: NotificationLockscreenUserManager, + private val statusBarWindowController: StatusBarWindowController, + private val wakefulnessLifecycle: WakefulnessLifecycle, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val deviceProvisionedController: DeviceProvisionedController, + private val userTracker: UserTracker, + private val activityIntentHelper: ActivityIntentHelper, + @Main private val mainExecutor: DelayableExecutor, +) : ActivityStarterInternal { + private val centralSurfaces: CentralSurfaces? + get() = centralSurfacesOptLazy.get().getOrNull() + + override fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean, + callback: ActivityStarter.Callback?, + flags: Int, + animationController: ActivityTransitionAnimator.Controller?, + customMessage: String?, + disallowEnterPictureInPictureWhileLaunching: Boolean, + userHandle: UserHandle?, + ) { + val userHandle: UserHandle = userHandle ?: getActivityUserHandle(intent) + + if (onlyProvisioned && !deviceProvisionedController.isDeviceProvisioned) return + + val willLaunchResolverActivity: Boolean = + activityIntentHelper.wouldLaunchResolverActivity( + intent, + lockScreenUserManager.currentUserId + ) + + val animate = + animationController != null && + !willLaunchResolverActivity && + shouldAnimateLaunch(isActivityIntent = true) + val animController = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = dismissShade, + isLaunchForActivity = true, + ) + + // If we animate, we will dismiss the shade only once the animation is done. This is + // taken care of by the StatusBarLaunchAnimationController. + val dismissShadeDirectly = dismissShade && animController == null + + val runnable = Runnable { + assistManagerLazy.get().hideAssist() + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + intent.addFlags(flags) + val result = intArrayOf(ActivityManager.START_CANCELED) + activityTransitionAnimator.startIntentWithAnimation( + animController, + animate, + intent.getPackage() + ) { adapter: RemoteAnimationAdapter? -> + val options = + ActivityOptions(CentralSurfaces.getActivityOptions(displayId, adapter)) + + // We know that the intent of the caller is to dismiss the keyguard and + // this runnable is called right after the keyguard is solved, so we tell + // WM that we should dismiss it to avoid flickers when opening an activity + // that can also be shown over the keyguard. + options.setDismissKeyguardIfInsecure() + options.setDisallowEnterPictureInPictureWhileLaunching( + disallowEnterPictureInPictureWhileLaunching + ) + if (CameraIntents.isInsecureCameraIntent(intent)) { + // Normally an activity will set it's requested rotation + // animation on its window. However when launching an activity + // causes the orientation to change this is too late. In these cases + // the default animation is used. This doesn't look good for + // the camera (as it rotates the camera contents out of sync + // with physical reality). So, we ask the WindowManager to + // force the cross fade animation if an orientation change + // happens to occur during the launch. + options.rotationAnimationHint = + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS + } + if (Settings.Panel.ACTION_VOLUME == intent.action) { + // Settings Panel is implemented as activity(not a dialog), so + // underlying app is paused and may enter picture-in-picture mode + // as a result. + // So we need to disable picture-in-picture mode here + // if it is volume panel. + options.setDisallowEnterPictureInPictureWhileLaunching(true) + } + try { + result[0] = + ActivityTaskManager.getService() + .startActivityAsUser( + null, + context.basePackageName, + context.attributionTag, + intent, + intent.resolveTypeIfNeeded(context.contentResolver), + null, + null, + 0, + Intent.FLAG_ACTIVITY_NEW_TASK, + null, + options.toBundle(), + userHandle.identifier, + ) + } catch (e: RemoteException) { + Log.w(TAG, "Unable to start activity", e) + } + result[0] + } + callback?.onActivityStarted(result[0]) + } + val cancelRunnable = Runnable { + callback?.onActivityStarted(ActivityManager.START_CANCELED) + } + // Do not deferKeyguard when occluded because, when keyguard is occluded, + // we do not launch the activity until keyguard is done. + val occluded = (keyguardStateController.isShowing && keyguardStateController.isOccluded) + val deferred = !occluded + executeRunnableDismissingKeyguard( + runnable, + cancelRunnable, + dismissShadeDirectly, + willLaunchResolverActivity, + deferred, + animate, + customMessage, + ) + } + + override fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + associatedView: View?, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreen: Boolean, + fillInIntent: Intent?, + extraOptions: Bundle?, + ) { + val animationController = + if (associatedView is ExpandableNotificationRow) { + centralSurfaces?.getAnimatorControllerFromNotification(associatedView) + } else animationController + + val willLaunchResolverActivity = + (intent.isActivity && + activityIntentHelper.wouldPendingLaunchResolverActivity( + intent, + lockScreenUserManager.currentUserId, + )) + + val actuallyShowOverLockscreen = + showOverLockscreen && + intent.isActivity && + activityIntentHelper.wouldPendingShowOverLockscreen( + intent, + lockScreenUserManager.currentUserId + ) + + val animate = + !willLaunchResolverActivity && + animationController != null && + shouldAnimateLaunch(intent.isActivity, actuallyShowOverLockscreen) + + // We wrap animationCallback with a StatusBarLaunchAnimatorController so + // that the shade is collapsed after the animation (or when it is cancelled, + // aborted, etc). + val statusBarController = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = true, + isLaunchForActivity = intent.isActivity, + ) + val controller = + if (actuallyShowOverLockscreen) { + wrapAnimationControllerForLockscreen(statusBarController) + } else { + statusBarController + } + + // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we + // run the animation on the keyguard). The animation will take care of (instantly) + // collapsing the shade and hiding the keyguard once it is done. + val collapse = !animate + val runnable = Runnable { + try { + activityTransitionAnimator.startPendingIntentWithAnimation( + controller, + animate, + intent.creatorPackage, + actuallyShowOverLockscreen, + object : ActivityTransitionAnimator.PendingIntentStarter { + override fun startPendingIntent( + animationAdapter: RemoteAnimationAdapter? + ): Int { + val options = + ActivityOptions( + CentralSurfaces.getActivityOptions(displayId, animationAdapter) + .apply { extraOptions?.let { putAll(it) } } + ) + // TODO b/221255671: restrict this to only be set for + // notifications + options.isEligibleForLegacyPermissionPrompt = true + options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED + ) + return intent.sendAndReturnResult( + context, + 0, + fillInIntent, + null, + null, + null, + options.toBundle() + ) + } + }, + ) + } catch (e: PendingIntent.CanceledException) { + // the stack trace isn't very helpful here. + // Just log the exception message. + Log.w(TAG, "Sending intent failed: $e") + if (!collapse) { + // executeRunnableDismissingKeyguard did not collapse for us already. + shadeControllerLazy.get().collapseOnMainThread() + } + // TODO: Dismiss Keyguard. + } + if (intent.isActivity) { + assistManagerLazy.get().hideAssist() + // This activity could have started while the device is dreaming, in which case + // the dream would occlude the activity. In order to show the newly started + // activity, we wake from the dream. + keyguardUpdateMonitor.awakenFromDream() + } + intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) } + } + + if (!actuallyShowOverLockscreen) { + postOnUiThread(delay = 0) { + executeRunnableDismissingKeyguard( + runnable = runnable, + afterKeyguardGone = willLaunchResolverActivity, + dismissShade = collapse, + willAnimateOnKeyguard = animate, + ) + } + } else { + postOnUiThread(delay = 0, runnable) + } + } + + override fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle?, + ) { + val userHandle = userHandle ?: getActivityUserHandle(intent) + // Make sure that we dismiss the keyguard if it is directly dismissible or when we don't + // want to show the activity above it. + if (keyguardStateController.isUnlocked || !showOverLockscreenWhenLocked) { + startActivityDismissingKeyguard( + intent = intent, + onlyProvisioned = false, + dismissShade = dismissShade, + disallowEnterPictureInPictureWhileLaunching = false, + callback = null, + flags = 0, + animationController = animationController, + userHandle = userHandle, + ) + return + } + + val animate = + animationController != null && + shouldAnimateLaunch(/* isActivityIntent= */ true, showOverLockscreenWhenLocked) + + var controller: ActivityTransitionAnimator.Controller? = null + if (animate) { + // Wrap the animation controller to dismiss the shade and set + // mIsLaunchingActivityOverLockscreen during the animation. + val delegate = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = dismissShade, + isLaunchForActivity = true, + ) + controller = wrapAnimationControllerForLockscreen(delegate) + } else if (dismissShade) { + // The animation will take care of dismissing the shade at the end of the animation. + // If we don't animate, collapse it directly. + shadeControllerLazy.get().cancelExpansionAndCollapseShade() + } + + // We should exit the dream to prevent the activity from starting below the + // dream. + if (keyguardUpdateMonitor.isDreaming) { + centralSurfaces?.awakenDreams() + } + + activityTransitionAnimator.startIntentWithAnimation( + controller, + animate, + intent.getPackage(), + showOverLockscreenWhenLocked + ) { adapter: RemoteAnimationAdapter? -> + TaskStackBuilder.create(context) + .addNextIntent(intent) + .startActivities(CentralSurfaces.getActivityOptions(displayId, adapter), userHandle) + } + } + + override fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String?, + ) { + if ( + !action.willRunAnimationOnKeyguard() && + wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP && + keyguardStateController.canDismissLockScreen() && + !statusBarStateController.leaveOpenOnKeyguardHide() && + dozeServiceHostLazy.get().isPulsing + ) { + // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a + // pulse. + // TODO: Factor this transition out of BiometricUnlockController. + biometricUnlockControllerLazy + .get() + .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) + } + if (keyguardStateController.isShowing) { + statusBarKeyguardViewManagerLazy + .get() + .dismissWithAction(action, cancel, afterKeyguardGone, customMessage) + } else { + // If the keyguard isn't showing but the device is dreaming, we should exit the + // dream. + if (keyguardUpdateMonitor.isDreaming) { + centralSurfaces?.awakenDreams() + } + action.onDismiss() + } + } + + override fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable?, + dismissShade: Boolean, + afterKeyguardGone: Boolean, + deferred: Boolean, + willAnimateOnKeyguard: Boolean, + customMessage: String?, + ) { + val onDismissAction: ActivityStarter.OnDismissAction = + object : ActivityStarter.OnDismissAction { + override fun onDismiss(): Boolean { + if (runnable != null) { + if ( + keyguardStateController.isShowing && keyguardStateController.isOccluded + ) { + statusBarKeyguardViewManagerLazy + .get() + .addAfterKeyguardGoneRunnable(runnable) + } else { + mainExecutor.execute(runnable) + } + } + if (dismissShade) { + shadeControllerLazy.get().collapseShadeForActivityStart() + } + return deferred + } + + override fun willRunAnimationOnKeyguard(): Boolean { + return willAnimateOnKeyguard + } + } + dismissKeyguardThenExecute( + onDismissAction, + cancelAction, + afterKeyguardGone, + customMessage, + ) + } + + /** + * Return a [ActivityTransitionAnimator.Controller] wrapping `animationController` so that: + * - if it launches in the notification shade window and `dismissShade` is true, then the shade + * will be instantly dismissed at the end of the animation. + * - if it launches in status bar window, it will make the status bar window match the device + * size during the animation (that way, the animation won't be clipped by the status bar + * size). + * + * @param animationController the controller that is wrapped and will drive the main animation. + * @param dismissShade whether the notification shade will be dismissed at the end of the + * animation. This is ignored if `animationController` is not animating in the shade window. + * @param isLaunchForActivity whether the launch is for an activity. + */ + private fun wrapAnimationControllerForShadeOrStatusBar( + animationController: ActivityTransitionAnimator.Controller?, + dismissShade: Boolean, + isLaunchForActivity: Boolean, + ): ActivityTransitionAnimator.Controller? { + if (animationController == null) { + return null + } + val rootView = animationController.transitionContainer.rootView + val controllerFromStatusBar: Optional<ActivityTransitionAnimator.Controller> = + statusBarWindowController.wrapAnimationControllerIfInStatusBar( + rootView, + animationController + ) + if (controllerFromStatusBar.isPresent) { + return controllerFromStatusBar.get() + } + + centralSurfaces?.let { + // If the view is not in the status bar, then we are animating a view in the shade. + // We have to make sure that we collapse it when the animation ends or is cancelled. + if (dismissShade) { + return StatusBarTransitionAnimatorController( + animationController, + shadeAnimationInteractor, + shadeControllerLazy.get(), + notifShadeWindowControllerLazy.get(), + commandQueue, + displayId, + isLaunchForActivity + ) + } + } + + return animationController + } + + /** + * Wraps an animation controller so that if an activity would be launched on top of the + * lockscreen, the correct flags are set for it to be occluded. + */ + private fun wrapAnimationControllerForLockscreen( + animationController: ActivityTransitionAnimator.Controller? + ): ActivityTransitionAnimator.Controller? { + return animationController?.let { + object : DelegateTransitionAnimatorController(it) { + override fun onIntentStarted(willAnimate: Boolean) { + delegate.onIntentStarted(willAnimate) + if (willAnimate) { + centralSurfaces?.setIsLaunchingActivityOverLockscreen(true) + } + } + + override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { + super.onTransitionAnimationStart(isExpandingFullyAbove) + + // Double check that the keyguard is still showing and not going + // away, but if so set the keyguard occluded. Typically, WM will let + // KeyguardViewMediator know directly, but we're overriding that to + // play the custom launch animation, so we need to take care of that + // here. The unocclude animation is not overridden, so WM will call + // KeyguardViewMediator's unocclude animation runner when the + // activity is exited. + if ( + keyguardStateController.isShowing && + !keyguardStateController.isKeyguardGoingAway + ) { + Log.d(TAG, "Setting occluded = true in #startActivity.") + keyguardViewMediatorLazy + .get() + .setOccluded(true /* isOccluded */, true /* animate */) + } + } + + override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { + // Set mIsLaunchingActivityOverLockscreen to false before actually + // finishing the animation so that we can assume that + // mIsLaunchingActivityOverLockscreen being true means that we will + // collapse the shade (or at least run the post collapse runnables) + // later on. + centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) + delegate.onTransitionAnimationEnd(isExpandingFullyAbove) + } + + override fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean?) { + if (newKeyguardOccludedState != null) { + keyguardViewMediatorLazy + .get() + .setOccluded(newKeyguardOccludedState, false /* animate */) + } + + // Set mIsLaunchingActivityOverLockscreen to false before actually + // finishing the animation so that we can assume that + // mIsLaunchingActivityOverLockscreen being true means that we will + // collapse the shade (or at least run the // post collapse + // runnables) later on. + centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) + delegate.onTransitionAnimationCancelled(newKeyguardOccludedState) + } + } + } + } + + /** Retrieves the current user handle to start the Activity. */ + private fun getActivityUserHandle(intent: Intent): UserHandle { + val packages: Array<String> = context.resources.getStringArray(R.array.system_ui_packages) + for (pkg in packages) { + val componentName = intent.component ?: break + if (pkg == componentName.packageName) { + return UserHandle(UserHandle.myUserId()) + } + } + return userTracker.userHandle + } + + /** + * Whether we should animate an activity launch. + * + * Note: This method must be called *before* dismissing the keyguard. + */ + private fun shouldAnimateLaunch( + isActivityIntent: Boolean, + showOverLockscreen: Boolean, + ): Boolean { + // TODO(b/294418322): Support launch animations when occluded. + if (keyguardStateController.isOccluded) { + return false + } + + // Always animate if we are not showing the keyguard or if we animate over the lockscreen + // (without unlocking it). + if (showOverLockscreen || !keyguardStateController.isShowing) { + return true + } + + // We don't animate non-activity launches as they can break the animation. + // TODO(b/184121838): Support non activity launches on the lockscreen. + return isActivityIntent + } + + override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { + return shouldAnimateLaunch(isActivityIntent, false) + } + + private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { + mainExecutor.executeDelayed(runnable, delay.toLong()) + } + + companion object { + private const val TAG = "LegacyActivityStarterInternalImpl" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractor.kt deleted file mode 100644 index ecd89eab1d4b..000000000000 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/VolumeSliderInteractor.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2024 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.systemui.volume.panel.component.volume.domain.interactor - -import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope -import javax.inject.Inject - -/** Converts from slider value to volume and back. */ -@VolumePanelScope -class VolumeSliderInteractor @Inject constructor() { - - /** mimic percentage volume setting */ - private val displayValueRange: ClosedFloatingPointRange<Float> = 0f..100f - - /** - * Translates [volume], that belongs to [volumeRange] to the value that belongs to - * [displayValueRange]. - */ - fun processVolumeToValue( - volume: Int, - volumeRange: ClosedRange<Int>, - ): Float { - val currentRangeStart: Float = volumeRange.start.toFloat() - val targetRangeStart: Float = displayValueRange.start - val currentRangeLength: Float = (volumeRange.endInclusive.toFloat() - currentRangeStart) - val targetRangeLength: Float = displayValueRange.endInclusive - targetRangeStart - if (currentRangeLength == 0f || targetRangeLength == 0f) { - return 0f - } - val volumeFraction: Float = (volume.toFloat() - currentRangeStart) / currentRangeLength - return targetRangeStart + volumeFraction * targetRangeLength - } -} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt index 57b5d570fbbd..1ae1ebb99f8b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt @@ -24,7 +24,6 @@ import com.android.settingslib.volume.shared.model.AudioStreamModel import com.android.settingslib.volume.shared.model.RingerMode import com.android.systemui.common.shared.model.Icon import com.android.systemui.res.R -import com.android.systemui.volume.panel.component.volume.domain.interactor.VolumeSliderInteractor import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -44,7 +43,6 @@ constructor( @Assisted private val coroutineScope: CoroutineScope, private val context: Context, private val audioVolumeInteractor: AudioVolumeInteractor, - private val volumeSliderInteractor: VolumeSliderInteractor, ) : SliderViewModel { private val audioStream = audioStreamWrapper.audioStream @@ -105,10 +103,6 @@ constructor( return State( value = volume.toFloat(), valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(), - valueText = - SliderViewModel.formatValue( - volumeSliderInteractor.processVolumeToValue(volume, volumeRange) - ), icon = getIcon(ringerMode), label = labelsByStream[audioStream]?.let(context::getString) ?: error("No label for the stream: $audioStream"), @@ -157,7 +151,6 @@ constructor( override val valueRange: ClosedFloatingPointRange<Float>, override val icon: Icon, override val label: String, - override val valueText: String, override val disabledMessage: String?, override val isEnabled: Boolean, override val a11yStep: Int, diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt index 8d8fa17bf986..3689303ab28d 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt @@ -22,7 +22,6 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.res.R import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession -import com.android.systemui.volume.panel.component.volume.domain.interactor.VolumeSliderInteractor import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -41,7 +40,6 @@ constructor( @Assisted private val coroutineScope: CoroutineScope, private val context: Context, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, - private val volumeSliderInteractor: VolumeSliderInteractor, ) : SliderViewModel { override val slider: StateFlow<SliderState> = @@ -66,13 +64,6 @@ constructor( value = currentVolume.toFloat(), valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(), icon = Icon.Resource(R.drawable.ic_cast, null), - valueText = - SliderViewModel.formatValue( - volumeSliderInteractor.processVolumeToValue( - volume = currentVolume, - volumeRange = volumeRange, - ) - ), label = context.getString(R.string.media_device_cast), isEnabled = true, a11yStep = 1 @@ -83,13 +74,13 @@ constructor( override val value: Float, override val valueRange: ClosedFloatingPointRange<Float>, override val icon: Icon, - override val valueText: String, override val label: String, override val isEnabled: Boolean, override val a11yStep: Int, ) : SliderState { override val disabledMessage: String? get() = null + override val isMutable: Boolean get() = false } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt index 8eb0b8947c37..d71a9d8dae94 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt @@ -28,7 +28,6 @@ sealed interface SliderState { val valueRange: ClosedFloatingPointRange<Float> val icon: Icon? val isEnabled: Boolean - val valueText: String val label: String /** * A11y slider controls works by adjusting one step up or down. The default slider step isn't @@ -42,7 +41,6 @@ sealed interface SliderState { override val value: Float = 0f override val valueRange: ClosedFloatingPointRange<Float> = 0f..1f override val icon: Icon? = null - override val valueText: String = "" override val label: String = "" override val disabledMessage: String? = null override val a11yStep: Int = 0 diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt index e78f833086f8..74aee559194b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt @@ -26,9 +26,4 @@ interface SliderViewModel { fun onValueChanged(state: SliderState, newValue: Float) fun toggleMuted(state: SliderState) - - companion object { - - fun formatValue(value: Float): String = "%.0f".format(value) - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java index 7311f4a5ef71..e7caf000ef67 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java @@ -41,6 +41,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.systemui.DejankUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.wakelock.WakeLockFake; import org.junit.After; @@ -69,6 +71,7 @@ public class DozeUiTest extends SysuiTestCase { private Handler mHandler; private HandlerThread mHandlerThread; private DozeUi mDozeUi; + private FakeExecutor mFakeExecutor; @Before public void setUp() throws Exception { @@ -80,9 +83,9 @@ public class DozeUiTest extends SysuiTestCase { mHandlerThread.start(); mWakeLock = new WakeLockFake(); mHandler = mHandlerThread.getThreadHandler(); - + mFakeExecutor = new FakeExecutor(new FakeSystemClock()); mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler, - mDozeParameters, mDozeLog); + mDozeParameters, mFakeExecutor, mDozeLog); mDozeUi.setDozeMachine(mMachine); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt index 85a20e22818f..01754c4b5598 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt @@ -23,6 +23,7 @@ import com.android.keyguard.KeyguardClockSwitch import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardRepository @@ -49,6 +50,7 @@ import org.mockito.Mockito.mock @SmallTest @RunWith(JUnit4::class) +@DisableSceneContainer class KeyguardClockViewModelTest : SysuiTestCase() { private lateinit var kosmos: Kosmos private lateinit var underTest: KeyguardClockViewModel @@ -71,7 +73,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockCentered_largeClock() = testScope.runTest { with(kosmos) { @@ -84,7 +85,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockNotCentered_largeClock_splitShadeLargeClock() = testScope.runTest { with(kosmos) { @@ -98,7 +98,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockNotCentered_smallClock_splitShadeSmallClock() = testScope.runTest { with(kosmos) { @@ -112,7 +111,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_singleShade_smallClock_smallClock() = testScope.runTest { with(kosmos) { @@ -124,7 +122,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_singleShade_largeClock_largeClock() = testScope.runTest { with(kosmos) { @@ -136,7 +133,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun hasCustomPositionUpdatedAnimation_withConfigTrue_isTrue() = testScope.runTest { with(kosmos) { @@ -151,7 +147,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun hasCustomPositionUpdatedAnimation_withConfigFalse_isFalse() = testScope.runTest { with(kosmos) { @@ -167,7 +162,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun testClockSize_alwaysSmallClockSize() = testScope.runTest { kosmos.fakeKeyguardClockRepository.setSelectedClockSize(SettingsClockSize.SMALL) @@ -178,7 +172,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun testClockSize_dynamicClockSize() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL) @@ -191,7 +184,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun isLargeClockVisible_whenLargeClockSize_isTrue() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE) @@ -200,7 +192,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun isLargeClockVisible_whenSmallClockSize_isFalse() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt index f2abb909e004..7c33648e08a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt @@ -1,15 +1,14 @@ package com.android.systemui.shade.transition -import android.platform.test.annotations.DisableFlags import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope import com.android.systemui.scene.domain.interactor.SceneInteractor @@ -70,7 +69,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun onPanelExpansionChanged_setsFractionEqualToEventFraction() { underTest.onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT) @@ -78,7 +77,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun onPanelStateChanged_forwardsToScrimTransitionController() { startLegacyPanelExpansion() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt index de6108632153..d2fc087e44bd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt @@ -19,12 +19,10 @@ package com.android.systemui.statusbar import android.animation.ObjectAnimator -import android.platform.test.annotations.DisableFlags import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.shared.model.AuthenticationMethodModel @@ -35,6 +33,7 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.jank.interactionJankMonitor @@ -187,7 +186,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testChangeState_logged() { TestableLooper.get(this).runWithLooper { underTest.state = StatusBarState.KEYGUARD @@ -214,7 +213,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_appliesState_sameStateButDifferentUpcomingState() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.KEYGUARD) @@ -227,7 +226,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_appliesState_differentStateEqualToUpcomingState() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.KEYGUARD) @@ -239,7 +238,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_doesNotApplyState_currentAndUpcomingStatesSame() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.SHADE) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt index 54108642385f..edab9d9f7fdf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt @@ -50,7 +50,8 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro systemClock, uiEventLogger, userTracker, - avalancheProvider + avalancheProvider, + systemSettings ) } @@ -82,7 +83,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -97,7 +98,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_suppressConversationFromBeforeEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldNotHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_DEFAULT @@ -112,7 +113,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowHighPriorityConversation() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -125,7 +126,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCall() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -138,7 +139,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCategoryReminder() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -151,7 +152,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCategoryEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -164,7 +165,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowFsi() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { assertFsiNotSuppressed() } } @@ -173,7 +174,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowColorized() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt index 24f670831193..3b979a7c1386 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt @@ -77,6 +77,8 @@ import com.android.systemui.util.FakeEventLog import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.settings.FakeGlobalSettings +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.utils.leaks.FakeBatteryController import com.android.systemui.utils.leaks.FakeKeyguardStateController @@ -126,6 +128,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { protected val uiEventLogger = UiEventLoggerFake() protected val userTracker = FakeUserTracker() protected val avalancheProvider: AvalancheProvider = mock() + lateinit var systemSettings: SystemSettings protected abstract val provider: VisualInterruptionDecisionProvider @@ -153,6 +156,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { deviceProvisionedController.currentUser = userId userTracker.set(listOf(user), /* currentUserIndex = */ 0) + systemSettings = FakeSettings() provider.start() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt index 620ad9c19bfa..60aaa646fced 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.EventLog import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock object VisualInterruptionDecisionProviderTestUtil { @@ -51,7 +52,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemClock: SystemClock, uiEventLogger: UiEventLogger, userTracker: UserTracker, - avalancheProvider: AvalancheProvider + avalancheProvider: AvalancheProvider, + systemSettings: SystemSettings ): VisualInterruptionDecisionProvider { return if (VisualInterruptionRefactor.isEnabled) { VisualInterruptionDecisionProviderImpl( @@ -70,7 +72,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemClock, uiEventLogger, userTracker, - avalancheProvider + avalancheProvider, + systemSettings ) } else { NotificationInterruptStateProviderWrapper( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index abb9432425bc..1e058cac8001 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -20,7 +20,6 @@ import static android.view.View.GONE; import static android.view.WindowInsets.Type.ime; import static com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION; -import static com.android.systemui.Flags.FLAG_SCENE_CONTAINER; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL; @@ -72,6 +71,7 @@ import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.ExpandHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.DisableSceneContainer; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; @@ -227,7 +227,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testUpdateStackHeight_qsExpansionZero() { final float expansionFraction = 0.2f; final float overExpansion = 50f; @@ -726,7 +726,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header + @DisableSceneContainer // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_noOffset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(0, 0, 1000, 1000); @@ -743,7 +743,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header + @DisableSceneContainer // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_Offset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(100, 100, 1000, 1000); @@ -763,14 +763,14 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void setFractionToShade_recomputesStackHeight() { mStackScroller.setFractionToShade(1f); verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat()); } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSetOwnScrollY_shadeNotClosing_scrollYChanges() { // Given: shade is not closing, scrollY is 0 mAmbientState.setScrollY(0); @@ -869,7 +869,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSplitShade_hasTopOverscroll() { mTestableResources .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true); @@ -942,7 +942,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSetMaxDisplayedNotifications_notifiesListeners() { ExpandableView.OnHeightChangedListener listener = mock(ExpandableView.OnHeightChangedListener.class); @@ -957,7 +957,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer public void testDispatchTouchEvent_sceneContainerDisabled() { MotionEvent event = MotionEvent.obtain( SystemClock.uptimeMillis(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 2f153d8b7003..25e4728725e9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -181,7 +181,9 @@ import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.MessageRouterImpl; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.settings.FakeGlobalSettings; +import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.GlobalSettings; +import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.SystemClock; import com.android.systemui.volume.VolumeComponent; @@ -325,6 +327,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { private ShadeController mShadeController; private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings(); + private final SystemSettings mSystemSettings = new FakeSettings(); private final FakeEventLog mFakeEventLog = new FakeEventLog(); private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock); private final FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock); @@ -375,7 +378,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFakeSystemClock, mock(UiEventLogger.class), mUserTracker, - mAvalancheProvider); + mAvalancheProvider, + mSystemSettings); mVisualInterruptionDecisionProvider.start(); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index aabd4e9e79be..c24c86c8cb2a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -174,6 +174,7 @@ import com.android.systemui.user.domain.interactor.SelectedUserInteractor; import com.android.systemui.user.domain.interactor.UserSwitcherInteractor; import com.android.systemui.util.FakeEventLog; import com.android.systemui.util.settings.FakeGlobalSettings; +import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; @@ -554,7 +555,8 @@ public class BubblesTest extends SysuiTestCase { mock(SystemClock.class), mock(UiEventLogger.class), mock(UserTracker.class), - mock(AvalancheProvider.class) + mock(AvalancheProvider.class), + mock(SystemSettings.class) ); interruptionDecisionProvider.start(); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.kt new file mode 100644 index 000000000000..09f34308bdb9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 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.systemui.flags + +import android.platform.test.annotations.DisableFlags +import com.android.systemui.Flags.FLAG_SCENE_CONTAINER + +/** + * This includes @[DisableFlags] to work with [SetFlagsRule] to disable all aconfig flags required + * by that feature. + */ +@DisableFlags( + FLAG_SCENE_CONTAINER, +) +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +annotation class DisableSceneContainer diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 73584154df3a..8a699ef39280 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -1617,9 +1617,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ final int displayId = displays[i].getDisplayId(); onDisplayRemoved(displayId); } - if (com.android.server.accessibility.Flags.cleanupA11yOverlays()) { detachAllOverlays(); - } } /** diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 603a95c31e5b..1015ad9fe1da 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -880,6 +880,14 @@ public class AccountManagerService packagesToVisibility = Collections.emptyMap(); accountRemovedReceivers = Collections.emptyList(); } + if (notify) { + Integer oldVisibility = + accounts.accountsDb.findAccountVisibility(account, packageName); + if (oldVisibility != null && oldVisibility == newVisibility) { + // Database will not be updated - skip LOGIN_ACCOUNTS_CHANGED broadcast. + notify = false; + } + } if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) { return false; diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java index 16514fa813dc..e6de14bcf9aa 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java @@ -29,7 +29,6 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; -import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -122,7 +121,8 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub { + " without permission " + Manifest.permission.DUMP); return; } - IndentingPrintWriter radioPrintWriter = new IndentingPrintWriter(printWriter); + android.util.IndentingPrintWriter radioPrintWriter = + new android.util.IndentingPrintWriter(printWriter); radioPrintWriter.printf("BroadcastRadioService\n"); radioPrintWriter.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java index ab083429a200..93fb7b2525fb 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java @@ -26,7 +26,6 @@ import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; import android.os.Binder; import android.os.RemoteException; -import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; @@ -139,7 +138,7 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub { + " without permission " + Manifest.permission.DUMP); return; } - IndentingPrintWriter radioPw = new IndentingPrintWriter(pw); + android.util.IndentingPrintWriter radioPw = new android.util.IndentingPrintWriter(pw); radioPw.printf("BroadcastRadioService\n"); radioPw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioLogger.java b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java index cca351bc0d73..2c8f499c619b 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioLogger.java +++ b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java @@ -14,31 +14,35 @@ * limitations under the License. */ -package com.android.server.broadcastradio.aidl; +package com.android.server.broadcastradio; import android.text.TextUtils; -import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.Log; import com.android.server.utils.Slogf; /** - * Event logger to log and dump events of radio module and tuner session - * for AIDL broadcast radio HAL + * Event logger to log and dump events of broadcast radio service client for HIDL and AIDL + * broadcast HAL. */ -final class RadioLogger { +public final class RadioEventLogger { private final String mTag; private final boolean mDebug; private final LocalLog mEventLogger; - RadioLogger(String tag, int loggerQueueSize) { + public RadioEventLogger(String tag, int loggerQueueSize) { mTag = tag; mDebug = Log.isLoggable(mTag, Log.DEBUG); mEventLogger = new LocalLog(loggerQueueSize); } - void logRadioEvent(String logFormat, Object... args) { + /** + * Log broadcast radio service event + * @param logFormat String format of log message + * @param args Arguments of log message + */ + public void logRadioEvent(String logFormat, Object... args) { String log = TextUtils.formatSimple(logFormat, args); mEventLogger.log(log); if (mDebug) { @@ -46,7 +50,11 @@ final class RadioLogger { } } - void dump(IndentingPrintWriter pw) { + /** + * Dump broadcast radio service event + * @param pw Indenting print writer for dump + */ + public void dump(android.util.IndentingPrintWriter pw) { mEventLogger.dump(pw); } } diff --git a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java index b618aa3d65dc..9654a93d2036 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java @@ -22,7 +22,6 @@ import android.hardware.radio.IAnnouncementListener; import android.hardware.radio.ICloseHandle; import android.os.IBinder; import android.os.RemoteException; -import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -94,7 +93,7 @@ public final class AnnouncementAggregator extends ICloseHandle.Stub { if (mCloseHandle != null) mCloseHandle.close(); } - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("ModuleWatcher:\n"); pw.increaseIndent(); @@ -192,7 +191,8 @@ public final class AnnouncementAggregator extends ICloseHandle.Stub { @Override protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { - IndentingPrintWriter announcementPrintWriter = new IndentingPrintWriter(printWriter); + android.util.IndentingPrintWriter announcementPrintWriter = + new android.util.IndentingPrintWriter(printWriter); announcementPrintWriter.printf("AnnouncementAggregator\n"); announcementPrintWriter.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java index 086f3aa8ad65..1c421614599d 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java @@ -29,7 +29,6 @@ import android.os.IServiceCallback; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; -import android.util.IndentingPrintWriter; import android.util.Log; import android.util.SparseArray; @@ -261,7 +260,7 @@ public final class BroadcastRadioServiceImpl { * * @param pw The file to which {@link BroadcastRadioServiceImpl} state is dumped. */ - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { synchronized (mLock) { pw.printf("Next module id available: %d\n", mNextModuleId); pw.printf("ServiceName to module id map:\n"); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java index cd865105c48e..0cac35641ed0 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java @@ -38,10 +38,10 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -59,7 +59,7 @@ final class RadioModule { private final Object mLock = new Object(); private final Handler mHandler; - private final RadioLogger mLogger; + private final RadioEventLogger mLogger; private final RadioManager.ModuleProperties mProperties; /** @@ -197,7 +197,7 @@ final class RadioModule { mProperties = Objects.requireNonNull(properties, "properties cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); mHandler = new Handler(Looper.getMainLooper()); - mLogger = new RadioLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); + mLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable @@ -524,7 +524,7 @@ final class RadioModule { return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("RadioModule\n"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java index 4ed36ec9878c..925f149b12cf 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java @@ -29,9 +29,9 @@ import android.os.Binder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -45,7 +45,7 @@ final class TunerSession extends ITuner.Stub { private final Object mLock = new Object(); - private final RadioLogger mLogger; + private final RadioEventLogger mLogger; private final RadioModule mModule; final int mUserId; final android.hardware.radio.ITunerCallback mCallback; @@ -70,7 +70,7 @@ final class TunerSession extends ITuner.Stub { mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback, "callback cannot be null"); mUid = Binder.getCallingUid(); - mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); + mLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @Override @@ -434,7 +434,7 @@ final class TunerSession extends ITuner.Stub { } } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("TunerSession\n"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java index 3198842c1ff3..e1650c227266 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -30,7 +30,6 @@ import android.hidl.manager.V1_0.IServiceNotification; import android.os.IHwBinder.DeathRecipient; import android.os.RemoteException; import android.util.ArrayMap; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -222,7 +221,7 @@ public final class BroadcastRadioService { * * @param pw The file to which BroadcastRadioService state is dumped. */ - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { synchronized (mLock) { pw.printf("Next module id available: %d\n", mNextModuleId); pw.printf("ServiceName to module id map:\n"); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java deleted file mode 100644 index b8d12280ac05..000000000000 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2022 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.server.broadcastradio.hal2; - -import android.util.IndentingPrintWriter; -import android.util.LocalLog; -import android.util.Log; - -import com.android.server.utils.Slogf; - -final class RadioEventLogger { - private final String mTag; - private final LocalLog mEventLogger; - - RadioEventLogger(String tag, int loggerQueueSize) { - mTag = tag; - mEventLogger = new LocalLog(loggerQueueSize); - } - - @SuppressWarnings("AnnotateFormatMethod") - void logRadioEvent(String logFormat, Object... args) { - String log = String.format(logFormat, args); - mEventLogger.log(log); - if (Log.isLoggable(mTag, Log.DEBUG)) { - Slogf.d(mTag, log); - } - } - - void dump(IndentingPrintWriter pw) { - mEventLogger.dump(pw); - } -} diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index 0e11df8282a7..7269f24fc4b1 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -40,11 +40,11 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import android.util.MutableInt; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -453,7 +453,7 @@ final class RadioModule { return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("RadioModule\n"); pw.increaseIndent(); pw.printf("BroadcastRadioService: %s\n", mService); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java index 6d435e38117f..b1b5d3488a5b 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java @@ -31,11 +31,11 @@ import android.os.Binder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import android.util.MutableBoolean; import android.util.MutableInt; import com.android.internal.annotations.GuardedBy; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -389,7 +389,7 @@ final class TunerSession extends ITuner.Stub { } } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("TunerSession\n"); pw.increaseIndent(); pw.printf("HIDL HAL Session: %s\n", mHwSession); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index 3d01c5f8ed48..3e23f972bd45 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -16,10 +16,12 @@ package com.android.server.inputmethod; +import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityOptions; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; @@ -452,9 +454,12 @@ final class InputMethodBindingController { intent.setComponent(component); intent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.input_method_binding_label); + var options = ActivityOptions.makeBasic() + .setPendingIntentCreatorBackgroundActivityStartMode( + MODE_BACKGROUND_ACTIVITY_START_DENIED); intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), - PendingIntent.FLAG_IMMUTABLE)); + PendingIntent.FLAG_IMMUTABLE, options.toBundle())); return intent; } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 4b8e4852aee7..6c93fe787816 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -32,6 +32,7 @@ import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_RRO; import static android.os.Trace.traceBegin; import static android.os.Trace.traceEnd; + import static com.android.server.om.OverlayManagerServiceImpl.OperationFailedException; import android.annotation.NonNull; @@ -279,7 +280,8 @@ public final class OverlayManagerService extends SystemService { HandlerThread packageMonitorThread = new HandlerThread(TAG); packageMonitorThread.start(); - mPackageMonitor.register(context, packageMonitorThread.getLooper(), true); + mPackageMonitor.register( + context, packageMonitorThread.getLooper(), UserHandle.ALL, true); final IntentFilter userFilter = new IntentFilter(); userFilter.addAction(ACTION_USER_ADDED); @@ -369,17 +371,17 @@ public final class OverlayManagerService extends SystemService { @Override public void onPackageAppearedWithExtras(String packageName, Bundle extras) { - handlePackageAdd(packageName, extras); + handlePackageAdd(packageName, extras, getChangingUserId()); } @Override public void onPackageChangedWithExtras(String packageName, Bundle extras) { - handlePackageChange(packageName, extras); + handlePackageChange(packageName, extras, getChangingUserId()); } @Override public void onPackageDisappearedWithExtras(String packageName, Bundle extras) { - handlePackageRemove(packageName, extras); + handlePackageRemove(packageName, extras, getChangingUserId()); } } @@ -393,54 +395,45 @@ public final class OverlayManagerService extends SystemService { return userIds; } - private void handlePackageAdd(String packageName, Bundle extras) { + private void handlePackageAdd(String packageName, Bundle extras, int userId) { final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); if (replacing) { - onPackageReplaced(packageName, userIds); + onPackageReplaced(packageName, userId); } else { - onPackageAdded(packageName, userIds); + onPackageAdded(packageName, userId); } } - private void handlePackageChange(String packageName, Bundle extras) { - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); + private void handlePackageChange(String packageName, Bundle extras, int userId) { if (!ACTION_OVERLAY_CHANGED.equals(extras.getString(EXTRA_REASON))) { - onPackageChanged(packageName, userIds); + onPackageChanged(packageName, userId); } } - private void handlePackageRemove(String packageName, Bundle extras) { + private void handlePackageRemove(String packageName, Bundle extras, int userId) { final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); final boolean systemUpdateUninstall = extras.getBoolean(Intent.EXTRA_SYSTEM_UPDATE_UNINSTALL, false); - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); if (replacing) { - onPackageReplacing(packageName, systemUpdateUninstall, userIds); + onPackageReplacing(packageName, systemUpdateUninstall, userId); } else { - onPackageRemoved(packageName, userIds); + onPackageRemoved(packageName, userId); } } - private void onPackageAdded(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageAdded(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageAdded " + packageName); - for (final int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageAdded(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageAdded(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageAdded internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageAdded(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageAdded(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageAdded internal error", e); } } } @@ -449,21 +442,18 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageChanged(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageChanged(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageChanged " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageChanged(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageChanged internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageChanged(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageChanged internal error", e); } } } @@ -473,20 +463,18 @@ public final class OverlayManagerService extends SystemService { } private void onPackageReplacing(@NonNull final String packageName, - boolean systemUpdateUninstall, @NonNull final int[] userIds) { + boolean systemUpdateUninstall, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplacing " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked(mImpl.onPackageReplacing(packageName, - systemUpdateUninstall, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageReplacing internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked(mImpl.onPackageReplacing(packageName, + systemUpdateUninstall, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageReplacing internal error", e); } } } @@ -495,21 +483,18 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageReplaced(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageReplaced(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplaced " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageReplaced(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageReplaced internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageReplaced(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageReplaced internal error", e); } } } @@ -518,15 +503,12 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageRemoved(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageRemoved(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageRemoved " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - mPackageManager.onPackageRemoved(packageName, userId); - updateTargetPackagesLocked(mImpl.onPackageRemoved(packageName, userId)); - } + synchronized (mLock) { + mPackageManager.onPackageRemoved(packageName, userId); + updateTargetPackagesLocked(mImpl.onPackageRemoved(packageName, userId)); } } finally { traceEnd(TRACE_TAG_RRO); diff --git a/services/core/jni/com_android_server_am_OomConnection.cpp b/services/core/jni/com_android_server_am_OomConnection.cpp index 054937fc683e..4d07776d8023 100644 --- a/services/core/jni/com_android_server_am_OomConnection.cpp +++ b/services/core/jni/com_android_server_am_OomConnection.cpp @@ -92,9 +92,11 @@ static jobjectArray android_server_am_OomConnection_waitOom(JNIEnv* env, jobject memevent_listener.deregisterAllEvents(); jniThrowRuntimeException(env, "Failed creating java string for process name"); } - jobject java_oom_kill = env->NewObject(sOomKillRecordInfo.clazz, sOomKillRecordInfo.ctor, - oom_kill.timestamp_ms, oom_kill.pid, oom_kill.uid, - process_name, oom_kill.oom_score_adj); + jobject java_oom_kill = + env->NewObject(sOomKillRecordInfo.clazz, sOomKillRecordInfo.ctor, + oom_kill.timestamp_ms, oom_kill.pid, oom_kill.uid, process_name, + oom_kill.oom_score_adj, oom_kill.total_vm_kb, oom_kill.anon_rss_kb, + oom_kill.file_rss_kb, oom_kill.shmem_rss_kb, oom_kill.pgtables_kb); if (java_oom_kill == NULL) { memevent_listener.deregisterAllEvents(); jniThrowRuntimeException(env, "Failed to create OomKillRecord object"); @@ -115,8 +117,8 @@ int register_android_server_am_OomConnection(JNIEnv* env) { sOomKillRecordInfo.clazz = FindClassOrDie(env, "android/os/OomKillRecord"); sOomKillRecordInfo.clazz = MakeGlobalRefOrDie(env, sOomKillRecordInfo.clazz); - sOomKillRecordInfo.ctor = - GetMethodIDOrDie(env, sOomKillRecordInfo.clazz, "<init>", "(JIILjava/lang/String;S)V"); + sOomKillRecordInfo.ctor = GetMethodIDOrDie(env, sOomKillRecordInfo.clazz, "<init>", + "(JIILjava/lang/String;SJJJJJ)V"); return RegisterMethodsOrDie(env, "com/android/server/am/OomConnection", sOomConnectionMethods, NELEM(sOomConnectionMethods)); diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index ab36ba250986..0c92abce7254 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -3194,6 +3194,78 @@ public class AccountManagerServiceTest extends AndroidTestCase { } @SmallTest + public void testAccountsChangedBroadcastMarkedAccountAsVisibleThreeTimes() throws Exception { + unlockSystemUser(); + + HashMap<String, Integer> visibility = new HashMap<>(); + visibility.put("testpackage1", AccountManager.VISIBILITY_VISIBLE); + + addAccountRemovedReceiver("testpackage1"); + mAms.registerAccountListener( + new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, + "testpackage1"); + mAms.addAccountExplicitlyWithVisibility( + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + /* password= */ "p11", + /* extras= */ null, + visibility, + /* callerPackage= */ null); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + } + + @SmallTest + public void testAccountsChangedBroadcastChangedVisibilityTwoTimes() throws Exception { + unlockSystemUser(); + + HashMap<String, Integer> visibility = new HashMap<>(); + visibility.put("testpackage1", AccountManager.VISIBILITY_VISIBLE); + + addAccountRemovedReceiver("testpackage1"); + mAms.registerAccountListener( + new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, + "testpackage1"); + mAms.addAccountExplicitlyWithVisibility( + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + /* password= */ "p11", + /* extras= */ null, + visibility, + /* callerPackage= */ null); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_NOT_VISIBLE); + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + + updateBroadcastCounters(7); + assertEquals(mVisibleAccountsChangedBroadcasts, 3); + assertEquals(mLoginAccountsChangedBroadcasts, 3); + assertEquals(mAccountRemovedBroadcasts, 1); + } + + @SmallTest public void testRegisterAccountListenerCredentialsUpdate() throws Exception { unlockSystemUser(); mAms.registerAccountListener( diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt index 46ad77e1eff9..519b4296d93a 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.close +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -122,7 +122,7 @@ class CloseSecondaryActivityInSplitTest(flicker: LegacyFlickerTest) : companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. * diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/HorizontalSplitChangeRatioTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/HorizontalSplitChangeRatioTest.kt index af4f7a721464..4cd6d15b2983 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/HorizontalSplitChangeRatioTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/HorizontalSplitChangeRatioTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.layoutchange +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -114,11 +114,11 @@ class HorizontalSplitChangeRatioTest(flicker: LegacyFlickerTest) : // Compare dimensions of two splits, given we're using default split attributes, // both activities take up the same visible size on the display. check { "height" } - .that(topLayerRegion.region.height) - .isEqual(bottomLayerRegion.region.height) + .that(topLayerRegion.region.bounds.height()) + .isEqual(bottomLayerRegion.region.bounds.height()) check { "width" } - .that(topLayerRegion.region.width) - .isEqual(bottomLayerRegion.region.width) + .that(topLayerRegion.region.bounds.width()) + .isEqual(bottomLayerRegion.region.bounds.width()) topLayerRegion.notOverlaps(bottomLayerRegion.region) // Layers of two activities sum to be fullscreen size on display. topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds) @@ -132,14 +132,17 @@ class HorizontalSplitChangeRatioTest(flicker: LegacyFlickerTest) : // Compare dimensions of two splits, given we're using default split attributes, // both activities take up the same visible size on the display. check { "height" } - .that(topLayerRegion.region.height) - .isLower(bottomLayerRegion.region.height) + .that(topLayerRegion.region.bounds.height()) + .isLower(bottomLayerRegion.region.bounds.height()) check { "height" } - .that(topLayerRegion.region.height / 0.3f - bottomLayerRegion.region.height / 0.7f) + .that( + topLayerRegion.region.bounds.height() / 0.3f - + bottomLayerRegion.region.bounds.height() / 0.7f + ) .isLower(0.1f) check { "width" } - .that(topLayerRegion.region.width) - .isEqual(bottomLayerRegion.region.width) + .that(topLayerRegion.region.bounds.width()) + .isEqual(bottomLayerRegion.region.bounds.width()) topLayerRegion.notOverlaps(bottomLayerRegion.region) // Layers of two activities sum to be fullscreen size on display. topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds) @@ -148,7 +151,7 @@ class HorizontalSplitChangeRatioTest(flicker: LegacyFlickerTest) : companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt index e511b727d57f..5df8b57294f0 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.open +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -132,7 +132,7 @@ class MainActivityStartsSecondaryWithAlwaysExpandTest(flicker: LegacyFlickerTest companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt index 4352177a8984..78004ccc3f97 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.open +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -143,7 +143,7 @@ class OpenThirdActivityOverSplitTest(flicker: LegacyFlickerTest) : companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. * diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt index 62cf6cd528e9..cf4edd50040b 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.open +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -156,11 +156,11 @@ class OpenTrampolineActivityTest(flicker: LegacyFlickerTest) : ActivityEmbedding it.timestamp ) check { "height" } - .that(mainActivityRegion.region.height) - .isEqual(secondaryActivityRegion.region.height) + .that(mainActivityRegion.region.bounds.height()) + .isEqual(secondaryActivityRegion.region.bounds.height()) check { "width" } - .that(mainActivityRegion.region.width) - .isEqual(secondaryActivityRegion.region.width) + .that(mainActivityRegion.region.bounds.width()) + .isEqual(secondaryActivityRegion.region.bounds.width()) mainActivityRegion .plus(secondaryActivityRegion.region) .coversExactly(startDisplayBounds) @@ -192,11 +192,11 @@ class OpenTrampolineActivityTest(flicker: LegacyFlickerTest) : ActivityEmbedding // Compare dimensions of two splits, given we're using default split attributes, // both activities take up the same visible size on the display. check { "height" } - .that(leftLayerRegion.region.height) - .isEqual(rightLayerRegion.region.height) + .that(leftLayerRegion.region.bounds.height()) + .isEqual(rightLayerRegion.region.bounds.height()) check { "width" } - .that(leftLayerRegion.region.width) - .isEqual(rightLayerRegion.region.width) + .that(leftLayerRegion.region.bounds.width()) + .isEqual(rightLayerRegion.region.bounds.width()) leftLayerRegion.notOverlaps(rightLayerRegion.region) // Layers of two activities sum to be fullscreen size on display. leftLayerRegion.plus(rightLayerRegion.region).coversExactly(startDisplayBounds) @@ -211,7 +211,7 @@ class OpenTrampolineActivityTest(flicker: LegacyFlickerTest) : ActivityEmbedding companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/SecondaryActivityEnterPipTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/SecondaryActivityEnterPipTest.kt index aa8b4cebe91d..bc3696b3ed1c 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/SecondaryActivityEnterPipTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/SecondaryActivityEnterPipTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.activityembedding.pip +import android.graphics.Rect import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -79,11 +79,11 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : // Compare dimensions of two splits, given we're using default split attributes, // both activities take up the same visible size on the display. check { "height" } - .that(leftLayerRegion.region.height) - .isEqual(rightLayerRegion.region.height) + .that(leftLayerRegion.region.bounds.height()) + .isEqual(rightLayerRegion.region.bounds.height()) check { "width" } - .that(leftLayerRegion.region.width) - .isEqual(rightLayerRegion.region.width) + .that(leftLayerRegion.region.bounds.width()) + .isEqual(rightLayerRegion.region.bounds.width()) leftLayerRegion.notOverlaps(rightLayerRegion.region) leftLayerRegion.plus(rightLayerRegion.region).coversExactly(startDisplayBounds) } @@ -136,9 +136,11 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : val pipWindowRegion = visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) check { "height" } - .that(pipWindowRegion.region.height) - .isLower(startDisplayBounds.height / 2) - check { "width" }.that(pipWindowRegion.region.width).isLower(startDisplayBounds.width) + .that(pipWindowRegion.region.bounds.height()) + .isLower(startDisplayBounds.height() / 2) + check { "width" } + .that(pipWindowRegion.region.bounds.width()) + .isLower(startDisplayBounds.width()) } } @@ -151,7 +153,7 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : ComponentNameMatcher.PIP_CONTENT_OVERLAY.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> - if (startDisplayBounds.width > startDisplayBounds.height) { + if (startDisplayBounds.width() > startDisplayBounds.height()) { // Only verify when the display is landscape, because otherwise the final pip // window can be to the left of the original secondary activity. current.screenBounds.isToTheRightBottom(previous.screenBounds.region, 3) @@ -162,8 +164,12 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : } flicker.assertLayersEnd { val pipRegion = visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) - check { "height" }.that(pipRegion.region.height).isLower(startDisplayBounds.height / 2) - check { "width" }.that(pipRegion.region.width).isLower(startDisplayBounds.width) + check { "height" } + .that(pipRegion.region.bounds.height()) + .isLower(startDisplayBounds.height() / 2) + check { "width" } + .that(pipRegion.region.bounds.width()) + .isLower(startDisplayBounds.width()) } } @@ -175,7 +181,7 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : invoke("secondaryLayerNotJumpToLeft") { val secondaryVisibleRegion = it.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) - if (secondaryVisibleRegion.region.isNotEmpty) { + if (!secondaryVisibleRegion.region.isEmpty) { check { "left" }.that(secondaryVisibleRegion.region.bounds.left).isGreater(0) } } @@ -222,7 +228,7 @@ class SecondaryActivityEnterPipTest(flicker: LegacyFlickerTest) : companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. * diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt index 3d834c16163f..f5e6c7854eba 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt @@ -85,11 +85,11 @@ open class RotateSplitNoChangeTest(flicker: LegacyFlickerTest) : RotationTransit // Compare dimensions of two splits, given we're using default split attributes, // both activities take up the same visible size on the display. check { "height" } - .that(leftLayerRegion.region.height) - .isEqual(rightLayerRegion.region.height) + .that(leftLayerRegion.region.bounds.height()) + .isEqual(rightLayerRegion.region.bounds.height()) check { "width" } - .that(leftLayerRegion.region.width) - .isEqual(rightLayerRegion.region.width) + .that(leftLayerRegion.region.bounds.width()) + .isEqual(rightLayerRegion.region.bounds.width()) leftLayerRegion.notOverlaps(rightLayerRegion.region) // Layers of two activities sum to be fullscreen size on display. leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace) @@ -108,11 +108,11 @@ open class RotateSplitNoChangeTest(flicker: LegacyFlickerTest) : RotationTransit val rightLayerRegion = this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) check { "height" } - .that(leftLayerRegion.region.height) - .isEqual(rightLayerRegion.region.height) + .that(leftLayerRegion.region.bounds.height()) + .isEqual(rightLayerRegion.region.bounds.height()) check { "width" } - .that(leftLayerRegion.region.width) - .isEqual(rightLayerRegion.region.width) + .that(leftLayerRegion.region.bounds.width()) + .isEqual(rightLayerRegion.region.bounds.width()) leftLayerRegion.notOverlaps(rightLayerRegion.region) leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace) } diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt index 13902184ac6e..ee2c05e82d51 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt @@ -16,9 +16,9 @@ package com.android.server.wm.flicker.activityembedding.rotation +import android.graphics.Rect import android.platform.test.annotations.Presubmit import android.tools.Position -import android.tools.datatypes.Rect import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest import android.tools.traces.Condition @@ -97,7 +97,7 @@ abstract class RotationTransition(flicker: LegacyFlickerTest) : ActivityEmbeddin val navBarPosition = display.navBarPosition(isGesturalNavigation) val navBarRegion = dump.layerState .getLayerWithBuffer(ComponentNameMatcher.NAV_BAR) - ?.visibleRegion?.bounds ?: Rect.EMPTY + ?.visibleRegion?.bounds ?: Rect() when (navBarPosition) { Position.TOP -> diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt index 7298e5f71b05..fb9258304870 100644 --- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt @@ -16,9 +16,9 @@ package com.android.server.wm.flicker.activityembedding.splitscreen +import android.graphics.Rect import android.platform.test.annotations.Presubmit import android.platform.test.annotations.RequiresDevice -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -32,6 +32,7 @@ import com.android.wm.shell.flicker.utils.SplitScreenUtils import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible +import kotlin.math.abs import org.junit.FixMethodOrder import org.junit.Ignore import org.junit.Test @@ -135,19 +136,25 @@ class EnterSystemSplitTest(flicker: LegacyFlickerTest) : ActivityEmbeddingTestBa .plus(systemDivider.region) .coversExactly(startDisplayBounds) check { "ActivityEmbeddingSplitHeight" } - .that(leftAELayerRegion.region.height) - .isEqual(rightAELayerRegion.region.height) + .that(leftAELayerRegion.region.bounds.height()) + .isEqual(rightAELayerRegion.region.bounds.height()) check { "SystemSplitHeight" } - .that(rightAELayerRegion.region.height) - .isEqual(secondaryAppLayerRegion.region.height) + .that(rightAELayerRegion.region.bounds.height()) + .isEqual(secondaryAppLayerRegion.region.bounds.height()) // TODO(b/292283182): Remove this special case handling. check { "ActivityEmbeddingSplitWidth" } - .that(Math.abs(leftAELayerRegion.region.width - rightAELayerRegion.region.width)) + .that( + abs( + leftAELayerRegion.region.bounds.width() - + rightAELayerRegion.region.bounds.width() + ) + ) .isLower(2) check { "SystemSplitWidth" } .that( - Math.abs( - secondaryAppLayerRegion.region.width - 2 * rightAELayerRegion.region.width + abs( + secondaryAppLayerRegion.region.bounds.width() - + 2 * rightAELayerRegion.region.bounds.width() ) ) .isLower(2) @@ -167,18 +174,24 @@ class EnterSystemSplitTest(flicker: LegacyFlickerTest) : ActivityEmbeddingTestBa val secondaryAppLayerRegion = visibleRegion(ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent()) check { "ActivityEmbeddingSplitHeight" } - .that(leftAEWindowRegion.region.height) - .isEqual(rightAEWindowRegion.region.height) + .that(leftAEWindowRegion.region.bounds.height()) + .isEqual(rightAEWindowRegion.region.bounds.height()) check { "SystemSplitHeight" } - .that(rightAEWindowRegion.region.height) - .isEqual(secondaryAppLayerRegion.region.height) + .that(rightAEWindowRegion.region.bounds.height()) + .isEqual(secondaryAppLayerRegion.region.bounds.height()) check { "ActivityEmbeddingSplitWidth" } - .that(Math.abs(leftAEWindowRegion.region.width - rightAEWindowRegion.region.width)) + .that( + abs( + leftAEWindowRegion.region.bounds.width() - + rightAEWindowRegion.region.bounds.width() + ) + ) .isLower(2) check { "SystemSplitWidth" } .that( - Math.abs( - secondaryAppLayerRegion.region.width - 2 * rightAEWindowRegion.region.width + abs( + secondaryAppLayerRegion.region.bounds.width() - + 2 * rightAEWindowRegion.region.bounds.width() ) ) .isLower(2) @@ -190,7 +203,7 @@ class EnterSystemSplitTest(flicker: LegacyFlickerTest) : ActivityEmbeddingTestBa companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() /** * Creates the test configurations. * diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt index b1d78cbc034e..a71599d25632 100644 --- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt +++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt @@ -19,8 +19,9 @@ package com.android.server.wm.flicker.launch import android.app.Instrumentation import android.app.WallpaperManager import android.content.res.Resources +import android.graphics.Rect +import android.graphics.Region import android.platform.test.annotations.Presubmit -import android.tools.datatypes.Region import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -213,6 +214,12 @@ class TaskTransitionTest(flicker: LegacyFlickerTest) : BaseTest(flicker) { private fun LayersTraceSubject.visibleRegionCovers( component: IComponentMatcher, + expectedArea: Rect, + isOptional: Boolean = true + ): LayersTraceSubject = visibleRegionCovers(component, Region(expectedArea), isOptional) + + private fun LayersTraceSubject.visibleRegionCovers( + component: IComponentMatcher, expectedArea: Region, isOptional: Boolean = true ): LayersTraceSubject = diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt index 7e486abbd30f..da8368f3cedf 100644 --- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt +++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt @@ -83,11 +83,12 @@ class CloseImeOnDismissPopupDialogTest(flicker: LegacyFlickerTest) : BaseTest(fl } if (imeSnapshotLayers.isNotEmpty()) { val visibleAreas = - imeSnapshotLayers - .mapNotNull { imeSnapshotLayer -> imeSnapshotLayer.layer.visibleRegion } + imeSnapshotLayers.mapNotNull { imeSnapshotLayer -> + imeSnapshotLayer.layer.visibleRegion + } val imeVisibleRegion = RegionSubject(visibleAreas, timestamp) val appVisibleRegion = it.visibleRegion(imeTestApp) - if (imeVisibleRegion.region.isNotEmpty) { + if (!imeVisibleRegion.region.isEmpty) { imeVisibleRegion.coversAtMost(appVisibleRegion.region) } } diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt index e8249bca4c2d..48ec4d1fed2c 100644 --- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt +++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt @@ -115,7 +115,10 @@ class ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest(flicker: LegacyF .isEqual(true) imeLayerSubjects.forEach { imeLayerSubject -> - imeLayerSubject.check { "alpha" }.that(imeLayerSubject.layer.color.a).isEqual(1.0f) + imeLayerSubject + .check { "alpha" } + .that(imeLayerSubject.layer.color.alpha()) + .isEqual(1.0f) } } } diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt index 617237d37368..92b865542257 100644 --- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt +++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt @@ -50,7 +50,7 @@ class ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker: LegacyFlickerTe testApp.launchViaIntent(wmHelper) testApp.openIME(wmHelper) this.setRotation(flicker.scenario.startRotation) - device.pressRecentApps() + tapl.launchedAppState.switchToOverview() wmHelper.StateSyncBuilder().withRecentsActivityVisible().waitForAndVerify() } transitions { diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt index a14dc62b0023..7aa525fcccef 100644 --- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt +++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt @@ -191,7 +191,7 @@ class ShowImeWhileEnteringOverviewTest(flicker: LegacyFlickerTest) : BaseTest(fl this.invoke("imeLayerIsVisibleAndAlignAppWidow") { val imeVisibleRegion = it.visibleRegion(ComponentNameMatcher.IME) val appVisibleRegion = it.visibleRegion(imeTestApp) - if (imeVisibleRegion.region.isNotEmpty) { + if (!imeVisibleRegion.region.isEmpty) { it.isVisible(ComponentNameMatcher.IME) imeVisibleRegion.coversAtMost(appVisibleRegion.region) } diff --git a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt index 8b09b590e790..9bb62e1e1794 100644 --- a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt +++ b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt @@ -16,9 +16,9 @@ package com.android.server.wm.flicker.quickswitch +import android.graphics.Rect import android.platform.test.annotations.Presubmit import android.tools.NavBar -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -237,7 +237,7 @@ class QuickSwitchBetweenTwoAppsBackTest(flicker: LegacyFlickerTest) : BaseTest(f override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd() companion object { - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt index c54ddcf793f6..491b9945d12d 100644 --- a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt +++ b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.quickswitch +import android.graphics.Rect import android.tools.NavBar -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -285,7 +285,7 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes super.visibleWindowsShownMoreThanOneConsecutiveEntry() companion object { - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt index 69a84a0cbcb0..de54c95da361 100644 --- a/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt +++ b/tests/FlickerTests/QuickSwitch/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt @@ -16,10 +16,10 @@ package com.android.server.wm.flicker.quickswitch +import android.graphics.Rect import android.platform.test.annotations.Presubmit import android.tools.NavBar import android.tools.Rotation -import android.tools.datatypes.Rect import android.tools.flicker.junit.FlickerParametersRunnerFactory import android.tools.flicker.legacy.FlickerBuilder import android.tools.flicker.legacy.LegacyFlickerTest @@ -266,7 +266,7 @@ class QuickSwitchFromLauncherTest(flicker: LegacyFlickerTest) : BaseTest(flicker companion object { /** {@inheritDoc} */ - private var startDisplayBounds = Rect.EMPTY + private var startDisplayBounds = Rect() @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt index 8853c1db856f..348d0af5a2d3 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt @@ -279,12 +279,11 @@ fun LegacyFlickerTest.snapshotStartingWindowLayerCoversExactlyOnApp( subject.isVisible } val visibleAreas = - snapshotLayers - .mapNotNull { snapshotLayer -> snapshotLayer.layer.visibleRegion } + snapshotLayers.mapNotNull { snapshotLayer -> snapshotLayer.layer.visibleRegion } val snapshotRegion = RegionSubject(visibleAreas, it.timestamp) val appVisibleRegion = it.visibleRegion(component) // Verify the size of snapshotRegion covers appVisibleRegion exactly in animation. - if (snapshotRegion.region.isNotEmpty && appVisibleRegion.region.isNotEmpty) { + if (!snapshotRegion.region.isEmpty && !appVisibleRegion.region.isEmpty) { snapshotRegion.coversExactly(appVisibleRegion.region) } } diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt index ffed4087acff..ef8d84fb915a 100644 --- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt +++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt @@ -45,13 +45,7 @@ constructor( require(gameView != null) { "Mock game app view not found." } val bound = gameView.getVisibleBounds() - return uiDevice.swipe( - bound.centerX(), - 0, - bound.centerX(), - bound.centerY(), - SWIPE_STEPS - ) + return uiDevice.swipe(bound.centerX(), 0, bound.centerX(), bound.centerY(), SWIPE_STEPS) } /** diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt index b09e53b6400d..634b6eedd7e6 100644 --- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt +++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt @@ -17,8 +17,8 @@ package com.android.server.wm.flicker.helpers import android.app.Instrumentation -import android.tools.datatypes.Rect -import android.tools.datatypes.Region +import android.graphics.Rect +import android.graphics.Region import android.tools.device.apphelpers.StandardAppHelper import android.tools.helpers.FIND_TIMEOUT import android.tools.helpers.SYSTEMUI_PACKAGE @@ -86,7 +86,7 @@ constructor( .add("letterboxAppRepositioned") { val letterboxAppWindow = getWindowRegion(wmHelper) val appRegionBounds = letterboxAppWindow.bounds - val appWidth = appRegionBounds.width + val appWidth = appRegionBounds.width() return@add if (right) appRegionBounds.left == displayBounds.right - appWidth && appRegionBounds.right == displayBounds.right @@ -108,7 +108,7 @@ constructor( .add("letterboxAppRepositioned") { val letterboxAppWindow = getWindowRegion(wmHelper) val appRegionBounds = letterboxAppWindow.bounds - val appHeight = appRegionBounds.height + val appHeight = appRegionBounds.height() return@add if (bottom) appRegionBounds.bottom == displayBounds.bottom && appRegionBounds.top == (displayBounds.bottom - appHeight + navBarHeight) diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt index db933b30a822..43fd57bf39aa 100644 --- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt +++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt @@ -18,10 +18,11 @@ package com.android.server.wm.flicker.helpers import android.app.Instrumentation import android.content.Intent +import android.graphics.Rect +import android.graphics.Region import android.media.session.MediaController import android.media.session.MediaSessionManager -import android.tools.datatypes.Rect -import android.tools.datatypes.Region +import android.tools.datatypes.coversMoreThan import android.tools.device.apphelpers.StandardAppHelper import android.tools.helpers.FIND_TIMEOUT import android.tools.helpers.SYSTEMUI_PACKAGE @@ -62,7 +63,7 @@ open class PipAppHelper(instrumentation: Instrumentation) : /** Drags the PIP window to the provided final coordinates without releasing the pointer. */ fun dragPipWindowAwayFromEdgeWithoutRelease(wmHelper: WindowManagerStateHelper, steps: Int) { - val initWindowRect = getWindowRect(wmHelper).clone() + val initWindowRect = Rect(getWindowRect(wmHelper)) // initial pointer at the center of the window val initialCoord = @@ -101,7 +102,7 @@ open class PipAppHelper(instrumentation: Instrumentation) : * @throws IllegalStateException if default display bounds are not available */ fun dragPipWindowAwayFromEdge(wmHelper: WindowManagerStateHelper, steps: Int) { - val initWindowRect = getWindowRect(wmHelper).clone() + val initWindowRect = Rect(getWindowRect(wmHelper)) // initial pointer at the center of the window val startX = initWindowRect.centerX() @@ -153,12 +154,12 @@ open class PipAppHelper(instrumentation: Instrumentation) : val windowRect = getWindowRect(wmHelper) // first pointer's initial x coordinate is halfway between the left edge and the center - val initLeftX = (windowRect.centerX() - windowRect.width / 4).toFloat() + val initLeftX = (windowRect.centerX() - windowRect.width() / 4).toFloat() // second pointer's initial x coordinate is halfway between the right edge and the center - val initRightX = (windowRect.centerX() + windowRect.width / 4).toFloat() + val initRightX = (windowRect.centerX() + windowRect.width() / 4).toFloat() // horizontal distance the window should increase by - val distIncrease = windowRect.width * percent + val distIncrease = windowRect.width() * percent // final x-coordinates val finalLeftX = initLeftX - (distIncrease / 2) @@ -183,7 +184,7 @@ open class PipAppHelper(instrumentation: Instrumentation) : adjustedSteps ) - waitForPipWindowToExpandFrom(wmHelper, Region.from(windowRect)) + waitForPipWindowToExpandFrom(wmHelper, Region(windowRect)) } /** @@ -201,12 +202,12 @@ open class PipAppHelper(instrumentation: Instrumentation) : val windowRect = getWindowRect(wmHelper) // first pointer's initial x coordinate is halfway between the left edge and the center - val initLeftX = (windowRect.centerX() - windowRect.width / 4).toFloat() + val initLeftX = (windowRect.centerX() - windowRect.width() / 4).toFloat() // second pointer's initial x coordinate is halfway between the right edge and the center - val initRightX = (windowRect.centerX() + windowRect.width / 4).toFloat() + val initRightX = (windowRect.centerX() + windowRect.width() / 4).toFloat() // decrease by the distance specified through the percentage - val distDecrease = windowRect.width * percent + val distDecrease = windowRect.width() * percent // get the final x-coordinates and make sure they are not passing the center of the window val finalLeftX = Math.min(initLeftX + (distDecrease / 2), windowRect.centerX().toFloat()) @@ -231,7 +232,7 @@ open class PipAppHelper(instrumentation: Instrumentation) : adjustedSteps ) - waitForPipWindowToMinimizeFrom(wmHelper, Region.from(windowRect)) + waitForPipWindowToMinimizeFrom(wmHelper, Region(windowRect)) } /** @@ -375,7 +376,7 @@ open class PipAppHelper(instrumentation: Instrumentation) : uiDevice.click(windowRect.centerX(), windowRect.centerY()) Log.d(TAG, "Wait for app transition to end") wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify() - waitForPipWindowToExpandFrom(wmHelper, Region.from(windowRect)) + waitForPipWindowToExpandFrom(wmHelper, Region(windowRect)) } private fun waitForPipWindowToExpandFrom( |