diff options
343 files changed, 4524 insertions, 2209 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 4e34b63be0d6..59a7cbc16587 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -21,6 +21,7 @@ aconfig_declarations_group { // !!! KEEP THIS LIST ALPHABETICAL !!! "aconfig_mediacodec_flags_java_lib", "android.adaptiveauth.flags-aconfig-java", + "android.app.appfunctions.flags-aconfig-java", "android.app.contextualsearch.flags-aconfig-java", "android.app.flags-aconfig-java", "android.app.ondeviceintelligence-aconfig-java", @@ -1383,6 +1384,21 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +// AppFunctions +aconfig_declarations { + name: "android.app.appfunctions.flags-aconfig", + exportable: true, + package: "android.app.appfunctions.flags", + container: "system", + srcs: ["core/java/android/app/appfunctions/flags/flags.aconfig"], +} + +java_aconfig_library { + name: "android.app.appfunctions.flags-aconfig-java", + aconfig_declarations: "android.app.appfunctions.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Adaptive Auth aconfig_declarations { name: "android.adaptiveauth.flags-aconfig", diff --git a/INPUT_OWNERS b/INPUT_OWNERS index 06ead06fc13a..9b1016e7b7e9 100644 --- a/INPUT_OWNERS +++ b/INPUT_OWNERS @@ -1,4 +1,5 @@ # Bug component: 136048 +# Please assign bugs to android-framework-input-triage@. arpitks@google.com asmitapoddar@google.com hcutts@google.com diff --git a/TEST_MAPPING b/TEST_MAPPING index 49384cde5803..5db077220b20 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -137,13 +137,14 @@ "name": "CtsStrictJavaPackagesTestCases" } ], - "postsubmit-ravenwood": [ + "ravenwood-presubmit": [ { "name": "CtsUtilTestCasesRavenwood", - "host": true, - "file_patterns": [ - "[Rr]avenwood" - ] + "host": true + }, + { + "name": "RavenwoodBivalentTest", + "host": true } ], "postsubmit-managedprofile-stress": [ diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java index d7b1c9a2d3a2..f20b1706129b 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java @@ -43,7 +43,6 @@ import java.util.concurrent.atomic.AtomicLong; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -143,7 +142,7 @@ public final class ClientSocketPerfTest { // Always use the same server for consistency across the benchmarks. server = config.serverFactory().newServer( - ChannelType.CHANNEL, config.messageSize(), config.protocol().getProtocols(), + config.messageSize(), config.protocol().getProtocols(), ciphers(config)); server.setMessageProcessor(new ServerEndpoint.MessageProcessor() { @@ -197,7 +196,6 @@ public final class ClientSocketPerfTest { */ @Test @Parameters(method = "getParams") - @Ignore("b/351034205") public void time(Config config) throws Exception { reset(); setup(config); diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java index 0655f45726ba..ba2acb8a5205 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java @@ -43,10 +43,10 @@ public enum EndpointFactory { factories.clientFactory, channelType, port, protocols, ciphers); } - public ServerEndpoint newServer(ChannelType channelType, int messageSize, + public ServerEndpoint newServer(int messageSize, String[] protocols, String[] ciphers) throws IOException { return new ServerEndpoint(factories.serverFactory, factories.serverSocketFactory, - channelType, messageSize, protocols, ciphers); + messageSize, protocols, ciphers); } private static final class Factories { diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java index 3631c3f29287..1e4f12460936 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java @@ -34,8 +34,6 @@ import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; -import org.conscrypt.ChannelType; - /** * A simple socket-based test server. */ @@ -63,7 +61,6 @@ final class ServerEndpoint { } private final ServerSocket serverSocket; - private final ChannelType channelType; private final SSLSocketFactory socketFactory; private final int messageSize; private final String[] protocols; @@ -78,11 +75,10 @@ final class ServerEndpoint { private volatile Future<?> processFuture; ServerEndpoint(SSLSocketFactory socketFactory, SSLServerSocketFactory serverSocketFactory, - ChannelType channelType, int messageSize, String[] protocols, + int messageSize, String[] protocols, String[] cipherSuites) throws IOException { - this.serverSocket = channelType.newServerSocket(serverSocketFactory); + this.serverSocket = serverSocketFactory.createServerSocket(); this.socketFactory = socketFactory; - this.channelType = channelType; this.messageSize = messageSize; this.protocols = protocols; this.cipherSuites = cipherSuites; @@ -134,7 +130,7 @@ final class ServerEndpoint { if (stopping) { return; } - socket = channelType.accept(serverSocket, socketFactory); + socket = (SSLSocket) serverSocket.accept(); socket.setEnabledProtocols(protocols); socket.setEnabledCipherSuites(cipherSuites); diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java index 8916a3c55a9a..af3c405eab82 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java @@ -43,7 +43,6 @@ import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -131,8 +130,7 @@ public final class ServerSocketPerfTest { final ChannelType channelType = config.channelType(); - server = config.serverFactory().newServer( - channelType, config.messageSize(), + server = config.serverFactory().newServer(config.messageSize(), new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config)); server.setMessageProcessor(new MessageProcessor() { @Override @@ -202,7 +200,6 @@ public final class ServerSocketPerfTest { @Test @Parameters(method = "getParams") - @Ignore("b/351034205") public void throughput(Config config) throws Exception { setup(config); BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); diff --git a/apct-tests/perftests/multiuser/Android.bp b/apct-tests/perftests/multiuser/Android.bp index 856dba3f804c..9eea712b33dd 100644 --- a/apct-tests/perftests/multiuser/Android.bp +++ b/apct-tests/perftests/multiuser/Android.bp @@ -45,3 +45,8 @@ filegroup { "trace_configs/trace_config_multi_user.textproto", ], } + +prebuilt_etc { + name: "trace_config_multi_user.textproto", + src: ":multi_user_trace_config", +} diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index ba66ff72bfdd..d61439c0751c 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -357,6 +357,7 @@ public class AlarmManagerService extends SystemService { } // TODO(b/172085676): Move inside alarm store. + @GuardedBy("mLock") private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = new SparseArray<>(); private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = @@ -2616,6 +2617,13 @@ public class AlarmManagerService extends SystemService { mInFlightListeners.add(callback); } } + + /** @see AlarmManagerInternal#getNextAlarmTriggerTimeForUser(int) */ + @Override + public long getNextAlarmTriggerTimeForUser(@UserIdInt int userId) { + final AlarmManager.AlarmClockInfo nextAlarm = getNextAlarmClockImpl(userId); + return nextAlarm != null ? nextAlarm.getTriggerTime() : 0; + } } boolean hasUseExactAlarmInternal(String packageName, int uid) { diff --git a/core/api/current.txt b/core/api/current.txt index ea039a7103a3..36c9175830a3 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -10684,6 +10684,7 @@ package android.content { field public static final String ACTIVITY_SERVICE = "activity"; field public static final String ALARM_SERVICE = "alarm"; field public static final String APPWIDGET_SERVICE = "appwidget"; + field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String APP_FUNCTION_SERVICE = "app_function"; field public static final String APP_OPS_SERVICE = "appops"; field public static final String APP_SEARCH_SERVICE = "app_search"; field public static final String AUDIO_SERVICE = "audio"; diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e73f4718732f..114a2c4d5649 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -16,6 +16,8 @@ package android.app; +import static android.app.appfunctions.flags.Flags.enableAppFunctionManager; + import android.accounts.AccountManager; import android.accounts.IAccountManager; import android.adservices.AdServicesFrameworkInitializer; @@ -28,6 +30,8 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.app.ambientcontext.AmbientContextManager; import android.app.ambientcontext.IAmbientContextManager; +import android.app.appfunctions.AppFunctionManager; +import android.app.appfunctions.IAppFunctionManager; import android.app.appsearch.AppSearchManagerFrameworkInitializer; import android.app.blob.BlobStoreManagerFrameworkInitializer; import android.app.contentsuggestions.ContentSuggestionsManager; @@ -925,6 +929,21 @@ public final class SystemServiceRegistry { return new CompanionDeviceManager(service, ctx.getOuterContext()); }}); + if (enableAppFunctionManager()) { + registerService(Context.APP_FUNCTION_SERVICE, AppFunctionManager.class, + new CachedServiceFetcher<>() { + @Override + public AppFunctionManager createService(ContextImpl ctx) + throws ServiceNotFoundException { + IAppFunctionManager service; + //TODO(b/357551503): If the feature not present avoid look up every time + service = IAppFunctionManager.Stub.asInterface( + ServiceManager.getServiceOrThrow(Context.APP_FUNCTION_SERVICE)); + return new AppFunctionManager(service, ctx.getOuterContext()); + } + }); + } + registerService(Context.VIRTUAL_DEVICE_SERVICE, VirtualDeviceManager.class, new CachedServiceFetcher<VirtualDeviceManager>() { @Override diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java new file mode 100644 index 000000000000..a01e373c5e83 --- /dev/null +++ b/core/java/android/app/appfunctions/AppFunctionManager.java @@ -0,0 +1,44 @@ +/* + * 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 android.app.appfunctions; + +import android.annotation.SystemService; +import android.content.Context; + +/** + * Provides app functions related functionalities. + * + * <p>App function is a specific piece of functionality that an app offers to the system. These + * functionalities can be integrated into various system features. + * + * @hide + */ +@SystemService(Context.APP_FUNCTION_SERVICE) +public final class AppFunctionManager { + private final IAppFunctionManager mService; + private final Context mContext; + + /** + * TODO(b/357551503): add comments when implement this class + * + * @hide + */ + public AppFunctionManager(IAppFunctionManager mService, Context context) { + this.mService = mService; + this.mContext = context; + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt b/core/java/android/app/appfunctions/IAppFunctionManager.aidl index d8b93482854a..018bc758f69f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt +++ b/core/java/android/app/appfunctions/IAppFunctionManager.aidl @@ -14,21 +14,11 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.functional +package android.app.appfunctions; -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowSingleWindow -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [DragAppWindowSingleWindow]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class DragAppWindowSingleWindowTest : DragAppWindowSingleWindow() -{ - @Test - override fun dragAppWindow() { - super.dragAppWindow() - } -} +/** +* Interface between an app and the server implementation service (AppFunctionManagerService). +* @hide +*/ +oneway interface IAppFunctionManager { +}
\ No newline at end of file diff --git a/core/java/android/app/appfunctions/flags/flags.aconfig b/core/java/android/app/appfunctions/flags/flags.aconfig new file mode 100644 index 000000000000..367effc9e9bb --- /dev/null +++ b/core/java/android/app/appfunctions/flags/flags.aconfig @@ -0,0 +1,11 @@ +package: "android.app.appfunctions.flags" +container: "system" + +flag { + name: "enable_app_function_manager" + is_exported: true + is_fixed_read_only: true + namespace: "machine_learning" + description: "This flag the new App Function manager system service." + bug: "357551503" +}
\ No newline at end of file diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9aebfc8e5fd7..9dccc9ae7145 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -16,6 +16,7 @@ package android.content; +import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER; import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS; import android.annotation.AttrRes; @@ -51,6 +52,7 @@ import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.VrManager; import android.app.ambientcontext.AmbientContextManager; +import android.app.appfunctions.AppFunctionManager; import android.app.people.PeopleManager; import android.app.time.TimeManager; import android.companion.virtual.VirtualDeviceManager; @@ -6310,6 +6312,16 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an + * {@link AppFunctionManager} for + * executing app functions. + * + * @see #getSystemService(String) + */ + @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER) + public static final String APP_FUNCTION_SERVICE = "app_function"; + + /** + * Use with {@link #getSystemService(String)} to retrieve an * {@link android.content.integrity.AppIntegrityManager}. * @hide */ diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING index b0ab11f48858..1fab3cffcebd 100644 --- a/core/java/android/content/pm/TEST_MAPPING +++ b/core/java/android/content/pm/TEST_MAPPING @@ -171,6 +171,17 @@ "include-filter": "android.content.pm.cts.PackageManagerShellCommandMultiUserTest" } ] + }, + { + "name":"CtsPackageInstallerCUJTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] } ] } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index de3984756416..ff737a4f9fb8 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -58,8 +58,6 @@ import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING; import static android.view.inputmethod.Flags.ctrlShiftShortcut; import static android.view.inputmethod.Flags.predictiveBackIme; -import static java.lang.annotation.RetentionPolicy.SOURCE; - import android.annotation.AnyThread; import android.annotation.CallSuper; import android.annotation.DrawableRes; @@ -500,36 +498,53 @@ public class InputMethodService extends AbstractInputMethodService { public static final int BACK_DISPOSITION_ADJUST_NOTHING = 3; /** - * Enum flag to be used for {@link #setBackDisposition(int)}. + * The disposition mode that indicates the expected affordance for the back button. * * @hide */ - @Retention(SOURCE) - @IntDef(value = {BACK_DISPOSITION_DEFAULT, BACK_DISPOSITION_WILL_NOT_DISMISS, - BACK_DISPOSITION_WILL_DISMISS, BACK_DISPOSITION_ADJUST_NOTHING}, - prefix = "BACK_DISPOSITION_") + @IntDef(prefix = { "BACK_DISPOSITION_" }, value = { + BACK_DISPOSITION_DEFAULT, + BACK_DISPOSITION_WILL_NOT_DISMISS, + BACK_DISPOSITION_WILL_DISMISS, + BACK_DISPOSITION_ADJUST_NOTHING, + }) + @Retention(RetentionPolicy.SOURCE) public @interface BackDispositionMode {} /** + * The IME is active, and ready to accept touch/key events. It may or may not be visible. + * * @hide - * The IME is active. It may or may not be visible. */ - public static final int IME_ACTIVE = 0x1; + public static final int IME_ACTIVE = 1 << 0; /** - * @hide * The IME is perceptibly visible to the user. + * + * @hide */ - public static final int IME_VISIBLE = 0x2; + public static final int IME_VISIBLE = 1 << 1; /** - * @hide * The IME is visible, but not yet perceptible to the user (e.g. fading in) * by {@link android.view.WindowInsetsController}. * * @see InputMethodManager#reportPerceptible + * @hide + */ + public static final int IME_VISIBLE_IMPERCEPTIBLE = 1 << 2; + + /** + * The IME window visibility state. + * + * @hide */ - public static final int IME_VISIBLE_IMPERCEPTIBLE = 0x4; + @IntDef(flag = true, prefix = { "IME_" }, value = { + IME_ACTIVE, + IME_VISIBLE, + IME_VISIBLE_IMPERCEPTIBLE, + }) + public @interface ImeWindowVisibility {} // Min and max values for back disposition. private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT; @@ -1342,7 +1357,8 @@ public class InputMethodService extends AbstractInputMethodService { mImeSurfaceRemoverRunnable = null; } - private void setImeWindowStatus(int visibilityFlags, int backDisposition) { + private void setImeWindowStatus(@ImeWindowVisibility int visibilityFlags, + @BackDispositionMode int backDisposition) { mPrivOps.setImeWindowStatusAsync(visibilityFlags, backDisposition); } @@ -3301,7 +3317,7 @@ public class InputMethodService extends AbstractInputMethodService { ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_HIDE_WINDOW); ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", mDumper, null /* icProto */); - setImeWindowStatus(0, mBackDisposition); + setImeWindowStatus(0 /* visibilityFlags */, mBackDisposition); if (android.view.inputmethod.Flags.refactorInsetsController()) { // The ImeInsetsSourceProvider need the statsToken when dispatching the control. We // send the token here, so that another request in the provider can be cancelled. @@ -4476,6 +4492,7 @@ public class InputMethodService extends AbstractInputMethodService { }; } + @ImeWindowVisibility private int mapToImeWindowStatus() { return IME_ACTIVE | (isInputViewShown() ? IME_VISIBLE : 0); diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 06e53ac8e7a2..133b3d1add49 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -267,10 +267,10 @@ public class DreamService extends Service implements Window.Callback { private boolean mDozing; private boolean mWindowless; private boolean mPreviewMode; - private volatile int mDozeScreenState = Display.STATE_UNKNOWN; - private volatile @Display.StateReason int mDozeScreenStateReason = Display.STATE_REASON_UNKNOWN; - private volatile int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; - private volatile float mDozeScreenBrightnessFloat = PowerManager.BRIGHTNESS_INVALID_FLOAT; + private int mDozeScreenState = Display.STATE_UNKNOWN; + private @Display.StateReason int mDozeScreenStateReason = Display.STATE_REASON_UNKNOWN; + private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; + private float mDozeScreenBrightnessFloat = PowerManager.BRIGHTNESS_INVALID_FLOAT; private boolean mDebug = false; @@ -913,13 +913,15 @@ public class DreamService extends Service implements Window.Callback { */ @UnsupportedAppUsage public void startDozing() { - if (mCanDoze && !mDozing) { - mDozing = true; - updateDoze(); + synchronized (this) { + if (mCanDoze && !mDozing) { + mDozing = true; + updateDoze(); + } } } - private void updateDoze() { + private synchronized void updateDoze() { if (mDreamToken == null) { Slog.w(mTag, "Updating doze without a dream token."); return; @@ -927,6 +929,9 @@ public class DreamService extends Service implements Window.Callback { if (mDozing) { try { + Slog.v(mTag, "UpdateDoze mDozeScreenState=" + mDozeScreenState + + " mDozeScreenBrightness=" + mDozeScreenBrightness + + " mDozeScreenBrightnessFloat=" + mDozeScreenBrightnessFloat); if (startAndStopDozingInBackground()) { mDreamManager.startDozingOneway( mDreamToken, mDozeScreenState, mDozeScreenStateReason, @@ -1048,10 +1053,12 @@ public class DreamService extends Service implements Window.Callback { */ @UnsupportedAppUsage public void setDozeScreenState(int state, @Display.StateReason int reason) { - if (mDozeScreenState != state) { - mDozeScreenState = state; - mDozeScreenStateReason = reason; - updateDoze(); + synchronized (this) { + if (mDozeScreenState != state) { + mDozeScreenState = state; + mDozeScreenStateReason = reason; + updateDoze(); + } } } @@ -1103,9 +1110,11 @@ public class DreamService extends Service implements Window.Callback { if (brightness != PowerManager.BRIGHTNESS_DEFAULT) { brightness = clampAbsoluteBrightness(brightness); } - if (mDozeScreenBrightness != brightness) { - mDozeScreenBrightness = brightness; - updateDoze(); + synchronized (this) { + if (mDozeScreenBrightness != brightness) { + mDozeScreenBrightness = brightness; + updateDoze(); + } } } @@ -1141,9 +1150,12 @@ public class DreamService extends Service implements Window.Callback { if (!Float.isNaN(brightness)) { brightness = clampAbsoluteBrightnessFloat(brightness); } - if (!BrightnessSynchronizer.floatEquals(mDozeScreenBrightnessFloat, brightness)) { - mDozeScreenBrightnessFloat = brightness; - updateDoze(); + + synchronized (this) { + if (!BrightnessSynchronizer.floatEquals(mDozeScreenBrightnessFloat, brightness)) { + mDozeScreenBrightnessFloat = brightness; + updateDoze(); + } } } diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 09306c791537..288be9c392e1 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.SystemProperties; import android.util.AttributeSet; import android.util.TypedValue; +import android.view.WindowInsets; import dalvik.system.CloseGuard; @@ -881,12 +882,13 @@ public abstract class Animation implements Cloneable { } /** - * @return if a window animation has outsets applied to it. + * @return the edges to which outsets should be applied if run as a windoow animation. * * @hide */ - public boolean hasExtension() { - return false; + @WindowInsets.Side.InsetsSide + public int getExtensionEdges() { + return 0x0; } /** diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java index 5aaa994f3f8f..bbdc9d0392ba 100644 --- a/core/java/android/view/animation/AnimationSet.java +++ b/core/java/android/view/animation/AnimationSet.java @@ -21,6 +21,7 @@ import android.content.res.TypedArray; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; +import android.view.WindowInsets; import java.util.ArrayList; import java.util.List; @@ -540,12 +541,12 @@ public class AnimationSet extends Animation { /** @hide */ @Override - public boolean hasExtension() { + @WindowInsets.Side.InsetsSide + public int getExtensionEdges() { + int edge = 0x0; for (Animation animation : mAnimations) { - if (animation.hasExtension()) { - return true; - } + edge |= animation.getExtensionEdges(); } - return false; + return edge; } } diff --git a/core/java/android/view/animation/ExtendAnimation.java b/core/java/android/view/animation/ExtendAnimation.java index 210eb8a1ca9d..1aeee07538f8 100644 --- a/core/java/android/view/animation/ExtendAnimation.java +++ b/core/java/android/view/animation/ExtendAnimation.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Insets; import android.util.AttributeSet; +import android.view.WindowInsets; /** * An animation that controls the outset of an object. @@ -151,9 +152,12 @@ public class ExtendAnimation extends Animation { /** @hide */ @Override - public boolean hasExtension() { - return mFromInsets.left < 0 || mFromInsets.top < 0 || mFromInsets.right < 0 - || mFromInsets.bottom < 0; + @WindowInsets.Side.InsetsSide + public int getExtensionEdges() { + return (mFromInsets.left < 0 || mToInsets.left < 0 ? WindowInsets.Side.LEFT : 0) + | (mFromInsets.right < 0 || mToInsets.right < 0 ? WindowInsets.Side.RIGHT : 0) + | (mFromInsets.top < 0 || mToInsets.top < 0 ? WindowInsets.Side.TOP : 0) + | (mFromInsets.bottom < 0 || mToInsets.bottom < 0 ? WindowInsets.Side.BOTTOM : 0); } @Override diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig index a6ae948604a5..adbc59867c0c 100644 --- a/core/java/android/window/flags/windowing_sdk.aconfig +++ b/core/java/android/window/flags/windowing_sdk.aconfig @@ -61,16 +61,6 @@ flag { flag { namespace: "windowing_sdk" - name: "fix_pip_restore_to_overlay" - description: "Restore exit-pip activity back to ActivityEmbedding overlay" - bug: "297887697" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { - namespace: "windowing_sdk" name: "activity_embedding_animation_customization_flag" description: "Whether the animation customization feature for AE is enabled" bug: "293658614" @@ -128,3 +118,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + namespace: "windowing_sdk" + name: "ae_back_stack_restore" + description: "Allow the ActivityEmbedding back stack to be restored after process restarted" + bug: "289875940" + is_fixed_read_only: true +} diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java index 921363c3e5af..b009c99dc9e3 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java @@ -20,6 +20,8 @@ import android.annotation.AnyThread; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; @@ -106,13 +108,10 @@ public final class InputMethodPrivilegedOperations { * * @param vis visibility flags * @param backDisposition disposition flags - * @see android.inputmethodservice.InputMethodService#IME_ACTIVE - * @see android.inputmethodservice.InputMethodService#IME_VISIBLE - * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT - * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_ADJUST_NOTHING */ @AnyThread - public void setImeWindowStatusAsync(int vis, int backDisposition) { + public void setImeWindowStatusAsync(@ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java index 69d1cb34005d..7bfb8003fd18 100644 --- a/core/java/com/android/internal/jank/Cuj.java +++ b/core/java/com/android/internal/jank/Cuj.java @@ -210,8 +210,16 @@ public class Cuj { */ public static final int CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE = 116; + /** + * Track interaction of exiting desktop mode on closing the last window. + * + * <p>Tracking starts when the last window is closed and finishes when the animation to exit + * desktop mode ends. + */ + public static final int CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE = 117; + // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE. - @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE; + @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE; /** @hide */ @IntDef({ @@ -319,7 +327,8 @@ public class Cuj { CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN, CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE, CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH, - CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE + CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE, + CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE }) @Retention(RetentionPolicy.SOURCE) public @interface CujType {} @@ -438,6 +447,7 @@ public class Cuj { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE; + CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE; } private Cuj() { @@ -666,6 +676,8 @@ public class Cuj { return "LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH"; case CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE: return "DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE"; + case CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE: + return "DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java index e0c90d83768c..cb20ceb5484b 100644 --- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java +++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java @@ -33,6 +33,7 @@ import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Gro import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.GROUP_ID; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.LEVEL; +import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.LOCATION; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE; import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.INTERNED_DATA; import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.PROTOLOG_MESSAGE; @@ -449,6 +450,8 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto case (int) GROUP_ID: os.write(GROUP_ID, pis.readInt(GROUP_ID)); break; + case (int) LOCATION: + os.write(LOCATION, pis.readInt(LOCATION)); default: throw new RuntimeException( "Unexpected field id " + pis.getFieldNumber()); diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java index 7240aff022d4..3adc6b20ecb1 100644 --- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -16,6 +16,8 @@ package com.android.internal.statusbar; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; @@ -30,7 +32,9 @@ public final class RegisterStatusBarResult implements Parcelable { public final int mDisabledFlags1; // switch[0] public final int mAppearance; // switch[1] public final AppearanceRegion[] mAppearanceRegions; // switch[2] + @ImeWindowVisibility public final int mImeWindowVis; // switch[3] + @BackDispositionMode public final int mImeBackDisposition; // switch[4] public final boolean mShowImeSwitcher; // switch[5] public final int mDisabledFlags2; // switch[6] @@ -42,10 +46,11 @@ public final class RegisterStatusBarResult implements Parcelable { public final LetterboxDetails[] mLetterboxDetails; public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1, - int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis, - int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, - boolean navbarColorManagedByIme, int behavior, int requestedVisibleTypes, - String packageName, int transientBarTypes, LetterboxDetails[] letterboxDetails) { + int appearance, AppearanceRegion[] appearanceRegions, + @ImeWindowVisibility int imeWindowVis, @BackDispositionMode int imeBackDisposition, + boolean showImeSwitcher, int disabledFlags2, boolean navbarColorManagedByIme, + int behavior, int requestedVisibleTypes, String packageName, int transientBarTypes, + LetterboxDetails[] letterboxDetails) { mIcons = new ArrayMap<>(icons); mDisabledFlags1 = disabledFlags1; mAppearance = appearance; diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 25e710784a8f..26d180cdcb1a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -695,12 +695,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen break; case TYPE_ACTIVITY_REPARENTED_TO_TASK: final IBinder candidateAssociatedActToken, lastOverlayToken; - if (Flags.fixPipRestoreToOverlay()) { - candidateAssociatedActToken = change.getOtherActivityToken(); - lastOverlayToken = change.getTaskFragmentToken(); - } else { - candidateAssociatedActToken = lastOverlayToken = null; - } + candidateAssociatedActToken = change.getOtherActivityToken(); + lastOverlayToken = change.getTaskFragmentToken(); onActivityReparentedToTask( wct, taskId, @@ -1023,10 +1019,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Nullable OverlayContainerRestoreParams getOverlayContainerRestoreParams( @Nullable IBinder associatedActivityToken, @Nullable IBinder overlayToken) { - if (!Flags.fixPipRestoreToOverlay()) { - return null; - } - if (associatedActivityToken == null || overlayToken == null) { return null; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java index d0e2c998e961..ee3e6f368505 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java @@ -36,7 +36,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; -import com.android.window.flags.Flags; import java.util.ArrayList; import java.util.Collections; @@ -257,7 +256,7 @@ class TaskFragmentContainer { mPendingAppearedIntent = pendingAppearedIntent; // Save the information necessary for restoring the overlay when needed. - if (Flags.fixPipRestoreToOverlay() && overlayTag != null && pendingAppearedIntent != null + if (overlayTag != null && pendingAppearedIntent != null && associatedActivity != null && !associatedActivity.isFinishing()) { final IBinder associatedActivityToken = associatedActivity.getActivityToken(); final OverlayContainerRestoreParams params = new OverlayContainerRestoreParams(mToken, diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java index 475475b05272..90eeb583d070 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java @@ -874,8 +874,6 @@ public class OverlayPresentationTest { @Test public void testOnActivityReparentedToTask_overlayRestoration() { - mSetFlagRule.enableFlags(Flags.FLAG_FIX_PIP_RESTORE_TO_OVERLAY); - // Prepares and mock the data necessary for the test. final IBinder activityToken = mActivity.getActivityToken(); final Intent intent = new Intent(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java index 8d30db64a3e5..53551387230c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java @@ -18,6 +18,7 @@ package com.android.wm.shell.activityembedding; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; +import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import android.annotation.CallSuper; import android.graphics.Point; @@ -146,6 +147,14 @@ class ActivityEmbeddingAnimationAdapter { /** To be overridden by subclasses to adjust the animation surface change. */ void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) { // Update the surface position and alpha. + if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() + && mAnimation.getExtensionEdges() != 0x0 + && !(mChange.hasFlags(FLAG_TRANSLUCENT) + && mChange.getActivityComponent() != null)) { + // Extend non-translucent activities + t.setEdgeExtensionEffect(mLeash, mAnimation.getExtensionEdges()); + } + mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y); t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix); t.setAlpha(mLeash, mTransformation.getAlpha()); @@ -165,7 +174,7 @@ class ActivityEmbeddingAnimationAdapter { if (!cropRect.intersect(mWholeAnimationBounds)) { // Hide the surface when it is outside of the animation area. t.setAlpha(mLeash, 0); - } else if (mAnimation.hasExtension()) { + } else if (mAnimation.getExtensionEdges() != 0) { // Allow the surface to be shown in its original bounds in case we want to use edge // extensions. cropRect.union(mContentBounds); @@ -180,6 +189,10 @@ class ActivityEmbeddingAnimationAdapter { @CallSuper void onAnimationEnd(@NonNull SurfaceControl.Transaction t) { onAnimationUpdate(t, mAnimation.getDuration()); + if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() + && mAnimation.getExtensionEdges() != 0x0) { + t.setEdgeExtensionEffect(mLeash, /* edge */ 0); + } } final long getDurationHint() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java index 5696a544152c..d2cef4baf798 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java @@ -144,8 +144,10 @@ class ActivityEmbeddingAnimationRunner { // ending states. prepareForJumpCut(info, startTransaction); } else { - addEdgeExtensionIfNeeded(startTransaction, finishTransaction, - postStartTransactionCallbacks, adapters); + if (!com.android.graphics.libgui.flags.Flags.edgeExtensionShader()) { + addEdgeExtensionIfNeeded(startTransaction, finishTransaction, + postStartTransactionCallbacks, adapters); + } addBackgroundColorIfNeeded(info, startTransaction, finishTransaction, adapters); for (ActivityEmbeddingAnimationAdapter adapter : adapters) { duration = Math.max(duration, adapter.getDurationHint()); @@ -341,7 +343,7 @@ class ActivityEmbeddingAnimationRunner { @NonNull List<ActivityEmbeddingAnimationAdapter> adapters) { for (ActivityEmbeddingAnimationAdapter adapter : adapters) { final Animation animation = adapter.mAnimation; - if (!animation.hasExtension()) { + if (animation.getExtensionEdges() == 0) { continue; } if (adapter.mChange.hasFlags(FLAG_TRANSLUCENT) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index 7275c6494140..12422874ca5d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -95,6 +95,7 @@ import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; /** * Controls the window animation run when a user initiates a back gesture. @@ -1209,7 +1210,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION - && !isGestureBackTransition(info)) { + && isNotGestureBackTransition(info)) { return false; } @@ -1364,7 +1365,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont // try to handle unexpected transition mergePendingTransitions(info); - if (!isGestureBackTransition(info) || shouldCancelAnimation(info) + if (isNotGestureBackTransition(info) || shouldCancelAnimation(info) || !mCloseTransitionRequested) { if (mPrepareOpenTransition != null) { applyFinishOpenTransition(); @@ -1395,8 +1396,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont // Cancel close animation if something happen unexpected, let another handler to handle private boolean shouldCancelAnimation(@NonNull TransitionInfo info) { - final boolean noCloseAllowed = - info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION; + final boolean noCloseAllowed = !mCloseTransitionRequested + && info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION; boolean unableToHandle = false; boolean filterTargets = false; for (int i = info.getChanges().size() - 1; i >= 0; --i) { @@ -1455,7 +1456,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION) { return false; } - + // Must have open target, must not have close target. + if (hasAnimationInMode(info, TransitionUtil::isClosingMode) + || !hasAnimationInMode(info, TransitionUtil::isOpeningMode)) { + return false; + } SurfaceControl openingLeash = null; if (mApps != null) { for (int i = mApps.length - 1; i >= 0; --i) { @@ -1482,17 +1487,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return true; } - private boolean isGestureBackTransition(@NonNull TransitionInfo info) { - for (int i = info.getChanges().size() - 1; i >= 0; --i) { - final TransitionInfo.Change c = info.getChanges().get(i); - if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) - && (TransitionUtil.isOpeningMode(c.getMode()) - || TransitionUtil.isClosingMode(c.getMode()))) { - return true; - } - } - return false; - } /** * Check whether this transition is triggered from back gesture commitment. * Reparent the transition targets to animation leashes, so the animation won't be broken. @@ -1501,10 +1495,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @NonNull SurfaceControl.Transaction st, @NonNull SurfaceControl.Transaction ft, @NonNull Transitions.TransitionFinishCallback finishCallback) { - if (info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION - || !mCloseTransitionRequested) { + if (!mCloseTransitionRequested) { return false; } + // must have close target + if (!hasAnimationInMode(info, TransitionUtil::isClosingMode)) { + return false; + } + if (mApps == null) { + // animation is done + applyAndFinish(st, ft, finishCallback); + return true; + } SurfaceControl openingLeash = null; SurfaceControl closingLeash = null; for (int i = mApps.length - 1; i >= 0; --i) { @@ -1522,6 +1524,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont final Point offset = c.getEndRelOffset(); st.setPosition(c.getLeash(), offset.x, offset.y); st.reparent(c.getLeash(), openingLeash); + st.setAlpha(c.getLeash(), 1.0f); } else if (TransitionUtil.isClosingMode(c.getMode())) { st.reparent(c.getLeash(), closingLeash); } @@ -1592,6 +1595,21 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } } + private static boolean isNotGestureBackTransition(@NonNull TransitionInfo info) { + return !hasAnimationInMode(info, TransitionUtil::isOpenOrCloseMode); + } + + private static boolean hasAnimationInMode(@NonNull TransitionInfo info, + Predicate<Integer> mode) { + for (int i = info.getChanges().size() - 1; i >= 0; --i) { + final TransitionInfo.Change c = info.getChanges().get(i); + if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) && mode.test(c.getMode())) { + return true; + } + } + return false; + } + private static ComponentName findComponentName(TransitionInfo.Change change) { final ComponentName componentName = change.getActivityComponent(); if (componentName != null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index efa1031bf814..f002d8904626 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -1601,6 +1601,11 @@ public class BubbleStackView extends FrameLayout getResources().getColor(android.R.color.system_neutral1_1000))); mManageMenuScrim.setBackgroundDrawable(new ColorDrawable( getResources().getColor(android.R.color.system_neutral1_1000))); + if (mShowingManage) { + // the manage menu location depends on the manage button location which may need a + // layout pass, so post this to the looper + post(() -> showManageMenu(true)); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt index 73aa7ceea68d..a6ed3b8cb50c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt @@ -22,6 +22,7 @@ import android.app.TaskInfo import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.content.Context import android.os.IBinder +import android.os.Trace import android.util.SparseArray import android.view.SurfaceControl import android.view.WindowManager @@ -51,6 +52,8 @@ import com.android.wm.shell.shared.TransitionUtil import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions +const val VISIBLE_TASKS_COUNTER_NAME = "DESKTOP_MODE_VISIBLE_TASKS" + /** * A [Transitions.TransitionObserver] that observes transitions and the proposed changes to log * appropriate desktop mode session log events. This observes transitions related to desktop mode @@ -292,8 +295,14 @@ class DesktopModeLoggerTransitionObserver( val previousTaskInfo = preTransitionVisibleFreeformTasks[taskId] when { // new tasks added - previousTaskInfo == null -> + previousTaskInfo == null -> { desktopModeEventLogger.logTaskAdded(sessionId, currentTaskUpdate) + Trace.setCounter( + Trace.TRACE_TAG_WINDOW_MANAGER, + VISIBLE_TASKS_COUNTER_NAME, + postTransitionVisibleFreeformTasks.size().toLong() + ) + } // old tasks that were resized or repositioned // TODO(b/347935387): Log changes only once they are stable. buildTaskUpdateForTask(previousTaskInfo) != currentTaskUpdate -> @@ -305,6 +314,11 @@ class DesktopModeLoggerTransitionObserver( preTransitionVisibleFreeformTasks.forEach { taskId, taskInfo -> if (!postTransitionVisibleFreeformTasks.containsKey(taskId)) { desktopModeEventLogger.logTaskRemoved(sessionId, buildTaskUpdateForTask(taskInfo)) + Trace.setCounter( + Trace.TRACE_TAG_WINDOW_MANAGER, + VISIBLE_TASKS_COUNTER_NAME, + postTransitionVisibleFreeformTasks.size().toLong() + ) } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 778478405dda..de6887a2173b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -502,15 +502,19 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { backgroundColorForTransition = getTransitionBackgroundColorIfSet(info, change, a, backgroundColorForTransition); - if (!isTask && a.hasExtension()) { - if (!TransitionUtil.isOpeningType(mode)) { - // Can screenshot now (before startTransaction is applied) - edgeExtendWindow(change, a, startTransaction, finishTransaction); + if (!isTask && a.getExtensionEdges() != 0x0) { + if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader()) { + finishTransaction.setEdgeExtensionEffect(change.getLeash(), /* edge */ 0); } else { - // Need to screenshot after startTransaction is applied otherwise activity - // may not be visible or ready yet. - postStartTransactionCallbacks - .add(t -> edgeExtendWindow(change, a, t, finishTransaction)); + if (!TransitionUtil.isOpeningType(mode)) { + // Can screenshot now (before startTransaction is applied) + edgeExtendWindow(change, a, startTransaction, finishTransaction); + } else { + // Need to screenshot after startTransaction is applied otherwise + // activity may not be visible or ready yet. + postStartTransactionCallbacks + .add(t -> edgeExtendWindow(change, a, t, finishTransaction)); + } } } @@ -558,7 +562,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { buildSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish, mTransactionPool, mMainExecutor, animRelOffset, cornerRadius, - clipRect); + clipRect, change.getActivityComponent() != null); final TransitionInfo.AnimationOptions options; if (Flags.moveAnimationOptionsToChange()) { @@ -823,7 +827,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { @NonNull Animation anim, @NonNull SurfaceControl leash, @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius, - @Nullable Rect clipRect) { + @Nullable Rect clipRect, boolean isActivity) { final SurfaceControl.Transaction transaction = pool.acquire(); final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); final Transformation transformation = new Transformation(); @@ -835,13 +839,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix, - position, cornerRadius, clipRect); + position, cornerRadius, clipRect, isActivity); }; va.addUpdateListener(updateListener); final Runnable finisher = () -> { applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix, - position, cornerRadius, clipRect); + position, cornerRadius, clipRect, isActivity); pool.release(transaction); mainExecutor.execute(() -> { @@ -931,7 +935,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { a.restrictDuration(MAX_ANIMATION_DURATION); a.scaleCurrentDuration(mTransitionAnimationScaleSetting); buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool, - mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds()); + mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(), + change.getActivityComponent() != null); } private void attachThumbnailAnimation(@NonNull ArrayList<Animator> animations, @@ -955,7 +960,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { a.restrictDuration(MAX_ANIMATION_DURATION); a.scaleCurrentDuration(mTransitionAnimationScaleSetting); buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool, - mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds()); + mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(), + change.getActivityComponent() != null); } private static int getWallpaperTransitType(TransitionInfo info) { @@ -1005,9 +1011,14 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private static void applyTransformation(long time, SurfaceControl.Transaction t, SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix, - Point position, float cornerRadius, @Nullable Rect immutableClipRect) { + Point position, float cornerRadius, @Nullable Rect immutableClipRect, + boolean isActivity) { tmpTransformation.clear(); anim.getTransformation(time, tmpTransformation); + if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() + && anim.getExtensionEdges() != 0x0 && isActivity) { + t.setEdgeExtensionEffect(leash, anim.getExtensionEdges()); + } if (position != null) { tmpTransformation.getMatrix().postTranslate(position.x, position.y); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index e196254628d0..195882553602 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -325,21 +325,21 @@ class ScreenRotationAnimation { @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) { buildSurfaceAnimation(animations, mRotateEnterAnimation, mSurfaceControl, finishCallback, mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */, - null /* clipRect */); + null /* clipRect */, false /* isActivity */); } private void startScreenshotRotationAnimation(@NonNull ArrayList<Animator> animations, @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) { buildSurfaceAnimation(animations, mRotateExitAnimation, mAnimLeash, finishCallback, mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */, - null /* clipRect */); + null /* clipRect */, false /* isActivity */); } private void buildScreenshotAlphaAnimation(@NonNull ArrayList<Animator> animations, @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) { buildSurfaceAnimation(animations, mRotateAlphaAnimation, mAnimLeash, finishCallback, mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */, - null /* clipRect */); + null /* clipRect */, false /* isActivity */); } private void startColorAnimation(float animationScale, @NonNull ShellExecutor animExecutor) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/OWNERS b/libs/WindowManager/Shell/tests/e2e/desktopmode/OWNERS index 73a5a23909c5..73a5a23909c5 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/OWNERS +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/OWNERS diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp new file mode 100644 index 000000000000..50581f7e01f3 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp @@ -0,0 +1,38 @@ +// +// Copyright (C) 2020 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: "WMShellFlickerTestsDesktopMode", + defaults: ["WMShellFlickerTestsDefault"], + manifest: "AndroidManifest.xml", + test_config_template: "AndroidTestTemplate.xml", + srcs: ["src/**/*.kt"], + static_libs: [ + "WMShellFlickerTestsBase", + "WMShellScenariosDesktopMode", + "WMShellTestUtils", + ], + data: ["trace_config/*"], +} diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml new file mode 100644 index 000000000000..1bbbefadaa03 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml @@ -0,0 +1,77 @@ +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.wm.shell.flicker"> + + <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> + <!-- Read and write traces from external storage --> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <!-- Allow the test to write directly to /sdcard/ --> + <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> + <!-- Write secure settings --> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> + <!-- Capture screen contents --> + <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> + <!-- Enable / Disable tracing !--> + <uses-permission android:name="android.permission.DUMP" /> + <!-- Run layers trace --> + <uses-permission android:name="android.permission.HARDWARE_TEST"/> + <!-- Capture screen recording --> + <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/> + <!-- Workaround grant runtime permission exception from b/152733071 --> + <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> + <uses-permission android:name="android.permission.READ_LOGS"/> + <!-- Force-stop test apps --> + <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/> + <!-- Control test app's media session --> + <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/> + <!-- ATM.removeRootTasksWithActivityTypes() --> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> + <!-- Enable bubble notification--> + <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> + + <!-- Allow the test to write directly to /sdcard/ and connect to trace processor --> + <application android:requestLegacyExternalStorage="true" + android:networkSecurityConfig="@xml/network_security_config" + android:largeHeap="true"> + <uses-library android:name="android.test.runner"/> + + <service android:name=".NotificationListener" + android:exported="true" + android:label="WMShellTestsNotificationListenerService" + android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> + <intent-filter> + <action android:name="android.service.notification.NotificationListenerService" /> + </intent-filter> + </service> + + <!-- (b/197936012) Remove startup provider due to test timeout issue --> + <provider + android:name="androidx.startup.InitializationProvider" + android:authorities="${applicationId}.androidx-startup" + tools:node="remove" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.wm.shell.flicker" + android:label="WindowManager Shell Flicker Tests"> + </instrumentation> +</manifest> diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidTestTemplate.xml index a66dfb4566f9..40dbbac32c7f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidTestTemplate.xml @@ -59,13 +59,6 @@ <option name="test-file-name" value="{MODULE}.apk"/> <option name="test-file-name" value="FlickerTestApp.apk"/> </target_preparer> - <!-- Enable mocking GPS location by the test app --> - <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> - <option name="run-command" - value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/> - <option name="teardown-command" - value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/> - </target_preparer> <!-- Needed for pushing the trace config file --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> @@ -97,7 +90,7 @@ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector"> <option name="pull-pattern-keys" value="perfetto_file_path"/> <option name="directory-keys" - value="/data/user/0/com.android.wm.shell.flicker.service/files"/> + value="/data/user/0/com.android.wm.shell.flicker/files"/> <option name="collect-on-run-ended-only" value="true"/> <option name="clean-up" value="true"/> </metrics_collector> diff --git a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/res/xml/network_security_config.xml index 4bd9ca049f55..4bd9ca049f55 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/res/xml/network_security_config.xml diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitLandscape.kt index 5563bb9fa934..b697d80fd500 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,9 +23,9 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP -import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP +import com.android.wm.shell.scenarios.CloseAllAppsWithAppHeaderExit import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitPortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitPortrait.kt index 3d16d2219c78..a11e876c5bce 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,9 +23,9 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP -import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP +import com.android.wm.shell.scenarios.CloseAllAppsWithAppHeaderExit import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt index 430f80b9a927..8584b599a96c 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.flicker.AssertionInvocationGroup import android.tools.flicker.assertors.assertions.AppLayerIsInvisibleAtEnd diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragLandscape.kt index 9dfafe958b0b..f7b25565271f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,8 +23,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP -import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP +import com.android.wm.shell.scenarios.EnterDesktopWithDrag import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragPortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragPortrait.kt index 1c7d6237eb8a..f4bf0f97b042 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,8 +23,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP -import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP +import com.android.wm.shell.scenarios.EnterDesktopWithDrag import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizeLandscape.kt index 6319cf74ed8f..45e5fdc28b0e 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizeLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,8 +23,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE +import com.android.wm.shell.scenarios.ResizeAppWithCornerResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizePortrait.kt index 431f6e3d3ea2..62a2571a2804 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizePortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.flicker.FlickerConfig import android.tools.flicker.annotation.ExpectedScenarios @@ -22,8 +22,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE +import com.android.wm.shell.scenarios.ResizeAppWithCornerResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizeLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizeLandscape.kt index 8d1a53021683..ea8b10b28855 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizeLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizeLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,8 +23,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE +import com.android.wm.shell.scenarios.ResizeAppWithCornerResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizePortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizePortrait.kt index 2d81c8c44799..d7bba6ec49d2 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizePortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizePortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,8 +23,8 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE +import com.android.wm.shell.scenarios.ResizeAppWithCornerResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/trace_config/trace_config.textproto index 9f2e49755fec..9f2e49755fec 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/trace_config/trace_config.textproto diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp new file mode 100644 index 000000000000..4389f09b0e5d --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp @@ -0,0 +1,46 @@ +// +// Copyright (C) 2020 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"], +} + +java_library { + name: "WMShellScenariosDesktopMode", + platform_apis: true, + optimize: { + enabled: false, + }, + srcs: ["src/**/*.kt"], + static_libs: [ + "WMShellFlickerTestsBase", + "WMShellTestUtils", + "wm-shell-flicker-utils", + "androidx.test.ext.junit", + "flickertestapplib", + "flickerlib-helpers", + "flickerlib-trace_processor_shell", + "platform-test-annotations", + "wm-flicker-common-app-helpers", + "launcher-helper-lib", + "launcher-aosp-tapl", + ], +} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/CloseAllAppsWithAppHeaderExit.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithAppHeaderExit.kt index e77a45729124..e9056f3c44d4 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/CloseAllAppsWithAppHeaderExit.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithAppHeaderExit.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -28,16 +29,18 @@ import com.android.server.wm.flicker.helpers.MailAppHelper import com.android.server.wm.flicker.helpers.NonResizeableAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner -@Ignore("Base Test Class") -abstract class CloseAllAppsWithAppHeaderExit +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class CloseAllAppsWithAppHeaderExit @JvmOverloads constructor(val rotation: Rotation = Rotation.ROTATION_0) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindow.kt index bbf0ce5f8165..ca1dc1a7f658 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindow.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.ImeAppHelper import com.android.server.wm.flicker.helpers.MailAppHelper @@ -25,12 +26,13 @@ import com.android.window.flags.Flags import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner -/** Base scenario test for window drag CUJ with multiple windows. */ -@Ignore("Base Test Class") -abstract class DragAppWindowMultiWindow : DragAppWindowScenarioTestBase() +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class DragAppWindowMultiWindow : DragAppWindowScenarioTestBase() { private val imeAppHelper = ImeAppHelper(instrumentation) private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation)) diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowScenarioTestBase.kt index a613ca1660ea..7219287d97d3 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowScenarioTestBase.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -24,7 +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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.Ignore import org.junit.Rule import org.junit.Test diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowSingleWindow.kt index 0655620d58b7..91cfd17340fc 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowSingleWindow.kt @@ -14,20 +14,21 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Test - -/** Base scenario test for window drag CUJ with single window. */ -@Ignore("Base Test Class") -abstract class DragAppWindowSingleWindow : DragAppWindowScenarioTestBase() +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class DragAppWindowSingleWindow : DragAppWindowScenarioTestBase() { private val simpleAppHelper = SimpleAppHelper(instrumentation) private val testApp = DesktopModeAppHelper(simpleAppHelper) diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithAppHandleMenu.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithAppHandleMenu.kt index 47a215a97c00..107305044d55 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithAppHandleMenu.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithAppHandleMenu.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.traces.parsers.WindowManagerStateHelper import androidx.test.platform.app.InstrumentationRegistry @@ -27,12 +28,12 @@ import com.android.window.flags.Flags import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Test - -/** Base test class for enter desktop with app handle menu CUJ. */ -@Ignore("Base Test Class") -abstract class EnterDesktopWithAppHandleMenu { +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class EnterDesktopWithAppHandleMenu { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val tapl = LauncherInstrumentation() diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithDrag.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt index fe139d2d24a0..0f0d2df4337c 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithDrag.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -26,17 +27,18 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner - -@Ignore("Base Test Class") -abstract class EnterDesktopWithDrag +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class EnterDesktopWithDrag @JvmOverloads constructor(val rotation: Rotation = Rotation.ROTATION_0) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ExitDesktopWithDragToTopDragZone.kt index 0b6c9af17e7a..533be8895fb9 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ExitDesktopWithDragToTopDragZone.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -26,17 +27,18 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner - -@Ignore("Base Test Class") -abstract class ExitDesktopWithDragToTopDragZone +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class ExitDesktopWithDragToTopDragZone @JvmOverloads constructor(val rotation: Rotation = Rotation.ROTATION_0) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindow.kt index 20e2167c28f2..e3660fe13bc2 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindow.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -26,17 +27,17 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test - -/** Base scenario test for maximize app window CUJ in desktop mode. */ -@Ignore("Base Test Class") -abstract class MaximizeAppWindow +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class MaximizeAppWindow { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val tapl = LauncherInstrumentation() diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MinimizeWindowOnAppOpen.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MinimizeWindowOnAppOpen.kt index c8477102a7ad..b86765e23422 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MinimizeWindowOnAppOpen.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MinimizeWindowOnAppOpen.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.traces.parsers.WindowManagerStateHelper import androidx.test.platform.app.InstrumentationRegistry @@ -31,16 +32,17 @@ import com.android.window.flags.Flags import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Test - +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner /** * Base scenario test for minimizing the least recently used window when a new window is opened * above the window limit. For tangor devices, which this test currently runs on, the window limit * is 4. */ -@Ignore("Base Test Class") -abstract class MinimizeWindowOnAppOpen() +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class MinimizeWindowOnAppOpen() { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val tapl = LauncherInstrumentation() diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithCornerResize.kt index 136cf378aa09..63e7387f7a8a 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithCornerResize.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -26,17 +27,18 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner - -@Ignore("Base Test Class") -abstract class ResizeAppWithCornerResize +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class ResizeAppWithCornerResize @JvmOverloads constructor(val rotation: Rotation = Rotation.ROTATION_0, val horizontalChange: Int = 50, diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/SwitchToOverviewFromDesktop.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/SwitchToOverviewFromDesktop.kt index b4cadf4f300b..53e36e23fd95 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/SwitchToOverviewFromDesktop.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/SwitchToOverviewFromDesktop.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.scenarios +package com.android.wm.shell.scenarios +import android.platform.test.annotations.Postsubmit import android.app.Instrumentation import android.tools.NavBar import android.tools.Rotation @@ -26,21 +27,23 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.helpers.DesktopModeAppHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.window.flags.Flags -import com.android.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner /** * Base test for opening recent apps overview from desktop mode. * * Navigation mode can be passed as a constructor parameter, by default it is set to gesture navigation. */ -@Ignore("Base Test Class") -abstract class SwitchToOverviewFromDesktop +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +open class SwitchToOverviewFromDesktop @JvmOverloads constructor(val navigationMode: NavBar = NavBar.MODE_GESTURAL) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/e2e/splitscreen/OWNERS index 3ab6a1ee061d..3ab6a1ee061d 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/OWNERS diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp index 35b2f56bca92..35b2f56bca92 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidManifest.xml index 9ff2161daa51..9ff2161daa51 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidManifest.xml diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml index 85715db3d952..85715db3d952 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/OWNERS index 3ab6a1ee061d..3ab6a1ee061d 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/OWNERS diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/res/xml/network_security_config.xml index 4bd9ca049f55..4bd9ca049f55 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/res/xml/network_security_config.xml diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt index 7f48499b0558..7f48499b0558 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt index dd45f654d3bc..dd45f654d3bc 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt index 6d396ea6e9d4..6d396ea6e9d4 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt index 2ed916e56c67..2ed916e56c67 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt index 1a455311b3b6..1a455311b3b6 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt index 0cb1e4006c0d..0cb1e4006c0d 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt index ff406b75b235..ff406b75b235 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt index 2b817988a589..2b817988a589 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt index 186af54fb57b..186af54fb57b 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt index dad5db94d062..a9dba4a3178b 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt @@ -17,11 +17,13 @@ package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Presubmit +import android.tools.NavBar import android.tools.Rotation +import android.tools.ScenarioBuilder 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.SERVICE_TRACE_CONFIG import android.tools.traces.component.ComponentNameMatcher import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.splitscreen.benchmark.MultipleShowImeRequestsInSplitScreenBenchmark @@ -35,7 +37,7 @@ import org.junit.runners.Parameterized /** * Test quick switch between two split pairs. * - * To run this test: `atest WMShellFlickerTestsSplitScreenGroup2:MultipleShowImeRequestsInSplitScreen` + * To run this test: `atest WMShellFlickerTestsSplitScreenGroupOther:MultipleShowImeRequestsInSplitScreen` */ @RequiresDevice @RunWith(Parameterized::class) @@ -58,10 +60,22 @@ class MultipleShowImeRequestsInSplitScreen(override val flicker: LegacyFlickerTe } companion object { + private fun createFlickerTest( + navBarMode: NavBar + ) = LegacyFlickerTest(ScenarioBuilder() + .withStartRotation(Rotation.ROTATION_0) + .withEndRotation(Rotation.ROTATION_0) + .withNavBarMode(navBarMode), resultReaderProvider = { scenario -> + android.tools.flicker.datastore.CachedResultReader( + scenario, SERVICE_TRACE_CONFIG + ) + }) + @Parameterized.Parameters(name = "{0}") @JvmStatic - fun getParams() = LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) + fun getParams() = listOf( + createFlickerTest(NavBar.MODE_GESTURAL), + createFlickerTest(NavBar.MODE_3BUTTON) ) } -} +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt index 9dde49011ed0..9dde49011ed0 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt index 5222b08240c6..5222b08240c6 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt index a8a8ae88a9e7..a8a8ae88a9e7 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt index 836f664ca544..836f664ca544 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt index 3c4a1caecb8d..3c4a1caecb8d 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt index a72b3d15eb9e..a72b3d15eb9e 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt index d34998815fca..3018b56b13b2 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt @@ -16,7 +16,6 @@ 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.junit.FlickerParametersRunnerFactory diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt index 7e8e50843b90..7e8e50843b90 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt index c99fcc4129d5..c99fcc4129d5 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt index ef3a87955bd6..ef3a87955bd6 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt index 18550d7f0467..18550d7f0467 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt index d16c5d77410c..d16c5d77410c 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt index f8be6be08782..f8be6be08782 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt index a99ef64e7bf5..a99ef64e7bf5 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt index f58400966531..f58400966531 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt index 7084f6aec1fb..7084f6aec1fb 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt index 249253185607..249253185607 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt index 51074f634e30..51074f634e30 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt index 6a6aa1abc9f3..6a6aa1abc9f3 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt index 3a2316f7a10c..3a2316f7a10c 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt index ded0b0729998..ded0b0729998 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt index 7b1397baa7a3..7b1397baa7a3 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt index 457288f445df..457288f445df 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt index 7493538fa2ba..7493538fa2ba 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/trace_config/trace_config.textproto index 67316d2d7c0f..67316d2d7c0f 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/trace_config/trace_config.textproto diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp new file mode 100644 index 000000000000..dd0018aae058 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp @@ -0,0 +1,41 @@ +// +// Copyright (C) 2020 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: "WMShellFlickerServiceTests", + defaults: ["WMShellFlickerTestsDefault"], + manifest: "AndroidManifest.xml", + test_config_template: "AndroidTestTemplate.xml", + srcs: ["src/**/*.kt"], + static_libs: [ + "WMShellFlickerTestsBase", + "WMShellScenariosSplitScreen", + "WMShellTestUtils", + ], + data: [ + ":FlickerTestApp", + "trace_config/*", + ], +} diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidManifest.xml index d54b6941d975..662e7f346cb3 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidManifest.xml @@ -16,7 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" - package="com.android.wm.shell.flicker.service"> + package="com.android.wm.shell"> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> <!-- Read and write traces from external storage --> @@ -71,7 +71,7 @@ </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.wm.shell.flicker.service" + android:targetPackage="com.android.wm.shell" android:label="WindowManager Flicker Service Tests"> </instrumentation> </manifest> diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml new file mode 100644 index 000000000000..6c903a2e8c42 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<configuration description="WMShell Platinum Tests {MODULE}"> + <option name="test-tag" value="FlickerTests"/> + <!-- Needed for storing the perfetto trace files in the sdcard/test_results--> + <option name="isolated-storage" value="false"/> + + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <!-- disable DeprecatedTargetSdk warning --> + <option name="run-command" value="setprop debug.wm.disable_deprecated_target_sdk_dialog 1"/> + <!-- keeps the screen on during tests --> + <option name="screen-always-on" value="on"/> + <!-- prevents the phone from restarting --> + <option name="force-skip-system-props" value="true"/> + <!-- set WM tracing verbose level to all --> + <option name="run-command" value="cmd window tracing level all"/> + <!-- set WM tracing to frame (avoid incomplete states) --> + <option name="run-command" value="cmd window tracing frame"/> + <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests --> + <option name="run-command" value="pm disable com.google.android.internal.betterbug"/> + <!-- ensure lock screen mode is swipe --> + <option name="run-command" value="locksettings set-disabled false"/> + <!-- restart launcher to activate TAPL --> + <option name="run-command" + value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/> + <!-- Increase trace size: 20mb for WM and 80mb for SF --> + <option name="run-command" value="cmd window tracing size 20480"/> + <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="test-user-token" value="%TEST_USER%"/> + <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/> + <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/> + <option name="run-command" value="settings put system show_touches 1"/> + <option name="run-command" value="settings put system pointer_location 1"/> + <option name="teardown-command" + value="settings delete secure show_ime_with_hard_keyboard"/> + <option name="teardown-command" value="settings delete system show_touches"/> + <option name="teardown-command" value="settings delete system pointer_location"/> + <option name="teardown-command" + value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true"/> + <option name="test-file-name" value="{MODULE}.apk"/> + <option name="test-file-name" value="FlickerTestApp.apk"/> + </target_preparer> + <!-- Needed for pushing the trace config file --> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="{PACKAGE}"/> + <option name="shell-timeout" value="6600s"/> + <option name="test-timeout" value="6000s"/> + <option name="hidden-api-checks" value="false"/> + <option name="device-listeners" value="android.tools.collectors.DefaultUITraceListener"/> + <!-- DefaultUITraceListener args --> + <option name="instrumentation-arg" key="per_run" value="true"/> + <option name="instrumentation-arg" key="perfetto_persist_pid_track" value="true"/> + </test> + <!-- Needed for pulling the collected trace config on to the host --> + <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector"> + <option name="pull-pattern-keys" value="perfetto_file_path"/> + <option name="directory-keys" + value="/data/user/0/com.android.wm.shell/files"/> + <option name="collect-on-run-ended-only" value="true"/> + <option name="clean-up" value="true"/> + </metrics_collector> +</configuration> diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/res/xml/network_security_config.xml new file mode 100644 index 000000000000..4bd9ca049f55 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/res/xml/network_security_config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config> diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavLandscape.kt index 1684a26ac3d2..3cb9cf24d522 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit +import com.android.wm.shell.scenarios.CopyContentInSplit import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavPortrait.kt index 3b5fad60d8ee..b27a8aedb5c1 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit +import com.android.wm.shell.scenarios.CopyContentInSplit import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt index 2b8a90305d90..9388114889c0 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider +import com.android.wm.shell.scenarios.DismissSplitScreenByDivider import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt index b284fe1caad5..30ef4927bfa0 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider +import com.android.wm.shell.scenarios.DismissSplitScreenByDivider import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt index a400ee44caa5..059f967fbb51 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome +import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt index 7f5ee4c2cdda..0c6d546cf8e5 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome +import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavLandscape.kt index 1b075c498bc0..14fb72bc349a 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize +import com.android.wm.shell.scenarios.DragDividerToResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavPortrait.kt index 6ca373714f8a..9be61a59f101 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize +import com.android.wm.shell.scenarios.DragDividerToResize import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt index f7d231f02935..c12d1990d3ed 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt index ab819fad292a..11cd38ad72a4 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt index a6b732c47ea2..66d4bfa977c4 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt index 07e5f4b0b472..f3a11eb96101 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt index 272569456d7b..327ecc34a01e 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt index 58cc4d70fde4..dd5a3950537c 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt index 85897a136e33..8e7cf309c911 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt index 891b6df89b45..0324dac44b3a 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt index 798365218b04..2fa141eb9a91 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview +import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt index 1bdea66fc596..01769138ddff 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview +import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt index bab0c0aa1e6a..1db28dcc4f09 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider +import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt index 17a59ab8a173..c69167bcf67f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider +import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt index 2c36d647b719..602283a136b3 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp +import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt index 6e91d047e64b..7cc14e091540 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp +import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt index a921b4663d09..daf6547673af 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome +import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt index 05f8912f6f47..b0f5e6564b97 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome +import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt index 1ae1f53b9bc1..88fa783a679d 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent +import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt index e14ca550c84d..aa36f44fd499 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent +import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt index ce0c4c456587..292f413e0037 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs +import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt index 5a8d2d51bec4..865958fe82b4 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.Rotation import android.tools.flicker.FlickerConfig @@ -23,7 +23,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs +import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt index d44261549544..6c36e8476cc3 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.flicker.FlickerConfig import android.tools.flicker.annotation.ExpectedScenarios @@ -22,7 +22,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen +import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt index ddc8a0697beb..61ccd36dd106 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker import android.tools.flicker.FlickerConfig import android.tools.flicker.annotation.ExpectedScenarios @@ -22,7 +22,7 @@ import android.tools.flicker.annotation.FlickerConfigProvider import android.tools.flicker.config.FlickerConfig import android.tools.flicker.config.FlickerServiceConfig import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen +import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/Android.bp index a5bc26152d16..90210b1262c7 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/Android.bp @@ -26,9 +26,7 @@ package { filegroup { name: "WMShellFlickerServicePlatinumTests-src", srcs: [ - "src/**/platinum/*.kt", - "src/**/scenarios/*.kt", - "src/**/common/*.kt", + "src/**/*.kt", ], } @@ -43,33 +41,42 @@ java_library { ], static_libs: [ "wm-shell-flicker-utils", + "WMShellScenariosSplitScreen", ], } android_test { - name: "WMShellFlickerServiceTests", - defaults: ["WMShellFlickerTestsDefault"], - manifest: "AndroidManifest.xml", - package_name: "com.android.wm.shell.flicker.service", - instrumentation_target_package: "com.android.wm.shell.flicker.service", - test_config_template: "AndroidTestTemplate.xml", - srcs: ["src/**/*.kt"], - static_libs: ["WMShellFlickerTestsBase"], - data: ["trace_config/*"], -} - -android_test { name: "WMShellFlickerServicePlatinumTests", - defaults: ["WMShellFlickerTestsDefault"], + platform_apis: true, + certificate: "platform", + optimize: { + enabled: false, + }, manifest: "AndroidManifest.xml", - package_name: "com.android.wm.shell.flicker.service", - instrumentation_target_package: "com.android.wm.shell.flicker.service", test_config_template: "AndroidTestTemplate.xml", test_suites: [ "device-tests", "device-platinum-tests", ], srcs: [":WMShellFlickerServicePlatinumTests-src"], - static_libs: ["WMShellFlickerTestsBase"], - data: ["trace_config/*"], + static_libs: [ + "WMShellFlickerTestsBase", + "WMShellScenariosSplitScreen", + "WMShellTestUtils", + "ui-trace-collector", + "collector-device-lib", + "wm-shell-flicker-utils", + "androidx.test.ext.junit", + "flickertestapplib", + "flickerlib-helpers", + "flickerlib-trace_processor_shell", + "platform-test-annotations", + "wm-flicker-common-app-helpers", + "launcher-helper-lib", + "launcher-aosp-tapl", + ], + data: [ + ":FlickerTestApp", + "trace_config/*", + ], } diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml new file mode 100644 index 000000000000..662e7f346cb3 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml @@ -0,0 +1,77 @@ +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.wm.shell"> + + <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> + <!-- Read and write traces from external storage --> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <!-- Allow the test to write directly to /sdcard/ --> + <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> + <!-- Write secure settings --> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> + <!-- Capture screen contents --> + <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> + <!-- Enable / Disable tracing !--> + <uses-permission android:name="android.permission.DUMP" /> + <!-- Run layers trace --> + <uses-permission android:name="android.permission.HARDWARE_TEST"/> + <!-- Capture screen recording --> + <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/> + <!-- Workaround grant runtime permission exception from b/152733071 --> + <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> + <uses-permission android:name="android.permission.READ_LOGS"/> + <!-- Force-stop test apps --> + <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/> + <!-- Control test app's media session --> + <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/> + <!-- ATM.removeRootTasksWithActivityTypes() --> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> + <!-- Enable bubble notification--> + <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> + + <!-- Allow the test to write directly to /sdcard/ and connect to trace processor --> + <application android:requestLegacyExternalStorage="true" + android:networkSecurityConfig="@xml/network_security_config" + android:largeHeap="true"> + <uses-library android:name="android.test.runner"/> + + <service android:name=".NotificationListener" + android:exported="true" + android:label="WMShellTestsNotificationListenerService" + android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> + <intent-filter> + <action android:name="android.service.notification.NotificationListenerService" /> + </intent-filter> + </service> + + <!-- (b/197936012) Remove startup provider due to test timeout issue --> + <provider + android:name="androidx.startup.InitializationProvider" + android:authorities="${applicationId}.androidx-startup" + tools:node="remove" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.wm.shell" + android:label="WindowManager Flicker Service Tests"> + </instrumentation> +</manifest> diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml new file mode 100644 index 000000000000..6c903a2e8c42 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<configuration description="WMShell Platinum Tests {MODULE}"> + <option name="test-tag" value="FlickerTests"/> + <!-- Needed for storing the perfetto trace files in the sdcard/test_results--> + <option name="isolated-storage" value="false"/> + + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <!-- disable DeprecatedTargetSdk warning --> + <option name="run-command" value="setprop debug.wm.disable_deprecated_target_sdk_dialog 1"/> + <!-- keeps the screen on during tests --> + <option name="screen-always-on" value="on"/> + <!-- prevents the phone from restarting --> + <option name="force-skip-system-props" value="true"/> + <!-- set WM tracing verbose level to all --> + <option name="run-command" value="cmd window tracing level all"/> + <!-- set WM tracing to frame (avoid incomplete states) --> + <option name="run-command" value="cmd window tracing frame"/> + <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests --> + <option name="run-command" value="pm disable com.google.android.internal.betterbug"/> + <!-- ensure lock screen mode is swipe --> + <option name="run-command" value="locksettings set-disabled false"/> + <!-- restart launcher to activate TAPL --> + <option name="run-command" + value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/> + <!-- Increase trace size: 20mb for WM and 80mb for SF --> + <option name="run-command" value="cmd window tracing size 20480"/> + <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="test-user-token" value="%TEST_USER%"/> + <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/> + <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/> + <option name="run-command" value="settings put system show_touches 1"/> + <option name="run-command" value="settings put system pointer_location 1"/> + <option name="teardown-command" + value="settings delete secure show_ime_with_hard_keyboard"/> + <option name="teardown-command" value="settings delete system show_touches"/> + <option name="teardown-command" value="settings delete system pointer_location"/> + <option name="teardown-command" + value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true"/> + <option name="test-file-name" value="{MODULE}.apk"/> + <option name="test-file-name" value="FlickerTestApp.apk"/> + </target_preparer> + <!-- Needed for pushing the trace config file --> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="{PACKAGE}"/> + <option name="shell-timeout" value="6600s"/> + <option name="test-timeout" value="6000s"/> + <option name="hidden-api-checks" value="false"/> + <option name="device-listeners" value="android.tools.collectors.DefaultUITraceListener"/> + <!-- DefaultUITraceListener args --> + <option name="instrumentation-arg" key="per_run" value="true"/> + <option name="instrumentation-arg" key="perfetto_persist_pid_track" value="true"/> + </test> + <!-- Needed for pulling the collected trace config on to the host --> + <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector"> + <option name="pull-pattern-keys" value="perfetto_file_path"/> + <option name="directory-keys" + value="/data/user/0/com.android.wm.shell/files"/> + <option name="collect-on-run-ended-only" value="true"/> + <option name="clean-up" value="true"/> + </metrics_collector> +</configuration> diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/res/xml/network_security_config.xml new file mode 100644 index 000000000000..4bd9ca049f55 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/res/xml/network_security_config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config> diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavLandscape.kt index 64293b288a2e..4c2ca6763fc2 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit +import com.android.wm.shell.scenarios.CopyContentInSplit import org.junit.Test open class CopyContentInSplitGesturalNavLandscape : CopyContentInSplit(Rotation.ROTATION_90) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavPortrait.kt index 517ba2dfc164..0cca31002722 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit +import com.android.wm.shell.scenarios.CopyContentInSplit import org.junit.Test open class CopyContentInSplitGesturalNavPortrait : CopyContentInSplit(Rotation.ROTATION_0) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavLandscape.kt index 1bafe3b0898c..7aa62cf906e4 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider +import com.android.wm.shell.scenarios.DismissSplitScreenByDivider import org.junit.Test open class DismissSplitScreenByDividerGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavPortrait.kt index fd0100fd6c21..de11fc6774a2 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider +import com.android.wm.shell.scenarios.DismissSplitScreenByDivider import org.junit.Test open class DismissSplitScreenByDividerGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavLandscape.kt index 850b3d8f9867..daa6aac30285 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome +import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome import org.junit.Test open class DismissSplitScreenByGoHomeGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavPortrait.kt index 0b752bf7f58e..ff57d0057039 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome +import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome import org.junit.Test open class DismissSplitScreenByGoHomeGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavLandscape.kt index 3c52aa71eb9d..0ac19c8d8452 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize +import com.android.wm.shell.scenarios.DragDividerToResize import org.junit.Test open class DragDividerToResizeGesturalNavLandscape : DragDividerToResize(Rotation.ROTATION_90) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavPortrait.kt index c2e21b89a480..5713602e7136 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize +import com.android.wm.shell.scenarios.DragDividerToResize import org.junit.Test open class DragDividerToResizeGesturalNavPortrait : DragDividerToResize(Rotation.ROTATION_0) { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt index bf85ab44df5e..d7333f1a4eda 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test open class EnterSplitScreenByDragFromAllAppsGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt index 0ac4ca20e303..e29a140e4bdf 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test open class EnterSplitScreenByDragFromAllAppsGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt index 80bd088a192f..9ccccb1da273 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test open class EnterSplitScreenByDragFromNotificationGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt index 0dffb4af8d41..87a4d0847b96 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test open class EnterSplitScreenByDragFromNotificationGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt index b721f2fe294a..559652c1e8a5 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test open class EnterSplitScreenByDragFromShortcutGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt index 22cbc77d024b..bcb8e0c698af 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test open class EnterSplitScreenByDragFromShortcutGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt index ac0f9e25285d..39e0fede7fae 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test open class EnterSplitScreenByDragFromTaskbarGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt index f7a229d5ff16..643162926f79 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar +import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test open class EnterSplitScreenByDragFromTaskbarGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavLandscape.kt index 6dbbcb0fcfb5..2093424ea1de 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview +import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview import org.junit.Test open class EnterSplitScreenFromOverviewGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavPortrait.kt index bd69ea98a67b..f89259d496b2 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview +import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview import org.junit.Test open class EnterSplitScreenFromOverviewGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt index 404b96fafd24..e5aff0c0800f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider +import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test open class SwitchAppByDoubleTapDividerGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt index a79687ddf68f..defade909913 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider +import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test open class SwitchAppByDoubleTapDividerGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt index b52eb4cd6533..e28deca37b24 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp +import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test open class SwitchBackToSplitFromAnotherAppGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt index d79620c73132..99fb06c20a0b 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp +import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test open class SwitchBackToSplitFromAnotherAppGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavLandscape.kt index d27bfa1a22c9..7045e660b8b8 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome +import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome import org.junit.Test open class SwitchBackToSplitFromHomeGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavPortrait.kt index 3c7d4d4806cf..b2da052c6209 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome +import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome import org.junit.Test open class SwitchBackToSplitFromHomeGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavLandscape.kt index 26a2034f16d9..04d7f62ecf53 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent +import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent import org.junit.Test open class SwitchBackToSplitFromRecentGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavPortrait.kt index 5154b35ed0e6..bc36fb748226 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent +import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent import org.junit.Test open class SwitchBackToSplitFromRecentGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavLandscape.kt index 86451c524ee6..ceda4da6a94f 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavLandscape.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs +import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs import org.junit.Test open class SwitchBetweenSplitPairsGesturalNavLandscape : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavPortrait.kt index baf72b40d6d4..365c5cc34d11 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavPortrait.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.Rotation -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs +import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs import org.junit.Test open class SwitchBetweenSplitPairsGesturalNavPortrait : diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt index 9caab9b5182a..a8662979407e 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen +import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.BlockJUnit4ClassRunner diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt index bf484e5cef98..6d59001374e9 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.platinum +package com.android.wm.shell import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen +import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.BlockJUnit4ClassRunner diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp new file mode 100644 index 000000000000..60c7de7b3931 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp @@ -0,0 +1,47 @@ +// +// Copyright (C) 2020 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"], +} + +java_library { + name: "WMShellScenariosSplitScreen", + platform_apis: true, + optimize: { + enabled: false, + }, + srcs: ["src/**/*.kt"], + static_libs: [ + "WMShellFlickerTestsBase", + "WMShellTestUtils", + "wm-shell-flicker-utils", + "androidx.test.ext.junit", + "flickertestapplib", + "flickerlib-helpers", + "flickerlib-trace_processor_shell", + "platform-test-annotations", + "wm-flicker-common-app-helpers", + "wm-flicker-common-assertions", + "launcher-helper-lib", + "launcher-aosp-tapl", + ], +} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/CopyContentInSplit.kt index 61710742abb4..ba4654260864 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/CopyContentInSplit.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByDivider.kt index c1a8ee714abd..d774a31220da 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByDivider.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByGoHome.kt index 600855a8ab38..5aa161911a9a 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByGoHome.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DragDividerToResize.kt index b5a6d83afd05..668f3678bb38 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DragDividerToResize.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromAllApps.kt index a189325d52ea..06c7b9bc384d 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromAllApps.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -24,7 +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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Assume 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/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromNotification.kt index bcd0f126daef..96b22bf86742 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromNotification.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -25,7 +25,7 @@ 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.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Assume diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromShortcut.kt index 3f07be083041..9e05b630d840 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromShortcut.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -24,7 +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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Assume diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromTaskbar.kt index 532801357d60..90900557e582 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromTaskbar.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Assume diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenFromOverview.kt index be4035d6af7f..d5cc92e5d268 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenFromOverview.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before 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/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt index 2406bdeebdf2..26203d4afccd 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.graphics.Point @@ -25,7 +25,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromAnotherApp.kt index de26982501a3..2ccffa85b5c1 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromAnotherApp.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromHome.kt index 873b0199f0e8..8673c464ad19 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromHome.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromRecent.kt index 15934d0f3944..c7cbc3e44553 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromRecent.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBetweenSplitPairs.kt index 79e69ae084f4..4ded148f6113 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBetweenSplitPairs.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/UnlockKeyguardToSplitScreen.kt index 0f932d46d3d3..7b062fcc6b5a 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/UnlockKeyguardToSplitScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.scenarios +package com.android.wm.shell.scenarios import android.app.Instrumentation import android.tools.NavBar @@ -23,7 +23,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.wm.shell.flicker.service.common.Utils +import com.android.wm.shell.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/e2e/utils/Android.bp b/libs/WindowManager/Shell/tests/e2e/utils/Android.bp new file mode 100644 index 000000000000..51d9c401dfba --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/utils/Android.bp @@ -0,0 +1,31 @@ +// +// Copyright (C) 2020 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_team: "trendy_team_windowing_tools", + default_applicable_licenses: ["frameworks_base_license"], +} + +java_library { + name: "WMShellTestUtils", + srcs: ["src/**/*.kt"], + static_libs: ["WMShellFlickerTestsBase"], +} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/Utils.kt index 4c6c6cce0105..dee67f3f2e0e 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt +++ b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/Utils.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.common +package com.android.wm.shell import android.app.Instrumentation import android.platform.test.rule.NavigationModeRule 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 a5e0550d9c79..3ffc9d7b87f6 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 @@ -21,6 +21,7 @@ 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.Flags import com.android.wm.shell.flicker.pip.common.ClosePipTransition import org.junit.FixMethodOrder import org.junit.Test @@ -60,7 +61,7 @@ class ClosePipBySwipingDownTest(flicker: LegacyFlickerTest) : ClosePipTransition val pipCenterY = pipRegion.centerY() val displayCenterX = device.displayWidth / 2 val barComponent = - if (flicker.scenario.isTablet) { + if (flicker.scenario.isTablet || Flags.enableTaskbarOnPhones()) { ComponentNameMatcher.TASK_BAR } else { ComponentNameMatcher.NAV_BAR diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt deleted file mode 100644 index 9ba3a45fb5b7..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt +++ /dev/null @@ -1,34 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [CloseAllAppsWithAppHeaderExit]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class CloseAllAppsWithAppHeaderExitTest : CloseAllAppsWithAppHeaderExit() { - - @Test - override fun closeAllAppsInDesktop() { - super.closeAllAppsInDesktop() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt deleted file mode 100644 index 546ce2d10a7d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt +++ /dev/null @@ -1,33 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithAppHandleMenu -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [EnterDesktopWithAppHandleMenu]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class EnterDesktopWithAppHandleMenuTest : EnterDesktopWithAppHandleMenu() { - @Test - override fun enterDesktopWithAppHandleMenu() { - super.enterDesktopWithAppHandleMenu() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt deleted file mode 100644 index b5fdb168c8ed..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt +++ /dev/null @@ -1,35 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import android.tools.Rotation -import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [EnterDesktopWithDrag]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class EnterDesktopWithDragTest : EnterDesktopWithDrag(Rotation.ROTATION_0) { - - @Test - override fun enterDesktopWithDrag() { - super.enterDesktopWithDrag() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt deleted file mode 100644 index 8f802d245275..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt +++ /dev/null @@ -1,35 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import android.tools.Rotation -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ExitDesktopWithDragToTopDragZone -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [ExitDesktopWithDragToTopDragZone]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class ExitDesktopWithDragToTopDragZoneTest : - ExitDesktopWithDragToTopDragZone(Rotation.ROTATION_0) { - @Test - override fun exitDesktopWithDragToTopDragZone() { - super.exitDesktopWithDragToTopDragZone() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt deleted file mode 100644 index 63c428a0451f..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt +++ /dev/null @@ -1,36 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.MinimizeWindowOnAppOpen -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [MinimizeWindowOnAppOpen]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class MinimizeWindowOnAppOpenTest : MinimizeWindowOnAppOpen() -{ - @Test - override fun openAppToMinimizeWindow() { - // Launch a new app while 4 apps are already open on desktop. This should result in the - // first app we opened to be minimized. - super.openAppToMinimizeWindow() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt deleted file mode 100644 index 4797aaf553af..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt +++ /dev/null @@ -1,34 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import android.tools.Rotation -import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [ResizeAppWithCornerResize]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class ResizeAppWithCornerResizeTest : ResizeAppWithCornerResize(Rotation.ROTATION_0) { - @Test - override fun resizeAppWithCornerResize() { - super.resizeAppWithCornerResize() - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt deleted file mode 100644 index 9a7136103cd4..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt +++ /dev/null @@ -1,33 +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.wm.shell.flicker.service.desktopmode.functional - -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.SwitchToOverviewFromDesktop -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -/** Functional test for [SwitchToOverviewFromDesktop]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class SwitchToOverviewFromDesktopTest : SwitchToOverviewFromDesktop() { - @Test - override fun switchToOverview() { - super.switchToOverview() - } -} 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 4465a16a8e0f..acaf021981ed 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 @@ -28,12 +28,16 @@ import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible +import com.android.wm.shell.Flags import org.junit.Assume import org.junit.Test interface ICommonAssertions { val flicker: LegacyFlickerTest + val usesTaskbar: Boolean + get() = flicker.scenario.isTablet || Flags.enableTaskbarOnPhones() + /** Checks that all parts of the screen are covered during the transition */ @Presubmit @Test fun entireScreenCovered() = flicker.entireScreenCovered() @@ -43,7 +47,7 @@ interface ICommonAssertions { @Presubmit @Test fun navBarLayerIsVisibleAtStartAndEnd() { - Assume.assumeFalse(flicker.scenario.isTablet) + Assume.assumeFalse(usesTaskbar) flicker.navBarLayerIsVisibleAtStartAndEnd() } @@ -54,7 +58,7 @@ interface ICommonAssertions { @Presubmit @Test fun navBarLayerPositionAtStartAndEnd() { - Assume.assumeFalse(flicker.scenario.isTablet) + Assume.assumeFalse(usesTaskbar) flicker.navBarLayerPositionAtStartAndEnd() } @@ -66,7 +70,7 @@ interface ICommonAssertions { @Presubmit @Test fun navBarWindowIsAlwaysVisible() { - Assume.assumeFalse(flicker.scenario.isTablet) + Assume.assumeFalse(usesTaskbar) flicker.navBarWindowIsAlwaysVisible() } @@ -76,7 +80,7 @@ interface ICommonAssertions { @Presubmit @Test fun taskBarLayerIsVisibleAtStartAndEnd() { - Assume.assumeTrue(flicker.scenario.isTablet) + Assume.assumeTrue(usesTaskbar) flicker.taskBarLayerIsVisibleAtStartAndEnd() } @@ -88,7 +92,7 @@ interface ICommonAssertions { @Presubmit @Test fun taskBarWindowIsAlwaysVisible() { - Assume.assumeTrue(flicker.scenario.isTablet) + Assume.assumeTrue(usesTaskbar) flicker.taskBarWindowIsAlwaysVisible() } diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index d71f3b6884ae..23cd3ce965ff 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -143,6 +143,7 @@ cc_defaults { "aconfig_text_flags_c_lib", "server_configurable_flags", "libaconfig_storage_read_api_cc", + "libgraphicsenv", ], static_libs: [ "libEGL_blobCache", diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 1217b47664dd..b6476c9d466f 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -42,6 +42,11 @@ constexpr bool hdr_10bit_plus() { constexpr bool initialize_gl_always() { return false; } + +constexpr bool skip_eglmanager_telemetry() { + return false; +} + constexpr bool resample_gainmap_regions() { return false; } @@ -103,6 +108,7 @@ float Properties::maxHdrHeadroomOn8bit = 5.f; // TODO: Refine this number bool Properties::clipSurfaceViews = false; bool Properties::hdr10bitPlus = false; +bool Properties::skipTelemetry = false; bool Properties::resampleGainmapRegions = false; int Properties::timeoutMultiplier = 1; @@ -183,6 +189,8 @@ bool Properties::load() { hwui_flags::resample_gainmap_regions()); timeoutMultiplier = android::base::GetIntProperty("ro.hw_timeout_multiplier", 1); + skipTelemetry = base::GetBoolProperty(PROPERTY_SKIP_EGLMANAGER_TELEMETRY, + hwui_flags::skip_eglmanager_telemetry()); return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw); } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 73e80ce4afd0..db471527b861 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -234,6 +234,8 @@ enum DebugLevel { */ #define PROPERTY_INITIALIZE_GL_ALWAYS "debug.hwui.initialize_gl_always" +#define PROPERTY_SKIP_EGLMANAGER_TELEMETRY "debug.hwui.skip_eglmanager_telemetry" + /////////////////////////////////////////////////////////////////////////////// // Misc /////////////////////////////////////////////////////////////////////////////// @@ -342,6 +344,7 @@ public: static bool clipSurfaceViews; static bool hdr10bitPlus; + static bool skipTelemetry; static bool resampleGainmapRegions; static int timeoutMultiplier; diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index 13c0b00daa21..a1f51687b077 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -99,6 +99,13 @@ flag { } flag { + name: "skip_eglmanager_telemetry" + namespace: "core_graphics" + description: "Skip telemetry in EglManager's calls to eglCreateContext to avoid polluting telemetry" + bug: "347911216" +} + +flag { name: "resample_gainmap_regions" namespace: "core_graphics" description: "Resample gainmaps when decoding regions, to improve visual quality" diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 708b0113e13e..60104452f4c0 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -19,6 +19,7 @@ #include <EGL/eglext.h> #include <GLES/gl.h> #include <cutils/properties.h> +#include <graphicsenv/GpuStatsInfo.h> #include <log/log.h> #include <sync/sync.h> #include <utils/Trace.h> @@ -366,6 +367,10 @@ void EglManager::createContext() { contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); contextAttributes.push_back(Properties::contextPriority); } + if (Properties::skipTelemetry) { + contextAttributes.push_back(EGL_TELEMETRY_HINT_ANDROID); + contextAttributes.push_back(android::GpuStatsInfo::SKIP_TELEMETRY); + } contextAttributes.push_back(EGL_NONE); mEglContext = eglCreateContext( mEglDisplay, EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig, diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING index b3fb1e7b3034..ff836104f799 100644 --- a/packages/PackageInstaller/TEST_MAPPING +++ b/packages/PackageInstaller/TEST_MAPPING @@ -28,6 +28,17 @@ }, { "name": "CtsIntentSignatureTestCases" + }, + { + "name": "CtsPackageInstallerCUJTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] } ] } diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java index 9ad3e3c0af0f..170cb4546d0c 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java @@ -91,8 +91,7 @@ public class UninstallerActivity extends Activity { // be stale, if e.g. the app was uninstalled while the activity was destroyed. super.onCreate(null); - // TODO(b/318521110) Enable PIA v2 for archive dialog. - if (usePiaV2() && !isTv() && !isArchiveDialog(getIntent())) { + if (usePiaV2() && !isTv()) { Log.i(TAG, "Using Pia V2"); boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false); @@ -225,11 +224,6 @@ public class UninstallerActivity extends Activity { showConfirmationDialog(); } - private boolean isArchiveDialog(Intent intent) { - return (intent.getIntExtra(PackageInstaller.EXTRA_DELETE_FLAGS, 0) - & PackageManager.DELETE_ARCHIVE) != 0; - } - /** * Parses specific {@link android.content.pm.PackageManager.DeleteFlags} from {@link Intent} * to archive an app if requested. diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt index 186b69b4107b..3b0faf0cb56c 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt @@ -736,7 +736,8 @@ class InstallRepository(private val context: Context) { val appInfo = packageManager.getApplicationInfo( pkgName, PackageManager.MATCH_UNINSTALLED_PACKAGES ) - if (appInfo.flags and ApplicationInfo.FLAG_INSTALLED == 0) { + // If the package is archived, treat it as an update case. + if (!appInfo.isArchived && appInfo.flags and ApplicationInfo.FLAG_INSTALLED == 0) { return false } } catch (e: PackageManager.NameNotFoundException) { diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt index 0091a3e8b2cf..96525f645004 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt @@ -32,6 +32,8 @@ import android.content.pm.ActivityInfo import android.content.pm.ApplicationInfo import android.content.pm.PackageInstaller import android.content.pm.PackageManager +import android.content.pm.PackageManager.ApplicationInfoFlags +import android.content.pm.PackageManager.PackageInfoFlags import android.content.pm.VersionedPackage import android.graphics.drawable.Icon import android.os.Build @@ -51,6 +53,9 @@ import com.android.packageinstaller.v2.model.PackageUtil.getMaxTargetSdkVersionF import com.android.packageinstaller.v2.model.PackageUtil.getPackageNameForUid import com.android.packageinstaller.v2.model.PackageUtil.isPermissionGranted import com.android.packageinstaller.v2.model.PackageUtil.isProfileOfOrSame +import com.android.packageinstaller.v2.model.UninstallAborted.Companion.ABORT_REASON_UNINSTALL_DONE +import android.content.pm.Flags as PmFlags +import android.multiuser.Flags as MultiuserFlags class UninstallRepository(private val context: Context) { @@ -71,6 +76,7 @@ class UninstallRepository(private val context: Context) { private var uninstallFromAllUsers = false private var isClonedApp = false private var uninstallId = 0 + private var deleteFlags = 0 fun performPreUninstallChecks(intent: Intent, callerInfo: CallerInfo): UninstallStage { this.intent = intent @@ -155,7 +161,9 @@ class UninstallRepository(private val context: Context) { try { targetAppInfo = packageManager.getApplicationInfo( targetPackageName!!, - PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_ANY_USER.toLong()) + ApplicationInfoFlags.of( + PackageManager.MATCH_ANY_USER.toLong() or PackageManager.MATCH_ARCHIVED_PACKAGES + ) ) } catch (e: PackageManager.NameNotFoundException) { Log.e(LOG_TAG, "Unable to get packageName") @@ -180,9 +188,27 @@ class UninstallRepository(private val context: Context) { } } + parseDeleteFlags(intent) + return UninstallReady() } + /** + * Parses specific {@link android.content.pm.PackageManager.DeleteFlags} from {@link Intent} + * to archive an app if requested. + * + * Do not parse other flags because developers might pass here any flags which might cause + * unintended behaviour. + * For more context {@link com.android.server.pm.PackageArchiver#requestArchive}. + */ + private fun parseDeleteFlags(intent: Intent) { + val flags = intent.getIntExtra(PackageInstaller.EXTRA_DELETE_FLAGS, 0) + val archive = flags and PackageManager.DELETE_ARCHIVE + val keepData = flags and PackageManager.DELETE_KEEP_DATA + + deleteFlags = archive or keepData + } + fun generateUninstallDetails(): UninstallStage { val messageBuilder = StringBuilder() @@ -201,6 +227,8 @@ class UninstallRepository(private val context: Context) { } val isUpdate = (targetAppInfo!!.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 + val isArchive = + PmFlags.archiving() && ((deleteFlags and PackageManager.DELETE_ARCHIVE) != 0) val myUserHandle = Process.myUserHandle() val isSingleUser = isSingleUser() @@ -215,34 +243,54 @@ class UninstallRepository(private val context: Context) { ) ) } else if (uninstallFromAllUsers && !isSingleUser) { - messageBuilder.append(context.getString(R.string.uninstall_application_text_all_users)) + val messageString = if (isArchive) { + context.getString(R.string.archive_application_text_all_users) + } else { + context.getString(R.string.uninstall_application_text_all_users) + } + messageBuilder.append(messageString) } else if (uninstalledUser != myUserHandle) { // Uninstalling user is issuing uninstall for another user val customUserManager = context.createContextAsUser(uninstalledUser!!, 0) .getSystemService(UserManager::class.java) val userName = customUserManager!!.userName - var messageString = context.getString( - R.string.uninstall_application_text_user, - userName - ) + + var messageString = if (isArchive) { + context.getString(R.string.archive_application_text_user, userName) + } else { + context.getString(R.string.uninstall_application_text_user, userName) + } + if (userManager!!.isSameProfileGroup(myUserHandle, uninstalledUser!!)) { if (customUserManager.isManagedProfile) { - messageString = context.getString( + messageString = if (isArchive) { + context.getString( + R.string.archive_application_text_current_user_work_profile, userName + ) + } else { + context.getString( R.string.uninstall_application_text_current_user_work_profile, userName - ) + ) + } } else if (customUserManager.isCloneProfile){ isClonedApp = true messageString = context.getString( R.string.uninstall_application_text_current_user_clone_profile ) } else if (Flags.allowPrivateProfile() - && android.multiuser.Flags.enablePrivateSpaceFeatures() + && MultiuserFlags.enablePrivateSpaceFeatures() && customUserManager.isPrivateProfile ) { // TODO(b/324244123): Get these Strings from a User Property API. - messageString = context.getString( + messageString = if (isArchive) { + context.getString( + R.string.archive_application_text_current_user_private_profile, userName + ) + } else { + context.getString( R.string.uninstall_application_text_current_user_private_profile - ) + ) + } } } messageBuilder.append(messageString) @@ -262,6 +310,8 @@ class UninstallRepository(private val context: Context) { targetAppLabel ) ) + } else if (isArchive) { + messageBuilder.append(context.getString(R.string.archive_application_text)) } else { messageBuilder.append(context.getString(R.string.uninstall_application_text)) } @@ -270,15 +320,21 @@ class UninstallRepository(private val context: Context) { val title = if (isClonedApp) { context.getString(R.string.cloned_app_label, targetAppLabel) + } else if (isArchive) { + context.getString(R.string.archiving_app_label, targetAppLabel) } else { targetAppLabel.toString() } var suggestToKeepAppData = false try { - val pkgInfo = packageManager.getPackageInfo(targetPackageName!!, 0) + val pkgInfo = packageManager.getPackageInfo( + targetPackageName!!, PackageInfoFlags.of(PackageManager.MATCH_ARCHIVED_PACKAGES) + ) suggestToKeepAppData = - pkgInfo.applicationInfo != null && pkgInfo.applicationInfo!!.hasFragileUserData() + pkgInfo.applicationInfo != null + && pkgInfo.applicationInfo!!.hasFragileUserData() + && !isArchive } catch (e: PackageManager.NameNotFoundException) { Log.e(LOG_TAG, "Cannot check hasFragileUserData for $targetPackageName", e) } @@ -291,7 +347,7 @@ class UninstallRepository(private val context: Context) { ) } - return UninstallUserActionRequired(title, message, appDataSize) + return UninstallUserActionRequired(title, message, appDataSize, isArchive) } /** @@ -444,10 +500,11 @@ class UninstallRepository(private val context: Context) { callback!!.onUninstallComplete(targetPackageName!!, legacyStatus, message) // Since the caller already received the results, just finish the app at this point - uninstallResult.value = null + uninstallResult.value = UninstallAborted(ABORT_REASON_UNINSTALL_DONE) return } val returnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false) + if (returnResult || callingActivity != null) { val intent = Intent() intent.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus) @@ -717,6 +774,7 @@ class UninstallRepository(private val context: Context) { ): Boolean { var flags = if (uninstallFromAllUsers) PackageManager.DELETE_ALL_USERS else 0 flags = flags or if (keepData) PackageManager.DELETE_KEEP_DATA else 0 + flags = flags or deleteFlags return try { context.createContextAsUser(targetUser, 0) diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallStages.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallStages.kt index f086209fe498..316e8b7e3a73 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallStages.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallStages.kt @@ -38,7 +38,8 @@ class UninstallReady : UninstallStage(STAGE_READY) data class UninstallUserActionRequired( val title: String? = null, val message: String? = null, - val appDataSize: Long = 0 + val appDataSize: Long = 0, + val isArchive: Boolean = false ) : UninstallStage(STAGE_USER_ACTION_REQUIRED) data class UninstallUninstalling(val appLabel: CharSequence, val isCloneUser: Boolean) : @@ -96,6 +97,11 @@ data class UninstallAborted(val abortReason: Int) : UninstallStage(STAGE_ABORTED dialogTextResource = R.string.user_is_not_allowed_dlg_text } + ABORT_REASON_UNINSTALL_DONE -> { + dialogTitleResource = 0 + dialogTextResource = 0 + } + else -> { dialogTitleResource = 0 dialogTextResource = R.string.generic_error_dlg_text @@ -107,6 +113,7 @@ data class UninstallAborted(val abortReason: Int) : UninstallStage(STAGE_ABORTED const val ABORT_REASON_GENERIC_ERROR = 0 const val ABORT_REASON_APP_UNAVAILABLE = 1 const val ABORT_REASON_USER_NOT_ALLOWED = 2 + const val ABORT_REASON_UNINSTALL_DONE = 3 } } diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java index 87af1ae200ca..524b4e6a0e63 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java @@ -60,7 +60,7 @@ public class UninstallConfirmationFragment extends DialogFragment { Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData); AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()) .setTitle(mDialogData.getTitle()) - .setPositiveButton(R.string.ok, + .setPositiveButton(mDialogData.isArchive() ? R.string.archive : R.string.ok, (dialogInt, which) -> mUninstallActionListener.onPositiveResponse( mKeepData != null && mKeepData.isChecked())) .setNegativeButton(R.string.cancel, diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt index c88c4c94b5fb..0e71116db6cc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt @@ -25,6 +25,7 @@ import android.media.AudioManager.OnCommunicationDeviceChangedListener import android.provider.Settings import androidx.concurrent.futures.DirectExecutor import com.android.internal.util.ConcurrentUtils +import com.android.settingslib.volume.shared.AudioLogger import com.android.settingslib.volume.shared.AudioManagerEventsReceiver import com.android.settingslib.volume.shared.model.AudioManagerEvent import com.android.settingslib.volume.shared.model.AudioStream @@ -99,7 +100,7 @@ class AudioRepositoryImpl( private val contentResolver: ContentResolver, private val backgroundCoroutineContext: CoroutineContext, private val coroutineScope: CoroutineScope, - private val logger: Logger, + private val logger: AudioLogger, ) : AudioRepository { private val streamSettingNames: Map<AudioStream, String> = @@ -117,10 +118,10 @@ class AudioRepositoryImpl( override val mode: StateFlow<Int> = callbackFlow { - val listener = AudioManager.OnModeChangedListener { newMode -> trySend(newMode) } - audioManager.addOnModeChangedListener(ConcurrentUtils.DIRECT_EXECUTOR, listener) - awaitClose { audioManager.removeOnModeChangedListener(listener) } - } + val listener = AudioManager.OnModeChangedListener { newMode -> trySend(newMode) } + audioManager.addOnModeChangedListener(ConcurrentUtils.DIRECT_EXECUTOR, listener) + awaitClose { audioManager.removeOnModeChangedListener(listener) } + } .onStart { emit(audioManager.mode) } .flowOn(backgroundCoroutineContext) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), audioManager.mode) @@ -140,14 +141,14 @@ class AudioRepositoryImpl( override val communicationDevice: StateFlow<AudioDeviceInfo?> get() = callbackFlow { - val listener = OnCommunicationDeviceChangedListener { trySend(Unit) } - audioManager.addOnCommunicationDeviceChangedListener( - ConcurrentUtils.DIRECT_EXECUTOR, - listener, - ) + val listener = OnCommunicationDeviceChangedListener { trySend(Unit) } + audioManager.addOnCommunicationDeviceChangedListener( + ConcurrentUtils.DIRECT_EXECUTOR, + listener, + ) - awaitClose { audioManager.removeOnCommunicationDeviceChangedListener(listener) } - } + awaitClose { audioManager.removeOnCommunicationDeviceChangedListener(listener) } + } .filterNotNull() .map { audioManager.communicationDevice } .onStart { emit(audioManager.communicationDevice) } @@ -160,15 +161,15 @@ class AudioRepositoryImpl( override fun getAudioStream(audioStream: AudioStream): Flow<AudioStreamModel> { return merge( - audioManagerEventsReceiver.events.filter { - if (it is StreamAudioManagerEvent) { - it.audioStream == audioStream - } else { - true - } - }, - volumeSettingChanges(audioStream), - ) + audioManagerEventsReceiver.events.filter { + if (it is StreamAudioManagerEvent) { + it.audioStream == audioStream + } else { + true + } + }, + volumeSettingChanges(audioStream), + ) .conflate() .map { getCurrentAudioStream(audioStream) } .onStart { emit(getCurrentAudioStream(audioStream)) } @@ -251,11 +252,4 @@ class AudioRepositoryImpl( awaitClose { contentResolver.unregisterContentObserver(observer) } } } - - interface Logger { - - fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) - - fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) - } } diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt index 7a66335ef22f..ebba7f152b90 100644 --- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt @@ -34,6 +34,7 @@ import com.android.settingslib.bluetooth.onServiceStateChanged import com.android.settingslib.bluetooth.onSourceConnectedOrRemoved import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MIN +import com.android.settingslib.volume.shared.AudioSharingLogger import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -50,6 +51,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.runningFold import kotlinx.coroutines.flow.stateIn @@ -90,6 +92,7 @@ class AudioSharingRepositoryImpl( private val btManager: LocalBluetoothManager, private val coroutineScope: CoroutineScope, private val backgroundCoroutineContext: CoroutineContext, + private val logger: AudioSharingLogger ) : AudioSharingRepository { private val isAudioSharingProfilesReady: StateFlow<Boolean> = btManager.profileManager.onServiceStateChanged @@ -104,6 +107,7 @@ class AudioSharingRepositoryImpl( btManager.profileManager.leAudioBroadcastProfile.onBroadcastStartedOrStopped .map { isBroadcasting() } .onStart { emit(isBroadcasting()) } + .onEach { logger.onAudioSharingStateChanged(it) } .flowOn(backgroundCoroutineContext) } else { flowOf(false) @@ -156,6 +160,7 @@ class AudioSharingRepositoryImpl( .map { getSecondaryGroupId() }, primaryGroupId.map { getSecondaryGroupId() }) .onStart { emit(getSecondaryGroupId()) } + .onEach { logger.onSecondaryGroupIdChanged(it) } .flowOn(backgroundCoroutineContext) .stateIn( coroutineScope, @@ -202,6 +207,7 @@ class AudioSharingRepositoryImpl( acc } } + .onEach { logger.onVolumeMapChanged(it) } .flowOn(backgroundCoroutineContext) } else { emptyFlow() @@ -220,6 +226,7 @@ class AudioSharingRepositoryImpl( BluetoothUtils.getSecondaryDeviceForBroadcast(contentResolver, btManager) if (cachedDevice != null) { it.setDeviceVolume(cachedDevice.device, volume, /* isGroupOp= */ true) + logger.onSetDeviceVolumeRequested(volume) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioLogger.kt index f89908228bbf..84f7fcbd8b96 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioLogger.kt @@ -14,21 +14,14 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.functional +package com.android.settingslib.volume.shared -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.MaximizeAppWindow -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner +import com.android.settingslib.volume.shared.model.AudioStream +import com.android.settingslib.volume.shared.model.AudioStreamModel -/** Functional test for [MaximizeAppWindow]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class MaximizeAppWindowTest : MaximizeAppWindow() -{ - @Test - override fun maximizeAppWindow() { - super.maximizeAppWindow() - } -} +/** A log interface for audio streams volume events. */ +interface AudioLogger { + fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) + + fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioSharingLogger.kt index ed1d4887e818..18a4c6d1748d 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioSharingLogger.kt @@ -14,21 +14,16 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.desktopmode.functional +package com.android.settingslib.volume.shared -import android.platform.test.annotations.Postsubmit -import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowMultiWindow -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner +/** A log interface for audio sharing volume events. */ +interface AudioSharingLogger { -/** Functional test for [DragAppWindowMultiWindow]. */ -@RunWith(BlockJUnit4ClassRunner::class) -@Postsubmit -open class DragAppWindowMultiWindowTest : DragAppWindowMultiWindow() -{ - @Test - override fun dragAppWindow() { - super.dragAppWindow() - } -} + fun onAudioSharingStateChanged(state: Boolean) + + fun onSecondaryGroupIdChanged(groupId: Int) + + fun onVolumeMapChanged(map: Map<Int, Int>) + + fun onSetDeviceVolumeRequested(volume: Int) +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt index 078f0c8adba5..8c5a0851cc92 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt @@ -48,6 +48,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -101,7 +102,7 @@ class AudioSharingRepositoryTest { @Captor private lateinit var assistantCallbackCaptor: - ArgumentCaptor<BluetoothLeBroadcastAssistant.Callback> + ArgumentCaptor<BluetoothLeBroadcastAssistant.Callback> @Captor private lateinit var btCallbackCaptor: ArgumentCaptor<BluetoothCallback> @@ -110,6 +111,7 @@ class AudioSharingRepositoryTest { @Captor private lateinit var volumeCallbackCaptor: ArgumentCaptor<BluetoothVolumeControl.Callback> + private val logger = FakeAudioSharingRepositoryLogger() private val testScope = TestScope() private val context: Context = ApplicationProvider.getApplicationContext() @Spy private val contentResolver: ContentResolver = context.contentResolver @@ -135,16 +137,23 @@ class AudioSharingRepositoryTest { Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID_INVALID) + TEST_GROUP_ID_INVALID + ) underTest = AudioSharingRepositoryImpl( contentResolver, btManager, testScope.backgroundScope, testScope.testScheduler, + logger ) } + @After + fun tearDown() { + logger.reset() + } + @Test fun audioSharingStateChange_profileReady_emitValues() { testScope.runTest { @@ -160,6 +169,13 @@ class AudioSharingRepositoryTest { runCurrent() Truth.assertThat(states).containsExactly(false, true, false, true) + Truth.assertThat(logger.logs) + .containsAtLeastElementsIn( + listOf( + "onAudioSharingStateChanged state=true", + "onAudioSharingStateChanged state=false", + ) + ).inOrder() } } @@ -187,7 +203,8 @@ class AudioSharingRepositoryTest { Truth.assertThat(groupIds) .containsExactly( TEST_GROUP_ID_INVALID, - TEST_GROUP_ID2) + TEST_GROUP_ID2 + ) } } @@ -219,13 +236,16 @@ class AudioSharingRepositoryTest { triggerSourceAdded() runCurrent() triggerProfileConnectionChange( - BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) + BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT + ) runCurrent() triggerProfileConnectionChange( - BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO) + BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO + ) runCurrent() triggerProfileConnectionChange( - BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) + BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT + ) runCurrent() Truth.assertThat(groupIds) @@ -235,7 +255,16 @@ class AudioSharingRepositoryTest { TEST_GROUP_ID1, TEST_GROUP_ID_INVALID, TEST_GROUP_ID2, - TEST_GROUP_ID_INVALID) + TEST_GROUP_ID_INVALID + ) + Truth.assertThat(logger.logs) + .containsAtLeastElementsIn( + listOf( + "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID_INVALID", + "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID2", + "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID1", + ) + ).inOrder() } } @@ -257,11 +286,22 @@ class AudioSharingRepositoryTest { verify(volumeControl).unregisterCallback(any()) runCurrent() + val expectedMap1 = mapOf(TEST_GROUP_ID1 to TEST_VOLUME1) + val expectedMap2 = mapOf(TEST_GROUP_ID1 to TEST_VOLUME2) Truth.assertThat(volumeMaps) .containsExactly( emptyMap<Int, Int>(), - mapOf(TEST_GROUP_ID1 to TEST_VOLUME1), - mapOf(TEST_GROUP_ID1 to TEST_VOLUME2)) + expectedMap1, + expectedMap2 + ) + Truth.assertThat(logger.logs) + .containsAtLeastElementsIn( + listOf( + "onVolumeMapChanged map={}", + "onVolumeMapChanged map=$expectedMap1", + "onVolumeMapChanged map=$expectedMap2", + ) + ).inOrder() } } @@ -281,12 +321,19 @@ class AudioSharingRepositoryTest { Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID2) + TEST_GROUP_ID2 + ) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) underTest.setSecondaryVolume(TEST_VOLUME1) runCurrent() verify(volumeControl).setDeviceVolume(device1, TEST_VOLUME1, true) + Truth.assertThat(logger.logs) + .isEqualTo( + listOf( + "onSetVolumeRequested volume=$TEST_VOLUME1", + ) + ) } } @@ -313,7 +360,8 @@ class AudioSharingRepositoryTest { Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID1) + TEST_GROUP_ID1 + ) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) assistantCallbackCaptor.value.sourceAdded(device1, receiveState) } @@ -324,7 +372,8 @@ class AudioSharingRepositoryTest { Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID1) + TEST_GROUP_ID1 + ) assistantCallbackCaptor.value.sourceRemoved(device2) } @@ -334,7 +383,8 @@ class AudioSharingRepositoryTest { Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID1) + TEST_GROUP_ID1 + ) btCallbackCaptor.value.onProfileConnectionStateChanged(cachedDevice2, state, profile) } @@ -343,12 +393,14 @@ class AudioSharingRepositoryTest { .registerContentObserver( eq(Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast())), eq(false), - contentObserverCaptor.capture()) + contentObserverCaptor.capture() + ) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) Settings.Secure.putInt( contentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), - TEST_GROUP_ID2) + TEST_GROUP_ID2 + ) contentObserverCaptor.value.primaryChanged() } @@ -380,8 +432,9 @@ class AudioSharingRepositoryTest { onBroadcastStopped(TEST_REASON, TEST_BROADCAST_ID) } val sourceAdded: - BluetoothLeBroadcastAssistant.Callback.( - sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState) -> Unit = + BluetoothLeBroadcastAssistant.Callback.( + sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState + ) -> Unit = { sink, state -> onReceiveStateChanged(sink, TEST_SOURCE_ID, state) } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt index 389bf5304262..bd573fb2c675 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt @@ -16,10 +16,11 @@ package com.android.settingslib.volume.data.repository +import com.android.settingslib.volume.shared.AudioLogger import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.AudioStreamModel -class FakeAudioRepositoryLogger : AudioRepositoryImpl.Logger { +class FakeAudioRepositoryLogger : AudioLogger { private val mutableLogs: MutableList<String> = mutableListOf() val logs: List<String> diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.kt new file mode 100644 index 000000000000..cc4cc8d4ab96 --- /dev/null +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.kt @@ -0,0 +1,46 @@ +/* + * 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.settingslib.volume.data.repository + +import com.android.settingslib.volume.shared.AudioSharingLogger +import java.util.concurrent.CopyOnWriteArrayList + +class FakeAudioSharingRepositoryLogger : AudioSharingLogger { + private val mutableLogs = CopyOnWriteArrayList<String>() + val logs: List<String> + get() = mutableLogs.toList() + + fun reset() { + mutableLogs.clear() + } + + override fun onAudioSharingStateChanged(state: Boolean) { + mutableLogs.add("onAudioSharingStateChanged state=$state") + } + + override fun onSecondaryGroupIdChanged(groupId: Int) { + mutableLogs.add("onSecondaryGroupIdChanged groupId=$groupId") + } + + override fun onVolumeMapChanged(map: GroupIdToVolumes) { + mutableLogs.add("onVolumeMapChanged map=$map") + } + + override fun onSetDeviceVolumeRequested(volume: Int) { + mutableLogs.add("onSetVolumeRequested volume=$volume") + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index 7e7c76e6ecba..8cc997414d70 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -35,6 +35,7 @@ import android.os.Parcel; import android.os.ParcelUuid; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -545,6 +546,7 @@ public class CachedBluetoothDeviceManagerTest { * Test to verify OnDeviceUnpaired() for csip device unpair. */ @Test + @Ignore("b/359066481") public void onDeviceUnpaired_unpairCsipSubDevice() { when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java index 194a0e29de34..4e54d8f8688f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java @@ -40,6 +40,7 @@ import com.android.settingslib.testutils.OverpoweredReflectionHelper; import com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -58,6 +59,7 @@ import java.util.concurrent.TimeUnit; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowInteractionJankMonitor.class, SettingsJankMonitorTest.ShadowBuilder.class}) +@Ignore("b/359066481") public class SettingsJankMonitorTest { private static final String TEST_KEY = "key"; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java index 0d318c346521..325bb2c941b7 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java @@ -36,6 +36,7 @@ import com.android.settingslib.testutils.shadow.ShadowDefaultDialerManager; import com.android.settingslib.testutils.shadow.ShadowSmsApplication; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -86,6 +87,7 @@ public class PowerAllowlistBackendTest { mPowerAllowlistBackend = new PowerAllowlistBackend(mContext, mDeviceIdleService); } + @Ignore("b/359066481") @Test public void testIsAllowlisted() throws Exception { doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getFullPowerWhitelist(); @@ -160,6 +162,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isDefaultActiveApp(PACKAGE_ONE, UID)).isTrue(); } + @Ignore("b/359066481") @Test public void testIsSystemAllowlisted() throws Exception { doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getSystemPowerWhitelist(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java index f0f53d6e82ad..7f4bdaeac855 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java @@ -44,6 +44,7 @@ import com.android.settingslib.testutils.OverpoweredReflectionHelper; import com.android.settingslib.widget.preference.banner.R; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; @@ -53,6 +54,7 @@ import org.robolectric.shadows.ShadowDrawable; import org.robolectric.shadows.ShadowTouchDelegate; import org.robolectric.util.ReflectionHelpers; +@Ignore("b/359066481") @RunWith(RobolectricTestRunner.class) public class BannerMessagePreferenceTest { diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 30c4ee55842e..9ab853ff4964 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -690,7 +690,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { Cursor cursor = getContentResolver().query(Settings.Global.CONTENT_URI, PROJECTION, null, null, null); try { - return extractRelevantValues(cursor, GlobalSettings.SETTINGS_TO_BACKUP); + return extractRelevantValues(cursor, getGlobalSettingsToBackup()); } finally { cursor.close(); } @@ -1011,7 +1011,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { Settings.System.LEGACY_RESTORE_SETTINGS); validators = SystemSettingsValidators.VALIDATORS; } else if (contentUri.equals(Settings.Global.CONTENT_URI)) { - whitelist = ArrayUtils.concat(String.class, GlobalSettings.SETTINGS_TO_BACKUP, + whitelist = ArrayUtils.concat(String.class, getGlobalSettingsToBackup(), Settings.Global.LEGACY_RESTORE_SETTINGS); validators = GlobalSettingsValidators.VALIDATORS; } else { @@ -1021,6 +1021,17 @@ public class SettingsBackupAgent extends BackupAgentHelper { return new SettingsBackupWhitelist(whitelist, validators); } + private String[] getGlobalSettingsToBackup() { + // On watches, we don't want to backup or restore 'bluetooth_on' setting, as setting it to + // false during restore would cause watch OOBE to fail due to bluetooth connection loss. + if (isWatch()) { + return ArrayUtils.removeElement( + String.class, GlobalSettings.SETTINGS_TO_BACKUP, Settings.Global.BLUETOOTH_ON); + } + + return GlobalSettings.SETTINGS_TO_BACKUP; + } + private boolean isBlockedByDynamicList(Set<String> dynamicBlockList, Uri areaUri, String key) { String contentKey = Uri.withAppendedPath(areaUri, key).toString(); return dynamicBlockList.contains(contentKey); diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java index d4ca4a35ed26..3a39150523ac 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java @@ -26,6 +26,7 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.ContextWrapper; +import android.content.pm.PackageManager; import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; @@ -221,6 +222,21 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest { } @Test + public void testOnRestore_bluetoothOnRestoredOnNonWearablesOnly() { + TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext); + mAgentUnderTest.mSettingsHelper = settingsHelper; + + restoreGlobalSettings(generateBackupData(Map.of(Settings.Global.BLUETOOTH_ON, "0"))); + + var isWatch = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); + if (isWatch) { + assertFalse(settingsHelper.mWrittenValues.containsKey(Settings.Global.BLUETOOTH_ON)); + } else { + assertEquals("0", settingsHelper.mWrittenValues.get(Settings.Global.BLUETOOTH_ON)); + } + } + + @Test @EnableFlags(Flags.FLAG_CONFIGURABLE_FONT_SCALE_DEFAULT) public void testFindClosestAllowedFontScale() { final String[] availableFontScales = new String[]{"0.5", "0.9", "1.0", "1.1", "1.5"}; @@ -266,6 +282,20 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest { return buffer.array(); } + private void restoreGlobalSettings(byte[] backupData) { + mAgentUnderTest.restoreSettings( + backupData, + /* pos= */ 0, + backupData.length, + Settings.Global.CONTENT_URI, + null, + null, + null, + R.array.restore_blocked_global_settings, + /* dynamicBlockList= */ Collections.emptySet(), + /* settingsToPreserve= */ Collections.emptySet()); + } + private byte[] generateUncorruptedHeader() throws IOException { try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { mAgentUnderTest.writeHeader(os); diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 9f3c2bfb237a..1d9f46971502 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -482,6 +482,15 @@ android:exported="true" android:theme="@style/Theme.AppCompat.NoActionBar"> <intent-filter> + <action android:name="com.android.systemui.action.TOUCHPAD_TUTORIAL"/> + <category android:name="android.intent.category.DEFAULT"/> + </intent-filter> + </activity> + + <activity android:name=".inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity" + android:exported="true" + android:theme="@style/Theme.AppCompat.NoActionBar"> + <intent-filter> <action android:name="com.android.systemui.action.TOUCHPAD_KEYBOARD_TUTORIAL"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 1ff9a80c5bc0..17c3fd124f66 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -493,6 +493,16 @@ flag { } flag { + name: "status_bar_switch_to_spn_from_data_spn" + namespace: "systemui" + description: "Fix usage of the SPN broadcast extras" + bug: "350812372" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "haptic_volume_slider" namespace: "systemui" description: "Adds haptic feedback to the volume slider." @@ -1237,6 +1247,16 @@ flag { } flag { + name: "relock_with_power_button_immediately" + namespace: "systemui" + description: "UDFPS unlock followed by immediate power button push should relock" + bug: "343327511" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "lockscreen_preview_renderer_create_on_main_thread" namespace: "systemui" description: "Force preview renderer to be created on the main thread" diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt index 82febe6d9da6..808e6666e6e6 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt @@ -24,8 +24,10 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.approachLayout import androidx.compose.ui.layout.layout import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.viewinterop.AndroidView import com.android.compose.animation.scene.MovableElementKey import com.android.compose.animation.scene.SceneScope @@ -50,6 +52,7 @@ fun SceneScope.MediaCarousel( mediaHost: MediaHost, modifier: Modifier = Modifier, carouselController: MediaCarouselController, + offsetProvider: (() -> IntOffset)? = null, ) { if (!isVisible) { return @@ -59,21 +62,38 @@ fun SceneScope.MediaCarousel( MovableElement( key = MediaCarousel.Elements.Content, - modifier = modifier.height(mediaHeight).fillMaxWidth() + modifier = modifier.height(mediaHeight).fillMaxWidth(), ) { content { AndroidView( modifier = - Modifier.fillMaxSize().layout { measurable, constraints -> - val placeable = measurable.measure(constraints) + Modifier.fillMaxSize() + .approachLayout( + isMeasurementApproachInProgress = { offsetProvider != null }, + approachMeasure = { measurable, constraints -> + val placeable = measurable.measure(constraints) + layout(placeable.width, placeable.height) { + placeable.placeRelative( + offsetProvider?.invoke() ?: IntOffset.Zero + ) + } + } + ) + .layout { measurable, constraints -> + val placeable = measurable.measure(constraints) - // Notify controller to size the carousel for the current space - mediaHost.measurementInput = - MeasurementInput(placeable.width, placeable.height) - carouselController.setSceneContainerSize(placeable.width, placeable.height) + // Notify controller to size the carousel for the current space + mediaHost.measurementInput = + MeasurementInput(placeable.width, placeable.height) + carouselController.setSceneContainerSize( + placeable.width, + placeable.height + ) - layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) } - }, + layout(placeable.width, placeable.height) { + placeable.placeRelative(0, 0) + } + }, factory = { context -> FrameLayout(context).apply { layoutParams = diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt index 3f04f3728bef..70c0db1582c4 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt @@ -27,7 +27,6 @@ import com.android.systemui.scene.shared.model.Scenes /** [ElementContentPicker] implementation for the media carousel object. */ object MediaContentPicker : StaticElementContentPicker { - const val SHADE_FRACTION = 0.66f override val contents = setOf( Scenes.Lockscreen, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt index a9da733116fc..71fa6c9e567a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt @@ -25,7 +25,6 @@ import com.android.compose.animation.scene.TransitionBuilder import com.android.compose.animation.scene.UserActionDistance import com.android.compose.animation.scene.UserActionDistanceScope import com.android.systemui.media.controls.ui.composable.MediaCarousel -import com.android.systemui.media.controls.ui.composable.MediaContentPicker import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.shade.ui.composable.Shade @@ -54,13 +53,7 @@ fun TransitionBuilder.goneToSplitShadeTransition( fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) } fractionRange(start = .33f) { - val qsTranslation = - ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION - val qsExpansionDiff = - ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight - translate(MediaCarousel.Elements.Content, y = -(qsExpansionDiff + qsTranslation)) fade(MediaCarousel.Elements.Content) - fade(ShadeHeader.Elements.Clock) fade(ShadeHeader.Elements.CollapsedContentStart) fade(ShadeHeader.Elements.CollapsedContentEnd) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt index 21dfc49cbe7b..b677dff2dcf9 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt @@ -26,7 +26,6 @@ import com.android.compose.animation.scene.TransitionBuilder import com.android.compose.animation.scene.UserActionDistance import com.android.compose.animation.scene.UserActionDistanceScope import com.android.systemui.media.controls.ui.composable.MediaCarousel -import com.android.systemui.media.controls.ui.composable.MediaContentPicker import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.scene.shared.model.Scenes @@ -62,12 +61,9 @@ fun TransitionBuilder.toShadeTransition( fade(QuickSettings.Elements.FooterActions) } - val qsTranslation = ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION - val qsExpansionDiff = - ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight - - translate(QuickSettings.Elements.QuickQuickSettings, y = -qsTranslation) - translate(MediaCarousel.Elements.Content, y = -(qsExpansionDiff + qsTranslation)) + val qsTranslation = -ShadeHeader.Dimensions.CollapsedHeight * 0.66f + translate(QuickSettings.Elements.QuickQuickSettings, y = qsTranslation) + translate(MediaCarousel.Elements.Content, y = qsTranslation) translate(Notifications.Elements.NotificationScrim, Edge.Top, false) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt new file mode 100644 index 000000000000..e0b7909dcaa3 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt @@ -0,0 +1,79 @@ +/* + * 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.shade.ui.composable + +import androidx.compose.ui.unit.IntOffset +import com.android.systemui.qs.ui.adapter.QSSceneAdapter + +/** + * Provider for the extra offset for the Media section in the shade to accommodate for the squishing + * qs or qqs tiles. + */ +interface ShadeMediaOffsetProvider { + + /** Returns current offset to be applied to the Media Carousel */ + val offset: IntOffset + + /** + * [ShadeMediaOffsetProvider] implementation for Quick Settings. + * + * [updateLayout] should represent an access to some state to trigger Compose to relayout to + * track [QSSceneAdapter] internal state changes during the transition. + */ + class Qs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) : + ShadeMediaOffsetProvider { + + override val offset: IntOffset + get() = + calculateQsOffset( + updateLayout, + qsSceneAdapter.qsHeight, + qsSceneAdapter.squishedQsHeight + ) + } + + /** + * [ShadeMediaOffsetProvider] implementation for Quick Quick Settings. + * + * [updateLayout] should represent an access to some state to trigger Compose to relayout to + * track [QSSceneAdapter] internal state changes during the transition. + */ + class Qqs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) : + ShadeMediaOffsetProvider { + + override val offset: IntOffset + get() = + calculateQsOffset( + updateLayout, + qsSceneAdapter.qqsHeight, + qsSceneAdapter.squishedQqsHeight + ) + } + + companion object { + + protected fun calculateQsOffset( + updateLayout: () -> Unit, + qsHeight: Int, + qsSquishedHeight: Int + ): IntOffset { + updateLayout() + val distanceFromBottomToActualBottom = qsHeight - qsSquishedHeight + return IntOffset(0, -distanceFromBottomToActualBottom) + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt index 0e3fcf4598af..16972bc95e57 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt @@ -118,7 +118,6 @@ import kotlinx.coroutines.flow.Flow object Shade { object Elements { - val MediaCarousel = ElementKey("ShadeMediaCarousel") val BackgroundScrim = ElementKey("ShadeBackgroundScrim", contentPicker = LowestZIndexContentPicker) val SplitShadeStartColumn = ElementKey("SplitShadeStartColumn") @@ -283,6 +282,13 @@ private fun SceneScope.SingleShade( val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding() + val mediaOffsetProvider = remember { + ShadeMediaOffsetProvider.Qqs( + { @Suppress("UNUSED_EXPRESSION") tileSquishiness }, + viewModel.qsSceneAdapter, + ) + } + Box( modifier = modifier.thenIf(shouldPunchHoleBehindScrim) { @@ -335,12 +341,12 @@ private fun SceneScope.SingleShade( ) } - MediaCarousel( + ShadeMediaCarousel( isVisible = isMediaVisible, mediaHost = mediaHost, + mediaOffsetProvider = mediaOffsetProvider, modifier = - Modifier.fillMaxWidth() - .layoutId(QSMediaMeasurePolicy.LayoutId.Media), + Modifier.layoutId(QSMediaMeasurePolicy.LayoutId.Media), carouselController = mediaCarouselController, ) } @@ -497,6 +503,13 @@ private fun SceneScope.SplitShade( val brightnessMirrorShowingModifier = Modifier.graphicsLayer { alpha = contentAlpha } + val mediaOffsetProvider = remember { + ShadeMediaOffsetProvider.Qs( + { @Suppress("UNUSED_EXPRESSION") tileSquishiness }, + viewModel.qsSceneAdapter, + ) + } + Box { Box( modifier = @@ -570,11 +583,13 @@ private fun SceneScope.SplitShade( squishiness = { tileSquishiness }, ) } - MediaCarousel( + + ShadeMediaCarousel( isVisible = isMediaVisible, mediaHost = mediaHost, + mediaOffsetProvider = mediaOffsetProvider, modifier = - Modifier.fillMaxWidth().thenIf( + Modifier.thenIf( MediaContentPicker.shouldElevateMedia(layoutState) ) { Modifier.zIndex(1f) @@ -620,3 +635,25 @@ private fun SceneScope.SplitShade( ) } } + +@Composable +private fun SceneScope.ShadeMediaCarousel( + isVisible: Boolean, + mediaHost: MediaHost, + carouselController: MediaCarouselController, + mediaOffsetProvider: ShadeMediaOffsetProvider, + modifier: Modifier = Modifier, +) { + MediaCarousel( + modifier = modifier.fillMaxWidth(), + isVisible = isVisible, + mediaHost = mediaHost, + carouselController = carouselController, + offsetProvider = + if (MediaContentPicker.shouldElevateMedia(layoutState)) { + null + } else { + { mediaOffsetProvider.offset } + } + ) +} diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt index e13ca39149f3..ae5a84b859e5 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt @@ -120,7 +120,7 @@ fun ContentScope.animateContentFloatAsState( } @Deprecated( - "Use animateSceneFloatAsState() instead", + "Use animateContentFloatAsState() instead", replaceWith = ReplaceWith("animateContentFloatAsState(value, key, canOverflow)") ) @Composable @@ -171,7 +171,7 @@ fun ContentScope.animateContentDpAsState( } @Deprecated( - "Use animateSceneDpAsState() instead", + "Use animateContentDpAsState() instead", replaceWith = ReplaceWith("animateContentDpAsState(value, key, canOverflow)") ) @Composable diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt index a43028a340f4..712fe6b2ff50 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt @@ -459,38 +459,11 @@ private class DragControllerImpl( animateTo(targetScene = targetScene, targetOffset = targetOffset) } else { - // We are doing an overscroll animation between scenes. In this case, we can also start - // from the idle position. - - val startFromIdlePosition = swipeTransition.dragOffset == 0f - - if (startFromIdlePosition) { - // If there is a target scene, we start the overscroll animation. - val result = swipes.findUserActionResultStrict(velocity) - if (result == null) { - // We will not animate - swipeTransition.snapToScene(fromScene.key) - return 0f - } - - val newSwipeTransition = - SwipeTransition( - layoutState = layoutState, - coroutineScope = draggableHandler.coroutineScope, - fromScene = fromScene, - result = result, - swipes = swipes, - layoutImpl = draggableHandler.layoutImpl, - orientation = draggableHandler.orientation, - ) - .apply { _currentScene = swipeTransition._currentScene } - - updateTransition(newSwipeTransition) - animateTo(targetScene = fromScene, targetOffset = 0f) - } else { - // We were between two scenes: animate to the initial scene. - animateTo(targetScene = fromScene, targetOffset = 0f) + // We are doing an overscroll preview animation between scenes. + check(fromScene == swipeTransition._currentScene) { + "canChangeScene is false but currentScene != fromScene" } + animateTo(targetScene = fromScene, targetOffset = 0f) } // The onStop animation consumes any remaining velocity. diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt index a30b78049213..79b38563b8f9 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt @@ -17,6 +17,8 @@ package com.android.compose.animation.scene import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.Easing +import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset @@ -140,6 +142,7 @@ interface BaseTransitionBuilder : PropertyTransformationBuilder { fun fractionRange( start: Float? = null, end: Float? = null, + easing: Easing = LinearEasing, builder: PropertyTransformationBuilder.() -> Unit, ) } @@ -182,6 +185,7 @@ interface TransitionBuilder : BaseTransitionBuilder { fun timestampRange( startMillis: Int? = null, endMillis: Int? = null, + easing: Easing = LinearEasing, builder: PropertyTransformationBuilder.() -> Unit, ) diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt index 6515cb8f68ca..a63b19a0306f 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt @@ -18,6 +18,7 @@ package com.android.compose.animation.scene import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.DurationBasedAnimationSpec +import androidx.compose.animation.core.Easing import androidx.compose.animation.core.Spring import androidx.compose.animation.core.SpringSpec import androidx.compose.animation.core.VectorConverter @@ -163,9 +164,10 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder { override fun fractionRange( start: Float?, end: Float?, + easing: Easing, builder: PropertyTransformationBuilder.() -> Unit ) { - range = TransformationRange(start, end) + range = TransformationRange(start, end, easing) builder() range = null } @@ -251,6 +253,7 @@ internal class TransitionBuilderImpl : BaseTransitionBuilderImpl(), TransitionBu override fun timestampRange( startMillis: Int?, endMillis: Int?, + easing: Easing, builder: PropertyTransformationBuilder.() -> Unit ) { if (startMillis != null && (startMillis < 0 || startMillis > durationMillis)) { @@ -263,7 +266,7 @@ internal class TransitionBuilderImpl : BaseTransitionBuilderImpl(), TransitionBu val start = startMillis?.let { it.toFloat() / durationMillis } val end = endMillis?.let { it.toFloat() / durationMillis } - fractionRange(start, end, builder) + fractionRange(start, end, easing, builder) } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt index 77ec89161d43..eda8edeceeb9 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt @@ -16,6 +16,8 @@ package com.android.compose.animation.scene.transformation +import androidx.compose.animation.core.Easing +import androidx.compose.animation.core.LinearEasing import androidx.compose.ui.util.fastCoerceAtLeast import androidx.compose.ui.util.fastCoerceAtMost import androidx.compose.ui.util.fastCoerceIn @@ -90,11 +92,13 @@ internal class RangedPropertyTransformation<T>( data class TransformationRange( val start: Float, val end: Float, + val easing: Easing, ) { constructor( start: Float? = null, - end: Float? = null - ) : this(start ?: BoundUnspecified, end ?: BoundUnspecified) + end: Float? = null, + easing: Easing = LinearEasing, + ) : this(start ?: BoundUnspecified, end ?: BoundUnspecified, easing) init { require(!start.isSpecified() || (start in 0f..1f)) @@ -103,17 +107,20 @@ data class TransformationRange( } /** Reverse this range. */ - fun reversed() = TransformationRange(start = reverseBound(end), end = reverseBound(start)) + fun reversed() = + TransformationRange(start = reverseBound(end), end = reverseBound(start), easing = easing) /** Get the progress of this range given the global [transitionProgress]. */ fun progress(transitionProgress: Float): Float { - return when { - start.isSpecified() && end.isSpecified() -> - ((transitionProgress - start) / (end - start)).fastCoerceIn(0f, 1f) - !start.isSpecified() && !end.isSpecified() -> transitionProgress - end.isSpecified() -> (transitionProgress / end).fastCoerceAtMost(1f) - else -> ((transitionProgress - start) / (1f - start)).fastCoerceAtLeast(0f) - } + val progress = + when { + start.isSpecified() && end.isSpecified() -> + ((transitionProgress - start) / (end - start)).fastCoerceIn(0f, 1f) + !start.isSpecified() && !end.isSpecified() -> transitionProgress + end.isSpecified() -> (transitionProgress / end).fastCoerceAtMost(1f) + else -> ((transitionProgress - start) / (1f - start)).fastCoerceAtLeast(0f) + } + return easing.transform(progress) } private fun Float.isSpecified() = this != BoundUnspecified diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt index 68240b5337fe..bed6cefa459d 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt @@ -16,6 +16,7 @@ package com.android.compose.animation.scene +import androidx.compose.animation.core.CubicBezierEasing import androidx.compose.animation.core.SpringSpec import androidx.compose.animation.core.TweenSpec import androidx.compose.animation.core.spring @@ -107,6 +108,13 @@ class TransitionDslTest { fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) } fractionRange(start = 0.2f) { fade(TestElements.Foo) } fractionRange(end = 0.9f) { fade(TestElements.Foo) } + fractionRange( + start = 0.1f, + end = 0.8f, + easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + ) { + fade(TestElements.Foo) + } } } @@ -118,6 +126,11 @@ class TransitionDslTest { TransformationRange(start = 0.1f, end = 0.8f), TransformationRange(start = 0.2f, end = TransformationRange.BoundUnspecified), TransformationRange(start = TransformationRange.BoundUnspecified, end = 0.9f), + TransformationRange( + start = 0.1f, + end = 0.8f, + CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + ), ) } @@ -130,6 +143,13 @@ class TransitionDslTest { timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) } timestampRange(startMillis = 200) { fade(TestElements.Foo) } timestampRange(endMillis = 400) { fade(TestElements.Foo) } + timestampRange( + startMillis = 100, + endMillis = 300, + easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + ) { + fade(TestElements.Foo) + } } } @@ -141,6 +161,11 @@ class TransitionDslTest { TransformationRange(start = 100 / 500f, end = 300 / 500f), TransformationRange(start = 200 / 500f, end = TransformationRange.BoundUnspecified), TransformationRange(start = TransformationRange.BoundUnspecified, end = 400 / 500f), + TransformationRange( + start = 100 / 500f, + end = 300 / 500f, + easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + ), ) } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt new file mode 100644 index 000000000000..07901f27388d --- /dev/null +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compose.animation.scene.transformation + +import androidx.compose.animation.core.CubicBezierEasing +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.ui.Modifier +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compose.animation.scene.TestElements +import com.android.compose.animation.scene.testTransition +import com.android.compose.test.assertSizeIsEqualTo +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class EasingTest { + @get:Rule val rule = createComposeRule() + + @Test + fun testFractionRangeEasing() { + val easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + rule.testTransition( + fromSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Foo)) }, + toSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Bar)) }, + transition = { + // Scale during 4 frames. + spec = tween(16 * 4, easing = LinearEasing) + fractionRange(easing = easing) { + scaleSize(TestElements.Foo, width = 0f, height = 0f) + scaleSize(TestElements.Bar, width = 0f, height = 0f) + } + }, + ) { + // Foo is entering, is 100dp x 100dp at rest and is scaled by (2, 0.5) during the + // transition so it starts at 200dp x 50dp. + before { onElement(TestElements.Bar).assertDoesNotExist() } + at(0) { + onElement(TestElements.Foo).assertSizeIsEqualTo(100.dp, 100.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(0.dp, 0.dp) + } + at(16) { + // 25% linear progress is mapped to 68.5% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(31.5.dp, 31.5.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(68.5.dp, 68.5.dp) + } + at(32) { + // 50% linear progress is mapped to 89.5% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(10.5.dp, 10.5.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(89.5.dp, 89.5.dp) + } + at(48) { + // 75% linear progress is mapped to 97.8% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(2.2.dp, 2.2.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(97.8.dp, 97.8.dp) + } + after { + onElement(TestElements.Foo).assertDoesNotExist() + onElement(TestElements.Bar).assertSizeIsEqualTo(100.dp, 100.dp) + } + } + } + + @Test + fun testTimestampRangeEasing() { + val easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f) + rule.testTransition( + fromSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Foo)) }, + toSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Bar)) }, + transition = { + // Scale during 4 frames. + spec = tween(16 * 4, easing = LinearEasing) + timestampRange(easing = easing) { + scaleSize(TestElements.Foo, width = 0f, height = 0f) + scaleSize(TestElements.Bar, width = 0f, height = 0f) + } + }, + ) { + // Foo is entering, is 100dp x 100dp at rest and is scaled by (2, 0.5) during the + // transition so it starts at 200dp x 50dp. + before { onElement(TestElements.Bar).assertDoesNotExist() } + at(0) { + onElement(TestElements.Foo).assertSizeIsEqualTo(100.dp, 100.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(0.dp, 0.dp) + } + at(16) { + // 25% linear progress is mapped to 68.5% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(31.5.dp, 31.5.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(68.5.dp, 68.5.dp) + } + at(32) { + // 50% linear progress is mapped to 89.5% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(10.5.dp, 10.5.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(89.5.dp, 89.5.dp) + } + at(48) { + // 75% linear progress is mapped to 97.8% eased progress + onElement(TestElements.Foo).assertSizeIsEqualTo(2.2.dp, 2.2.dp) + onElement(TestElements.Bar).assertSizeIsEqualTo(97.8.dp, 97.8.dp) + } + after { + onElement(TestElements.Foo).assertDoesNotExist() + onElement(TestElements.Bar).assertSizeIsEqualTo(100.dp, 100.dp) + } + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index 0242c2d6b89d..e57a4cbc230e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -1039,6 +1039,22 @@ class CommunalInteractorTest : SysuiTestCase() { assertThat(showCommunalFromOccluded).isTrue() } + @Test + fun showCommunalFromOccluded_enteredOccludedFromDreaming() = + testScope.runTest { + kosmos.setCommunalAvailable(true) + val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded) + assertThat(showCommunalFromOccluded).isFalse() + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.DREAMING, + to = KeyguardState.OCCLUDED, + testScope + ) + + assertThat(showCommunalFromOccluded).isTrue() + } + private fun smartspaceTimer(id: String, timestamp: Long = 0L): CommunalSmartspaceTimer { return CommunalSmartspaceTimer( smartspaceTargetId = id, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt index 4a10d80430e9..8e4876d3c6df 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt @@ -42,6 +42,28 @@ class DozingToLockscreenTransitionViewModelTest : SysuiTestCase() { val underTest = kosmos.dozingToLockscreenTransitionViewModel @Test + fun lockscreenAlpha() = + testScope.runTest { + val lockscreenAlpha by collectValues(underTest.lockscreenAlpha) + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.1f)) + repository.sendTransitionStep(step(0.5f)) + repository.sendTransitionStep(step(1f)) + lockscreenAlpha.forEach { assertThat(it).isEqualTo(1f) } + } + + @Test + fun shortcutsAlpha() = + testScope.runTest { + val shortcutsAlpha by collectValues(underTest.shortcutsAlpha) + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.5f)) + repository.sendTransitionStep(step(1f)) + assertThat(shortcutsAlpha[0]).isEqualTo(0f) + assertThat(shortcutsAlpha[1]).isEqualTo(1f) + } + + @Test fun deviceEntryParentViewShows() = testScope.runTest { val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha) 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 f26c39d0ba6d..2dfff3ffc72b 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 @@ -32,6 +32,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.authentication.shared.model.AuthenticationMethodModel +import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.shared.logging.BouncerUiEvent import com.android.systemui.classifier.FalsingCollector @@ -109,6 +110,7 @@ class SceneContainerStartableTest : SysuiTestCase() { private val sceneInteractor by lazy { kosmos.sceneInteractor } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository } + private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository } private val sysUiState = kosmos.sysUiState private val falsingCollector = mock<FalsingCollector>().also { kosmos.falsingCollector = it } private val fakeSceneDataSource = kosmos.fakeSceneDataSource @@ -275,6 +277,66 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test + fun switchFromLockscreenToGoneAndHideAltBouncerWhenDeviceUnlocked() = + testScope.runTest { + val alternateBouncerVisible by + collectLastValue(bouncerRepository.alternateBouncerVisible) + val currentSceneKey by collectLastValue(sceneInteractor.currentScene) + + bouncerRepository.setAlternateVisible(true) + assertThat(alternateBouncerVisible).isTrue() + + prepareState( + authenticationMethod = AuthenticationMethodModel.Pin, + isDeviceUnlocked = false, + initialSceneKey = Scenes.Lockscreen, + ) + assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) + underTest.start() + + kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) + + assertThat(currentSceneKey).isEqualTo(Scenes.Gone) + assertThat(alternateBouncerVisible).isFalse() + } + + @Test + fun stayOnCurrentSceneAndHideAltBouncerWhenDeviceUnlocked_whenLeaveOpenShade() = + testScope.runTest { + val alternateBouncerVisible by + collectLastValue(bouncerRepository.alternateBouncerVisible) + val currentSceneKey by collectLastValue(sceneInteractor.currentScene) + + kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open + bouncerRepository.setAlternateVisible(true) + assertThat(alternateBouncerVisible).isTrue() + + val transitionState = + prepareState( + authenticationMethod = AuthenticationMethodModel.Pin, + isDeviceUnlocked = false, + initialSceneKey = Scenes.Lockscreen, + ) + assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) + underTest.start() + runCurrent() + + sceneInteractor.changeScene(Scenes.QuickSettings, "switching to qs for test") + transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings) + runCurrent() + assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings) + + kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) + + assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings) + assertThat(alternateBouncerVisible).isFalse() + } + + @Test fun switchFromBouncerToQuickSettingsWhenDeviceUnlocked_whenLeaveOpenShade() = testScope.runTest { val currentSceneKey by collectLastValue(sceneInteractor.currentScene) diff --git a/packages/SystemUI/res/layout/media_projection_app_selector.xml b/packages/SystemUI/res/layout/media_projection_app_selector.xml index b77f78dfc644..3b6a64ffa7d0 100644 --- a/packages/SystemUI/res/layout/media_projection_app_selector.xml +++ b/packages/SystemUI/res/layout/media_projection_app_selector.xml @@ -37,6 +37,7 @@ android:background="@*android:drawable/bottomsheet_background"> <ImageView + android:id="@+id/media_projection_app_selector_icon" android:layout_width="@dimen/media_projection_app_selector_icon_size" android:layout_height="@dimen/media_projection_app_selector_icon_size" android:layout_marginTop="@*android:dimen/chooser_edge_margin_normal" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 2ad6b6a4853c..f8303ea8e1c6 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -291,6 +291,8 @@ <string name="screenrecord_permission_dialog_warning_single_app">When you’re recording an app, anything shown or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string> <!-- Button to start a screen recording of the entire screen in the updated screen record dialog that allows to select an app to record [CHAR LIMIT=50]--> <string name="screenrecord_permission_dialog_continue_entire_screen">Record screen</string> + <!-- Title of the activity that allows to select an app to screen record [CHAR LIMIT=70] --> + <string name="screenrecord_app_selector_title">Choose app to record</string> <!-- Label for a switch to enable recording audio [CHAR LIMIT=NONE]--> <string name="screenrecord_audio_label">Record audio</string> @@ -1362,8 +1364,8 @@ <!-- Media projection permission dialog warning text for system services. [CHAR LIMIT=NONE] --> <string name="media_projection_sys_service_dialog_warning">The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string> - <!-- Title of the dialog that allows to select an app to share or record [CHAR LIMIT=NONE] --> - <string name="screen_share_permission_app_selector_title">Share or record an app</string> + <!-- Title of the activity that allows users to select an app to share or record [CHAR LIMIT=NONE] --> + <string name="screen_share_generic_app_selector_title">Share or record an app</string> <!-- Media projection that launched from 1P/3P apps --> <!-- 1P/3P app media projection permission dialog title. [CHAR LIMIT=NONE] --> @@ -1381,6 +1383,8 @@ <string name="media_projection_entry_app_permission_dialog_continue_entire_screen">Share screen</string> <!-- 1P/3P apps disabled the single app projection option. [CHAR LIMIT=NONE] --> <string name="media_projection_entry_app_permission_dialog_single_app_disabled"><xliff:g id="app_name" example="Meet">%1$s</xliff:g> has disabled this option</string> + <!-- Title of the activity that allows users to select an app to share to a 1P/3P app [CHAR LIMIT=70] --> + <string name="media_projection_entry_share_app_selector_title">Choose app to share</string> <!-- Casting that launched by SysUI (i.e. when there is no app name) --> <!-- System casting media projection permission dialog title. [CHAR LIMIT=100] --> @@ -1395,6 +1399,8 @@ <string name="media_projection_entry_cast_permission_dialog_warning_single_app">When you’re casting an app, anything shown or played in that app is visible. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string> <!-- System casting media projection permission button to continue for SysUI casting. [CHAR LIMIT=60] --> <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen">Cast screen</string> + <!-- Title of the activity that allows users to select an app to cast [CHAR LIMIT=70] --> + <string name="media_projection_entry_cast_app_selector_title">Choose app to cast</string> <!-- Other sharing (not recording nor casting) that launched by SysUI (currently not in use) --> <!-- System sharing media projection permission dialog title. [CHAR LIMIT=100] --> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java index 68d2eb358105..41ad4373455e 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java @@ -26,6 +26,7 @@ import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.BackDispositionMode; import android.os.Build; import android.os.Handler; import android.os.Message; @@ -105,8 +106,8 @@ public class Utilities { * @return updated set of flags from InputMethodService based off {@param oldHints} * Leaves original hints unmodified */ - public static int calculateBackDispositionHints(int oldHints, int backDisposition, - boolean imeShown, boolean showImeSwitcher) { + public static int calculateBackDispositionHints(int oldHints, + @BackDispositionMode int backDisposition, boolean imeShown, boolean showImeSwitcher) { int hints = oldHints; switch (backDisposition) { case InputMethodService.BACK_DISPOSITION_DEFAULT: diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index 6aaaf3d4ce9a..fbeb71514db4 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -184,7 +184,11 @@ constructor( keyguardTransitionInteractor.startedKeyguardTransitionStep .filter { step -> step.to == KeyguardState.OCCLUDED } .combine(isCommunalAvailable, ::Pair) - .map { (step, available) -> available && step.from == KeyguardState.GLANCEABLE_HUB } + .map { (step, available) -> + available && + (step.from == KeyguardState.GLANCEABLE_HUB || + step.from == KeyguardState.DREAMING) + } .flowOn(bgDispatcher) .stateIn( scope = applicationScope, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java index 32731117a8f6..79f4568d73be 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java @@ -33,6 +33,7 @@ import com.android.systemui.display.ui.viewmodel.ConnectingDisplayViewModel; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerImpl; import com.android.systemui.doze.DozeHost; +import com.android.systemui.inputdevice.tutorial.KeyboardTouchpadTutorialModule; import com.android.systemui.keyboard.shortcut.ShortcutHelperModule; import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule; import com.android.systemui.keyguard.ui.view.layout.blueprints.KeyguardBlueprintModule; @@ -77,7 +78,7 @@ import com.android.systemui.statusbar.policy.IndividualSensorPrivacyControllerIm import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl; import com.android.systemui.toast.ToastModule; -import com.android.systemui.touchpad.tutorial.TouchpadKeyboardTutorialModule; +import com.android.systemui.touchpad.tutorial.TouchpadTutorialModule; import com.android.systemui.unfold.SysUIUnfoldStartableModule; import com.android.systemui.unfold.UnfoldTransitionModule; import com.android.systemui.util.kotlin.SysUICoroutinesModule; @@ -122,6 +123,7 @@ import javax.inject.Named; KeyboardShortcutsModule.class, KeyguardBlueprintModule.class, KeyguardSectionsModule.class, + KeyboardTouchpadTutorialModule.class, MediaModule.class, MediaMuteAwaitConnectionCli.StartableModule.class, MultiUserUtilsModule.class, @@ -142,7 +144,7 @@ import javax.inject.Named; SysUIUnfoldStartableModule.class, UnfoldTransitionModule.Startables.class, ToastModule.class, - TouchpadKeyboardTutorialModule.class, + TouchpadTutorialModule.class, VolumeModule.class, WallpaperModule.class, ShortcutHelperModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index b0f2c18db565..cbea87676d3a 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -258,13 +258,6 @@ abstract class SystemUICoreStartableModule { @Binds @IntoMap - @ClassKey(KeyboardTouchpadTutorialCoreStartable::class) - abstract fun bindKeyboardTouchpadTutorialCoreStartable( - listener: KeyboardTouchpadTutorialCoreStartable - ): CoreStartable - - @Binds - @IntoMap @ClassKey(PhysicalKeyboardCoreStartable::class) abstract fun bindKeyboardCoreStartable(listener: PhysicalKeyboardCoreStartable): CoreStartable diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java index 0b336143c34a..6fd4d33806a3 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java @@ -16,8 +16,6 @@ package com.android.systemui.doze; -import java.util.concurrent.Executor; - /** * Forwards the currently used brightness to {@link DozeHost}. */ @@ -25,9 +23,8 @@ public class DozeBrightnessHostForwarder extends DozeMachine.Service.Delegate { private final DozeHost mHost; - public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host, - Executor bgExecutor) { - super(wrappedService, bgExecutor); + public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host) { + super(wrappedService); mHost = host; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index 5bfcc975d02d..cdcb03e59e8a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -253,9 +253,11 @@ public class DozeLog implements Dumpable { /** * Appends display state changed event to the logs * @param displayState new DozeMachine state + * @param afterRequest whether the request has successfully been sent else false for it's + * about to be requested */ - public void traceDisplayState(int displayState) { - mLogger.logDisplayStateChanged(displayState); + public void traceDisplayState(int displayState, boolean afterRequest) { + mLogger.logDisplayStateChanged(displayState, afterRequest); } /** @@ -402,18 +404,22 @@ public class DozeLog implements Dumpable { /** * Appends new AOD screen brightness to logs * @param brightness display brightness setting between 1 and 255 + * @param afterRequest whether the request has successfully been sent else false for it's + * about to be requested */ - public void traceDozeScreenBrightness(int brightness) { - mLogger.logDozeScreenBrightness(brightness); + public void traceDozeScreenBrightness(int brightness, boolean afterRequest) { + mLogger.logDozeScreenBrightness(brightness, afterRequest); } /** * Appends new AOD screen brightness to logs * @param brightness display brightness setting between {@link PowerManager#BRIGHTNESS_MIN} and * {@link PowerManager#BRIGHTNESS_MAX} + * @param afterRequest whether the request has successfully been sent else false for it's + * about to be requested */ - public void traceDozeScreenBrightnessFloat(float brightness) { - mLogger.logDozeScreenBrightnessFloat(brightness); + public void traceDozeScreenBrightnessFloat(float brightness, boolean afterRequest) { + mLogger.logDozeScreenBrightnessFloat(brightness, afterRequest); } /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt index a31dbec242fe..71287314102c 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt @@ -32,23 +32,18 @@ import java.util.Locale import javax.inject.Inject /** Interface for logging messages to the [DozeLog]. */ -class DozeLogger @Inject constructor( - @DozeLog private val buffer: LogBuffer -) { +class DozeLogger @Inject constructor(@DozeLog private val buffer: LogBuffer) { fun logPickupWakeup(isWithinVibrationThreshold: Boolean) { - buffer.log(TAG, DEBUG, { - bool1 = isWithinVibrationThreshold - }, { - "PickupWakeup withinVibrationThreshold=$bool1" - }) + buffer.log( + TAG, + DEBUG, + { bool1 = isWithinVibrationThreshold }, + { "PickupWakeup withinVibrationThreshold=$bool1" } + ) } fun logPulseStart(@Reason reason: Int) { - buffer.log(TAG, INFO, { - int1 = reason - }, { - "Pulse start, reason=${reasonToString(int1)}" - }) + buffer.log(TAG, INFO, { int1 = reason }, { "Pulse start, reason=${reasonToString(int1)}" }) } fun logPulseFinish() { @@ -60,52 +55,51 @@ class DozeLogger @Inject constructor( } fun logDozing(isDozing: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isDozing - }, { - "Dozing=$bool1" - }) + buffer.log(TAG, INFO, { bool1 = isDozing }, { "Dozing=$bool1" }) } fun logDozingChanged(isDozing: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isDozing - }, { - "Dozing changed dozing=$bool1" - }) + buffer.log(TAG, INFO, { bool1 = isDozing }, { "Dozing changed dozing=$bool1" }) } fun logPowerSaveChanged(powerSaveActive: Boolean, nextState: DozeMachine.State) { - buffer.log(TAG, INFO, { - bool1 = powerSaveActive - str1 = nextState.name - }, { - "Power save active=$bool1 nextState=$str1" - }) + buffer.log( + TAG, + INFO, + { + bool1 = powerSaveActive + str1 = nextState.name + }, + { "Power save active=$bool1 nextState=$str1" } + ) } fun logAlwaysOnSuppressedChange(isAodSuppressed: Boolean, nextState: DozeMachine.State) { - buffer.log(TAG, INFO, { - bool1 = isAodSuppressed - str1 = nextState.name - }, { - "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1" - }) - } - - fun logFling( - expand: Boolean, - aboveThreshold: Boolean, - screenOnFromTouch: Boolean - ) { - buffer.log(TAG, DEBUG, { - bool1 = expand - bool2 = aboveThreshold - bool4 = screenOnFromTouch - }, { - "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " + - "screenOnFromTouch=$bool4" - }) + buffer.log( + TAG, + INFO, + { + bool1 = isAodSuppressed + str1 = nextState.name + }, + { "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1" } + ) + } + + fun logFling(expand: Boolean, aboveThreshold: Boolean, screenOnFromTouch: Boolean) { + buffer.log( + TAG, + DEBUG, + { + bool1 = expand + bool2 = aboveThreshold + bool4 = screenOnFromTouch + }, + { + "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " + + "screenOnFromTouch=$bool4" + } + ) } fun logEmergencyCall() { @@ -113,280 +107,314 @@ class DozeLogger @Inject constructor( } fun logKeyguardBouncerChanged(isShowing: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isShowing - }, { - "Keyguard bouncer changed, showing=$bool1" - }) + buffer.log(TAG, INFO, { bool1 = isShowing }, { "Keyguard bouncer changed, showing=$bool1" }) } fun logScreenOn(isPulsing: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isPulsing - }, { - "Screen on, pulsing=$bool1" - }) + buffer.log(TAG, INFO, { bool1 = isPulsing }, { "Screen on, pulsing=$bool1" }) } fun logScreenOff(why: Int) { - buffer.log(TAG, INFO, { - int1 = why - }, { - "Screen off, why=$int1" - }) + buffer.log(TAG, INFO, { int1 = why }, { "Screen off, why=$int1" }) } fun logMissedTick(delay: String) { - buffer.log(TAG, ERROR, { - str1 = delay - }, { - "Missed AOD time tick by $str1" - }) + buffer.log(TAG, ERROR, { str1 = delay }, { "Missed AOD time tick by $str1" }) } fun logTimeTickScheduled(whenAt: Long, triggerAt: Long) { - buffer.log(TAG, DEBUG, { - long1 = whenAt - long2 = triggerAt - }, { - "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " + - "triggerAt=${DATE_FORMAT.format(Date(long2))}" - }) + buffer.log( + TAG, + DEBUG, + { + long1 = whenAt + long2 = triggerAt + }, + { + "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " + + "triggerAt=${DATE_FORMAT.format(Date(long2))}" + } + ) } fun logKeyguardVisibilityChange(isVisible: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isVisible - }, { - "Keyguard visibility change, isVisible=$bool1" - }) + buffer.log( + TAG, + INFO, + { bool1 = isVisible }, + { "Keyguard visibility change, isVisible=$bool1" } + ) } fun logPendingUnscheduleTimeTick(isPending: Boolean, isTimeTickScheduled: Boolean) { - buffer.log(TAG, INFO, { - bool1 = isPending - bool2 = isTimeTickScheduled - }, { - "Pending unschedule time tick, isPending=$bool1, isTimeTickScheduled:$bool2" - }) + 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 - }, { - "Doze state changed to $str1" - }) + buffer.log(TAG, INFO, { str1 = state.name }, { "Doze state changed to $str1" }) } fun logStateChangedSent(state: DozeMachine.State) { - buffer.log(TAG, INFO, { - str1 = state.name - }, { - "Doze state sent to all DozeMachineParts stateSent=$str1" - }) + buffer.log( + TAG, + INFO, + { str1 = state.name }, + { "Doze state sent to all DozeMachineParts stateSent=$str1" } + ) } fun logDisplayStateDelayedByUdfps(delayedDisplayState: Int) { - buffer.log(TAG, INFO, { - str1 = Display.stateToString(delayedDisplayState) - }, { - "Delaying display state change to: $str1 due to UDFPS activity" - }) - } - - fun logDisplayStateChanged(displayState: Int) { - buffer.log(TAG, INFO, { - str1 = Display.stateToString(displayState) - }, { - "Display state changed to $str1" - }) + buffer.log( + TAG, + INFO, + { str1 = Display.stateToString(delayedDisplayState) }, + { "Delaying display state change to: $str1 due to UDFPS activity" } + ) + } + + fun logDisplayStateChanged(displayState: Int, afterRequest: Boolean) { + buffer.log( + TAG, + INFO, + { + str1 = Display.stateToString(displayState) + bool1 = afterRequest + }, + { "Display state ${if (bool1) "changed" else "requested"} to $str1" } + ) } fun logWakeDisplay(isAwake: Boolean, @Reason reason: Int) { - buffer.log(TAG, DEBUG, { - bool1 = isAwake - int1 = reason - }, { - "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}" - }) + buffer.log( + TAG, + DEBUG, + { + bool1 = isAwake + int1 = reason + }, + { "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}" } + ) } fun logProximityResult(isNear: Boolean, millis: Long, @Reason reason: Int) { - buffer.log(TAG, DEBUG, { - bool1 = isNear - long1 = millis - int1 = reason - }, { - "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1" - }) + buffer.log( + TAG, + DEBUG, + { + bool1 = isNear + long1 = millis + int1 = reason + }, + { "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1" } + ) } fun logPostureChanged(posture: Int, partUpdated: String) { - buffer.log(TAG, INFO, { - int1 = posture - str1 = partUpdated - }, { - "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" + - " partUpdated=$str1" - }) + buffer.log( + TAG, + INFO, + { + int1 = posture + str1 = partUpdated + }, + { + "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" + + " partUpdated=$str1" + } + ) } /** - * Log why a pulse was dropped and the current doze machine state. The state can be null - * if the DozeMachine is the middle of transitioning between states. + * Log why a pulse was dropped and the current doze machine state. The state can be null if the + * DozeMachine is the middle of transitioning between states. */ fun logPulseDropped(from: String, state: DozeMachine.State?) { - buffer.log(TAG, INFO, { - str1 = from - str2 = state?.name - }, { - "Pulse dropped, cannot pulse from=$str1 state=$str2" - }) + buffer.log( + TAG, + INFO, + { + str1 = from + str2 = state?.name + }, + { "Pulse dropped, cannot pulse from=$str1 state=$str2" } + ) } fun logSensorEventDropped(sensorEvent: Int, reason: String) { - buffer.log(TAG, INFO, { - int1 = sensorEvent - str1 = reason - }, { - "SensorEvent [$int1] dropped, reason=$str1" - }) + buffer.log( + TAG, + INFO, + { + int1 = sensorEvent + str1 = reason + }, + { "SensorEvent [$int1] dropped, reason=$str1" } + ) } fun logPulseEvent(pulseEvent: String, dozing: Boolean, pulseReason: String) { - buffer.log(TAG, DEBUG, { - str1 = pulseEvent - bool1 = dozing - str2 = pulseReason - }, { - "Pulse-$str1 dozing=$bool1 pulseReason=$str2" - }) + buffer.log( + TAG, + DEBUG, + { + str1 = pulseEvent + bool1 = dozing + str2 = pulseReason + }, + { "Pulse-$str1 dozing=$bool1 pulseReason=$str2" } + ) } fun logPulseDropped(reason: String) { - buffer.log(TAG, INFO, { - str1 = reason - }, { - "Pulse dropped, why=$str1" - }) + buffer.log(TAG, INFO, { str1 = reason }, { "Pulse dropped, why=$str1" }) } fun logPulseTouchDisabledByProx(disabled: Boolean) { - buffer.log(TAG, DEBUG, { - bool1 = disabled - }, { - "Pulse touch modified by prox, disabled=$bool1" - }) + buffer.log( + TAG, + DEBUG, + { bool1 = disabled }, + { "Pulse touch modified by prox, disabled=$bool1" } + ) } fun logSensorTriggered(@Reason reason: Int) { - buffer.log(TAG, DEBUG, { - int1 = reason - }, { - "Sensor triggered, type=${reasonToString(int1)}" - }) + buffer.log( + TAG, + DEBUG, + { int1 = reason }, + { "Sensor triggered, type=${reasonToString(int1)}" } + ) } fun logAlwaysOnSuppressed(state: DozeMachine.State, reason: String) { - buffer.log(TAG, INFO, { - str1 = state.name - str2 = reason - }, { - "Always-on state suppressed, suppressed state=$str1 reason=$str2" - }) + buffer.log( + TAG, + INFO, + { + str1 = state.name + str2 = reason + }, + { "Always-on state suppressed, suppressed state=$str1 reason=$str2" } + ) } fun logImmediatelyEndDoze(reason: String) { - buffer.log(TAG, INFO, { - str1 = reason - }, { - "Doze immediately ended due to $str1" - }) - } - - fun logDozeScreenBrightness(brightness: Int) { - buffer.log(TAG, INFO, { - int1 = brightness - }, { - "Doze screen brightness set (int), brightness=$int1" - }) - } - - fun logDozeScreenBrightnessFloat(brightness: Float) { - buffer.log(TAG, INFO, { - double1 = brightness.toDouble() - }, { - "Doze screen brightness set (float), brightness=$double1" - }) + buffer.log(TAG, INFO, { str1 = reason }, { "Doze immediately ended due to $str1" }) + } + + fun logDozeScreenBrightness(brightness: Int, afterRequest: Boolean) { + buffer.log( + TAG, + INFO, + { + int1 = brightness + bool1 = afterRequest + }, + { + "Doze screen brightness ${if (bool1) "set" else "requested"}" + + " (int), brightness=$int1" + } + ) + } + + fun logDozeScreenBrightnessFloat(brightness: Float, afterRequest: Boolean) { + buffer.log( + TAG, + INFO, + { + double1 = brightness.toDouble() + bool1 = afterRequest + }, + { + "Doze screen brightness ${if (bool1) "set" else "requested"}" + + " (float), brightness=$double1" + } + ) } fun logSetAodDimmingScrim(scrimOpacity: Long) { - buffer.log(TAG, INFO, { - long1 = scrimOpacity - }, { - "Doze aod dimming scrim opacity set, opacity=$long1" - }) + buffer.log( + TAG, + INFO, + { long1 = scrimOpacity }, + { "Doze aod dimming scrim opacity set, opacity=$long1" } + ) } fun logCarModeEnded() { - buffer.log(TAG, INFO, {}, { - "Doze car mode ended" - }) + buffer.log(TAG, INFO, {}, { "Doze car mode ended" }) } fun logCarModeStarted() { - buffer.log(TAG, INFO, {}, { - "Doze car mode started" - }) + buffer.log(TAG, INFO, {}, { "Doze car mode started" }) } fun logSensorRegisterAttempt(sensorInfo: String, successfulRegistration: Boolean) { - buffer.log(TAG, INFO, { - str1 = sensorInfo - bool1 = successfulRegistration - }, { - "Register sensor. Success=$bool1 sensor=$str1" - }) + buffer.log( + TAG, + INFO, + { + str1 = sensorInfo + bool1 = successfulRegistration + }, + { "Register sensor. Success=$bool1 sensor=$str1" } + ) } fun logSensorUnregisterAttempt(sensorInfo: String, successfulUnregister: Boolean) { - buffer.log(TAG, INFO, { - str1 = sensorInfo - bool1 = successfulUnregister - }, { - "Unregister sensor. Success=$bool1 sensor=$str1" - }) + buffer.log( + TAG, + INFO, + { + str1 = sensorInfo + bool1 = successfulUnregister + }, + { "Unregister sensor. Success=$bool1 sensor=$str1" } + ) } fun logSensorUnregisterAttempt( - sensorInfo: String, - successfulUnregister: Boolean, - reason: String + sensorInfo: String, + successfulUnregister: Boolean, + reason: String ) { - buffer.log(TAG, INFO, { - str1 = sensorInfo - bool1 = successfulUnregister - str2 = reason - }, { - "Unregister sensor. reason=$str2. Success=$bool1 sensor=$str1" - }) + buffer.log( + TAG, + INFO, + { + str1 = sensorInfo + bool1 = successfulUnregister + str2 = reason + }, + { "Unregister sensor. reason=$str2. Success=$bool1 sensor=$str1" } + ) } fun logSkipSensorRegistration(sensor: String) { - buffer.log(TAG, DEBUG, { - str1 = sensor - }, { - "Skipping sensor registration because its already registered. sensor=$str1" - }) + buffer.log( + TAG, + DEBUG, + { str1 = sensor }, + { "Skipping sensor registration because its already registered. sensor=$str1" } + ) } fun logSetIgnoreTouchWhilePulsing(ignoreTouchWhilePulsing: Boolean) { - buffer.log(TAG, DEBUG, { - bool1 = ignoreTouchWhilePulsing - }, { - "Prox changed while pulsing. setIgnoreTouchWhilePulsing=$bool1" - }) + buffer.log( + TAG, + DEBUG, + { bool1 = ignoreTouchWhilePulsing }, + { "Prox changed while pulsing. setIgnoreTouchWhilePulsing=$bool1" } + ) } fun log(@CompileTimeConstant msg: String) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index 8198ef41bb49..e02e3fbc339b 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -39,7 +39,6 @@ import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.concurrent.Executor; import javax.inject.Inject; @@ -232,7 +231,6 @@ public class DozeMachine { } void onScreenState(int state) { - mDozeLog.traceDisplayState(state); for (Part part : mParts) { part.onScreenState(state); } @@ -516,11 +514,9 @@ public class DozeMachine { class Delegate implements Service { private final Service mDelegate; - private final Executor mBgExecutor; - public Delegate(Service delegate, Executor bgExecutor) { + public Delegate(Service delegate) { mDelegate = delegate; - mBgExecutor = bgExecutor; } @Override @@ -540,16 +536,12 @@ public class DozeMachine { @Override public void setDozeScreenBrightness(int brightness) { - mBgExecutor.execute(() -> { - mDelegate.setDozeScreenBrightness(brightness); - }); + mDelegate.setDozeScreenBrightness(brightness); } @Override public void setDozeScreenBrightnessFloat(float brightness) { - mBgExecutor.execute(() -> { - mDelegate.setDozeScreenBrightnessFloat(brightness); - }); + mDelegate.setDozeScreenBrightnessFloat(brightness); } } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java index 8d4447285af2..25c2c39f3e25 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java @@ -22,16 +22,14 @@ import androidx.annotation.VisibleForTesting; import com.android.systemui.statusbar.phone.DozeParameters; -import java.util.concurrent.Executor; - /** * Prevents usage of doze screen states on devices that don't support them. */ public class DozeScreenStatePreventingAdapter extends DozeMachine.Service.Delegate { @VisibleForTesting - DozeScreenStatePreventingAdapter(DozeMachine.Service inner, Executor bgExecutor) { - super(inner, bgExecutor); + DozeScreenStatePreventingAdapter(DozeMachine.Service inner) { + super(inner); } @Override @@ -49,8 +47,8 @@ public class DozeScreenStatePreventingAdapter extends DozeMachine.Service.Delega * return a new instance of {@link DozeScreenStatePreventingAdapter} wrapping {@code inner}. */ public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner, - DozeParameters params, Executor bgExecutor) { - return isNeeded(params) ? new DozeScreenStatePreventingAdapter(inner, bgExecutor) : inner; + DozeParameters params) { + return isNeeded(params) ? new DozeScreenStatePreventingAdapter(inner) : inner; } private static boolean isNeeded(DozeParameters params) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index ba38ab0583d4..2e372ff435c2 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -23,6 +23,7 @@ import android.os.SystemClock; import android.service.dreams.DreamService; import android.util.Log; +import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.doze.dagger.DozeComponent; import com.android.systemui.plugins.DozeServicePlugin; import com.android.systemui.plugins.DozeServicePlugin.RequestDoze; @@ -31,6 +32,7 @@ import com.android.systemui.plugins.PluginManager; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.concurrent.Executor; import javax.inject.Inject; @@ -43,9 +45,14 @@ public class DozeService extends DreamService private DozeMachine mDozeMachine; private DozeServicePlugin mDozePlugin; private PluginManager mPluginManager; + private DozeLog mDozeLog; + private Executor mBgExecutor; @Inject - public DozeService(DozeComponent.Builder dozeComponentBuilder, PluginManager pluginManager) { + public DozeService(DozeComponent.Builder dozeComponentBuilder, PluginManager pluginManager, + DozeLog dozeLog, @UiBackground Executor bgExecutor) { + mDozeLog = dozeLog; + mBgExecutor = bgExecutor; mDozeComponentBuilder = dozeComponentBuilder; setDebug(DEBUG); mPluginManager = pluginManager; @@ -143,9 +150,29 @@ public class DozeService extends DreamService @Override public void setDozeScreenState(int state) { + mDozeLog.traceDisplayState(state, /* afterRequest */ false); super.setDozeScreenState(state); + mDozeLog.traceDisplayState(state, /* afterRequest */ true); if (mDozeMachine != null) { mDozeMachine.onScreenState(state); } } + + @Override + public void setDozeScreenBrightness(int brightness) { + mBgExecutor.execute(() -> { + mDozeLog.traceDozeScreenBrightness(brightness, /* afterRequest */ false); + super.setDozeScreenBrightness(brightness); + mDozeLog.traceDozeScreenBrightness(brightness, /* afterRequest */ true); + }); + } + + @Override + public void setDozeScreenBrightnessFloat(float brightness) { + mBgExecutor.execute(() -> { + mDozeLog.traceDozeScreenBrightnessFloat(brightness, /* afterRequest */ false); + super.setDozeScreenBrightnessFloat(brightness); + mDozeLog.traceDozeScreenBrightnessFloat(brightness, /* afterRequest */ true); + }); + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java index f7773f1888b3..cfc952df83e8 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java @@ -22,16 +22,14 @@ import androidx.annotation.VisibleForTesting; import com.android.systemui.statusbar.phone.DozeParameters; -import java.util.concurrent.Executor; - /** * Prevents usage of doze screen states on devices that don't support them. */ public class DozeSuspendScreenStatePreventingAdapter extends DozeMachine.Service.Delegate { @VisibleForTesting - DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner, Executor bgExecutor) { - super(inner, bgExecutor); + DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) { + super(inner); } @Override @@ -47,8 +45,8 @@ public class DozeSuspendScreenStatePreventingAdapter extends DozeMachine.Service * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}. */ public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner, - DozeParameters params, Executor bgExecutor) { - return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner, bgExecutor) + DozeParameters params) { + return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner) : inner; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java index 8c3de4bd1928..f383a04eb3ee 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java +++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java @@ -19,7 +19,6 @@ package com.android.systemui.doze.dagger; import android.content.Context; import android.hardware.Sensor; -import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.doze.DozeAuthRemover; import com.android.systemui.doze.DozeBrightnessHostForwarder; import com.android.systemui.doze.DozeDockHandler; @@ -51,7 +50,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.concurrent.Executor; /** Dagger module for use with {@link com.android.systemui.doze.dagger.DozeComponent}. */ @Module @@ -60,13 +58,13 @@ public abstract class DozeModule { @DozeScope @WrappedService static DozeMachine.Service providesWrappedService(DozeMachine.Service dozeMachineService, - DozeHost dozeHost, DozeParameters dozeParameters, @UiBackground Executor bgExecutor) { + DozeHost dozeHost, DozeParameters dozeParameters) { DozeMachine.Service wrappedService = dozeMachineService; - wrappedService = new DozeBrightnessHostForwarder(wrappedService, dozeHost, bgExecutor); + wrappedService = new DozeBrightnessHostForwarder(wrappedService, dozeHost); wrappedService = DozeScreenStatePreventingAdapter.wrapIfNeeded( - wrappedService, dozeParameters, bgExecutor); + wrappedService, dozeParameters); wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded( - wrappedService, dozeParameters, bgExecutor); + wrappedService, dozeParameters); return wrappedService; } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt new file mode 100644 index 000000000000..8e6cb077a25e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt @@ -0,0 +1,50 @@ +/* + * 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.inputdevice.tutorial + +import android.app.Activity +import com.android.systemui.CoreStartable +import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity +import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor +import dagger.Binds +import dagger.BindsOptionalOf +import dagger.Module +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +interface KeyboardTouchpadTutorialModule { + + @Binds + @IntoMap + @ClassKey(KeyboardTouchpadTutorialCoreStartable::class) + fun bindKeyboardTouchpadTutorialCoreStartable( + listener: KeyboardTouchpadTutorialCoreStartable + ): CoreStartable + + @Binds + @IntoMap + @ClassKey(KeyboardTouchpadTutorialActivity::class) + fun activity(impl: KeyboardTouchpadTutorialActivity): Activity + + // TouchpadModule dependencies below + // all should be optional to not introduce touchpad dependency in all sysui variants + + @BindsOptionalOf fun touchpadScreensProvider(): TouchpadTutorialScreensProvider + + @BindsOptionalOf fun touchpadGesturesInteractor(): TouchpadGesturesInteractor +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadKeyboardTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/TouchpadTutorialScreensProvider.kt index 8ba8db498a36..bd3e771f40bc 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadKeyboardTutorialModule.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/TouchpadTutorialScreensProvider.kt @@ -14,20 +14,13 @@ * limitations under the License. */ -package com.android.systemui.touchpad.tutorial +package com.android.systemui.inputdevice.tutorial -import android.app.Activity -import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity -import dagger.Binds -import dagger.Module -import dagger.multibindings.ClassKey -import dagger.multibindings.IntoMap +import androidx.compose.runtime.Composable -@Module -interface TouchpadKeyboardTutorialModule { +interface TouchpadTutorialScreensProvider { - @Binds - @IntoMap - @ClassKey(TouchpadTutorialActivity::class) - fun activity(impl: TouchpadTutorialActivity): Activity + @Composable fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) + + @Composable fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionKeyTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionKeyTutorialScreen.kt index f7f26314bb50..c5b0ca78d65a 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionKeyTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionKeyTutorialScreen.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.touchpad.tutorial.ui.composable +package com.android.systemui.inputdevice.tutorial.ui.composable import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Box @@ -34,9 +34,9 @@ import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.type import com.airbnb.lottie.compose.rememberLottieDynamicProperties import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.FINISHED +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NOT_STARTED import com.android.systemui.res.R -import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.FINISHED -import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.NOT_STARTED @Composable fun ActionKeyTutorialScreen( diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionTutorialContent.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionTutorialContent.kt index 2b7f6742e335..c50b7dc06265 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionTutorialContent.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionTutorialContent.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.touchpad.tutorial.ui.composable +package com.android.systemui.inputdevice.tutorial.ui.composable import android.graphics.ColorFilter import android.graphics.PorterDuff @@ -60,9 +60,9 @@ import com.airbnb.lottie.compose.LottieDynamicProperty import com.airbnb.lottie.compose.animateLottieCompositionAsState import com.airbnb.lottie.compose.rememberLottieComposition import com.airbnb.lottie.compose.rememberLottieDynamicProperty -import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.FINISHED -import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.IN_PROGRESS -import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.NOT_STARTED +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.FINISHED +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.IN_PROGRESS +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NOT_STARTED enum class TutorialActionState { NOT_STARTED, diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialComponents.kt index f2276c8be71d..01ad585019d2 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialComponents.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.touchpad.tutorial.ui.composable +package com.android.systemui.inputdevice.tutorial.ui.composable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialScreenConfig.kt index d76ceb9380cd..0406bb9e6fef 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialScreenConfig.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.touchpad.tutorial.ui.composable +package com.android.systemui.inputdevice.tutorial.ui.composable import androidx.annotation.RawRes import androidx.annotation.StringRes diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt new file mode 100644 index 000000000000..3e382d669e5d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt @@ -0,0 +1,74 @@ +/* + * 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.inputdevice.tutorial.ui.view + +import android.os.Bundle +import android.view.WindowManager +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels +import androidx.compose.runtime.Composable +import com.android.compose.theme.PlatformTheme +import com.android.systemui.inputdevice.tutorial.TouchpadTutorialScreensProvider +import com.android.systemui.inputdevice.tutorial.ui.viewmodel.KeyboardTouchpadTutorialViewModel +import java.util.Optional +import javax.inject.Inject + +/** + * Activity for out of the box experience for keyboard and touchpad. Note that it's possible that + * either of them are actually not connected when this is launched + */ +class KeyboardTouchpadTutorialActivity +@Inject +constructor( + private val viewModelFactory: KeyboardTouchpadTutorialViewModel.Factory, + private val touchpadTutorialScreensProvider: Optional<TouchpadTutorialScreensProvider>, +) : ComponentActivity() { + + private val vm by + viewModels<KeyboardTouchpadTutorialViewModel>(factoryProducer = { viewModelFactory }) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + PlatformTheme { + KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) { finish() } + } + } + // required to handle 3+ fingers on touchpad + window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY) + } + + override fun onResume() { + super.onResume() + vm.onOpened() + } + + override fun onPause() { + super.onPause() + vm.onClosed() + } +} + +@Composable +fun KeyboardTouchpadTutorialContainer( + vm: KeyboardTouchpadTutorialViewModel, + touchpadTutorialScreensProvider: Optional<TouchpadTutorialScreensProvider>, + closeTutorial: () -> Unit +) {} diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt new file mode 100644 index 000000000000..39b1ec0f0390 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt @@ -0,0 +1,62 @@ +/* + * 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.inputdevice.tutorial.ui.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor +import java.util.Optional +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +class KeyboardTouchpadTutorialViewModel( + private val gesturesInteractor: Optional<TouchpadGesturesInteractor> +) : ViewModel() { + + private val _screen = MutableStateFlow(Screen.BACK_GESTURE) + val screen: StateFlow<Screen> = _screen + + fun goTo(screen: Screen) { + _screen.value = screen + } + + fun onOpened() { + gesturesInteractor.ifPresent { it.disableGestures() } + } + + fun onClosed() { + gesturesInteractor.ifPresent { it.enableGestures() } + } + + class Factory + @Inject + constructor(private val gesturesInteractor: Optional<TouchpadGesturesInteractor>) : + ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create(modelClass: Class<T>): T { + return KeyboardTouchpadTutorialViewModel(gesturesInteractor) as T + } + } +} + +enum class Screen { + BACK_GESTURE, + HOME_GESTURE, + ACTION_KEY +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 1f3df95b6e28..17c5977fc80a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -42,6 +42,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.Flags.notifyPowerManagerUserActivityBackground; import static com.android.systemui.Flags.refactorGetCurrentUser; +import static com.android.systemui.Flags.relockWithPowerButtonImmediately; import static com.android.systemui.Flags.translucentOccludingActivityFix; import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS; @@ -477,6 +478,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private boolean mUnlockingAndWakingFromDream = false; private boolean mHideAnimationRun = false; private boolean mHideAnimationRunning = false; + private boolean mIsKeyguardExitAnimationCanceled = false; private SoundPool mLockSounds; private int mLockSoundId; @@ -1588,10 +1590,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled( mSelectedUserInteractor.getSelectedUserId()), - true /* forceCallbacks */); + true /* forceCallbacks */, "setupLocked - keyguard service enabled"); } else { // The system's keyguard is disabled or missing. - setShowingLocked(false /* showing */, true /* forceCallbacks */); + setShowingLocked(false /* showing */, true /* forceCallbacks */, + "setupLocked - keyguard service disabled"); } mKeyguardTransitions.register( @@ -2833,9 +2836,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, playSound(mTrustedSoundId); } - private void updateActivityLockScreenState(boolean showing, boolean aodShowing) { + private void updateActivityLockScreenState(boolean showing, boolean aodShowing, String reason) { mUiBgExecutor.execute(() -> { - Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")"); + Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ", " + + reason + ")"); if (KeyguardWmStateRefactor.isEnabled()) { // Handled in WmLockscreenVisibilityManager if flag is enabled. @@ -2895,7 +2899,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // Force if we're showing in the middle of unlocking, to ensure we end up in the // correct state. - setShowingLocked(true, hidingOrGoingAway /* force */); + setShowingLocked(true, hidingOrGoingAway /* force */, "handleShowInner"); mHiding = false; if (!KeyguardWmStateRefactor.isEnabled()) { @@ -3067,15 +3071,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, mHiding = true; mKeyguardGoingAwayRunnable.run(); } else { - Log.d(TAG, "Hiding keyguard while occluded. Just hide the keyguard view and exit."); - if (!KeyguardWmStateRefactor.isEnabled()) { mKeyguardViewControllerLazy.get().hide( mSystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), mHideAnimation.getDuration()); } - onKeyguardExitFinished(); + onKeyguardExitFinished("Hiding keyguard while occluded. Just hide the keyguard " + + "view and exit."); } // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while @@ -3106,6 +3109,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime + " fadeoutDuration=" + fadeoutDuration); synchronized (KeyguardViewMediator.this) { + mIsKeyguardExitAnimationCanceled = false; // Tell ActivityManager that we canceled the keyguard animation if // handleStartKeyguardExitAnimation was called, but we're not hiding the keyguard, // unless we're animating the surface behind the keyguard and will be hiding the @@ -3125,7 +3129,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, Slog.w(TAG, "Failed to call onAnimationFinished", e); } } - setShowingLocked(mShowing, true /* force */); + setShowingLocked(mShowing, true /* force */, + "handleStartKeyguardExitAnimation - canceled"); return; } mHiding = false; @@ -3149,9 +3154,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, Slog.w(TAG, "Failed to call onAnimationFinished", e); } } - onKeyguardExitFinished(); - mKeyguardViewControllerLazy.get().hide(0 /* startTime */, - 0 /* fadeoutDuration */); + if (!mIsKeyguardExitAnimationCanceled) { + onKeyguardExitFinished("onRemoteAnimationFinished"); + mKeyguardViewControllerLazy.get().hide(0 /* startTime */, + 0 /* fadeoutDuration */); + } mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION); } @@ -3288,12 +3295,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, anim.start(); }); - onKeyguardExitFinished(); + onKeyguardExitFinished("remote animation disabled"); } } } - private void onKeyguardExitFinished() { + private void onKeyguardExitFinished(String reason) { if (DEBUG) Log.d(TAG, "onKeyguardExitFinished()"); // only play "unlock" noises if not on a call (since the incall UI // disables the keyguard) @@ -3301,7 +3308,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, playSounds(false); } - setShowingLocked(false); + setShowingLocked(false, "onKeyguardExitFinished: " + reason); mWakeAndUnlocking = false; mDismissCallbackRegistry.notifyDismissSucceeded(); resetKeyguardDonePendingLocked(); @@ -3349,6 +3356,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // A lock is pending, meaning the keyguard exit animation was cancelled because we're // re-locking. We should just end the surface-behind animation without exiting the // keyguard. The pending lock will be handled by onFinishedGoingToSleep(). + if (relockWithPowerButtonImmediately()) { + mIsKeyguardExitAnimationCanceled = true; + } finishSurfaceBehindRemoteAnimation(true /* showKeyguard */); maybeHandlePendingLock(); } else { @@ -3397,12 +3407,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, doKeyguardLocked(null); finishSurfaceBehindRemoteAnimation(true /* showKeyguard */); // Ensure WM is notified that we made a decision to show - setShowingLocked(true /* showing */, true /* force */); + setShowingLocked(true /* showing */, true /* force */, + "exitKeyguardAndFinishSurfaceBehindRemoteAnimation - relocked"); return; } - onKeyguardExitFinished(); + onKeyguardExitFinished("exitKeyguardAndFinishSurfaceBehindRemoteAnimation"); if (mKeyguardStateController.isDismissingFromSwipe() || wasShowing) { Log.d(TAG, "onKeyguardExitRemoteAnimationFinished" @@ -3459,7 +3470,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, mSurfaceBehindRemoteAnimationRequested = false; mKeyguardStateController.notifyKeyguardGoingAway(false); if (mShowing) { - setShowingLocked(true, true); + setShowingLocked(true, true, "hideSurfaceBehindKeyguard"); } } @@ -3805,7 +3816,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // update lock screen state in ATMS here, otherwise ATMS tries to resume activities when // enabling doze state. if (mShowing || !mPendingLock || !mDozeParameters.canControlUnlockedScreenOff()) { - setShowingLocked(mShowing); + setShowingLocked(mShowing, "setDozing"); } } @@ -3815,7 +3826,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // is 1f), then show the activity lock screen. if (mAnimatingScreenOff && mDozing && linear == 1f) { mAnimatingScreenOff = false; - setShowingLocked(mShowing, true); + setShowingLocked(mShowing, true, "onDozeAmountChanged"); } } @@ -3853,11 +3864,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } } - void setShowingLocked(boolean showing) { - setShowingLocked(showing, false /* forceCallbacks */); + void setShowingLocked(boolean showing, String reason) { + setShowingLocked(showing, false /* forceCallbacks */, reason); } - private void setShowingLocked(boolean showing, boolean forceCallbacks) { + private void setShowingLocked(boolean showing, boolean forceCallbacks, String reason) { final boolean aodShowing = mDozing && !mWakeAndUnlocking; final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks; final boolean updateActivityLockScreenState = showing != mShowing @@ -3868,9 +3879,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, notifyDefaultDisplayCallbacks(showing); } if (updateActivityLockScreenState) { - updateActivityLockScreenState(showing, aodShowing); + updateActivityLockScreenState(showing, aodShowing, reason); } - } private void notifyDefaultDisplayCallbacks(boolean showing) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS new file mode 100644 index 000000000000..443e98762c47 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS @@ -0,0 +1,11 @@ +set noparent + +# Bug component: 78010 + +amiko@google.com +beverlyt@google.com +bhinegardner@google.com +chandruis@google.com +jglazier@google.com +mpietal@google.com +tsuji@google.com diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt index a460d515e0b2..9d8a7a81b9dc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt @@ -51,7 +51,8 @@ constructor( onCancel = { 0f }, ) - val lockscreenAlpha: Flow<Float> = shortcutsAlpha + // Show immediately to avoid what can appear to be a flicker on device wakeup + val lockscreenAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(1f) val deviceEntryBackgroundViewAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(1f) diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index b48b40986f73..875e505db1c6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -94,6 +94,7 @@ import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.phone.SystemUIDialog; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; @@ -173,6 +174,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, private float mActiveRadius; private FeatureFlags mFeatureFlags; private UserTracker mUserTracker; + private VolumePanelGlobalStateInteractor mVolumePanelGlobalStateInteractor; public enum BroadcastNotifyDialog { ACTION_FIRST_LAUNCH, @@ -195,6 +197,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, PowerExemptionManager powerExemptionManager, KeyguardManager keyGuardManager, FeatureFlags featureFlags, + VolumePanelGlobalStateInteractor volumePanelGlobalStateInteractor, UserTracker userTracker) { mContext = context; mPackageName = packageName; @@ -209,6 +212,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mFeatureFlags = featureFlags; mUserTracker = userTracker; mToken = token; + mVolumePanelGlobalStateInteractor = volumePanelGlobalStateInteractor; InfoMediaManager imm = InfoMediaManager.createInstance(mContext, packageName, userHandle, lbm, token); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); @@ -436,7 +440,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, launchIntent.putExtra(EXTRA_ROUTE_ID, routeId); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mCallback.dismissDialog(); - mActivityStarter.startActivity(launchIntent, true, controller); + startActivity(launchIntent, controller); } } @@ -447,7 +451,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, if (launchIntent != null) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mCallback.dismissDialog(); - mActivityStarter.startActivity(launchIntent, true, controller); + startActivity(launchIntent, controller); } } @@ -951,10 +955,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, deepLinkIntent.putExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, PAGE_CONNECTED_DEVICES_KEY); - mActivityStarter.startActivity(deepLinkIntent, true, controller); + startActivity(deepLinkIntent, controller); return; } - mActivityStarter.startActivity(launchIntent, true, controller); + startActivity(launchIntent, controller); } void launchLeBroadcastNotifyDialog(View mediaOutputDialog, BroadcastSender broadcastSender, @@ -998,6 +1002,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true, broadcastSender, controller); @@ -1244,6 +1249,13 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return !device.isVolumeFixed(); } + private void startActivity(Intent intent, ActivityTransitionAnimator.Controller controller) { + // Media Output dialog can be shown from the volume panel. This makes sure the panel is + // closed when navigating to another activity, so it doesn't stays on top of it + mVolumePanelGlobalStateInteractor.setVisible(false); + mActivityStarter.startActivity(intent, true, controller); + } + @Override public void onDevicesUpdated(List<NearbyDevice> nearbyDevices) throws RemoteException { mNearbyDeviceInfoMap.clear(); diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt index d6affd2f0250..228b57603bed 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt @@ -32,6 +32,10 @@ import android.util.Log import android.view.View import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent +import android.widget.ImageView +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry @@ -52,6 +56,7 @@ import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRece import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.AsyncActivityLauncher +import java.lang.IllegalArgumentException import javax.inject.Inject class MediaProjectionAppSelectorActivity( @@ -116,6 +121,7 @@ class MediaProjectionAppSelectorActivity( super.onCreate(savedInstanceState) controller.init() + setIcon() // we override AppList's AccessibilityDelegate set in ResolverActivity.onCreate because in // our case this delegate must extend RecyclerViewAccessibilityDelegate, otherwise // RecyclerView scrolling is broken @@ -298,6 +304,29 @@ class MediaProjectionAppSelectorActivity( override fun createContentPreviewView(parent: ViewGroup): ViewGroup = recentsViewController.createView(parent) + /** Set up intent for the [ChooserActivity] */ + private fun Intent.configureChooserIntent( + resources: Resources, + hostUserHandle: UserHandle, + personalProfileUserHandle: UserHandle, + ) { + // Specify the query intent to show icons for all apps on the chooser screen + val queryIntent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) } + putExtra(Intent.EXTRA_INTENT, queryIntent) + + // Update the title of the chooser + putExtra(Intent.EXTRA_TITLE, resources.getString(titleResId)) + + // Select host app's profile tab by default + val selectedProfile = + if (hostUserHandle == personalProfileUserHandle) { + PROFILE_PERSONAL + } else { + PROFILE_WORK + } + putExtra(EXTRA_SELECTED_PROFILE, selectedProfile) + } + private val hostUserHandle: UserHandle get() { val extras = @@ -321,6 +350,54 @@ class MediaProjectionAppSelectorActivity( return intent.getIntExtra(EXTRA_HOST_APP_UID, /* defaultValue= */ -1) } + /** + * The type of screen sharing being performed. Used to show the right text and icon in the + * activity. + */ + private val screenShareType: ScreenShareType? + get() { + if (!intent.hasExtra(EXTRA_SCREEN_SHARE_TYPE)) { + return null + } else { + val type = intent.getStringExtra(EXTRA_SCREEN_SHARE_TYPE) ?: return null + return try { + enumValueOf<ScreenShareType>(type) + } catch (e: IllegalArgumentException) { + null + } + } + } + + @get:StringRes + private val titleResId: Int + get() = + when (screenShareType) { + ScreenShareType.ShareToApp -> + R.string.media_projection_entry_share_app_selector_title + ScreenShareType.SystemCast -> + R.string.media_projection_entry_cast_app_selector_title + ScreenShareType.ScreenRecord -> R.string.screenrecord_app_selector_title + null -> R.string.screen_share_generic_app_selector_title + } + + @get:DrawableRes + private val iconResId: Int + get() = + when (screenShareType) { + ScreenShareType.ShareToApp -> R.drawable.ic_present_to_all + ScreenShareType.SystemCast -> R.drawable.ic_cast_connected + ScreenShareType.ScreenRecord -> R.drawable.ic_screenrecord + null -> R.drawable.ic_present_to_all + } + + @get:ColorRes + private val iconTintResId: Int? + get() = + when (screenShareType) { + ScreenShareType.ScreenRecord -> R.color.screenrecord_icon_color + else -> null + } + companion object { const val TAG = "MediaProjectionAppSelectorActivity" @@ -343,30 +420,18 @@ class MediaProjectionAppSelectorActivity( const val EXTRA_HOST_APP_UID = "launched_from_host_uid" const val KEY_CAPTURE_TARGET = "capture_region" - /** Set up intent for the [ChooserActivity] */ - private fun Intent.configureChooserIntent( - resources: Resources, - hostUserHandle: UserHandle, - personalProfileUserHandle: UserHandle - ) { - // Specify the query intent to show icons for all apps on the chooser screen - val queryIntent = - Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) } - putExtra(Intent.EXTRA_INTENT, queryIntent) - - // Update the title of the chooser - val title = resources.getString(R.string.screen_share_permission_app_selector_title) - putExtra(Intent.EXTRA_TITLE, title) - - // Select host app's profile tab by default - val selectedProfile = - if (hostUserHandle == personalProfileUserHandle) { - PROFILE_PERSONAL - } else { - PROFILE_WORK - } - putExtra(EXTRA_SELECTED_PROFILE, selectedProfile) - } + /** + * The type of screen sharing being performed. + * + * The value set for this extra should match the name of a [ScreenShareType]. + */ + const val EXTRA_SCREEN_SHARE_TYPE = "screen_share_type" + } + + private fun setIcon() { + val iconView = findViewById<ImageView>(R.id.media_projection_app_selector_icon) ?: return + iconView.setImageResource(iconResId) + iconTintResId?.let { iconView.setColorFilter(this.resources.getColor(it, this.theme)) } } private fun setAppListAccessibilityDelegate() { @@ -406,4 +471,14 @@ class MediaProjectionAppSelectorActivity( return delegate.onRequestSendAccessibilityEvent(host, child, event) } } + + /** Enum describing what type of app screen sharing is being performed. */ + enum class ScreenShareType { + /** The selected app will be cast to another device. */ + SystemCast, + /** The selected app will be shared to another app on the device. */ + ShareToApp, + /** The selected app will be recorded. */ + ScreenRecord, + } } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java index 3c83db3f258d..18c6f53630a4 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java @@ -73,8 +73,7 @@ import javax.inject.Inject; import dagger.Lazy; -public class MediaProjectionPermissionActivity extends Activity - implements DialogInterface.OnClickListener { +public class MediaProjectionPermissionActivity extends Activity { private static final String TAG = "MediaProjectionPermissionActivity"; private static final float MAX_APP_NAME_SIZE_PX = 500f; private static final String ELLIPSIS = "\u2026"; @@ -269,7 +268,8 @@ public class MediaProjectionPermissionActivity extends Activity Consumer<BaseMediaProjectionPermissionDialogDelegate<AlertDialog>> onStartRecordingClicked = dialog -> { ScreenShareOption selectedOption = dialog.getSelectedScreenShareOption(); - grantMediaProjectionPermission(selectedOption.getMode()); + grantMediaProjectionPermission( + selectedOption.getMode(), hasCastingCapabilities); }; Runnable onCancelClicked = () -> finish(RECORD_CANCEL, /* projection= */ null); if (hasCastingCapabilities) { @@ -305,19 +305,6 @@ public class MediaProjectionPermissionActivity extends Activity } } - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == AlertDialog.BUTTON_POSITIVE) { - grantMediaProjectionPermission(ENTIRE_SCREEN); - } else { - if (mDialog != null) { - mDialog.dismiss(); - } - setResult(RESULT_CANCELED); - finish(RECORD_CANCEL, /* projection= */ null); - } - } - private void setUpDialog(AlertDialog dialog) { SystemUIDialog.registerDismissListener(dialog); SystemUIDialog.applyFlags(dialog); @@ -345,25 +332,21 @@ public class MediaProjectionPermissionActivity extends Activity return false; } - private void grantMediaProjectionPermission(int screenShareMode) { + private void grantMediaProjectionPermission( + int screenShareMode, boolean hasCastingCapabilities) { try { + IMediaProjection projection = MediaProjectionServiceHelper.createOrReuseProjection( + mUid, mPackageName, mReviewGrantedConsentRequired); if (screenShareMode == ENTIRE_SCREEN) { - final IMediaProjection projection = - MediaProjectionServiceHelper.createOrReuseProjection(mUid, mPackageName, - mReviewGrantedConsentRequired); final Intent intent = new Intent(); - intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, - projection.asBinder()); + setCommonIntentExtras(intent, hasCastingCapabilities, projection); setResult(RESULT_OK, intent); finish(RECORD_CONTENT_DISPLAY, projection); } if (screenShareMode == SINGLE_APP) { - IMediaProjection projection = MediaProjectionServiceHelper.createOrReuseProjection( - mUid, mPackageName, mReviewGrantedConsentRequired); final Intent intent = new Intent(this, MediaProjectionAppSelectorActivity.class); - intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, - projection.asBinder()); + setCommonIntentExtras(intent, hasCastingCapabilities, projection); intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE, getHostUserHandle()); intent.putExtra( @@ -391,6 +374,19 @@ public class MediaProjectionPermissionActivity extends Activity } } + private void setCommonIntentExtras( + Intent intent, + boolean hasCastingCapabilities, + IMediaProjection projection) throws RemoteException { + intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, + projection.asBinder()); + intent.putExtra( + MediaProjectionAppSelectorActivity.EXTRA_SCREEN_SHARE_TYPE, + hasCastingCapabilities + ? MediaProjectionAppSelectorActivity.ScreenShareType.SystemCast.name() + : MediaProjectionAppSelectorActivity.ScreenShareType.ShareToApp.name()); + } + private UserHandle getHostUserHandle() { return UserHandle.getUserHandleForUid(getLaunchedFromUid()); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 13a786a623dd..ac878c2d698d 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -38,6 +38,7 @@ import android.content.Context; import android.content.res.Configuration; import android.database.ContentObserver; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -516,7 +517,7 @@ public final class NavBarHelper implements * @return Whether the IME is shown on top of the screen given the {@code vis} flag of * {@link InputMethodService} and the keyguard states. */ - public boolean isImeShown(int vis) { + public boolean isImeShown(@ImeWindowVisibility int vis) { View shadeWindowView = mNotificationShadeWindowController.getWindowRootView(); boolean isKeyguardShowing = mKeyguardStateController.isShowing(); boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow() diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 15b1e4de878a..cb0bb4abb423 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -42,6 +42,8 @@ import android.content.Context; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.os.RemoteException; import android.os.Trace; import android.util.Log; @@ -424,8 +426,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, } @Override - public void setImeWindowStatus(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { boolean imeShown = mNavBarHelper.isImeShown(vis); if (!imeShown) { // Count imperceptible changes as visible so we transition taskbar out quickly. diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java index e895d83758f7..c706c3e97c96 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java @@ -68,6 +68,8 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -1098,8 +1100,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements // ----- CommandQueue Callbacks ----- @Override - public void setImeWindowStatus(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 9939075b77d2..1511f31a3f92 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -259,6 +259,13 @@ public class QSContainerImpl extends FrameLayout implements Dumpable { } /** + * @return height with the squishiness fraction applied. + */ + int getSquishedQqsHeight() { + return mHeader.getSquishedHeight(); + } + + /** * Returns the size of QS (or the QSCustomizer), regardless of the measured size of this view * @return size in pixels of QS (or QSCustomizer) */ @@ -267,6 +274,13 @@ public class QSContainerImpl extends FrameLayout implements Dumpable { : mQSPanel.getMeasuredHeight(); } + /** + * @return height with the squishiness fraction applied. + */ + int getSquishedQsHeight() { + return mQSPanel.getSquishedHeight(); + } + public void setExpansion(float expansion) { mQsExpansion = expansion; if (mQSPanelContainer != null) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java index a6fd35a9ee37..0b37b5b7be3d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java @@ -992,11 +992,25 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl return mContainer.getQqsHeight(); } + /** + * @return height with the squishiness fraction applied. + */ + public int getSquishedQqsHeight() { + return mContainer.getSquishedQqsHeight(); + } + public int getQSHeight() { return mContainer.getQsHeight(); } /** + * @return height with the squishiness fraction applied. + */ + public int getSquishedQsHeight() { + return mContainer.getSquishedQsHeight(); + } + + /** * Pass the size of the navbar when it's at the bottom of the device so it can be used as * padding * @param padding size of the bottom nav bar in px diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 032891fa715e..d3bed27ab2ab 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -733,6 +733,30 @@ public class QSPanel extends LinearLayout implements Tunable { mCanCollapse = canCollapse; } + /** + * @return height with the {@link QSPanel#setSquishinessFraction(float)} applied. + */ + public int getSquishedHeight() { + if (mFooter != null) { + final ViewGroup.LayoutParams footerLayoutParams = mFooter.getLayoutParams(); + final int footerBottomMargin; + if (footerLayoutParams instanceof MarginLayoutParams) { + footerBottomMargin = ((MarginLayoutParams) footerLayoutParams).bottomMargin; + } else { + footerBottomMargin = 0; + } + // This is the distance between the top of the QSPanel and the last view in the + // layout (which is the effective the bottom) + return mFooter.getBottom() + footerBottomMargin - getTop(); + } + if (mTileLayout != null) { + // Footer absence means that the panel is in the QQS. In this case it's just height + // of the tiles + paddings. + return mTileLayout.getTilesHeight() + getPaddingBottom() + getPaddingTop(); + } + return getHeight(); + } + @Nullable @VisibleForTesting View getMediaPlaceholder() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 5a3f1c0b7426..8fde52c910da 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -123,4 +123,11 @@ public class QuickStatusBarHeader extends FrameLayout { lp.setMarginEnd(marginEnd); view.setLayoutParams(lp); } + + /** + * @return height with the squishiness fraction applied. + */ + public int getSquishedHeight() { + return mHeaderQsPanel.getSquishedHeight(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt index ae2f32aae874..dfcf21628c3b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt @@ -34,7 +34,6 @@ import com.android.systemui.plugins.qs.QSContainerController import com.android.systemui.qs.QSContainerImpl import com.android.systemui.qs.QSImpl import com.android.systemui.qs.dagger.QSSceneComponent -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel.state import com.android.systemui.res.R import com.android.systemui.settings.brightness.MirrorController import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -126,12 +125,18 @@ interface QSSceneAdapter { /** The current height of QQS in the current [qsView], or 0 if there's no view. */ val qqsHeight: Int + /** @return height with the squishiness fraction applied. */ + val squishedQqsHeight: Int + /** * The current height of QS in the current [qsView], or 0 if there's no view. If customizing, it * will return the height allocated to the customizer. */ val qsHeight: Int + /** @return height with the squishiness fraction applied. */ + val squishedQsHeight: Int + /** Compatibility for use by LockscreenShadeTransitionController. Matches default from [QS] */ val isQsFullyCollapsed: Boolean get() = true @@ -273,9 +278,15 @@ constructor( override val qqsHeight: Int get() = qsImpl.value?.qqsHeight ?: 0 + override val squishedQqsHeight: Int + get() = qsImpl.value?.squishedQqsHeight ?: 0 + override val qsHeight: Int get() = qsImpl.value?.qsHeight ?: 0 + override val squishedQsHeight: Int + get() = qsImpl.value?.squishedQsHeight ?: 0 + // If value is null, there's no QS and therefore it's fully collapsed. override val isQsFullyCollapsed: Boolean get() = qsImpl.value?.isFullyCollapsed ?: true diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 3ec088c66e10..e73664d43952 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -154,7 +154,6 @@ constructor( handleKeyguardEnabledness() notifyKeyguardDismissCallbacks() refreshLockscreenEnabled() - handleHideAlternateBouncerOnTransitionToGone() } else { sceneLogger.logFrameworkEnabled( isEnabled = false, @@ -357,11 +356,10 @@ constructor( ) } val isOnLockscreen = renderedScenes.contains(Scenes.Lockscreen) - val isOnBouncer = - renderedScenes.contains(Scenes.Bouncer) || - alternateBouncerInteractor.isVisibleState() + val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState() + val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer) if (!deviceUnlockStatus.isUnlocked) { - return@mapNotNull if (isOnLockscreen || isOnBouncer) { + return@mapNotNull if (isOnLockscreen || isOnPrimaryBouncer) { // Already on lockscreen or bouncer, no need to change scenes. null } else { @@ -373,15 +371,32 @@ constructor( } if ( - isOnBouncer && + isOnPrimaryBouncer && deviceUnlockStatus.deviceUnlockSource == DeviceUnlockSource.TrustAgent ) { uiEventLogger.log(BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS) } when { - isOnBouncer -> - // When the device becomes unlocked in Bouncer, go to previous scene, - // or Gone. + isAlternateBouncerVisible -> { + // When the device becomes unlocked when the alternate bouncer is + // showing, always hide the alternate bouncer... + alternateBouncerInteractor.hide() + + // ... and go to Gone or stay on the current scene + if ( + isOnLockscreen || + !statusBarStateController.leaveOpenOnKeyguardHide() + ) { + Scenes.Gone to + "device was unlocked with alternate bouncer showing" + + " and shade didn't need to be left open" + } else { + null + } + } + isOnPrimaryBouncer -> + // When the device becomes unlocked in primary Bouncer, + // go to previous scene or Gone. if ( previousScene.value == Scenes.Lockscreen || !statusBarStateController.leaveOpenOnKeyguardHide() @@ -392,7 +407,7 @@ constructor( } else { val prevScene = previousScene.value (prevScene ?: Scenes.Gone) to - "device was unlocked with bouncer showing," + + "device was unlocked with primary bouncer showing," + " from sceneKey=$prevScene" } isOnLockscreen -> @@ -785,14 +800,4 @@ constructor( .collectLatest { deviceEntryInteractor.refreshLockscreenEnabled() } } } - - private fun handleHideAlternateBouncerOnTransitionToGone() { - applicationScope.launch { - sceneInteractor.transitionState - .map { it.isIdle(Scenes.Gone) } - .distinctUntilChanged() - .filter { it } - .collectLatest { alternateBouncerInteractor.hide() } - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt index 46ac54f63183..f3357ee53b7f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt @@ -146,6 +146,10 @@ class ScreenRecordPermissionDialogDelegate( hostUserHandle ) intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_UID, hostUid) + intent.putExtra( + MediaProjectionAppSelectorActivity.EXTRA_SCREEN_SHARE_TYPE, + MediaProjectionAppSelectorActivity.ScreenShareType.ScreenRecord.name, + ) activityStarter.startActivity(intent, /* dismissShade= */ true) } dialog.dismiss() diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 104d4b5427d4..65a59f50d1bf 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1339,6 +1339,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump "NotificationPanelViewController.updateResources"); if (splitShadeChanged) { + if (isPanelVisibleBecauseOfHeadsUp()) { + // workaround for b/324642496, because HUNs set state to OPENING + onPanelStateChanged(STATE_CLOSED); + } onSplitShadeEnabledChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 50be6dcaa678..a1477b57a22a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -37,6 +37,7 @@ import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.media.INearbyMediaDevicesProvider; import android.media.MediaRoute2Info; import android.os.Binder; @@ -257,10 +258,10 @@ public class CommandQueue extends IStatusBar.Stub implements * * @param displayId The id of the display to notify. * @param vis IME visibility. - * @param backDisposition Disposition mode of back button. It should be one of below flags: + * @param backDisposition Disposition mode of back button. * @param showImeSwitcher {@code true} to show IME switch button. */ - default void setImeWindowStatus(int displayId, int vis, + default void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, @BackDispositionMode int backDisposition, boolean showImeSwitcher) { } default void showRecentApps(boolean triggeredFromAltTab) { } default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } @@ -743,8 +744,8 @@ public class CommandQueue extends IStatusBar.Stub implements } @Override - public void setImeWindowStatus(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { synchronized (mLock) { mHandler.removeMessages(MSG_SHOW_IME_BUTTON); SomeArgs args = SomeArgs.obtain(); @@ -1205,8 +1206,8 @@ public class CommandQueue extends IStatusBar.Stub implements } } - private void handleShowImeButton(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + private void handleShowImeButton(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { if (displayId == INVALID_DISPLAY) return; boolean isConcurrentMultiUserModeEnabled = UserManager.isVisibleBackgroundUsersEnabled() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS index 69ebb7674f72..c4f539a4acdf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS @@ -5,3 +5,12 @@ set noparent caitlinshk@google.com evanlaird@google.com pixel@google.com + +per-file *Biometrics* = set noparent +per-file *Biometrics* = file:../keyguard/OWNERS +per-file *Doze* = set noparent +per-file *Doze* = file:../keyguard/OWNERS +per-file *Keyboard* = set noparent +per-file *Keyboard* = file:../keyguard/OWNERS +per-file *Keyguard* = set noparent +per-file *Keyguard* = file:../keyguard/OWNERS
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 9d13a17d8e02..cb3e26b9f8ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -1804,6 +1804,20 @@ public class ExpandableNotificationRow extends ActivatableNotificationView NotificationEntry childEntry, NotificationEntry containerEntry ); + + /** + * Called when resetting the alpha value for content views + */ + void logResetAllContentAlphas( + NotificationEntry entry + ); + + /** + * Called when resetting the alpha value for content views is skipped + */ + void logSkipResetAllContentAlphas( + NotificationEntry entry + ); } /** @@ -3001,6 +3015,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mChildrenContainer.animate().cancel(); } resetAllContentAlphas(); + } else { + mLogger.logSkipResetAllContentAlphas(getEntry()); } mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE); updateChildrenVisibility(); @@ -3186,6 +3202,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override protected void resetAllContentAlphas() { + mLogger.logResetAllContentAlphas(getEntry()); mPrivateLayout.setAlpha(1f); mPrivateLayout.setLayerType(LAYER_TYPE_NONE, null); mPublicLayout.setAlpha(1f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 4c76e3284dbe..c31a2cb8908b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -195,6 +195,20 @@ public class ExpandableNotificationRowController implements NotifViewController ) { mLogBufferLogger.logRemoveTransientRow(childEntry, containerEntry); } + + @Override + public void logResetAllContentAlphas( + NotificationEntry entry + ) { + mLogBufferLogger.logResetAllContentAlphas(entry); + } + + @Override + public void logSkipResetAllContentAlphas( + NotificationEntry entry + ) { + mLogBufferLogger.logSkipResetAllContentAlphas(entry); + } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt index 4f5a04f2bdc9..b1e90329e01a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt @@ -128,6 +128,24 @@ constructor( { "removeTransientRow from row: childKey: $str1 -- containerKey: $str2" } ) } + + fun logResetAllContentAlphas(entry: NotificationEntry) { + notificationRenderBuffer.log( + TAG, + LogLevel.INFO, + { str1 = entry.logKey }, + { "resetAllContentAlphas: $str1" } + ) + } + + fun logSkipResetAllContentAlphas(entry: NotificationEntry) { + notificationRenderBuffer.log( + TAG, + LogLevel.INFO, + { str1 = entry.logKey }, + { "Skip resetAllContentAlphas: $str1" } + ) + } } private const val TAG = "NotifRow" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index ada3c52b16ab..c4fbc37b2dd5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -30,6 +30,7 @@ import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; import static com.android.systemui.Flags.keyboardShortcutHelperRewrite; import static com.android.systemui.Flags.lightRevealMigration; import static com.android.systemui.Flags.newAodTransition; +import static com.android.systemui.Flags.relockWithPowerButtonImmediately; import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL; import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT; import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF; @@ -2352,11 +2353,13 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } else if (mState == StatusBarState.KEYGUARD && !mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing() && mStatusBarKeyguardViewManager.isSecure()) { - Log.d(TAG, "showBouncerOrLockScreenIfKeyguard, showingBouncer"); - if (SceneContainerFlag.isEnabled()) { - mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */); - } else { - mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); + if (!relockWithPowerButtonImmediately()) { + Log.d(TAG, "showBouncerOrLockScreenIfKeyguard, showingBouncer"); + if (SceneContainerFlag.isEnabled()) { + mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */); + } else { + mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index f13a593d08f2..ac1015521502 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -424,14 +424,12 @@ public final class DozeServiceHost implements DozeHost { @Override public void setDozeScreenBrightness(int brightness) { - mDozeLog.traceDozeScreenBrightness(brightness); mNotificationShadeWindowController.setDozeScreenBrightness(brightness); } @Override public void setDozeScreenBrightnessFloat(float brightness) { - mDozeLog.traceDozeScreenBrightnessFloat(brightness); mNotificationShadeWindowController.setDozeScreenBrightnessFloat(brightness); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt index 2e54972c4950..9cbfc440ab16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt @@ -198,7 +198,8 @@ constructor( fun logServiceProvidersUpdatedBroadcast(intent: Intent) { val showSpn = intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false) - val spn = intent.getStringExtra(TelephonyManager.EXTRA_DATA_SPN) + val spn = intent.getStringExtra(TelephonyManager.EXTRA_SPN) + val dataSpn = intent.getStringExtra(TelephonyManager.EXTRA_DATA_SPN) val showPlmn = intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false) val plmn = intent.getStringExtra(TelephonyManager.EXTRA_PLMN) @@ -208,12 +209,13 @@ constructor( { bool1 = showSpn str1 = spn + str2 = dataSpn bool2 = showPlmn - str2 = plmn + str3 = plmn }, { "Intent: ACTION_SERVICE_PROVIDERS_UPDATED." + - " showSpn=$bool1 spn=$str1 showPlmn=$bool2 plmn=$str2" + " showSpn=$bool1 spn=$str1 dataSpn=$str2 showPlmn=$bool2 plmn=$str3" } ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt index 99ed2d99c749..85bbe7e53493 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt @@ -21,6 +21,8 @@ import android.telephony.TelephonyManager.EXTRA_DATA_SPN import android.telephony.TelephonyManager.EXTRA_PLMN import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN import android.telephony.TelephonyManager.EXTRA_SHOW_SPN +import android.telephony.TelephonyManager.EXTRA_SPN +import com.android.systemui.Flags.statusBarSwitchToSpnFromDataSpn import com.android.systemui.log.table.Diffable import com.android.systemui.log.table.TableRowLogger @@ -96,7 +98,13 @@ sealed interface NetworkNameModel : Diffable<NetworkNameModel> { fun Intent.toNetworkNameModel(separator: String): NetworkNameModel? { val showSpn = getBooleanExtra(EXTRA_SHOW_SPN, false) - val spn = getStringExtra(EXTRA_DATA_SPN) + val spn = + if (statusBarSwitchToSpnFromDataSpn()) { + getStringExtra(EXTRA_SPN) + } else { + getStringExtra(EXTRA_DATA_SPN) + } + val showPlmn = getBooleanExtra(EXTRA_SHOW_PLMN, false) val plmn = getStringExtra(EXTRA_PLMN) diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt new file mode 100644 index 000000000000..238e8a1c01ad --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt @@ -0,0 +1,73 @@ +/* + * 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.touchpad.tutorial + +import android.app.Activity +import androidx.compose.runtime.Composable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.inputdevice.tutorial.TouchpadTutorialScreensProvider +import com.android.systemui.model.SysUiState +import com.android.systemui.settings.DisplayTracker +import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor +import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen +import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen +import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +import kotlinx.coroutines.CoroutineScope + +@Module +interface TouchpadTutorialModule { + + @Binds + @IntoMap + @ClassKey(TouchpadTutorialActivity::class) + fun activity(impl: TouchpadTutorialActivity): Activity + + companion object { + @Provides + fun touchpadScreensProvider(): TouchpadTutorialScreensProvider { + return ScreensProvider + } + + @SysUISingleton + @Provides + fun touchpadGesturesInteractor( + sysUiState: SysUiState, + displayTracker: DisplayTracker, + @Background backgroundScope: CoroutineScope + ): TouchpadGesturesInteractor { + return TouchpadGesturesInteractor(sysUiState, displayTracker, backgroundScope) + } + } +} + +private object ScreensProvider : TouchpadTutorialScreensProvider { + @Composable + override fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) { + BackGestureTutorialScreen(onDoneButtonClicked, onBack) + } + + @Composable + override fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) { + HomeGestureTutorialScreen(onDoneButtonClicked, onBack) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt index b6c2ae794da9..df95232758a4 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt @@ -16,22 +16,16 @@ package com.android.systemui.touchpad.tutorial.domain.interactor -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.model.SysUiState import com.android.systemui.settings.DisplayTracker import com.android.systemui.shared.system.QuickStepContract -import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -@SysUISingleton -class TouchpadGesturesInteractor -@Inject -constructor( +class TouchpadGesturesInteractor( private val sysUiState: SysUiState, private val displayTracker: DisplayTracker, - @Background private val backgroundScope: CoroutineScope + private val backgroundScope: CoroutineScope ) { fun disableGestures() { setGesturesState(disabled = true) diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt index 5980e1de85b4..1c8041ff5b31 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt @@ -21,6 +21,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import com.airbnb.lottie.compose.rememberLottieDynamicProperties import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig +import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty import com.android.systemui.res.R import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureMonitor import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt index dfe9c0df9ab7..57d7c84af4ba 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt @@ -28,6 +28,9 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInteropFilter import androidx.compose.ui.platform.LocalContext +import com.android.systemui.inputdevice.tutorial.ui.composable.ActionTutorialContent +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt index ed3110c04131..0a6283aa7417 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt @@ -21,6 +21,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import com.airbnb.lottie.compose.rememberLottieDynamicProperties import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig +import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty import com.android.systemui.res.R import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureMonitor diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt index 14355fa18335..65b452a81da8 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.android.systemui.inputdevice.tutorial.ui.composable.DoneButton import com.android.systemui.res.R @Composable diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt index 48e6397a0a42..256c5b590b14 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt @@ -27,7 +27,7 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.theme.PlatformTheme -import com.android.systemui.touchpad.tutorial.ui.composable.ActionKeyTutorialScreen +import com.android.systemui.inputdevice.tutorial.ui.composable.ActionKeyTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.TutorialSelectionScreen diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt index 5d8b6f144d97..d39daafd2311 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt @@ -79,13 +79,15 @@ interface AudioModule { localBluetoothManager: LocalBluetoothManager?, @Application coroutineScope: CoroutineScope, @Background coroutineContext: CoroutineContext, + volumeLogger: VolumeLogger ): AudioSharingRepository = if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { AudioSharingRepositoryImpl( contentResolver, localBluetoothManager, coroutineScope, - coroutineContext + coroutineContext, + volumeLogger ) } else { AudioSharingRepositoryEmptyImpl() diff --git a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt index 869a82a78848..d6b159e9b13a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt @@ -16,7 +16,8 @@ package com.android.systemui.volume.shared -import com.android.settingslib.volume.data.repository.AudioRepositoryImpl +import com.android.settingslib.volume.shared.AudioLogger +import com.android.settingslib.volume.shared.AudioSharingLogger import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.AudioStreamModel import com.android.systemui.dagger.SysUISingleton @@ -30,7 +31,7 @@ private const val TAG = "SysUI_Volume" /** Logs general System UI volume events. */ @SysUISingleton class VolumeLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) : - AudioRepositoryImpl.Logger { + AudioLogger, AudioSharingLogger { override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) { logBuffer.log( @@ -55,4 +56,35 @@ class VolumeLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuff { "Volume update received: stream=$str1 volume=$int1" } ) } + + override fun onAudioSharingStateChanged(state: Boolean) { + logBuffer.log( + TAG, + LogLevel.DEBUG, + { bool1 = state }, + { "Audio sharing state update: state=$bool1" } + ) + } + + override fun onSecondaryGroupIdChanged(groupId: Int) { + logBuffer.log( + TAG, + LogLevel.DEBUG, + { int1 = groupId }, + { "Secondary group id in audio sharing update: groupId=$int1" } + ) + } + + override fun onVolumeMapChanged(map: Map<Int, Int>) { + logBuffer.log( + TAG, + LogLevel.DEBUG, + { str1 = map.toString() }, + { "Volume map update: map=$str1" } + ) + } + + override fun onSetDeviceVolumeRequested(volume: Int) { + logBuffer.log(TAG, LogLevel.DEBUG, { int1 = volume }, { "Set device volume: volume=$int1" }) + } } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 9ca0591f9c5b..50efc21f50fc 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -34,6 +34,8 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.util.Log; import android.view.Display; import android.view.KeyEvent; @@ -378,8 +380,8 @@ public final class WMShell implements } @Override - public void setImeWindowStatus(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { if (displayId == mDisplayTracker.getDefaultDisplayId() && (vis & InputMethodService.IME_VISIBLE) != 0) { oneHanded.stopOneHanded( diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java index 419f7eda9d1f..299c38481b03 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java @@ -29,31 +29,22 @@ import androidx.test.filters.SmallTest; 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 org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.concurrent.Executor; - @SmallTest @RunWith(AndroidJUnit4.class) public class DozeScreenStatePreventingAdapterTest extends SysuiTestCase { - private Executor mExecutor; private DozeMachine.Service mInner; private DozeScreenStatePreventingAdapter mWrapper; @Before public void setup() throws Exception { - mExecutor = new FakeExecutor(new FakeSystemClock()); mInner = mock(DozeMachine.Service.class); - mWrapper = new DozeScreenStatePreventingAdapter( - mInner, - mExecutor - ); + mWrapper = new DozeScreenStatePreventingAdapter(mInner); } @Test @@ -98,7 +89,7 @@ public class DozeScreenStatePreventingAdapterTest extends SysuiTestCase { when(params.getDisplayStateSupported()).thenReturn(false); assertEquals(DozeScreenStatePreventingAdapter.class, - DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, mExecutor) + DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params) .getClass()); } @@ -107,7 +98,6 @@ public class DozeScreenStatePreventingAdapterTest extends SysuiTestCase { DozeParameters params = mock(DozeParameters.class); when(params.getDisplayStateSupported()).thenReturn(true); - assertSame(mInner, DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, - mExecutor)); + assertSame(mInner, DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java index 5a89710f6cf6..0d6a9ceece5c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java @@ -29,28 +29,22 @@ import androidx.test.filters.SmallTest; 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 org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.concurrent.Executor; - @SmallTest @RunWith(AndroidJUnit4.class) public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase { - private Executor mExecutor; private DozeMachine.Service mInner; private DozeSuspendScreenStatePreventingAdapter mWrapper; @Before public void setup() throws Exception { - mExecutor = new FakeExecutor(new FakeSystemClock()); mInner = mock(DozeMachine.Service.class); - mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner, mExecutor); + mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner); } @Test @@ -101,7 +95,7 @@ public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase { when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false); assertEquals(DozeSuspendScreenStatePreventingAdapter.class, - DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, mExecutor) + DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params) .getClass()); } @@ -110,7 +104,6 @@ public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase { DozeParameters params = mock(DozeParameters.class); when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true); - assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, - mExecutor)); + assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index e3a38a8d6763..37f1a3d73b0c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -443,7 +443,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onSystemReady(); TestableLooper.get(this).processAllMessages(); - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); TestableLooper.get(this).processAllMessages(); mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); @@ -463,7 +463,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onSystemReady(); TestableLooper.get(this).processAllMessages(); - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); TestableLooper.get(this).processAllMessages(); mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); @@ -570,7 +570,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { // When showing and provisioned mViewMediator.onSystemReady(); when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true); - mViewMediator.setShowingLocked(true); + mViewMediator.setShowingLocked(true, ""); // and a SIM becomes locked and requires a PIN mViewMediator.mUpdateCallback.onSimStateChanged( @@ -579,7 +579,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TelephonyManager.SIM_STATE_PIN_REQUIRED); // and the keyguard goes away - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); when(mKeyguardStateController.isShowing()).thenReturn(false); mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false); @@ -595,7 +595,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { // When showing and provisioned mViewMediator.onSystemReady(); when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true); - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); // and a SIM becomes locked and requires a PIN mViewMediator.mUpdateCallback.onSimStateChanged( @@ -604,7 +604,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TelephonyManager.SIM_STATE_PIN_REQUIRED); // and the keyguard goes away - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); when(mKeyguardStateController.isShowing()).thenReturn(false); mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false); @@ -843,7 +843,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onSystemReady(); TestableLooper.get(this).processAllMessages(); - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); TestableLooper.get(this).processAllMessages(); mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); @@ -863,7 +863,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onSystemReady(); TestableLooper.get(this).processAllMessages(); - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); TestableLooper.get(this).processAllMessages(); mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); @@ -978,7 +978,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testDoKeyguardWhileInteractive_resets() { - mViewMediator.setShowingLocked(true); + mViewMediator.setShowingLocked(true, ""); when(mKeyguardStateController.isShowing()).thenReturn(true); TestableLooper.get(this).processAllMessages(); @@ -992,7 +992,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() { - mViewMediator.setShowingLocked(true); + mViewMediator.setShowingLocked(true, ""); when(mKeyguardStateController.isShowing()).thenReturn(true); TestableLooper.get(this).processAllMessages(); @@ -1051,7 +1051,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.onSystemReady(); processAllMessagesAndBgExecutorMessages(); - mViewMediator.setShowingLocked(true); + mViewMediator.setShowingLocked(true, ""); RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{ mock(RemoteAnimationTarget.class) @@ -1123,7 +1123,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testNotStartingKeyguardWhenFlagIsDisabled() { - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); when(mKeyguardStateController.isShowing()).thenReturn(false); mViewMediator.onDreamingStarted(); @@ -1133,7 +1133,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testStartingKeyguardWhenFlagIsEnabled() { - mViewMediator.setShowingLocked(true); + mViewMediator.setShowingLocked(true, ""); when(mKeyguardStateController.isShowing()).thenReturn(true); mViewMediator.onDreamingStarted(); @@ -1174,7 +1174,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); // WHEN keyguard visibility becomes FALSE - mViewMediator.setShowingLocked(false); + mViewMediator.setShowingLocked(false, ""); keyguardUpdateMonitorCallback.onKeyguardVisibilityChanged(false); TestableLooper.get(this).processAllMessages(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index d5cd86ec0b76..c8cc6b5fdf93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -50,14 +50,18 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.LocalMediaManager; import com.android.systemui.SysuiTestCase; +import com.android.systemui.SysuiTestCaseExtKt; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.kosmos.Kosmos; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractorKosmosKt; import org.junit.Before; import org.junit.Test; @@ -73,6 +77,8 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { private static final String TEST_PACKAGE = "test_package"; + private final Kosmos mKosmos = SysuiTestCaseExtKt.testKosmos(this); + // Mock private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class); private MediaController mMediaController = mock(MediaController.class); @@ -122,6 +128,9 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE); mMediaControllers.add(mMediaController); when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers); + VolumePanelGlobalStateInteractor volumePanelGlobalStateInteractor = + VolumePanelGlobalStateInteractorKosmosKt.getVolumePanelGlobalStateInteractor( + mKosmos); mMediaOutputController = new MediaOutputController( @@ -139,6 +148,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + volumePanelGlobalStateInteractor, mUserTracker); // Using a fake package will cause routing operations to fail, so we intercept diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java index 87d224579e95..189a56145d27 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java @@ -51,14 +51,18 @@ import com.android.settingslib.media.BluetoothMediaDevice; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.systemui.SysuiTestCase; +import com.android.systemui.SysuiTestCaseExtKt; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.kosmos.Kosmos; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractorKosmosKt; import com.google.common.base.Strings; @@ -81,6 +85,8 @@ public class MediaOutputBroadcastDialogTest extends SysuiTestCase { private static final String BROADCAST_CODE_TEST = "112233"; private static final String BROADCAST_CODE_UPDATE_TEST = "11223344"; + private final Kosmos mKosmos = SysuiTestCaseExtKt.testKosmos(this); + // Mock private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class); private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class); @@ -123,6 +129,9 @@ public class MediaOutputBroadcastDialogTest extends SysuiTestCase { when(mLocalBluetoothLeBroadcast.getProgramInfo()).thenReturn(BROADCAST_NAME_TEST); when(mLocalBluetoothLeBroadcast.getBroadcastCode()).thenReturn( BROADCAST_CODE_TEST.getBytes(StandardCharsets.UTF_8)); + VolumePanelGlobalStateInteractor volumePanelGlobalStateInteractor = + VolumePanelGlobalStateInteractorKosmosKt.getVolumePanelGlobalStateInteractor( + mKosmos); mMediaOutputController = new MediaOutputController( @@ -140,6 +149,7 @@ public class MediaOutputBroadcastDialogTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + volumePanelGlobalStateInteractor, mUserTracker); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputBroadcastDialog = new MediaOutputBroadcastDialog(mContext, false, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index 856bc0b78215..714fad9d7478 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -72,15 +72,19 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.systemui.SysuiTestCase; +import com.android.systemui.SysuiTestCaseExtKt; import com.android.systemui.animation.ActivityTransitionAnimator; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.kosmos.Kosmos; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractorKosmosKt; import com.google.common.collect.ImmutableList; @@ -158,11 +162,16 @@ public class MediaOutputControllerTest extends SysuiTestCase { @Mock private UserTracker mUserTracker; + private final Kosmos mKosmos = SysuiTestCaseExtKt.testKosmos(this); + private FeatureFlags mFlags = mock(FeatureFlags.class); private View mDialogLaunchView = mock(View.class); private MediaOutputController.Callback mCallback = mock(MediaOutputController.Callback.class); final Notification mNotification = mock(Notification.class); + private final VolumePanelGlobalStateInteractor mVolumePanelGlobalStateInteractor = + VolumePanelGlobalStateInteractorKosmosKt.getVolumePanelGlobalStateInteractor( + mKosmos); private Context mSpyContext; private String mPackageName = null; @@ -194,6 +203,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn( mCachedBluetoothDeviceManager); + mMediaOutputController = new MediaOutputController( mSpyContext, @@ -210,6 +220,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false); @@ -304,6 +315,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); mMediaOutputController.start(mCb); @@ -346,6 +358,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); mMediaOutputController.start(mCb); @@ -602,6 +615,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); testMediaOutputController.start(mCb); reset(mCb); @@ -636,6 +650,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); testMediaOutputController.start(mCb); reset(mCb); @@ -683,6 +698,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); LocalMediaManager mockLocalMediaManager = mock(LocalMediaManager.class); @@ -710,6 +726,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); LocalMediaManager mockLocalMediaManager = mock(LocalMediaManager.class); @@ -990,6 +1007,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); @@ -1193,6 +1211,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + mVolumePanelGlobalStateInteractor, mUserTracker); testMediaOutputController.setTemporaryAllowListExceptionIfNeeded(mMediaDevice2); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index f20b04ae0e5c..90c2930f8e49 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -54,14 +54,18 @@ import com.android.settingslib.flags.Flags; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.systemui.SysuiTestCase; +import com.android.systemui.SysuiTestCaseExtKt; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.kosmos.Kosmos; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor; +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractorKosmosKt; import org.junit.After; import org.junit.Before; @@ -84,6 +88,8 @@ public class MediaOutputDialogTest extends SysuiTestCase { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private final Kosmos mKosmos = SysuiTestCaseExtKt.testKosmos(this); + // Mock private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class); private MediaController mMediaController = mock(MediaController.class); @@ -136,6 +142,9 @@ public class MediaOutputDialogTest extends SysuiTestCase { when(mMediaSessionManager.getActiveSessionsForUser(any(), Mockito.eq(userHandle))).thenReturn( mMediaControllers); + VolumePanelGlobalStateInteractor volumePanelGlobalStateInteractor = + VolumePanelGlobalStateInteractorKosmosKt.getVolumePanelGlobalStateInteractor( + mKosmos); mMediaOutputController = new MediaOutputController( @@ -153,6 +162,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { mPowerExemptionManager, mKeyguardManager, mFlags, + volumePanelGlobalStateInteractor, mUserTracker); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputDialog = makeTestDialog(mMediaOutputController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index 6916bbde0153..d10ea1f02367 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -15,7 +15,9 @@ package com.android.systemui.statusbar; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; +import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_ADJUST_NOTHING; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; +import static android.inputmethodservice.InputMethodService.IME_ACTIVE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT; @@ -194,9 +196,11 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testShowImeButton() { - mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, 1, 2, true); + mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, IME_ACTIVE, + BACK_DISPOSITION_ADJUST_NOTHING, true); waitForIdleSync(); - verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(1), eq(2), eq(true)); + verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(IME_ACTIVE), + eq(BACK_DISPOSITION_ADJUST_NOTHING), eq(true)); } @Test @@ -204,11 +208,13 @@ public class CommandQueueTest extends SysuiTestCase { // First show in default display to update the "last updated ime display" testShowImeButton(); - mCommandQueue.setImeWindowStatus(SECONDARY_DISPLAY, 1, 2, true); + mCommandQueue.setImeWindowStatus(SECONDARY_DISPLAY, IME_ACTIVE, + BACK_DISPOSITION_ADJUST_NOTHING, true); waitForIdleSync(); - verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(0), + verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(0) /* vis */, eq(BACK_DISPOSITION_DEFAULT), eq(false)); - verify(mCallbacks).setImeWindowStatus(eq(SECONDARY_DISPLAY), eq(1), eq(2), eq(true)); + verify(mCallbacks).setImeWindowStatus(eq(SECONDARY_DISPLAY), eq(IME_ACTIVE), + eq(BACK_DISPOSITION_ADJUST_NOTHING), eq(true)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index 8fd0b31b82f3..171520f72269 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback +import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN import android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN @@ -59,6 +60,7 @@ import android.telephony.TelephonyManager.DATA_UNKNOWN import android.telephony.TelephonyManager.ERI_OFF import android.telephony.TelephonyManager.ERI_ON import android.telephony.TelephonyManager.EXTRA_CARRIER_ID +import android.telephony.TelephonyManager.EXTRA_DATA_SPN import android.telephony.TelephonyManager.EXTRA_PLMN import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN import android.telephony.TelephonyManager.EXTRA_SHOW_SPN @@ -69,6 +71,7 @@ import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.mobile.MobileMappings +import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlagsClassic @@ -85,7 +88,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionMod import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig -import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength @@ -93,8 +95,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.Mobil import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor @@ -112,6 +112,8 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @@ -807,6 +809,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { } @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) fun networkName_usesBroadcastInfo_returnsDerived() = testScope.runTest { var latest: NetworkNameModel? = null @@ -815,14 +818,34 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val intent = spnIntent() val captor = argumentCaptor<BroadcastReceiver>() verify(context).registerReceiver(captor.capture(), any()) - captor.value!!.onReceive(context, intent) + captor.lastValue.onReceive(context, intent) - assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP)) + // spnIntent() sets all values to true and test strings + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) job.cancel() } @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_usesBroadcastInfo_returnsDerived_flagOff() = + testScope.runTest { + var latest: NetworkNameModel? = null + val job = underTest.networkName.onEach { latest = it }.launchIn(this) + + val intent = spnIntent() + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + captor.lastValue.onReceive(context, intent) + + // spnIntent() sets all values to true and test strings + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) + + job.cancel() + } + + @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) fun networkName_broadcastNotForThisSubId_keepsOldValue() = testScope.runTest { var latest: NetworkNameModel? = null @@ -831,22 +854,48 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val intent = spnIntent() val captor = argumentCaptor<BroadcastReceiver>() verify(context).registerReceiver(captor.capture(), any()) - captor.value!!.onReceive(context, intent) + captor.lastValue.onReceive(context, intent) + + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) + + // WHEN an intent with a different subId is sent + val wrongSubIntent = spnIntent(subId = 101) + + captor.lastValue.onReceive(context, wrongSubIntent) + + // THEN the previous intent's name is still used + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) + + job.cancel() + } + + @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_broadcastNotForThisSubId_keepsOldValue_flagOff() = + testScope.runTest { + var latest: NetworkNameModel? = null + val job = underTest.networkName.onEach { latest = it }.launchIn(this) + + val intent = spnIntent() + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + captor.lastValue.onReceive(context, intent) - assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP)) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) // WHEN an intent with a different subId is sent val wrongSubIntent = spnIntent(subId = 101) - captor.value!!.onReceive(context, wrongSubIntent) + captor.lastValue.onReceive(context, wrongSubIntent) // THEN the previous intent's name is still used - assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP)) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) job.cancel() } @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) fun networkName_broadcastHasNoData_updatesToDefault() = testScope.runTest { var latest: NetworkNameModel? = null @@ -855,9 +904,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val intent = spnIntent() val captor = argumentCaptor<BroadcastReceiver>() verify(context).registerReceiver(captor.capture(), any()) - captor.value!!.onReceive(context, intent) + captor.lastValue.onReceive(context, intent) - assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP)) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) val intentWithoutInfo = spnIntent( @@ -865,7 +914,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { showPlmn = false, ) - captor.value!!.onReceive(context, intentWithoutInfo) + captor.lastValue.onReceive(context, intentWithoutInfo) assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) @@ -873,6 +922,34 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { } @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_broadcastHasNoData_updatesToDefault_flagOff() = + testScope.runTest { + var latest: NetworkNameModel? = null + val job = underTest.networkName.onEach { latest = it }.launchIn(this) + + val intent = spnIntent() + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + captor.lastValue.onReceive(context, intent) + + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) + + val intentWithoutInfo = + spnIntent( + showSpn = false, + showPlmn = false, + ) + + captor.lastValue.onReceive(context, intentWithoutInfo) + + assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) + + job.cancel() + } + + @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers() = testScope.runTest { // Use the [StateFlow.value] getter so we can prove that the collection happens @@ -884,10 +961,172 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val intent = spnIntent() val captor = argumentCaptor<BroadcastReceiver>() verify(context).registerReceiver(captor.capture(), any()) - captor.value!!.onReceive(context, intent) + captor.lastValue.onReceive(context, intent) + + // The value is still there despite no active subscribers + assertThat(underTest.networkName.value) + .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) + } + + @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers_flagOff() = + testScope.runTest { + // Use the [StateFlow.value] getter so we can prove that the collection happens + // even when there is no [Job] + + // Starts out default + assertThat(underTest.networkName.value).isEqualTo(DEFAULT_NAME_MODEL) + + val intent = spnIntent() + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + captor.lastValue.onReceive(context, intent) // The value is still there despite no active subscribers - assertThat(underTest.networkName.value).isEqualTo(intent.toNetworkNameModel(SEP)) + assertThat(underTest.networkName.value) + .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) + } + + @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_allFieldsSet_doesNotUseDataSpn() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = SPN, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = PLMN, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) + } + + @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_allFieldsSet_flagOff() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = SPN, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = PLMN, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) + } + + @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = null, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = PLMN, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN")) + } + + @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull_flagOff() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = null, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = PLMN, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) + } + + @Test + fun networkName_showPlmn_noShowSPN() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = false, + spn = SPN, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = PLMN, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN")) + } + + @Test + @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_showPlmn_plmnNull_showSpn() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = SPN, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = null, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN")) + } + + @Test + @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) + fun networkName_showPlmn_plmnNull_showSpn_flagOff() = + testScope.runTest { + val latest by collectLastValue(underTest.networkName) + val captor = argumentCaptor<BroadcastReceiver>() + verify(context).registerReceiver(captor.capture(), any()) + val intent = + spnIntent( + subId = SUB_1_ID, + showSpn = true, + spn = SPN, + dataSpn = DATA_SPN, + showPlmn = true, + plmn = null, + ) + captor.lastValue.onReceive(context, intent) + assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN")) } @Test @@ -1128,14 +1367,16 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { private fun spnIntent( subId: Int = SUB_1_ID, showSpn: Boolean = true, - spn: String = SPN, + spn: String? = SPN, + dataSpn: String? = DATA_SPN, showPlmn: Boolean = true, - plmn: String = PLMN, + plmn: String? = PLMN, ): Intent = Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED).apply { putExtra(EXTRA_SUBSCRIPTION_INDEX, subId) putExtra(EXTRA_SHOW_SPN, showSpn) putExtra(EXTRA_SPN, spn) + putExtra(EXTRA_DATA_SPN, dataSpn) putExtra(EXTRA_SHOW_PLMN, showPlmn) putExtra(EXTRA_PLMN, plmn) } @@ -1148,6 +1389,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { private const val SEP = "-" private const val SPN = "testSpn" + private const val DATA_SPN = "testDataSpn" private const val PLMN = "testPlmn" } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt index b6194e3f511d..bbe753e8c7a5 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt @@ -27,7 +27,9 @@ import kotlinx.coroutines.flow.filterNotNull class FakeQSSceneAdapter( private val inflateDelegate: suspend (Context) -> View, override val qqsHeight: Int = 0, + override val squishedQqsHeight: Int = 0, override val qsHeight: Int = 0, + override val squishedQsHeight: Int = 0, ) : QSSceneAdapter { private val _customizerState = MutableStateFlow<CustomizerState>(CustomizerState.Hidden) diff --git a/services/Android.bp b/services/Android.bp index ded7379ad487..0006455f41b0 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -120,6 +120,7 @@ filegroup { ":services.backup-sources", ":services.companion-sources", ":services.contentcapture-sources", + ":services.appfunctions-sources", ":services.contentsuggestions-sources", ":services.contextualsearch-sources", ":services.coverage-sources", @@ -217,6 +218,7 @@ system_java_library { "services.autofill", "services.backup", "services.companion", + "services.appfunctions", "services.contentcapture", "services.contentsuggestions", "services.contextualsearch", diff --git a/services/appfunctions/Android.bp b/services/appfunctions/Android.bp new file mode 100644 index 000000000000..f8ee823ef0c9 --- /dev/null +++ b/services/appfunctions/Android.bp @@ -0,0 +1,25 @@ +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"], +} + +filegroup { + name: "services.appfunctions-sources", + srcs: ["java/**/*.java"], + path: "java", + visibility: ["//frameworks/base/services"], +} + +java_library_static { + name: "services.appfunctions", + defaults: ["platform_service_defaults"], + srcs: [ + ":services.appfunctions-sources", + "java/**/*.logtags", + ], + libs: ["services.core"], +} diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java new file mode 100644 index 000000000000..f30e770be32b --- /dev/null +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java @@ -0,0 +1,45 @@ +/* + * 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.server.appfunctions; + +import static android.app.appfunctions.flags.Flags.enableAppFunctionManager; + +import android.app.appfunctions.IAppFunctionManager; +import android.content.Context; + +import com.android.server.SystemService; + +/** + * Service that manages app functions. + */ +public class AppFunctionManagerService extends SystemService { + + public AppFunctionManagerService(Context context) { + super(context); + } + + @Override + public void onStart() { + if (enableAppFunctionManager()) { + publishBinderService(Context.APP_FUNCTION_SERVICE, new AppFunctionManagerStub()); + } + } + + private static class AppFunctionManagerStub extends IAppFunctionManager.Stub { + + } +} diff --git a/services/core/java/com/android/server/AlarmManagerInternal.java b/services/core/java/com/android/server/AlarmManagerInternal.java index b7f2b8d4ffe6..191137ade3a3 100644 --- a/services/core/java/com/android/server/AlarmManagerInternal.java +++ b/services/core/java/com/android/server/AlarmManagerInternal.java @@ -17,6 +17,7 @@ package com.android.server; import android.annotation.CurrentTimeMillisLong; +import android.annotation.UserIdInt; import android.app.PendingIntent; import com.android.server.SystemClockTime.TimeConfidence; @@ -36,6 +37,16 @@ public interface AlarmManagerInternal { /** Returns true if AlarmManager is delaying alarms due to device idle. */ boolean isIdling(); + /** + * Returns the time at which the next alarm for the given user is going to trigger, or 0 if + * there is none. + * + * <p>This value is UTC wall clock time in milliseconds, as returned by + * {@link System#currentTimeMillis()} for example. + * @see android.app.AlarmManager.AlarmClockInfo#getTriggerTime() + */ + long getNextAlarmTriggerTimeForUser(@UserIdInt int userId); + public void removeAlarmsForUid(int uid); public void registerInFlightListener(InFlightListener callback); diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index e57fe133eac8..bdba6bcf66c0 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -131,6 +131,7 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.ObjectUtils; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; +import com.android.server.AlarmManagerInternal; import com.android.server.FactoryResetter; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -247,6 +248,12 @@ class UserController implements Handler.Callback { private static final int USER_COMPLETED_EVENT_DELAY_MS = 5 * 1000; /** + * If a user has an alarm in the next this many milliseconds, avoid stopping it due to + * scheduled background stopping. + */ + private static final long TIME_BEFORE_USERS_ALARM_TO_AVOID_STOPPING_MS = 60 * 60_000; // 60 mins + + /** * Maximum number of users we allow to be running at a time, including system user. * * <p>This parameter only affects how many background users will be stopped when switching to a @@ -2418,6 +2425,12 @@ class UserController implements Handler.Callback { void processScheduledStopOfBackgroundUser(Integer userIdInteger) { final int userId = userIdInteger; Slogf.d(TAG, "Considering stopping background user %d due to inactivity", userId); + + if (avoidStoppingUserDueToUpcomingAlarm(userId)) { + // We want this user running soon for alarm-purposes, so don't stop it now. Reschedule. + scheduleStopOfBackgroundUser(userId); + return; + } synchronized (mLock) { if (getCurrentOrTargetUserIdLU() == userId) { return; @@ -2437,6 +2450,18 @@ class UserController implements Handler.Callback { } } + /** + * Returns whether we should avoid stopping the user now due to it having an alarm set to fire + * soon. + */ + private boolean avoidStoppingUserDueToUpcomingAlarm(@UserIdInt int userId) { + final long alarmWallclockMs + = mInjector.getAlarmManagerInternal().getNextAlarmTriggerTimeForUser(userId); + return System.currentTimeMillis() < alarmWallclockMs + && (alarmWallclockMs + < System.currentTimeMillis() + TIME_BEFORE_USERS_ALARM_TO_AVOID_STOPPING_MS); + } + private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) { TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG); t.traceBegin("timeoutUserSwitch-" + oldUserId + "-to-" + newUserId); @@ -3908,6 +3933,10 @@ class UserController implements Handler.Callback { return mPowerManagerInternal; } + AlarmManagerInternal getAlarmManagerInternal() { + return LocalServices.getService(AlarmManagerInternal.class); + } + KeyguardManager getKeyguardManager() { return mService.mContext.getSystemService(KeyguardManager.class); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index 079b7242b1f3..ec1993a9b444 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -18,6 +18,7 @@ package com.android.server.inputmethod; import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED; import static android.content.Context.DEVICE_ID_DEFAULT; +import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.INVALID_DISPLAY; @@ -32,6 +33,8 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManagerInternal; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.os.Binder; import android.os.IBinder; import android.os.Process; @@ -99,24 +102,16 @@ final class InputMethodBindingController { /** * A set of status bits regarding the active IME. * - * <p>This value is a combination of following two bits:</p> - * <dl> - * <dt>{@link InputMethodService#IME_ACTIVE}</dt> - * <dd> - * If this bit is ON, connected IME is ready to accept touch/key events. - * </dd> - * <dt>{@link InputMethodService#IME_VISIBLE}</dt> - * <dd> - * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible. - * </dd> - * </dl> - * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and - * {@link InputMethodBindingController#unbindCurrentMethod()}.</em> + * <em>Do not update this value outside of {@link #setImeWindowVis} and + * {@link InputMethodBindingController#unbindCurrentMethod}.</em> */ - @GuardedBy("ImfLock.class") private int mImeWindowVis; + @ImeWindowVisibility + @GuardedBy("ImfLock.class") + private int mImeWindowVis; + @BackDispositionMode @GuardedBy("ImfLock.class") - private int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; + private int mBackDisposition = BACK_DISPOSITION_DEFAULT; @Nullable private CountDownLatch mLatchForTesting; @@ -718,22 +713,24 @@ final class InputMethodBindingController { } @GuardedBy("ImfLock.class") - void setImeWindowVis(int imeWindowVis) { + void setImeWindowVis(@ImeWindowVisibility int imeWindowVis) { mImeWindowVis = imeWindowVis; } + @ImeWindowVisibility @GuardedBy("ImfLock.class") int getImeWindowVis() { return mImeWindowVis; } + @BackDispositionMode @GuardedBy("ImfLock.class") int getBackDisposition() { return mBackDisposition; } @GuardedBy("ImfLock.class") - void setBackDisposition(int backDisposition) { + void setBackDisposition(@BackDispositionMode int backDisposition) { mBackDisposition = backDisposition; } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 8afbd56728e4..36542837e582 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -86,6 +86,8 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.hardware.input.InputManager; import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.media.AudioManagerInternal; import android.net.Uri; import android.os.Binder; @@ -2618,7 +2620,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @GuardedBy("ImfLock.class") - private boolean shouldShowImeSwitcherLocked(int visibility, @UserIdInt int userId) { + private boolean shouldShowImeSwitcherLocked(@ImeWindowVisibility int visibility, + @UserIdInt int userId) { if (!mShowOngoingImeSwitcherForPhones) return false; // When the IME switcher dialog is shown, the IME switcher button should be hidden. // TODO(b/305849394): Make mMenuController multi-user aware. @@ -2722,8 +2725,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @GuardedBy("ImfLock.class") @SuppressWarnings("deprecation") - private void setImeWindowStatusLocked(int vis, int backDisposition, - @NonNull UserData userData) { + private void setImeWindowStatusLocked(@ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, @NonNull UserData userData) { final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId(); final int userId = userData.mUserId; @@ -2772,7 +2775,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final int userId = resolveImeUserIdFromDisplayIdLocked(displayId); if (disableImeIcon) { final var bindingController = getInputMethodBindingController(userId); - updateSystemUiLocked(0, bindingController.getBackDisposition(), userId); + updateSystemUiLocked(0 /* vis */, bindingController.getBackDisposition(), userId); } else { updateSystemUiLocked(userId); } @@ -2787,7 +2790,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @GuardedBy("ImfLock.class") - private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) { + private void updateSystemUiLocked(@ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, @UserIdInt int userId) { // To minimize app compat risk, ignore background users' request for single-user mode. // TODO(b/357178609): generalize the logic and remove this special rule. if (!mConcurrentMultiUserModeEnabled && userId != mCurrentImeUserId) { @@ -6812,7 +6816,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @Override - public void setImeWindowStatusAsync(int vis, int backDisposition) { + public void setImeWindowStatusAsync(@ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition) { synchronized (ImfLock.class) { if (!calledWithValidTokenLocked(mToken, mUserData)) { return; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java index c77b76864176..202543c7e7a5 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java @@ -614,242 +614,61 @@ final class InputMethodSubtypeSwitchingController { } } - @VisibleForTesting - public static class ControllerImpl { - - @NonNull - private final DynamicRotationList mSwitchingAwareRotationList; - @NonNull - private final StaticRotationList mSwitchingUnawareRotationList; - /** List of input methods and subtypes. */ - @Nullable - private final RotationList mRotationList; - /** List of input methods and subtypes suitable for hardware keyboards. */ - @Nullable - private final RotationList mHardwareRotationList; - - /** - * Whether there was a user action since the last input method and subtype switch. - * Used to determine the switching behaviour for {@link #MODE_AUTO}. - */ - private boolean mUserActionSinceSwitch; - - @NonNull - public static ControllerImpl createFrom(@Nullable ControllerImpl currentInstance, - @NonNull List<ImeSubtypeListItem> sortedEnabledItems, - @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) { - final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems, - true /* supportsSwitchingToNextInputMethod */); - final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems, - false /* supportsSwitchingToNextInputMethod */); - - final DynamicRotationList switchingAwareRotationList; - if (currentInstance != null && Objects.equals( - currentInstance.mSwitchingAwareRotationList.mImeSubtypeList, - switchingAwareImeSubtypes)) { - // Can reuse the current instance. - switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList; - } else { - switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes); - } - - final StaticRotationList switchingUnawareRotationList; - if (currentInstance != null && Objects.equals( - currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList, - switchingUnawareImeSubtypes)) { - // Can reuse the current instance. - switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList; - } else { - switchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes); - } - - final RotationList rotationList; - if (!Flags.imeSwitcherRevamp()) { - rotationList = null; - } else if (currentInstance != null && currentInstance.mRotationList != null - && Objects.equals( - currentInstance.mRotationList.mItems, sortedEnabledItems)) { - // Can reuse the current instance. - rotationList = currentInstance.mRotationList; - } else { - rotationList = new RotationList(sortedEnabledItems); - } - - final RotationList hardwareRotationList; - if (!Flags.imeSwitcherRevamp()) { - hardwareRotationList = null; - } else if (currentInstance != null && currentInstance.mHardwareRotationList != null - && Objects.equals( - currentInstance.mHardwareRotationList.mItems, hardwareKeyboardItems)) { - // Can reuse the current instance. - hardwareRotationList = currentInstance.mHardwareRotationList; - } else { - hardwareRotationList = new RotationList(hardwareKeyboardItems); - } - - return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList, - rotationList, hardwareRotationList); - } - - private ControllerImpl(@NonNull DynamicRotationList switchingAwareRotationList, - @NonNull StaticRotationList switchingUnawareRotationList, - @Nullable RotationList rotationList, - @Nullable RotationList hardwareRotationList) { - mSwitchingAwareRotationList = switchingAwareRotationList; - mSwitchingUnawareRotationList = switchingUnawareRotationList; - mRotationList = rotationList; - mHardwareRotationList = hardwareRotationList; - } + @NonNull + private DynamicRotationList mSwitchingAwareRotationList = + new DynamicRotationList(Collections.emptyList()); + @NonNull + private StaticRotationList mSwitchingUnawareRotationList = + new StaticRotationList(Collections.emptyList()); + /** List of input methods and subtypes. */ + @NonNull + private RotationList mRotationList = new RotationList(Collections.emptyList()); + /** List of input methods and subtypes suitable for hardware keyboards. */ + @NonNull + private RotationList mHardwareRotationList = new RotationList(Collections.emptyList()); - @Nullable - public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme, - @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype, - @SwitchMode int mode, boolean forward) { - if (imi == null) { - return null; - } - if (Flags.imeSwitcherRevamp() && mRotationList != null) { - return mRotationList.next(imi, subtype, onlyCurrentIme, - isRecency(mode, forward), forward); - } else if (imi.supportsSwitchingToNextInputMethod()) { - return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi, - subtype); - } else { - return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi, - subtype); - } - } + /** + * Whether there was a user action since the last input method and subtype switch. + * Used to determine the switching behaviour for {@link #MODE_AUTO}. + */ + private boolean mUserActionSinceSwitch; - @Nullable - public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme, - @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype, - @SwitchMode int mode, boolean forward) { - if (Flags.imeSwitcherRevamp() && mHardwareRotationList != null) { - return mHardwareRotationList.next(imi, subtype, onlyCurrentIme, - isRecency(mode, forward), forward); - } - return null; - } + /** + * Updates the list of input methods and subtypes used for switching. If the given items are + * equal to the existing ones (regardless of recency order), the update is skipped and the + * current recency order is kept. Otherwise, the recency order is reset. + * + * @param sortedEnabledItems the sorted list of enabled input methods and subtypes. + * @param hardwareKeyboardItems the unsorted list of enabled input method and subtypes + * suitable for hardware keyboards. + */ + @VisibleForTesting + void update(@NonNull List<ImeSubtypeListItem> sortedEnabledItems, + @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) { + final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems, + true /* supportsSwitchingToNextInputMethod */); + final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems, + false /* supportsSwitchingToNextInputMethod */); - /** - * Called when the user took an action that should update the recency of the current - * input method and subtype in the switching list. - * - * @param imi the currently selected input method. - * @param subtype the currently selected input method subtype, if any. - * @return {@code true} if the recency was updated, otherwise {@code false}. - * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary() - */ - public boolean onUserActionLocked(@NonNull InputMethodInfo imi, - @Nullable InputMethodSubtype subtype) { - boolean recencyUpdated = false; - if (Flags.imeSwitcherRevamp()) { - if (mRotationList != null) { - recencyUpdated |= mRotationList.setMostRecent(imi, subtype); - } - if (mHardwareRotationList != null) { - recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype); - } - if (recencyUpdated) { - mUserActionSinceSwitch = true; - } - } else if (imi.supportsSwitchingToNextInputMethod()) { - mSwitchingAwareRotationList.onUserAction(imi, subtype); - } - return recencyUpdated; + if (!Objects.equals(mSwitchingAwareRotationList.mImeSubtypeList, + switchingAwareImeSubtypes)) { + mSwitchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes); } - /** Called when the input method and subtype was changed. */ - public void onInputMethodSubtypeChanged() { - mUserActionSinceSwitch = false; + if (!Objects.equals(mSwitchingUnawareRotationList.mImeSubtypeList, + switchingUnawareImeSubtypes)) { + mSwitchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes); } - /** - * Whether the given mode and direction result in recency or static order. - * - * <p>{@link #MODE_AUTO} resolves to the recency order for the first forwards switch - * after an {@link #onUserActionLocked user action}, and otherwise to the static order.</p> - * - * @param mode the switching mode. - * @param forward the switching direction. - * @return {@code true} for the recency order, otherwise {@code false}. - */ - private boolean isRecency(@SwitchMode int mode, boolean forward) { - if (mode == MODE_AUTO && mUserActionSinceSwitch && forward) { - return true; - } else { - return mode == MODE_RECENT; - } + if (Flags.imeSwitcherRevamp() + && !Objects.equals(mRotationList.mItems, sortedEnabledItems)) { + mRotationList = new RotationList(sortedEnabledItems); } - @NonNull - private static List<ImeSubtypeListItem> filterImeSubtypeList( - @NonNull List<ImeSubtypeListItem> items, - boolean supportsSwitchingToNextInputMethod) { - final ArrayList<ImeSubtypeListItem> result = new ArrayList<>(); - final int numItems = items.size(); - for (int i = 0; i < numItems; i++) { - final ImeSubtypeListItem item = items.get(i); - if (item.mImi.supportsSwitchingToNextInputMethod() - == supportsSwitchingToNextInputMethod) { - result.add(item); - } - } - return result; + if (Flags.imeSwitcherRevamp() + && !Objects.equals(mHardwareRotationList.mItems, hardwareKeyboardItems)) { + mHardwareRotationList = new RotationList(hardwareKeyboardItems); } - - protected void dump(@NonNull Printer pw, @NonNull String prefix) { - pw.println(prefix + "mSwitchingAwareRotationList:"); - mSwitchingAwareRotationList.dump(pw, prefix + " "); - pw.println(prefix + "mSwitchingUnawareRotationList:"); - mSwitchingUnawareRotationList.dump(pw, prefix + " "); - if (Flags.imeSwitcherRevamp()) { - if (mRotationList != null) { - pw.println(prefix + "mRotationList:"); - mRotationList.dump(pw, prefix + " "); - } - if (mHardwareRotationList != null) { - pw.println(prefix + "mHardwareRotationList:"); - mHardwareRotationList.dump(pw, prefix + " "); - } - pw.println(prefix + "User action since last switch: " + mUserActionSinceSwitch); - } - } - } - - @NonNull - private ControllerImpl mController; - - InputMethodSubtypeSwitchingController() { - mController = ControllerImpl.createFrom(null, Collections.emptyList(), - Collections.emptyList()); - } - - /** - * Called when the user took an action that should update the recency of the current - * input method and subtype in the switching list. - * - * @param imi the currently selected input method. - * @param subtype the currently selected input method subtype, if any. - * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary() - */ - public void onUserActionLocked(@NonNull InputMethodInfo imi, - @Nullable InputMethodSubtype subtype) { - mController.onUserActionLocked(imi, subtype); - } - - /** Called when the input method and subtype was changed. */ - public void onInputMethodSubtypeChanged() { - mController.onInputMethodSubtypeChanged(); - } - - public void resetCircularListLocked(@NonNull Context context, - @NonNull InputMethodSettings settings) { - mController = ControllerImpl.createFrom(mController, - getSortedInputMethodAndSubtypeList( - false /* includeAuxiliarySubtypes */, false /* isScreenLocked */, - false /* forImeMenu */, context, settings), - getInputMethodAndSubtypeListForHardwareKeyboard(context, settings)); } /** @@ -869,7 +688,19 @@ final class InputMethodSubtypeSwitchingController { public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype, @SwitchMode int mode, boolean forward) { - return mController.getNextInputMethod(onlyCurrentIme, imi, subtype, mode, forward); + if (imi == null) { + return null; + } + if (Flags.imeSwitcherRevamp()) { + return mRotationList.next(imi, subtype, onlyCurrentIme, + isRecency(mode, forward), forward); + } else if (imi.supportsSwitchingToNextInputMethod()) { + return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi, + subtype); + } else { + return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi, + subtype); + } } /** @@ -890,11 +721,98 @@ final class InputMethodSubtypeSwitchingController { public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme, @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype, @SwitchMode int mode, boolean forward) { - return mController.getNextInputMethodForHardware(onlyCurrentIme, imi, subtype, mode, - forward); + if (Flags.imeSwitcherRevamp()) { + return mHardwareRotationList.next(imi, subtype, onlyCurrentIme, + isRecency(mode, forward), forward); + } + return null; } - public void dump(@NonNull Printer pw, @NonNull String prefix) { - mController.dump(pw, prefix); + /** + * Called when the user took an action that should update the recency of the current + * input method and subtype in the switching list. + * + * @param imi the currently selected input method. + * @param subtype the currently selected input method subtype, if any. + * @return {@code true} if the recency was updated, otherwise {@code false}. + * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary() + */ + public boolean onUserActionLocked(@NonNull InputMethodInfo imi, + @Nullable InputMethodSubtype subtype) { + boolean recencyUpdated = false; + if (Flags.imeSwitcherRevamp()) { + recencyUpdated |= mRotationList.setMostRecent(imi, subtype); + recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype); + if (recencyUpdated) { + mUserActionSinceSwitch = true; + } + } else if (imi.supportsSwitchingToNextInputMethod()) { + mSwitchingAwareRotationList.onUserAction(imi, subtype); + } + return recencyUpdated; + } + + /** Called when the input method and subtype was changed. */ + public void onInputMethodSubtypeChanged() { + mUserActionSinceSwitch = false; + } + + /** + * Whether the given mode and direction result in recency or static order. + * + * <p>{@link #MODE_AUTO} resolves to the recency order for the first forwards switch + * after an {@link #onUserActionLocked user action}, and otherwise to the static order.</p> + * + * @param mode the switching mode. + * @param forward the switching direction. + * @return {@code true} for the recency order, otherwise {@code false}. + */ + private boolean isRecency(@SwitchMode int mode, boolean forward) { + if (mode == MODE_AUTO && mUserActionSinceSwitch && forward) { + return true; + } else { + return mode == MODE_RECENT; + } + } + + @NonNull + private static List<ImeSubtypeListItem> filterImeSubtypeList( + @NonNull List<ImeSubtypeListItem> items, + boolean supportsSwitchingToNextInputMethod) { + final ArrayList<ImeSubtypeListItem> result = new ArrayList<>(); + final int numItems = items.size(); + for (int i = 0; i < numItems; i++) { + final ImeSubtypeListItem item = items.get(i); + if (item.mImi.supportsSwitchingToNextInputMethod() + == supportsSwitchingToNextInputMethod) { + result.add(item); + } + } + return result; + } + + void dump(@NonNull Printer pw, @NonNull String prefix) { + pw.println(prefix + "mSwitchingAwareRotationList:"); + mSwitchingAwareRotationList.dump(pw, prefix + " "); + pw.println(prefix + "mSwitchingUnawareRotationList:"); + mSwitchingUnawareRotationList.dump(pw, prefix + " "); + if (Flags.imeSwitcherRevamp()) { + pw.println(prefix + "mRotationList:"); + mRotationList.dump(pw, prefix + " "); + pw.println(prefix + "mHardwareRotationList:"); + mHardwareRotationList.dump(pw, prefix + " "); + pw.println(prefix + "User action since last switch: " + mUserActionSinceSwitch); + } + } + + InputMethodSubtypeSwitchingController() { + } + + public void resetCircularListLocked(@NonNull Context context, + @NonNull InputMethodSettings settings) { + update(getSortedInputMethodAndSubtypeList( + false /* includeAuxiliarySubtypes */, false /* isScreenLocked */, + false /* forImeMenu */, context, settings), + getInputMethodAndSubtypeListForHardwareKeyboard(context, settings)); } } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index db48835a9b82..0f50260a55d2 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -961,14 +961,17 @@ public class ZenModeHelper { if (origin == ORIGIN_USER_IN_SYSTEMUI && condition != null && condition.source == SOURCE_USER_ACTION) { // Apply as override, instead of actual condition. + // If the new override is the reverse of a previous (still active) override, try + // removing the previous override, as long as the resulting state, based on the + // previous owner-provided condition, is the desired one (active or inactive). + // This allows the rule owner to resume controlling the rule after + // snoozing-unsnoozing or activating-stopping. if (condition.state == STATE_TRUE) { - // Manually turn on a rule -> Apply override. - rule.setConditionOverride(OVERRIDE_ACTIVATE); + rule.resetConditionOverride(); + if (!rule.isAutomaticActive()) { + rule.setConditionOverride(OVERRIDE_ACTIVATE); + } } else if (condition.state == STATE_FALSE) { - // Manually turn off a rule. If the rule was manually activated before, reset - // override -- but only if this will not result in the rule turning on - // immediately because of a previously snoozed condition! In that case, apply - // deactivate-override. rule.resetConditionOverride(); if (rule.isAutomaticActive()) { rule.setConditionOverride(OVERRIDE_DEACTIVATE); diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 98e3e24c36b9..22b4d5def8f4 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -686,6 +686,9 @@ final class InstallPackageHelper { (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; final boolean fullApp = (installFlags & PackageManager.INSTALL_FULL_APP) != 0; + final boolean isPackageDeviceAdmin = mPm.isPackageDeviceAdmin(packageName, userId); + final boolean isProtectedPackage = mPm.mProtectedPackages != null + && mPm.mProtectedPackages.isPackageStateProtected(userId, packageName); // writer synchronized (mPm.mLock) { @@ -694,7 +697,8 @@ final class InstallPackageHelper { if (pkgSetting == null || pkgSetting.getPkg() == null) { return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); } - if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp())) { + if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp() + || isPackageDeviceAdmin || isProtectedPackage)) { return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); } if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) { diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING index c40608d12a0e..c95d88e8c697 100644 --- a/services/core/java/com/android/server/pm/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/TEST_MAPPING @@ -163,6 +163,22 @@ }, { "name": "CtsUpdateOwnershipEnforcementTestCases" + }, + { + "name": "CtsPackageInstallerCUJTestCases", + "file_patterns": [ + "core/java/.*Install.*", + "services/core/.*Install.*", + "services/core/java/com/android/server/pm/.*" + ], + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] } ], "imports": [ diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index b28da55b5196..1a2a196fe4e8 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -360,7 +360,13 @@ public class Notifier { IWakeLockCallback callback, int newFlags, String newTag, String newPackageName, int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag, IWakeLockCallback newCallback) { - + // Todo(b/359154665): We do this because the newWorkSource can potentially be updated + // before the request is processed on the notifier thread. This would generally happen is + // the Worksource's set method is called, which as of this comment happens only in + // PowerManager#setWorksource and WifiManager#WifiLock#setWorksource. Both these places + // need to be updated and the WorkSource#set should be deprecated to avoid falling into + // such traps + newWorkSource = (newWorkSource == null) ? null : new WorkSource(newWorkSource); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags); if (workSource != null && newWorkSource != null diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index a4a29a02f362..2faa68a9948f 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -20,6 +20,8 @@ import android.annotation.Nullable; import android.app.ITransientNotificationCallback; import android.content.ComponentName; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.os.Bundle; import android.os.IBinder; import android.os.UserHandle; @@ -54,13 +56,12 @@ public interface StatusBarManagerInternal { * Used by InputMethodManagerService to notify the IME status. * * @param displayId The display to which the IME is bound to. - * @param vis Bit flags about the IME visibility. - * (e.g. {@link android.inputmethodservice.InputMethodService#IME_ACTIVE}) - * @param backDisposition Bit flags about the IME back disposition. - * (e.g. {@link android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT}) + * @param vis The IME visibility. + * @param backDisposition The IME back disposition. * @param showImeSwitcher {@code true} when the IME switcher button should be shown. */ - void setImeWindowStatus(int displayId, int vis, int backDisposition, boolean showImeSwitcher); + void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher); /** * See {@link android.app.StatusBarManager#setIcon(String, int, int, String)}. diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index c3601b3c3090..e71f9eac98d4 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -26,6 +26,7 @@ import static android.app.StatusBarManager.NAV_BAR_MODE_KIDS; import static android.app.StatusBarManager.NavBarMode; import static android.app.StatusBarManager.SessionFlags; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.ViewRootImpl.CLIENT_TRANSIENT; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; @@ -60,6 +61,8 @@ import android.hardware.biometrics.PromptInfo; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; +import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService.ImeWindowVisibility; import android.media.INearbyMediaDevicesProvider; import android.media.MediaRoute2Info; import android.net.Uri; @@ -534,8 +537,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void setImeWindowStatus(int displayId, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition, boolean showImeSwitcher) { StatusBarManagerService.this.setImeWindowStatus(displayId, vis, backDisposition, showImeSwitcher); } @@ -1351,8 +1354,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void setImeWindowStatus(int displayId, final int vis, final int backDisposition, - final boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, @ImeWindowVisibility final int vis, + @BackDispositionMode final int backDisposition, final boolean showImeSwitcher) { enforceStatusBar(); if (SPEW) { @@ -1418,8 +1421,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private String mPackageName = "none"; private int mDisabled1 = 0; private int mDisabled2 = 0; + @ImeWindowVisibility private int mImeWindowVis = 0; - private int mImeBackDisposition = 0; + @BackDispositionMode + private int mImeBackDisposition = BACK_DISPOSITION_DEFAULT; private boolean mShowImeSwitcher = false; private LetterboxDetails[] mLetterboxDetails = new LetterboxDetails[0]; @@ -1462,7 +1467,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D return mDisabled1 == disabled1 && mDisabled2 == disabled2; } - private void setImeWindowState(final int vis, final int backDisposition, + private void setImeWindowState(@ImeWindowVisibility final int vis, + @BackDispositionMode final int backDisposition, final boolean showImeSwitcher) { mImeWindowVis = vis; mImeBackDisposition = backDisposition; diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java index 48a9311c0374..b03af4c3734a 100644 --- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java @@ -26,9 +26,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Point; import android.graphics.Rect; -import android.view.InsetsSource; -import android.view.InsetsState; -import android.view.RoundedCorner; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; @@ -44,12 +41,17 @@ class AppCompatLetterboxPolicy { private final ActivityRecord mActivityRecord; @NonNull private final LetterboxPolicyState mLetterboxPolicyState; + @NonNull + private final AppCompatRoundedCorners mAppCompatRoundedCorners; private boolean mLastShouldShowLetterboxUi; AppCompatLetterboxPolicy(@NonNull ActivityRecord activityRecord) { mActivityRecord = activityRecord; mLetterboxPolicyState = new LetterboxPolicyState(); + // TODO (b/358334569) Improve cutout logic dependency on app compat. + mAppCompatRoundedCorners = new AppCompatRoundedCorners(mActivityRecord, + this::isLetterboxedNotForDisplayCutout); } /** Cleans up {@link Letterbox} if it exists.*/ @@ -105,7 +107,7 @@ class AppCompatLetterboxPolicy { if (shouldNotLayoutLetterbox(w)) { return; } - updateRoundedCornersIfNeeded(w); + mAppCompatRoundedCorners.updateRoundedCornersIfNeeded(w); updateWallpaperForLetterbox(w); if (shouldShowLetterboxUi(w)) { mLetterboxPolicyState.layoutLetterboxIfNeeded(w); @@ -138,94 +140,20 @@ class AppCompatLetterboxPolicy { @VisibleForTesting @Nullable Rect getCropBoundsIfNeeded(@NonNull final WindowState mainWindow) { - if (!requiresRoundedCorners(mainWindow) || mActivityRecord.isInLetterboxAnimation()) { - // We don't want corner radius on the window. - // In the case the ActivityRecord requires a letterboxed animation we never want - // rounded corners on the window because rounded corners are applied at the - // animation-bounds surface level and rounded corners on the window would interfere - // with that leading to unexpected rounded corner positioning during the animation. - return null; - } - - final Rect cropBounds = new Rect(mActivityRecord.getBounds()); - - // In case of translucent activities we check if the requested size is different from - // the size provided using inherited bounds. In that case we decide to not apply rounded - // corners because we assume the specific layout would. This is the case when the layout - // of the translucent activity uses only a part of all the bounds because of the use of - // LayoutParams.WRAP_CONTENT. - final TransparentPolicy transparentPolicy = mActivityRecord.mAppCompatController - .getTransparentPolicy(); - if (transparentPolicy.isRunning() && (cropBounds.width() != mainWindow.mRequestedWidth - || cropBounds.height() != mainWindow.mRequestedHeight)) { - return null; - } - - // It is important to call {@link #adjustBoundsIfNeeded} before {@link cropBounds.offsetTo} - // because taskbar bounds used in {@link #adjustBoundsIfNeeded} - // are in screen coordinates - adjustBoundsForTaskbar(mainWindow, cropBounds); - - final float scale = mainWindow.mInvGlobalScale; - if (scale != 1f && scale > 0f) { - cropBounds.scale(scale); - } - - // ActivityRecord bounds are in screen coordinates while (0,0) for activity's surface - // control is in the top left corner of an app window so offsetting bounds - // accordingly. - cropBounds.offsetTo(0, 0); - return cropBounds; + return mAppCompatRoundedCorners.getCropBoundsIfNeeded(mainWindow); } - - // Returns rounded corners radius the letterboxed activity should have based on override in - // R.integer.config_letterboxActivityCornersRadius or min device bottom corner radii. - // Device corners can be different on the right and left sides, but we use the same radius - // for all corners for consistency and pick a minimal bottom one for consistency with a - // taskbar rounded corners. + /** + * Returns rounded corners radius the letterboxed activity should have based on override in + * R.integer.config_letterboxActivityCornersRadius or min device bottom corner radii. + * Device corners can be different on the right and left sides, but we use the same radius + * for all corners for consistency and pick a minimal bottom one for consistency with a + * taskbar rounded corners. + * + * @param mainWindow The {@link WindowState} to consider for the rounded corners calculation. + */ int getRoundedCornersRadius(@NonNull final WindowState mainWindow) { - if (!requiresRoundedCorners(mainWindow)) { - return 0; - } - final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord - .mAppCompatController.getAppCompatLetterboxOverrides(); - final int radius; - if (letterboxOverrides.getLetterboxActivityCornersRadius() >= 0) { - radius = letterboxOverrides.getLetterboxActivityCornersRadius(); - } else { - final InsetsState insetsState = mainWindow.getInsetsState(); - radius = Math.min( - getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_LEFT), - getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_RIGHT)); - } - - final float scale = mainWindow.mInvGlobalScale; - return (scale != 1f && scale > 0f) ? (int) (scale * radius) : radius; - } - - void adjustBoundsForTaskbar(@NonNull final WindowState mainWindow, - @NonNull final Rect bounds) { - // Rounded corners should be displayed above the taskbar. When taskbar is hidden, - // an insets frame is equal to a navigation bar which shouldn't affect position of - // rounded corners since apps are expected to handle navigation bar inset. - // This condition checks whether the taskbar is visible. - // Do not crop the taskbar inset if the window is in immersive mode - the user can - // swipe to show/hide the taskbar as an overlay. - // Adjust the bounds only in case there is an expanded taskbar, - // otherwise the rounded corners will be shown behind the navbar. - final InsetsSource expandedTaskbarOrNull = - AppCompatUtils.getExpandedTaskbarOrNull(mainWindow); - if (expandedTaskbarOrNull != null) { - // Rounded corners should be displayed above the expanded taskbar. - bounds.bottom = Math.min(bounds.bottom, expandedTaskbarOrNull.getFrame().top); - } - } - - private int getInsetsStateCornerRadius(@NonNull InsetsState insetsState, - @RoundedCorner.Position int position) { - final RoundedCorner corner = insetsState.getRoundedCorners().getRoundedCorner(position); - return corner == null ? 0 : corner.getRadius(); + return mAppCompatRoundedCorners.getRoundedCornersRadius(mainWindow); } private void updateWallpaperForLetterbox(@NonNull WindowState mainWindow) { @@ -248,25 +176,6 @@ class AppCompatLetterboxPolicy { } } - void updateRoundedCornersIfNeeded(@NonNull final WindowState mainWindow) { - final SurfaceControl windowSurface = mainWindow.getSurfaceControl(); - if (windowSurface == null || !windowSurface.isValid()) { - return; - } - - // cropBounds must be non-null for the cornerRadius to be ever applied. - mActivityRecord.getSyncTransaction() - .setCrop(windowSurface, getCropBoundsIfNeeded(mainWindow)) - .setCornerRadius(windowSurface, getRoundedCornersRadius(mainWindow)); - } - - private boolean requiresRoundedCorners(@NonNull final WindowState mainWindow) { - final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord - .mAppCompatController.getAppCompatLetterboxOverrides(); - return isLetterboxedNotForDisplayCutout(mainWindow) - && letterboxOverrides.isLetterboxActivityCornersRounded(); - } - private boolean isLetterboxedNotForDisplayCutout(@NonNull WindowState mainWindow) { return shouldShowLetterboxUi(mainWindow) && !mainWindow.isLetterboxedForDisplayCutout(); @@ -405,7 +314,7 @@ class AppCompatLetterboxPolicy { outBounds.set(mLetterbox.getInnerFrame()); final WindowState w = mActivityRecord.findMainWindow(); if (w != null) { - adjustBoundsForTaskbar(w, outBounds); + AppCompatUtils.adjustBoundsForTaskbar(w, outBounds); } } else { outBounds.setEmpty(); diff --git a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java new file mode 100644 index 000000000000..077ce00c6033 --- /dev/null +++ b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java @@ -0,0 +1,143 @@ +/* + * 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.server.wm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Rect; +import android.view.InsetsState; +import android.view.RoundedCorner; +import android.view.SurfaceControl; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.function.Predicate; + +/** + * Utility to unify rounded corners in app compat. + */ +class AppCompatRoundedCorners { + + @NonNull + private final ActivityRecord mActivityRecord; + @NonNull + private final Predicate<WindowState> mIsLetterboxedNotForDisplayCutout; + + AppCompatRoundedCorners(@NonNull ActivityRecord activityRecord, + @NonNull Predicate<WindowState> isLetterboxedNotForDisplayCutout) { + mActivityRecord = activityRecord; + mIsLetterboxedNotForDisplayCutout = isLetterboxedNotForDisplayCutout; + } + + void updateRoundedCornersIfNeeded(@NonNull final WindowState mainWindow) { + final SurfaceControl windowSurface = mainWindow.getSurfaceControl(); + if (windowSurface == null || !windowSurface.isValid()) { + return; + } + + // cropBounds must be non-null for the cornerRadius to be ever applied. + mActivityRecord.getSyncTransaction() + .setCrop(windowSurface, getCropBoundsIfNeeded(mainWindow)) + .setCornerRadius(windowSurface, getRoundedCornersRadius(mainWindow)); + } + + @VisibleForTesting + @Nullable + Rect getCropBoundsIfNeeded(@NonNull final WindowState mainWindow) { + if (!requiresRoundedCorners(mainWindow) || mActivityRecord.isInLetterboxAnimation()) { + // We don't want corner radius on the window. + // In the case the ActivityRecord requires a letterboxed animation we never want + // rounded corners on the window because rounded corners are applied at the + // animation-bounds surface level and rounded corners on the window would interfere + // with that leading to unexpected rounded corner positioning during the animation. + return null; + } + + final Rect cropBounds = new Rect(mActivityRecord.getBounds()); + + // In case of translucent activities we check if the requested size is different from + // the size provided using inherited bounds. In that case we decide to not apply rounded + // corners because we assume the specific layout would. This is the case when the layout + // of the translucent activity uses only a part of all the bounds because of the use of + // LayoutParams.WRAP_CONTENT. + final TransparentPolicy transparentPolicy = mActivityRecord.mAppCompatController + .getTransparentPolicy(); + if (transparentPolicy.isRunning() && (cropBounds.width() != mainWindow.mRequestedWidth + || cropBounds.height() != mainWindow.mRequestedHeight)) { + return null; + } + + // It is important to call {@link #adjustBoundsIfNeeded} before {@link cropBounds.offsetTo} + // because taskbar bounds used in {@link #adjustBoundsIfNeeded} + // are in screen coordinates + AppCompatUtils.adjustBoundsForTaskbar(mainWindow, cropBounds); + + final float scale = mainWindow.mInvGlobalScale; + if (scale != 1f && scale > 0f) { + cropBounds.scale(scale); + } + + // ActivityRecord bounds are in screen coordinates while (0,0) for activity's surface + // control is in the top left corner of an app window so offsetting bounds + // accordingly. + cropBounds.offsetTo(0, 0); + return cropBounds; + } + + /** + * Returns rounded corners radius the letterboxed activity should have based on override in + * R.integer.config_letterboxActivityCornersRadius or min device bottom corner radii. + * Device corners can be different on the right and left sides, but we use the same radius + * for all corners for consistency and pick a minimal bottom one for consistency with a + * taskbar rounded corners. + * + * @param mainWindow The {@link WindowState} to consider for rounded corners calculation. + */ + int getRoundedCornersRadius(@NonNull final WindowState mainWindow) { + if (!requiresRoundedCorners(mainWindow)) { + return 0; + } + final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord + .mAppCompatController.getAppCompatLetterboxOverrides(); + final int radius; + if (letterboxOverrides.getLetterboxActivityCornersRadius() >= 0) { + radius = letterboxOverrides.getLetterboxActivityCornersRadius(); + } else { + final InsetsState insetsState = mainWindow.getInsetsState(); + radius = Math.min( + getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_LEFT), + getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_RIGHT)); + } + + final float scale = mainWindow.mInvGlobalScale; + return (scale != 1f && scale > 0f) ? (int) (scale * radius) : radius; + } + + private static int getInsetsStateCornerRadius(@NonNull InsetsState insetsState, + @RoundedCorner.Position int position) { + final RoundedCorner corner = insetsState.getRoundedCorners().getRoundedCorner(position); + return corner == null ? 0 : corner.getRadius(); + } + + private boolean requiresRoundedCorners(@NonNull final WindowState mainWindow) { + final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord + .mAppCompatController.getAppCompatLetterboxOverrides(); + return mIsLetterboxedNotForDisplayCutout.test(mainWindow) + && letterboxOverrides.isLetterboxActivityCornersRounded(); + } + +} diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java index 91205fc757ad..2b842d99a3ab 100644 --- a/services/core/java/com/android/server/wm/AppCompatUtils.java +++ b/services/core/java/com/android/server/wm/AppCompatUtils.java @@ -37,7 +37,7 @@ import java.util.function.BooleanSupplier; /** * Utilities for App Compat policies and overrides. */ -class AppCompatUtils { +final class AppCompatUtils { /** * Lazy version of a {@link BooleanSupplier} which access an existing BooleanSupplier and @@ -232,6 +232,23 @@ class AppCompatUtils { return null; } + static void adjustBoundsForTaskbar(@NonNull final WindowState mainWindow, + @NonNull final Rect bounds) { + // Rounded corners should be displayed above the taskbar. When taskbar is hidden, + // an insets frame is equal to a navigation bar which shouldn't affect position of + // rounded corners since apps are expected to handle navigation bar inset. + // This condition checks whether the taskbar is visible. + // Do not crop the taskbar inset if the window is in immersive mode - the user can + // swipe to show/hide the taskbar as an overlay. + // Adjust the bounds only in case there is an expanded taskbar, + // otherwise the rounded corners will be shown behind the navbar. + final InsetsSource expandedTaskbarOrNull = getExpandedTaskbarOrNull(mainWindow); + if (expandedTaskbarOrNull != null) { + // Rounded corners should be displayed above the expanded taskbar. + bounds.bottom = Math.min(bounds.bottom, expandedTaskbarOrNull.getFrame().top); + } + } + private static void clearAppCompatTaskInfo(@NonNull AppCompatTaskInfo info) { info.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET; info.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET; diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java index 2755a80ea705..9b142f280b31 100644 --- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java +++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java @@ -109,10 +109,10 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa } @Override - public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, + public void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId) { if (!isTreatmentEnabledForActivity(cameraActivity)) { - return false; + return; } final int existingCameraCompatMode = cameraActivity.mAppCompatController .getAppCompatCameraOverrides() @@ -124,11 +124,9 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa cameraActivity.mAppCompatController.getAppCompatCameraOverrides() .setFreeformCameraCompatMode(newCameraCompatMode); forceUpdateActivityAndTask(cameraActivity); - return true; } else { mIsCameraCompatTreatmentPending = false; } - return false; } @Override diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java index 068fc001ae2c..63c90ff93224 100644 --- a/services/core/java/com/android/server/wm/CameraStateMonitor.java +++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java @@ -73,16 +73,6 @@ class CameraStateMonitor { private final ArrayList<CameraCompatStateListener> mCameraStateListeners = new ArrayList<>(); - /** - * {@link CameraCompatStateListener} which returned {@code true} on the last {@link - * CameraCompatStateListener#onCameraOpened(ActivityRecord, String)}, if any. - * - * <p>This allows the {@link CameraStateMonitor} to notify a particular listener when camera - * closes, so they can revert any changes. - */ - @Nullable - private CameraCompatStateListener mCurrentListenerForCameraActivity; - private final CameraManager.AvailabilityCallback mAvailabilityCallback = new CameraManager.AvailabilityCallback() { @Override @@ -167,12 +157,7 @@ class CameraStateMonitor { @NonNull String cameraId) { for (int i = 0; i < mCameraStateListeners.size(); i++) { CameraCompatStateListener listener = mCameraStateListeners.get(i); - boolean activeCameraTreatment = listener.onCameraOpened( - cameraActivity, cameraId); - if (activeCameraTreatment) { - mCurrentListenerForCameraActivity = listener; - break; - } + listener.onCameraOpened(cameraActivity, cameraId); } } @@ -226,19 +211,30 @@ class CameraStateMonitor { return; } - if (mCurrentListenerForCameraActivity != null) { - boolean closeSuccessful = - mCurrentListenerForCameraActivity.onCameraClosed(cameraId); - if (closeSuccessful) { - mCameraIdPackageBiMapping.removeCameraId(cameraId); - mCurrentListenerForCameraActivity = null; - } else { - rescheduleRemoveCameraActivity(cameraId); - } + final boolean closeSuccessfulForAllListeners = notifyListenersCameraClosed(cameraId); + if (closeSuccessfulForAllListeners) { + // Finish cleaning up. + mCameraIdPackageBiMapping.removeCameraId(cameraId); + } else { + // Not ready to process closure yet - the camera activity might be refreshing. + // Try again later. + rescheduleRemoveCameraActivity(cameraId); } } } + /** + * @return {@code false} if any listeners have reported issues processing the close. + */ + private boolean notifyListenersCameraClosed(@NonNull String cameraId) { + boolean closeSuccessfulForAllListeners = true; + for (int i = 0; i < mCameraStateListeners.size(); i++) { + closeSuccessfulForAllListeners &= mCameraStateListeners.get(i).onCameraClosed(cameraId); + } + + return closeSuccessfulForAllListeners; + } + // TODO(b/335165310): verify that this works in multi instance and permission dialogs. /** * Finds a visible activity with the given package name. @@ -286,11 +282,9 @@ class CameraStateMonitor { interface CameraCompatStateListener { /** * Notifies the compat listener that an activity has opened camera. - * - * @return true if the treatment has been applied. */ // TODO(b/336474959): try to decouple `cameraId` from the listeners. - boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId); + void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId); /** * Notifies the compat listener that camera is closed. * diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java index e50a089a4d5e..762180b1b778 100644 --- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java @@ -298,7 +298,7 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp } @Override - public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, + public void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId) { mCameraTask = cameraActivity.getTask(); // Checking whether an activity in fullscreen rather than the task as this camera @@ -306,7 +306,7 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp if (cameraActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { recomputeConfigurationForCameraCompatIfNeeded(cameraActivity); mDisplayContent.updateOrientation(); - return true; + return; } // Checking that the whole app is in multi-window mode as we shouldn't show toast // for the activity embedding case. @@ -320,7 +320,6 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp (String) packageManager.getApplicationLabel( packageManager.getApplicationInfo(cameraActivity.packageName, /* flags */ 0))); - return true; } catch (PackageManager.NameNotFoundException e) { ProtoLog.e(WM_DEBUG_ORIENTATION, "DisplayRotationCompatPolicy: Multi-window toast not shown as " @@ -328,7 +327,6 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp cameraActivity.packageName); } } - return false; } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index 561ff7db5b9d..7212d379162b 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -407,8 +407,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr change.setTaskFragmentToken(lastParentTfToken); } // Only pass the activity token to the client if it belongs to the same process. - if (Flags.fixPipRestoreToOverlay() && nextFillTaskActivity != null - && nextFillTaskActivity.getPid() == mOrganizerPid) { + if (nextFillTaskActivity != null && nextFillTaskActivity.getPid() == mOrganizerPid) { change.setOtherActivityToken(nextFillTaskActivity.token); } return change; diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java index 34b9913c9738..2c58c61701cc 100644 --- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java +++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java @@ -97,10 +97,10 @@ public class WindowAnimationSpec implements AnimationSpec { /** * @return If a window animation has outsets applied to it. - * @see Animation#hasExtension() + * @see Animation#getExtensionEdges() */ public boolean hasExtension() { - return mAnimation.hasExtension(); + return mAnimation.getExtensionEdges() != 0; } @Override diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index f1e94deb8a45..a5085fc3147c 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -211,7 +211,6 @@ cc_defaults { "android.system.suspend-V1-ndk", "server_configurable_flags", "service.incremental", - "android.companion.virtualdevice.flags-aconfig-cc", ], static_libs: [ diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp index 9ec5ae5a8e51..6f7276079970 100644 --- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp +++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp @@ -19,273 +19,22 @@ #include <android-base/unique_fd.h> #include <android/input.h> #include <android/keycodes.h> -#include <android_companion_virtualdevice_flags.h> -#include <errno.h> -#include <fcntl.h> #include <input/Input.h> #include <input/VirtualInputDevice.h> -#include <linux/uinput.h> -#include <math.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedUtfChars.h> -#include <utils/Log.h> -#include <map> -#include <set> #include <string> using android::base::unique_fd; namespace android { -namespace vd_flags = android::companion::virtualdevice::flags; - static constexpr jlong INVALID_PTR = 0; -enum class DeviceType { - KEYBOARD, - MOUSE, - TOUCHSCREEN, - DPAD, - STYLUS, - ROTARY_ENCODER, -}; - -static unique_fd invalidFd() { - return unique_fd(-1); -} - -/** Creates a new uinput device and assigns a file descriptor. */ -static unique_fd openUinput(const char* readableName, jint vendorId, jint productId, - const char* phys, DeviceType deviceType, jint screenHeight, - jint screenWidth) { - unique_fd fd(TEMP_FAILURE_RETRY(::open("/dev/uinput", O_WRONLY | O_NONBLOCK))); - if (fd < 0) { - ALOGE("Error creating uinput device: %s", strerror(errno)); - return invalidFd(); - } - - ioctl(fd, UI_SET_PHYS, phys); - - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_SYN); - switch (deviceType) { - case DeviceType::DPAD: - for (const auto& [_, keyCode] : VirtualDpad::DPAD_KEY_CODE_MAPPING) { - ioctl(fd, UI_SET_KEYBIT, keyCode); - } - break; - case DeviceType::KEYBOARD: - for (const auto& [_, keyCode] : VirtualKeyboard::KEY_CODE_MAPPING) { - ioctl(fd, UI_SET_KEYBIT, keyCode); - } - break; - case DeviceType::MOUSE: - ioctl(fd, UI_SET_EVBIT, EV_REL); - ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); - ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT); - ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE); - ioctl(fd, UI_SET_KEYBIT, BTN_BACK); - ioctl(fd, UI_SET_KEYBIT, BTN_FORWARD); - ioctl(fd, UI_SET_RELBIT, REL_X); - ioctl(fd, UI_SET_RELBIT, REL_Y); - ioctl(fd, UI_SET_RELBIT, REL_WHEEL); - ioctl(fd, UI_SET_RELBIT, REL_HWHEEL); - if (vd_flags::high_resolution_scroll()) { - ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES); - ioctl(fd, UI_SET_RELBIT, REL_HWHEEL_HI_RES); - } - break; - case DeviceType::TOUCHSCREEN: - ioctl(fd, UI_SET_EVBIT, EV_ABS); - ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOOL_TYPE); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR); - ioctl(fd, UI_SET_ABSBIT, ABS_MT_PRESSURE); - ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT); - break; - case DeviceType::STYLUS: - ioctl(fd, UI_SET_EVBIT, EV_ABS); - ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH); - ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS); - ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS2); - ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_PEN); - ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_RUBBER); - ioctl(fd, UI_SET_ABSBIT, ABS_X); - ioctl(fd, UI_SET_ABSBIT, ABS_Y); - ioctl(fd, UI_SET_ABSBIT, ABS_TILT_X); - ioctl(fd, UI_SET_ABSBIT, ABS_TILT_Y); - ioctl(fd, UI_SET_ABSBIT, ABS_PRESSURE); - ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT); - break; - case DeviceType::ROTARY_ENCODER: - ioctl(fd, UI_SET_EVBIT, EV_REL); - ioctl(fd, UI_SET_RELBIT, REL_WHEEL); - if (vd_flags::high_resolution_scroll()) { - ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES); - } - break; - default: - ALOGE("Invalid input device type %d", static_cast<int32_t>(deviceType)); - return invalidFd(); - } - - int version; - if (ioctl(fd, UI_GET_VERSION, &version) == 0 && version >= 5) { - uinput_setup setup; - memset(&setup, 0, sizeof(setup)); - strlcpy(setup.name, readableName, UINPUT_MAX_NAME_SIZE); - setup.id.version = 1; - setup.id.bustype = BUS_VIRTUAL; - setup.id.vendor = vendorId; - setup.id.product = productId; - if (deviceType == DeviceType::TOUCHSCREEN) { - uinput_abs_setup xAbsSetup; - xAbsSetup.code = ABS_MT_POSITION_X; - xAbsSetup.absinfo.maximum = screenWidth - 1; - xAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &xAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput x axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup yAbsSetup; - yAbsSetup.code = ABS_MT_POSITION_Y; - yAbsSetup.absinfo.maximum = screenHeight - 1; - yAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &yAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput y axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup majorAbsSetup; - majorAbsSetup.code = ABS_MT_TOUCH_MAJOR; - majorAbsSetup.absinfo.maximum = screenWidth - 1; - majorAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &majorAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput major axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup pressureAbsSetup; - pressureAbsSetup.code = ABS_MT_PRESSURE; - pressureAbsSetup.absinfo.maximum = 255; - pressureAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &pressureAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput pressure axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup slotAbsSetup; - slotAbsSetup.code = ABS_MT_SLOT; - slotAbsSetup.absinfo.maximum = MAX_POINTERS - 1; - slotAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &slotAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput slots: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup trackingIdAbsSetup; - trackingIdAbsSetup.code = ABS_MT_TRACKING_ID; - trackingIdAbsSetup.absinfo.maximum = MAX_POINTERS - 1; - trackingIdAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &trackingIdAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput tracking ids: %s", strerror(errno)); - return invalidFd(); - } - } else if (deviceType == DeviceType::STYLUS) { - uinput_abs_setup xAbsSetup; - xAbsSetup.code = ABS_X; - xAbsSetup.absinfo.maximum = screenWidth - 1; - xAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &xAbsSetup) != 0) { - ALOGE("Error creating stylus uinput x axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup yAbsSetup; - yAbsSetup.code = ABS_Y; - yAbsSetup.absinfo.maximum = screenHeight - 1; - yAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &yAbsSetup) != 0) { - ALOGE("Error creating stylus uinput y axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup tiltXAbsSetup; - tiltXAbsSetup.code = ABS_TILT_X; - tiltXAbsSetup.absinfo.maximum = 90; - tiltXAbsSetup.absinfo.minimum = -90; - if (ioctl(fd, UI_ABS_SETUP, &tiltXAbsSetup) != 0) { - ALOGE("Error creating stylus uinput tilt x axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup tiltYAbsSetup; - tiltYAbsSetup.code = ABS_TILT_Y; - tiltYAbsSetup.absinfo.maximum = 90; - tiltYAbsSetup.absinfo.minimum = -90; - if (ioctl(fd, UI_ABS_SETUP, &tiltYAbsSetup) != 0) { - ALOGE("Error creating stylus uinput tilt y axis: %s", strerror(errno)); - return invalidFd(); - } - uinput_abs_setup pressureAbsSetup; - pressureAbsSetup.code = ABS_PRESSURE; - pressureAbsSetup.absinfo.maximum = 255; - pressureAbsSetup.absinfo.minimum = 0; - if (ioctl(fd, UI_ABS_SETUP, &pressureAbsSetup) != 0) { - ALOGE("Error creating touchscreen uinput pressure axis: %s", strerror(errno)); - return invalidFd(); - } - } - if (ioctl(fd, UI_DEV_SETUP, &setup) != 0) { - ALOGE("Error creating uinput device: %s", strerror(errno)); - return invalidFd(); - } - } else { - // UI_DEV_SETUP was not introduced until version 5. Try setting up manually. - ALOGI("Falling back to version %d manual setup", version); - uinput_user_dev fallback; - memset(&fallback, 0, sizeof(fallback)); - strlcpy(fallback.name, readableName, UINPUT_MAX_NAME_SIZE); - fallback.id.version = 1; - fallback.id.bustype = BUS_VIRTUAL; - fallback.id.vendor = vendorId; - fallback.id.product = productId; - if (deviceType == DeviceType::TOUCHSCREEN) { - fallback.absmin[ABS_MT_POSITION_X] = 0; - fallback.absmax[ABS_MT_POSITION_X] = screenWidth - 1; - fallback.absmin[ABS_MT_POSITION_Y] = 0; - fallback.absmax[ABS_MT_POSITION_Y] = screenHeight - 1; - fallback.absmin[ABS_MT_TOUCH_MAJOR] = 0; - fallback.absmax[ABS_MT_TOUCH_MAJOR] = screenWidth - 1; - fallback.absmin[ABS_MT_PRESSURE] = 0; - fallback.absmax[ABS_MT_PRESSURE] = 255; - } else if (deviceType == DeviceType::STYLUS) { - fallback.absmin[ABS_X] = 0; - fallback.absmax[ABS_X] = screenWidth - 1; - fallback.absmin[ABS_Y] = 0; - fallback.absmax[ABS_Y] = screenHeight - 1; - fallback.absmin[ABS_TILT_X] = -90; - fallback.absmax[ABS_TILT_X] = 90; - fallback.absmin[ABS_TILT_Y] = -90; - fallback.absmax[ABS_TILT_Y] = 90; - fallback.absmin[ABS_PRESSURE] = 0; - fallback.absmax[ABS_PRESSURE] = 255; - } - if (TEMP_FAILURE_RETRY(write(fd, &fallback, sizeof(fallback))) != sizeof(fallback)) { - ALOGE("Error creating uinput device: %s", strerror(errno)); - return invalidFd(); - } - } - - if (ioctl(fd, UI_DEV_CREATE) != 0) { - ALOGE("Error creating uinput device: %s", strerror(errno)); - return invalidFd(); - } - - return fd; -} - static unique_fd openUinputJni(JNIEnv* env, jstring name, jint vendorId, jint productId, - jstring phys, DeviceType deviceType, int screenHeight, - int screenWidth) { + jstring phys, DeviceType deviceType, jint screenHeight, + jint screenWidth) { ScopedUtfChars readableName(env, name); ScopedUtfChars readablePhys(env, phys); return openUinput(readableName.c_str(), vendorId, productId, readablePhys.c_str(), deviceType, diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 622c36c35351..09c54cb40373 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -16,6 +16,7 @@ package com.android.server; +import static android.app.appfunctions.flags.Flags.enableAppFunctionManager; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; @@ -120,6 +121,7 @@ import com.android.server.am.ActivityManagerService; import com.android.server.ambientcontext.AmbientContextManagerService; import com.android.server.app.GameManagerService; import com.android.server.appbinding.AppBindingService; +import com.android.server.appfunctions.AppFunctionManagerService; import com.android.server.apphibernation.AppHibernationService; import com.android.server.appop.AppOpMigrationHelper; import com.android.server.appop.AppOpMigrationHelperImpl; @@ -1727,6 +1729,12 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startService(LogcatManagerService.class); t.traceEnd(); + t.traceBegin("StartAppFunctionManager"); + if (enableAppFunctionManager()) { + mSystemServiceManager.startService(AppFunctionManagerService.class); + } + t.traceEnd(); + } catch (Throwable e) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting core service"); diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java index a27ad9a0f4e6..770451cc838d 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java @@ -44,7 +44,6 @@ import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl; import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem; import org.junit.Rule; @@ -178,19 +177,20 @@ public final class InputMethodSubtypeSwitchingControllerTest { return items; } - private void assertNextInputMethod(@NonNull ControllerImpl controller, boolean onlyCurrentIme, - @NonNull ImeSubtypeListItem currentItem, @Nullable ImeSubtypeListItem nextItem) { + private void assertNextInputMethod(@NonNull InputMethodSubtypeSwitchingController controller, + boolean onlyCurrentIme, @NonNull ImeSubtypeListItem currentItem, + @Nullable ImeSubtypeListItem nextItem) { InputMethodSubtype subtype = null; if (currentItem.mSubtypeName != null) { subtype = createTestSubtype(currentItem.mSubtypeName.toString()); } - final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme, + final ImeSubtypeListItem nextIme = controller.getNextInputMethodLocked(onlyCurrentIme, currentItem.mImi, subtype, MODE_STATIC, true /* forward */); assertEquals(nextItem, nextIme); } - private void assertRotationOrder(@NonNull ControllerImpl controller, boolean onlyCurrentIme, - ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) { + private void assertRotationOrder(@NonNull InputMethodSubtypeSwitchingController controller, + boolean onlyCurrentIme, ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) { final int numItems = expectedRotationOrderOfImeSubtypeList.length; for (int i = 0; i < numItems; i++) { final int nextIndex = (i + 1) % numItems; @@ -200,7 +200,7 @@ public final class InputMethodSubtypeSwitchingControllerTest { } } - private boolean onUserAction(@NonNull ControllerImpl controller, + private boolean onUserAction(@NonNull InputMethodSubtypeSwitchingController controller, @NonNull ImeSubtypeListItem subtypeListItem) { InputMethodSubtype subtype = null; if (subtypeListItem.mSubtypeName != null) { @@ -228,8 +228,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6); final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7); - final ControllerImpl controller = ControllerImpl.createFrom( - null /* currentInstance */, enabledItems, new ArrayList<>()); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(enabledItems, new ArrayList<>()); // switching-aware loop assertRotationOrder(controller, false /* onlyCurrentIme */, @@ -286,8 +286,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6); final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7); - final ControllerImpl controller = ControllerImpl.createFrom( - null /* currentInstance */, enabledItems, new ArrayList<>()); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(enabledItems, new ArrayList<>()); // === switching-aware loop === assertRotationOrder(controller, false /* onlyCurrentIme */, @@ -336,11 +336,10 @@ public final class InputMethodSubtypeSwitchingControllerTest { // Rotation order should be preserved when created with the same subtype list. final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes(); - final ControllerImpl newController = ControllerImpl.createFrom(controller, - sameEnabledItems, new ArrayList<>()); - assertRotationOrder(newController, false /* onlyCurrentIme */, + controller.update(sameEnabledItems, new ArrayList<>()); + assertRotationOrder(controller, false /* onlyCurrentIme */, subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp); - assertRotationOrder(newController, false /* onlyCurrentIme */, + assertRotationOrder(controller, false /* onlyCurrentIme */, switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme, switchUnawareJapaneseIme_ja_jp); @@ -348,11 +347,10 @@ public final class InputMethodSubtypeSwitchingControllerTest { final List<ImeSubtypeListItem> differentEnabledItems = List.of( latinIme_en_us, latinIme_fr, subtypeAwareIme, switchingUnawareLatinIme_en_uk, switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme); - final ControllerImpl anotherController = ControllerImpl.createFrom(controller, - differentEnabledItems, new ArrayList<>()); - assertRotationOrder(anotherController, false /* onlyCurrentIme */, + controller.update(differentEnabledItems, new ArrayList<>()); + assertRotationOrder(controller, false /* onlyCurrentIme */, latinIme_en_us, latinIme_fr, subtypeAwareIme); - assertRotationOrder(anotherController, false /* onlyCurrentIme */, + assertRotationOrder(controller, false /* onlyCurrentIme */, switchingUnawareLatinIme_en_uk, switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme); } @@ -520,8 +518,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian); final var hardwareSimpleIme = List.of(hardwareSimple); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); final int mode = MODE_STATIC; @@ -583,8 +581,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian); final var hardwareSimpleIme = List.of(hardwareSimple); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); final int mode = MODE_RECENT; @@ -666,8 +664,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian); final var hardwareSimpleIme = List.of(hardwareSimple); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); final int mode = MODE_AUTO; @@ -777,92 +775,73 @@ public final class InputMethodSubtypeSwitchingControllerTest { final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian); final var hardwareSimpleIme = List.of(hardwareSimple); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); final int mode = MODE_RECENT; // Recency order is initialized to static order. assertNextOrder(controller, false /* forHardware */, mode, items, List.of(latinIme, simpleIme)); - assertNextOrder(controller, true /* forHardware */, mode, hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme)); // User action on french IME. assertTrue("Recency updated for french IME", onUserAction(controller, french)); - final var equalItems = new ArrayList<>(items); - final var otherItems = new ArrayList<>(items); - otherItems.remove(simple); - - final var equalController = ControllerImpl.createFrom(controller, equalItems, - hardwareItems); - final var otherController = ControllerImpl.createFrom(controller, otherItems, - hardwareItems); - final var recencyItems = List.of(french, english, italian, simple); final var recencyLatinIme = List.of(french, english, italian); final var recencySimpleIme = List.of(simple); - assertNextOrder(controller, false /* forHardware */, mode, - recencyItems, List.of(recencyLatinIme, recencySimpleIme)); + final var equalItems = new ArrayList<>(items); + controller.update(equalItems, hardwareItems); - // The order of equal non-hardware items is unchanged. - assertNextOrder(equalController, false /* forHardware */, mode, + // The order of non-hardware items remains unchanged when updated with equal items. + assertNextOrder(controller, false /* forHardware */, mode, recencyItems, List.of(recencyLatinIme, recencySimpleIme)); - - // The order of other hardware items is reset. - assertNextOrder(otherController, false /* forHardware */, mode, - latinIme, List.of(latinIme)); - - // The order of hardware remains unchanged. + // The order of hardware items remains unchanged when only non-hardware items are updated. assertNextOrder(controller, true /* forHardware */, mode, hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme)); - assertNextOrder(equalController, true /* forHardware */, mode, - hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme)); + final var otherItems = new ArrayList<>(items); + otherItems.remove(simple); + controller.update(otherItems, hardwareItems); - assertNextOrder(otherController, true /* forHardware */, mode, + // The order of non-hardware items is reset when updated with other items. + assertNextOrder(controller, false /* forHardware */, mode, + latinIme, List.of(latinIme)); + // The order of hardware items remains unchanged when only non-hardware items are updated. + assertNextOrder(controller, true /* forHardware */, mode, hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme)); assertTrue("Recency updated for french hardware IME", onUserAction(controller, hardwareFrench)); - final var equalHardwareItems = new ArrayList<>(hardwareItems); - final var otherHardwareItems = new ArrayList<>(hardwareItems); - otherHardwareItems.remove(hardwareSimple); - - final var equalHardwareController = ControllerImpl.createFrom(controller, items, - equalHardwareItems); - final var otherHardwareController = ControllerImpl.createFrom(controller, items, - otherHardwareItems); - final var recencyHardwareItems = List.of(hardwareFrench, hardwareEnglish, hardwareItalian, hardwareSimple); final var recencyHardwareLatinIme = List.of(hardwareFrench, hardwareEnglish, hardwareItalian); final var recencyHardwareSimpleIme = List.of(hardwareSimple); - // The order of non-hardware items remains unchanged. - assertNextOrder(controller, false /* forHardware */, mode, - recencyItems, List.of(recencyLatinIme, recencySimpleIme)); - - assertNextOrder(equalHardwareController, false /* forHardware */, mode, - recencyItems, List.of(recencyLatinIme, recencySimpleIme)); - - assertNextOrder(otherHardwareController, false /* forHardware */, mode, - recencyItems, List.of(recencyLatinIme, recencySimpleIme)); + final var equalHardwareItems = new ArrayList<>(hardwareItems); + controller.update(otherItems, equalHardwareItems); + // The order of non-hardware items remains unchanged when only hardware items are updated. + assertNextOrder(controller, false /* forHardware */, mode, + latinIme, List.of(latinIme)); + // The order of hardware items remains unchanged when updated with equal items. assertNextOrder(controller, true /* forHardware */, mode, recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme)); - // The order of equal hardware items is unchanged. - assertNextOrder(equalHardwareController, true /* forHardware */, mode, - recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme)); + final var otherHardwareItems = new ArrayList<>(hardwareItems); + otherHardwareItems.remove(hardwareSimple); + controller.update(otherItems, otherHardwareItems); - // The order of other hardware items is reset. - assertNextOrder(otherHardwareController, true /* forHardware */, mode, + // The order of non-hardware items remains unchanged when only hardware items are updated. + assertNextOrder(controller, false /* forHardware */, mode, + latinIme, List.of(latinIme)); + // The order of hardware items is reset when updated with other items. + assertNextOrder(controller, true /* forHardware */, mode, hardwareLatinIme, List.of(hardwareLatinIme)); } @@ -882,8 +861,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { addTestImeSubtypeListItems(hardwareItems, "hardwareSwitchUnaware", "hardwareSwitchUnaware", null, false /* supportsSwitchingToNextInputMethod*/); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) { assertNextOrder(controller, false /* forHardware */, false /* onlyCurrentIme */, @@ -910,8 +889,7 @@ public final class InputMethodSubtypeSwitchingControllerTest { addTestImeSubtypeListItems(hardwareItems, "HardwareIme", "HardwareIme", List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, List.of(), - List.of()); + final var controller = new InputMethodSubtypeSwitchingController(); assertNextItemNoAction(controller, false /* forHardware */, items, null /* expectedNext */); @@ -940,8 +918,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { addTestImeSubtypeListItems(unknownHardwareItems, "HardwareUnknownIme", "HardwareUnknownIme", List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, - items, hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); assertNextItemNoAction(controller, false /* forHardware */, items, null /* expectedNext */); @@ -979,8 +957,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { addTestImeSubtypeListItems(unknownHardwareItems, "HardwareUnknownIme", "HardwareUnknownIme", List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */); - final var controller = ControllerImpl.createFrom(null /* currentInstance */, items, - hardwareItems); + final var controller = new InputMethodSubtypeSwitchingController(); + controller.update(items, hardwareItems); assertTrue("Recency updated for french IME", onUserAction(controller, french)); @@ -1118,8 +1096,9 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @param allItems the list of items across all IMEs. * @param perImeItems the list of lists of items per IME. */ - private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware, - @SwitchMode int mode, boolean forward, @NonNull List<ImeSubtypeListItem> allItems, + private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller, + boolean forHardware, @SwitchMode int mode, boolean forward, + @NonNull List<ImeSubtypeListItem> allItems, @NonNull List<List<ImeSubtypeListItem>> perImeItems) { assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode, forward, allItems); @@ -1142,8 +1121,8 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @param allItems the list of items across all IMEs. * @param perImeItems the list of lists of items per IME. */ - private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware, - @SwitchMode int mode, @NonNull List<ImeSubtypeListItem> allItems, + private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller, + boolean forHardware, @SwitchMode int mode, @NonNull List<ImeSubtypeListItem> allItems, @NonNull List<List<ImeSubtypeListItem>> perImeItems) { assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode, true /* forward */, allItems); @@ -1170,7 +1149,7 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @param forward whether to search forwards or backwards in the list. * @param items the list of items to verify, in the expected order. */ - private static void assertNextOrder(@NonNull ControllerImpl controller, + private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller, boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward, @NonNull List<ImeSubtypeListItem> items) { final int numItems = items.size(); @@ -1214,7 +1193,7 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @param item the item to find the next value from. * @param expectedNext the expected next value. */ - private static void assertNextItem(@NonNull ControllerImpl controller, + private static void assertNextItem(@NonNull InputMethodSubtypeSwitchingController controller, boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward, @NonNull ImeSubtypeListItem item, @Nullable ImeSubtypeListItem expectedNext) { final var nextItem = getNextItem(controller, forHardware, onlyCurrentIme, mode, forward, @@ -1234,15 +1213,16 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @return the next item found, otherwise {@code null}. */ @Nullable - private static ImeSubtypeListItem getNextItem(@NonNull ControllerImpl controller, - boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward, + private static ImeSubtypeListItem getNextItem( + @NonNull InputMethodSubtypeSwitchingController controller, boolean forHardware, + boolean onlyCurrentIme, @SwitchMode int mode, boolean forward, @NonNull ImeSubtypeListItem item) { final var subtype = item.mSubtypeName != null ? createTestSubtype(item.mSubtypeName.toString()) : null; return forHardware ? controller.getNextInputMethodForHardware( onlyCurrentIme, item.mImi, subtype, mode, forward) - : controller.getNextInputMethod( + : controller.getNextInputMethodLocked( onlyCurrentIme, item.mImi, subtype, mode, forward); } @@ -1255,8 +1235,9 @@ public final class InputMethodSubtypeSwitchingControllerTest { * @param items the list of items to verify. * @param expectedNext the expected next item. */ - private void assertNextItemNoAction(@NonNull ControllerImpl controller, boolean forHardware, - @NonNull List<ImeSubtypeListItem> items, @Nullable ImeSubtypeListItem expectedNext) { + private void assertNextItemNoAction(@NonNull InputMethodSubtypeSwitchingController controller, + boolean forHardware, @NonNull List<ImeSubtypeListItem> items, + @Nullable ImeSubtypeListItem expectedNext) { for (var item : items) { for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) { assertNextItem(controller, forHardware, false /* onlyCurrentIme */, mode, diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java index d45e31248d0b..fc4d8d871fd5 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java @@ -61,7 +61,6 @@ import com.android.server.statusbar.StatusBarManagerInternal; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.concurrent.Executor; @@ -264,8 +263,8 @@ public class NotifierTest { BatteryStats.WAKE_TYPE_PARTIAL, false); verifyNoMoreInteractions(mWakeLockLog, mBatteryStats); - WorkSource worksourceOld = Mockito.mock(WorkSource.class); - WorkSource worksourceNew = Mockito.mock(WorkSource.class); + WorkSource worksourceOld = new WorkSource(/*uid=*/ 1); + WorkSource worksourceNew = new WorkSource(/*uid=*/ 2); mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null, @@ -309,6 +308,40 @@ public class NotifierTest { verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1); } + @Test + public void + test_notifierProcessesWorkSourceDeepCopy_OnWakelockChanging() throws RemoteException { + when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true); + createNotifier(); + clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); + IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { + @Override public void onStateChanged(boolean enabled) throws RemoteException { + throw new RemoteException("Just testing"); + } + }; + + final int uid = 1234; + final int pid = 5678; + mTestLooper.dispatchAll(); + WorkSource worksourceOld = new WorkSource(/*uid=*/ 1); + WorkSource worksourceNew = new WorkSource(/*uid=*/ 2); + + mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null, + exceptingCallback, + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, worksourceNew, /* newHistoryTag= */ null, + exceptingCallback); + // The newWorksource is modified before notifier could process it. + worksourceNew.set(/*uid=*/ 3); + + mTestLooper.dispatchAll(); + verify(mBatteryStats).noteChangeWakelockFromSource(worksourceOld, pid, + "wakelockTag", null, BatteryStats.WAKE_TYPE_PARTIAL, + new WorkSource(/*uid=*/ 2), pid, "wakelockTag", null, + BatteryStats.WAKE_TYPE_FULL, false); + } + @Test public void testOnWakeLockListener_FullWakeLock_ProcessesOnHandler() throws RemoteException { diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index a8e350b05f18..1db46bf17655 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -105,6 +105,7 @@ import android.view.Display; import androidx.test.filters.SmallTest; import com.android.internal.widget.LockPatternUtils; +import com.android.server.AlarmManagerInternal; import com.android.server.FgThread; import com.android.server.SystemService; import com.android.server.am.UserState.KeyEvictedCallback; @@ -124,6 +125,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -730,6 +732,39 @@ public class UserControllerTest { mUserController.getRunningUsersLU()); } + /** Test scheduling stopping of background users - reschedule if user with a scheduled alarm. */ + @Test + public void testScheduleStopOfBackgroundUser_rescheduleIfAlarm() throws Exception { + mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_SCHEDULE_STOP_OF_BACKGROUND_USER); + + mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, + /* maxRunningUsers= */ 10, /* delayUserDataLocking= */ false, + /* backgroundUserScheduledStopTimeSecs= */ 2); + + setUpAndStartUserInBackground(TEST_USER_ID); + assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID), + new HashSet<>(mUserController.getRunningUsersLU())); + + // Initially, the background user has an alarm that will fire soon. So don't stop the user. + when(mInjector.mAlarmManagerInternal.getNextAlarmTriggerTimeForUser(eq(TEST_USER_ID))) + .thenReturn(System.currentTimeMillis() + Duration.ofMinutes(2).toMillis()); + assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID); + assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID), + new HashSet<>(mUserController.getRunningUsersLU())); + + // Now, that alarm is gone and the next alarm isn't for a long time. Do stop the user. + when(mInjector.mAlarmManagerInternal.getNextAlarmTriggerTimeForUser(eq(TEST_USER_ID))) + .thenReturn(System.currentTimeMillis() + Duration.ofDays(1).toMillis()); + assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID); + assertEquals(newHashSet(SYSTEM_USER_ID), + new HashSet<>(mUserController.getRunningUsersLU())); + + // No-one is scheduled to stop anymore. + assertAndProcessScheduledStopBackgroundUser(false, null); + verify(mInjector.mAlarmManagerInternal, never()) + .getNextAlarmTriggerTimeForUser(eq(SYSTEM_USER_ID)); + } + /** * Process queued SCHEDULED_STOP_BACKGROUND_USER_MSG message, if expected. * @param userId the user we are checking to see whether it is scheduled. @@ -1747,6 +1782,7 @@ public class UserControllerTest { private final WindowManagerService mWindowManagerMock; private final ActivityTaskManagerInternal mActivityTaskManagerInternal; private final PowerManagerInternal mPowerManagerInternal; + private final AlarmManagerInternal mAlarmManagerInternal; private final KeyguardManager mKeyguardManagerMock; private final LockPatternUtils mLockPatternUtilsMock; @@ -1769,6 +1805,7 @@ public class UserControllerTest { mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class); mStorageManagerMock = mock(IStorageManager.class); mPowerManagerInternal = mock(PowerManagerInternal.class); + mAlarmManagerInternal = mock(AlarmManagerInternal.class); mKeyguardManagerMock = mock(KeyguardManager.class); when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true); mLockPatternUtilsMock = mock(LockPatternUtils.class); @@ -1839,6 +1876,11 @@ public class UserControllerTest { } @Override + AlarmManagerInternal getAlarmManagerInternal() { + return mAlarmManagerInternal; + } + + @Override KeyguardManager getKeyguardManager() { return mKeyguardManagerMock; } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 212e61e10448..ed8ebc842be8 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -4972,7 +4972,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_FALSE), - ORIGIN_APP, SYSTEM_UID); + ORIGIN_APP, CUSTOM_PKG_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { @@ -6491,6 +6491,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "adding", CUSTOM_PKG_UID); + Condition autoOn = new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, + SOURCE_CONTEXT); ZenRule zenRule; mZenModeHelper.setAutomaticZenRuleState(ruleId, @@ -6508,6 +6510,57 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(zenRule.isAutomaticActive()).isFalse(); assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE); assertThat(zenRule.condition).isNull(); + + // Bonus check: app has resumed control over the rule and can now turn it on. + mZenModeHelper.setAutomaticZenRuleState(ruleId, autoOn, ORIGIN_APP, CUSTOM_PKG_UID); + zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); + assertThat(zenRule.isAutomaticActive()).isTrue(); + assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE); + assertThat(zenRule.condition).isEqualTo(autoOn); + } + + @Test + @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI}) + public void setAutomaticZenRuleState_manualDeactivationAndThenReactivation_removesOverride() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond")) + .setPackage(mPkg) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "adding", + CUSTOM_PKG_UID); + Condition autoOn = new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, + SOURCE_CONTEXT); + Condition autoOff = new Condition(rule.getConditionId(), "auto-off", STATE_FALSE, + SOURCE_CONTEXT); + ZenRule zenRule; + + mZenModeHelper.setAutomaticZenRuleState(ruleId, autoOn, ORIGIN_APP, CUSTOM_PKG_UID); + zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); + assertThat(zenRule.isAutomaticActive()).isTrue(); + assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE); + assertThat(zenRule.condition).isEqualTo(autoOn); + + mZenModeHelper.setAutomaticZenRuleState(ruleId, + new Condition(rule.getConditionId(), "manual-off", STATE_FALSE, SOURCE_USER_ACTION), + ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID); + zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); + assertThat(zenRule.isAutomaticActive()).isFalse(); + assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE); + assertThat(zenRule.condition).isEqualTo(autoOn); + + mZenModeHelper.setAutomaticZenRuleState(ruleId, + new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION), + ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID); + zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); + assertThat(zenRule.isAutomaticActive()).isTrue(); + assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE); + assertThat(zenRule.condition).isEqualTo(autoOn); + + // Bonus check: app has resumed control over the rule and can now turn it off. + mZenModeHelper.setAutomaticZenRuleState(ruleId, autoOff, ORIGIN_APP, CUSTOM_PKG_UID); + zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); + assertThat(zenRule.isAutomaticActive()).isFalse(); + assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE); + assertThat(zenRule.condition).isEqualTo(autoOff); } @Test @@ -6521,7 +6574,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(ruleId, new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT), - ORIGIN_APP, SYSTEM_UID); + ORIGIN_APP, CUSTOM_PKG_UID); ZenRule zenRuleOn = mZenModeHelper.mConfig.automaticRules.get(ruleId); assertThat(zenRuleOn.isAutomaticActive()).isTrue(); assertThat(zenRuleOn.getConditionOverride()).isEqualTo(OVERRIDE_NONE); diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java index 12f5714f91c7..d2232729f271 100644 --- a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java @@ -43,10 +43,10 @@ import org.junit.runner.RunWith; import java.util.concurrent.Executor; /** - * Tests for {@link DisplayRotationCompatPolicy}. + * Tests for {@link CameraStateMonitor}. * * Build/Install/Run: - * atest WmTests:DisplayRotationCompatPolicyTests + * atest WmTests:CameraStateMonitorTests */ @SmallTest @Presubmit @@ -68,23 +68,14 @@ public final class CameraStateMonitorTests extends WindowTestsBase { private ActivityRecord mActivity; private Task mTask; - // Simulates a listener which will not react to the change on a particular activity. - private final FakeCameraCompatStateListener mNotInterestedListener = - new FakeCameraCompatStateListener( - /*onCameraOpenedReturnValue=*/ false, - /*simulateUnsuccessfulCloseOnce=*/ false); // Simulates a listener which will react to the change on a particular activity - for example // put the activity in a camera compat mode. - private final FakeCameraCompatStateListener mInterestedListener = - new FakeCameraCompatStateListener( - /*onCameraOpenedReturnValue=*/ true, - /*simulateUnsuccessfulCloseOnce=*/ false); + private final FakeCameraCompatStateListener mListener = + new FakeCameraCompatStateListener(/* simulateUnsuccessfulCloseOnce= */ false); // Simulates a listener which for some reason cannot process `onCameraClosed` event once it // first arrives - this means that the update needs to be postponed. private final FakeCameraCompatStateListener mListenerCannotClose = - new FakeCameraCompatStateListener( - /*onCameraOpenedReturnValue=*/ true, - /*simulateUnsuccessfulCloseOnce=*/ true); + new FakeCameraCompatStateListener(/* simulateUnsuccessfulCloseOnce= */ true); @Before public void setUp() throws Exception { @@ -129,44 +120,31 @@ public final class CameraStateMonitorTests extends WindowTestsBase { @After public void tearDown() { // Remove all listeners. - mCameraStateMonitor.removeCameraStateListener(mNotInterestedListener); - mCameraStateMonitor.removeCameraStateListener(mInterestedListener); + mCameraStateMonitor.removeCameraStateListener(mListener); mCameraStateMonitor.removeCameraStateListener(mListenerCannotClose); // Reset the listener's state. - mNotInterestedListener.resetCounters(); - mInterestedListener.resetCounters(); + mListener.resetCounters(); mListenerCannotClose.resetCounters(); } @Test public void testOnCameraOpened_listenerAdded_notifiesCameraOpened() { - mCameraStateMonitor.addCameraStateListener(mNotInterestedListener); + mCameraStateMonitor.addCameraStateListener(mListener); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); - assertEquals(1, mNotInterestedListener.mOnCameraOpenedCounter); + assertEquals(1, mListener.mOnCameraOpenedCounter); } @Test - public void testOnCameraOpened_listenerReturnsFalse_doesNotNotifyCameraClosed() { - mCameraStateMonitor.addCameraStateListener(mNotInterestedListener); - // Listener returns false on `onCameraOpened`. - mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); - - mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); - - assertEquals(0, mNotInterestedListener.mOnCameraClosedCounter); - } - - @Test - public void testOnCameraOpened_listenerReturnsTrue_notifyCameraClosed() { - mCameraStateMonitor.addCameraStateListener(mInterestedListener); + public void testOnCameraOpened_cameraClosed_notifyCameraClosed() { + mCameraStateMonitor.addCameraStateListener(mListener); // Listener returns true on `onCameraOpened`. mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); - assertEquals(1, mInterestedListener.mOnCameraClosedCounter); + assertEquals(1, mListener.mOnCameraClosedCounter); } @Test @@ -182,32 +160,22 @@ public final class CameraStateMonitorTests extends WindowTestsBase { @Test public void testReconnectedToDifferentCamera_notifiesListener() { - mCameraStateMonitor.addCameraStateListener(mInterestedListener); + mCameraStateMonitor.addCameraStateListener(mListener); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_2, TEST_PACKAGE_1); - assertEquals(2, mInterestedListener.mOnCameraOpenedCounter); + assertEquals(2, mListener.mOnCameraOpenedCounter); } @Test public void testDifferentAppConnectedToCamera_notifiesListener() { - mCameraStateMonitor.addCameraStateListener(mInterestedListener); + mCameraStateMonitor.addCameraStateListener(mListener); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_2); - assertEquals(2, mInterestedListener.mOnCameraOpenedCounter); - } - - @Test - public void testCameraAlreadyClosed_notifiesListenerOnce() { - mCameraStateMonitor.addCameraStateListener(mInterestedListener); - mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); - mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); - mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); - - assertEquals(1, mInterestedListener.mOnCameraClosedCounter); + assertEquals(2, mListener.mOnCameraOpenedCounter); } private void configureActivity(@NonNull String packageName) { @@ -232,7 +200,6 @@ public final class CameraStateMonitorTests extends WindowTestsBase { int mOnCameraOpenedCounter = 0; int mOnCameraClosedCounter = 0; - boolean mOnCameraOpenedReturnValue = true; private boolean mOnCameraClosedReturnValue = true; /** @@ -242,17 +209,14 @@ public final class CameraStateMonitorTests extends WindowTestsBase { * subsequent calls. This fake implementation tests the * retry mechanism in {@link CameraStateMonitor}. */ - FakeCameraCompatStateListener(boolean onCameraOpenedReturnValue, - boolean simulateUnsuccessfulCloseOnce) { - mOnCameraOpenedReturnValue = onCameraOpenedReturnValue; + FakeCameraCompatStateListener(boolean simulateUnsuccessfulCloseOnce) { mOnCameraClosedReturnValue = !simulateUnsuccessfulCloseOnce; } @Override - public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, + public void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId) { mOnCameraOpenedCounter++; - return mOnCameraOpenedReturnValue; } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java index 771e290f60fd..e57e36d36621 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java @@ -59,6 +59,7 @@ public class DimmerTests extends WindowTestsBase { TestWindowContainer(WindowManagerService wm) { super(wm); + setVisibleRequested(true); } @Override diff --git a/tests/FlickerTests/ActivityEmbedding/Android.bp b/tests/FlickerTests/ActivityEmbedding/Android.bp index e09fbf6adc02..c681ce96a269 100644 --- a/tests/FlickerTests/ActivityEmbedding/Android.bp +++ b/tests/FlickerTests/ActivityEmbedding/Android.bp @@ -24,6 +24,9 @@ package { default_applicable_licenses: ["frameworks_base_license"], } +//////////////////////////////////////////////////////////////////////////////// +// Begin to cleanup after CL merges + filegroup { name: "FlickerTestsOtherCommon-src", srcs: ["src/**/ActivityEmbeddingTestBase.kt"], @@ -82,3 +85,123 @@ android_test { ":FlickerTestsOtherCommon-src", ], } + +// End to cleanup after CL merges +//////////////////////////////////////////////////////////////////////////////// + +android_test { + name: "FlickerTestsActivityEmbedding", + defaults: ["FlickerTestsDefault"], + manifest: "AndroidManifest.xml", + package_name: "com.android.server.wm.flicker", + instrumentation_target_package: "com.android.server.wm.flicker", + test_config_template: "AndroidTestTemplate.xml", + srcs: ["src/**/*"], + static_libs: [ + "FlickerTestsBase", + "FlickerTestsOtherCommon", + ], + data: ["trace_config/*"], +} + +//////////////////////////////////////////////////////////////////////////////// +// Begin breakdowns for FlickerTestsActivityEmbedding module + +test_module_config { + name: "FlickerTestsActivityEmbedding-CatchAll", + base: "FlickerTestsActivityEmbedding", + exclude_filters: [ + "com.android.server.wm.flicker.activityembedding.close.CloseSecondaryActivityInSplitTest", + "com.android.server.wm.flicker.activityembedding.layoutchange.HorizontalSplitChangeRatioTest", + "com.android.server.wm.flicker.activityembedding.open.MainActivityStartsSecondaryWithAlwaysExpandTest", + "com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingPlaceholderSplitTest", + "com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingSecondaryToSplitTest", + "com.android.server.wm.flicker.activityembedding.open.OpenThirdActivityOverSplitTest", + "com.android.server.wm.flicker.activityembedding.open.OpenTrampolineActivityTest", + "com.android.server.wm.flicker.activityembedding.pip.SecondaryActivityEnterPipTest", + "com.android.server.wm.flicker.activityembedding.rotation.RotateSplitNoChangeTest", + "com.android.server.wm.flicker.activityembedding.rtl.RTLStartSecondaryWithPlaceholderTest", + "com.android.server.wm.flicker.activityembedding.splitscreen.EnterSystemSplitTest", + ], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Close-CloseSecondaryActivityInSplitTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.close.CloseSecondaryActivityInSplitTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-LayoutChange-HorizontalSplitChangeRatioTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.layoutchange.HorizontalSplitChangeRatioTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Open-MainActivityStartsSecondaryWithAlwaysExpandTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.open.MainActivityStartsSecondaryWithAlwaysExpandTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Open-OpenActivityEmbeddingPlaceholderSplitTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingPlaceholderSplitTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Open-OpenActivityEmbeddingSecondaryToSplitTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingSecondaryToSplitTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Open-OpenThirdActivityOverSplitTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenThirdActivityOverSplitTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Open-OpenTrampolineActivityTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenTrampolineActivityTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Pip-SecondaryActivityEnterPipTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.pip.SecondaryActivityEnterPipTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Rotation-RotateSplitNoChangeTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.rotation.RotateSplitNoChangeTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-Rtl-RTLStartSecondaryWithPlaceholderTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.rtl.RTLStartSecondaryWithPlaceholderTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsActivityEmbedding-SplitScreen-EnterSystemSplitTest", + base: "FlickerTestsActivityEmbedding", + include_filters: ["com.android.server.wm.flicker.activityembedding.splitscreen.EnterSystemSplitTest"], + test_suites: ["device-tests"], +} + +// End breakdowns for FlickerTestsActivityEmbedding module +//////////////////////////////////////////////////////////////////////////////// diff --git a/tests/FlickerTests/AppLaunch/Android.bp b/tests/FlickerTests/AppLaunch/Android.bp index 72a90650927f..b61739f100ab 100644 --- a/tests/FlickerTests/AppLaunch/Android.bp +++ b/tests/FlickerTests/AppLaunch/Android.bp @@ -15,6 +15,7 @@ // package { + default_team: "trendy_team_windowing_animations_transitions", // 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" @@ -23,6 +24,9 @@ package { default_applicable_licenses: ["frameworks_base_license"], } +//////////////////////////////////////////////////////////////////////////////// +// Begin to cleanup after CL merges + filegroup { name: "FlickerTestsAppLaunchCommon-src", srcs: ["src/**/common/*"], @@ -69,3 +73,122 @@ android_test { ], data: ["trace_config/*"], } + +// End to cleanup after CL merges +//////////////////////////////////////////////////////////////////////////////// + +android_test { + name: "FlickerTestsAppLaunch", + defaults: ["FlickerTestsDefault"], + manifest: "AndroidManifest.xml", + test_config_template: "AndroidTestTemplate.xml", + srcs: ["src/**/*"], + static_libs: [ + "FlickerTestsBase", + "FlickerTestsAppLaunchCommon", + ], + data: ["trace_config/*"], +} + +//////////////////////////////////////////////////////////////////////////////// +// Begin breakdowns for FlickerTestsAppLaunch module + +test_module_config { + name: "FlickerTestsAppLaunch-CatchAll", + base: "FlickerTestsAppLaunch", + exclude_filters: [ + "com.android.server.wm.flicker.launch.TaskTransitionTest", + "com.android.server.wm.flicker.launch.ActivityTransitionTest", + "com.android.server.wm.flicker.launch.OpenAppFromIconColdTest", + "com.android.server.wm.flicker.launch.OpenAppFromIntentColdAfterCameraTest", + "com.android.server.wm.flicker.launch.OpenAppFromIntentColdTest", + "com.android.server.wm.flicker.launch.OpenAppFromIntentWarmTest", + "com.android.server.wm.flicker.launch.OpenAppFromLockscreenViaIntentTest", + "com.android.server.wm.flicker.launch.OpenAppFromOverviewTest", + "com.android.server.wm.flicker.launch.OpenCameraFromHomeOnDoubleClickPowerButtonTest", + "com.android.server.wm.flicker.launch.OpenTransferSplashscreenAppFromLauncherTransition", + "com.android.server.wm.flicker.launch.OverrideTaskTransitionTest", + "com.android.server.wm.flicker.launch.TaskTransitionTest", + ], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-ActivityTransitionTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.ActivityTransitionTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromIconColdTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIconColdTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromIntentColdAfterCameraTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentColdAfterCameraTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromIntentColdTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentColdTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromIntentWarmTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentWarmTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromLockscreenViaIntentTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromLockscreenViaIntentTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenAppFromOverviewTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromOverviewTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenCameraFromHomeOnDoubleClickPowerButtonTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenCameraFromHomeOnDoubleClickPowerButtonTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OpenTransferSplashscreenAppFromLauncherTransition", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OpenTransferSplashscreenAppFromLauncherTransition"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-OverrideTaskTransitionTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.OverrideTaskTransitionTest"], + test_suites: ["device-tests"], +} + +test_module_config { + name: "FlickerTestsAppLaunch-TaskTransitionTest", + base: "FlickerTestsAppLaunch", + include_filters: ["com.android.server.wm.flicker.launch.TaskTransitionTest"], + test_suites: ["device-tests"], +} + +// End breakdowns for FlickerTestsAppLaunch module +//////////////////////////////////////////////////////////////////////////////// diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java index fad94d45c85d..7d0c5966b5dc 100644 --- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java +++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java @@ -126,30 +126,35 @@ public class PerfettoProtoLogImplTest { .setMessage("My Test Debug Log Message %b") .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_DEBUG) .setGroupId(1) + .setLocation("com/test/MyTestClass.java:123") ).addMessages( Protolog.ProtoLogViewerConfig.MessageData.newBuilder() .setMessageId(2) .setMessage("My Test Verbose Log Message %b") .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_VERBOSE) .setGroupId(1) + .setLocation("com/test/MyTestClass.java:342") ).addMessages( Protolog.ProtoLogViewerConfig.MessageData.newBuilder() .setMessageId(3) .setMessage("My Test Warn Log Message %b") .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WARN) .setGroupId(1) + .setLocation("com/test/MyTestClass.java:563") ).addMessages( Protolog.ProtoLogViewerConfig.MessageData.newBuilder() .setMessageId(4) .setMessage("My Test Error Log Message %b") .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_ERROR) .setGroupId(1) + .setLocation("com/test/MyTestClass.java:156") ).addMessages( Protolog.ProtoLogViewerConfig.MessageData.newBuilder() .setMessageId(5) .setMessage("My Test WTF Log Message %b") .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WTF) .setGroupId(1) + .setLocation("com/test/MyTestClass.java:192") ); ViewerConfigInputStreamProvider viewerConfigInputStreamProvider = Mockito.mock( @@ -465,6 +470,26 @@ public class PerfettoProtoLogImplTest { .isEqualTo("My test message :: test, 2, 4, 6, 0.400000, true"); } + @Test + public void supportsLocationInformation() throws IOException { + PerfettoTraceMonitor traceMonitor = + PerfettoTraceMonitor.newBuilder().enableProtoLog(true).build(); + try { + traceMonitor.start(); + mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1, + LogDataType.BOOLEAN, new Object[]{true}); + } finally { + traceMonitor.stop(mWriter); + } + + final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig); + final ProtoLogTrace protolog = reader.readProtoLogTrace(); + + Truth.assertThat(protolog.messages).hasSize(1); + Truth.assertThat(protolog.messages.get(0).getLocation()) + .isEqualTo("com/test/MyTestClass.java:123"); + } + private long addMessageToConfig(ProtologCommon.ProtoLogLevel logLevel, String message) { final long messageId = new Random().nextLong(); mViewerConfigBuilder.addMessages(Protolog.ProtoLogViewerConfig.MessageData.newBuilder() |