Merge "Modernize LightsOutNotifController" into main
diff --git a/cmds/gpu_counter_producer/Android.bp b/cmds/gpu_counter_producer/Android.bp
index 2232345..d645d06 100644
--- a/cmds/gpu_counter_producer/Android.bp
+++ b/cmds/gpu_counter_producer/Android.bp
@@ -19,6 +19,4 @@
"-Wunused",
"-Wunreachable-code",
],
-
- soc_specific: true,
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 275fe77..c282e4b6 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -307,7 +307,7 @@
field public static final String RECOVER_KEYSTORE = "android.permission.RECOVER_KEYSTORE";
field public static final String REGISTER_CALL_PROVIDER = "android.permission.REGISTER_CALL_PROVIDER";
field public static final String REGISTER_CONNECTION_MANAGER = "android.permission.REGISTER_CONNECTION_MANAGER";
- field public static final String REGISTER_NSD_OFFLOAD_ENGINE = "android.permission.REGISTER_NSD_OFFLOAD_ENGINE";
+ field @FlaggedApi("com.android.net.flags.register_nsd_offload_engine") public static final String REGISTER_NSD_OFFLOAD_ENGINE = "android.permission.REGISTER_NSD_OFFLOAD_ENGINE";
field public static final String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
field public static final String REGISTER_STATS_PULL_ATOM = "android.permission.REGISTER_STATS_PULL_ATOM";
field public static final String REMOTE_DISPLAY_PROVIDER = "android.permission.REMOTE_DISPLAY_PROVIDER";
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b5f7f23..6c10f49 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -7604,15 +7604,17 @@
* @param taskDescription The TaskDescription properties that describe the task with this activity
*/
public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
- if (mTaskDescription != taskDescription) {
- mTaskDescription.copyFromPreserveHiddenFields(taskDescription);
- // Scale the icon down to something reasonable if it is provided
- if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
- final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
- final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size,
- true);
- mTaskDescription.setIcon(Icon.createWithBitmap(icon));
- }
+ if (taskDescription == null || mTaskDescription.equals(taskDescription)) {
+ return;
+ }
+
+ mTaskDescription.copyFromPreserveHiddenFields(taskDescription);
+ // Scale the icon down to something reasonable if it is provided
+ if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
+ final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
+ final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size,
+ true);
+ mTaskDescription.setIcon(Icon.createWithBitmap(icon));
}
ActivityClient.getInstance().setTaskDescription(mToken, mTaskDescription);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7b075e6..4d208c6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2301,6 +2301,7 @@
<!-- Allows system apps to call methods to register itself as a mDNS offload engine.
<p>Not for use by third-party or privileged applications.
@SystemApi
+ @FlaggedApi("com.android.net.flags.register_nsd_offload_engine")
@hide This should only be used by system apps.
-->
<permission android:name="android.permission.REGISTER_NSD_OFFLOAD_ENGINE"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index b528089d15..5c02dbc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.transition;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static com.android.wm.shell.transition.Transitions.TransitionObserver;
@@ -61,9 +62,10 @@
}
final int mode = change.getMode();
+ final boolean isBackGesture = change.hasFlags(FLAG_BACK_GESTURE_ANIMATED);
if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME
- && TransitionUtil.isOpenOrCloseMode(mode)) {
- notifyHomeVisibilityChanged(TransitionUtil.isOpeningType(mode));
+ && (TransitionUtil.isOpenOrCloseMode(mode) || isBackGesture)) {
+ notifyHomeVisibilityChanged(TransitionUtil.isOpeningType(mode) || isBackGesture);
}
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index a5629c8..b355ab0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -14,8 +14,6 @@
import android.window.TransitionInfo
import android.window.TransitionInfo.FLAG_IS_WALLPAPER
import androidx.test.filters.SmallTest
-import com.android.server.testutils.any
-import com.android.server.testutils.mock
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
@@ -28,8 +26,10 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
+import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyZeroInteractions
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
index ea7c0d9..421c445 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
@@ -18,8 +18,10 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -145,6 +147,26 @@
verify(mListener, times(0)).onHomeVisibilityChanged(anyBoolean());
}
+ @Test
+ public void testHomeActivityWithBackGestureNotifiesHomeIsVisible() throws RemoteException {
+ TransitionInfo info = mock(TransitionInfo.class);
+ TransitionInfo.Change change = mock(TransitionInfo.Change.class);
+ ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
+ when(change.getTaskInfo()).thenReturn(taskInfo);
+ when(info.getChanges()).thenReturn(new ArrayList<>(List.of(change)));
+
+ when(change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)).thenReturn(true);
+ setupTransitionInfo(taskInfo, change, ACTIVITY_TYPE_HOME, TRANSIT_CHANGE);
+
+ mHomeTransitionObserver.onTransitionReady(mock(IBinder.class),
+ info,
+ mock(SurfaceControl.Transaction.class),
+ mock(SurfaceControl.Transaction.class));
+
+ verify(mListener, times(1)).onHomeVisibilityChanged(true);
+ }
+
+
/**
* Helper class to initialize variables for the rest.
*/
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm
index 93a5082..071f9f4 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm
@@ -116,6 +116,9 @@
base: 'w'
shift, capslock: 'W'
shift+capslock: 'w'
+ ralt: '\u1e83'
+ shift+ralt, capslock+ralt: '\u1e82'
+ shift+capslock+ralt: '\u1e83'
}
key E {
@@ -147,6 +150,9 @@
base: 'y'
shift, capslock: 'Y'
shift+capslock: 'y'
+ ralt: '\u00fd'
+ shift+ralt, capslock+ralt: '\u00dd'
+ shift+capslock+ralt: '\u00fd'
}
key U {
@@ -313,6 +319,9 @@
base: 'c'
shift, capslock: 'C'
shift+capslock: 'c'
+ ralt: '\u00e7'
+ shift+ralt, capslock+ralt: '\u00c7'
+ shift+capslock+ralt: '\u00e7'
}
key V {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_french.kcm b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
index 4906304..636f98d 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_french.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
@@ -44,7 +44,7 @@
label: '2'
base: '\u00e9'
shift: '2'
- ralt: '~'
+ ralt: '\u0303'
}
key 3 {
@@ -79,7 +79,7 @@
label: '7'
base: '\u00e8'
shift: '7'
- ralt: '`'
+ ralt: '\u0300'
}
key 8 {
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 7f23f74..ee49b23 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -94,7 +94,7 @@
android:name="keyboard_layout_swiss_german"
android:label="@string/keyboard_layout_swiss_german_label"
android:keyboardLayout="@raw/keyboard_layout_swiss_german"
- android:keyboardLocale="de-Latn-CH"
+ android:keyboardLocale="de-Latn-CH|gsw-Latn-CH"
android:keyboardLayoutType="qwertz" />
<keyboard-layout
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index d65a69c..9ee3d22 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -64,13 +64,13 @@
import com.android.internal.annotations.GuardedBy;
import com.android.settingslib.volume.MediaSessions;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.util.RingerModeLiveData;
@@ -99,6 +99,7 @@
@SysUISingleton
public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpable {
private static final String TAG = Util.logTag(VolumeDialogControllerImpl.class);
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int TOUCH_FEEDBACK_TIMEOUT_MS = 1000;
private static final int DYNAMIC_STREAM_START_INDEX = 100;
@@ -1339,14 +1340,24 @@
private boolean showForSession(Token token) {
if (mVolumeAdjustmentForRemoteGroupSessions) {
+ if (DEBUG) {
+ Log.d(TAG, "Volume adjustment for remote group sessions allowed,"
+ + " showForSession: true");
+ }
return true;
}
MediaController ctr = new MediaController(mContext, token);
String packageName = ctr.getPackageName();
List<RoutingSessionInfo> sessions =
mRouter2Manager.getRoutingSessions(packageName);
-
+ if (DEBUG) {
+ Log.d(TAG, "Found " + sessions.size() + " routing sessions for package name "
+ + packageName);
+ }
for (RoutingSessionInfo session : sessions) {
+ if (DEBUG) {
+ Log.d(TAG, "Found routingSessionInfo: " + session);
+ }
if (!session.isSystemSession()
&& session.getVolumeHandling() != MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
return true;
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 215970e..e51ef29 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -864,6 +864,23 @@
}
@Override
+ public @NonNull Set<String> getAllPersistentDeviceIds() {
+ Set<String> persistentIds = new ArraySet<>();
+ synchronized (mVirtualDeviceManagerLock) {
+ for (int i = 0; i < mActiveAssociations.size(); ++i) {
+ AssociationInfo associationInfo = mActiveAssociations.get(i);
+ if (VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES.contains(
+ associationInfo.getDeviceProfile())) {
+ persistentIds.add(
+ VirtualDeviceImpl.createPersistentDeviceId(
+ associationInfo.getId()));
+ }
+ }
+ }
+ return persistentIds;
+ }
+
+ @Override
public void registerAppsOnVirtualDeviceListener(
@NonNull AppsOnVirtualDeviceListener listener) {
synchronized (mVirtualDeviceManagerLock) {
diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
index a570d09..6940ffe 100644
--- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
+++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
@@ -69,6 +69,11 @@
}
@Override
+ public void onProcessCaptureRequest(int streamId, int frameId) throws RemoteException {
+ camera.onProcessCaptureRequest(streamId, frameId, /*metadata=*/ null);
+ }
+
+ @Override
public void onStreamClosed(int streamId) throws RemoteException {
camera.onStreamClosed(streamId);
}
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index ea92154..61e4f36 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -19,6 +19,9 @@
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
import static android.media.AudioSystem.isBluetoothDevice;
+import static android.media.AudioSystem.isBluetoothLeDevice;
+
+import static com.android.media.audio.Flags.dsaOverBtLeAudio;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1625,10 +1628,10 @@
}
private int getHeadSensorHandleUpdateTracker() {
- int headHandle = -1;
+ Sensor htSensor = null;
if (sRoutingDevices.isEmpty()) {
logloge("getHeadSensorHandleUpdateTracker: no device, no head tracker");
- return headHandle;
+ return -1;
}
final AudioDeviceAttributes currentDevice = sRoutingDevices.get(0);
List<String> deviceAddresses = mAudioService.getDeviceAddresses(currentDevice);
@@ -1642,27 +1645,86 @@
for (String address : deviceAddresses) {
UUID routingDeviceUuid = UuidUtils.uuidFromAudioDeviceAttributes(
new AudioDeviceAttributes(currentDevice.getInternalType(), address));
- for (Sensor sensor : sensors) {
- final UUID uuid = sensor.getUuid();
- if (uuid.equals(routingDeviceUuid)) {
- headHandle = sensor.getHandle();
- if (!setHasHeadTracker(currentDevice)) {
- headHandle = -1;
+ if (dsaOverBtLeAudio()) {
+ for (Sensor sensor : sensors) {
+ final UUID uuid = sensor.getUuid();
+ if (uuid.equals(routingDeviceUuid)) {
+ htSensor = sensor;
+ HeadtrackerInfo info = new HeadtrackerInfo(sensor);
+ if (isBluetoothLeDevice(currentDevice.getInternalType())) {
+ if (info.getMajorVersion() == 2) {
+ // Version 2 is used only by LE Audio profile
+ break;
+ }
+ // we do not break, as this could be a match on the A2DP sensor
+ // for a dual mode headset.
+ } else if (info.getMajorVersion() == 1) {
+ // Version 1 is used only by A2DP profile
+ break;
+ }
}
+ if (htSensor == null && uuid.equals(UuidUtils.STANDALONE_UUID)) {
+ htSensor = sensor;
+ // we do not break, perhaps we find a head tracker on device.
+ }
+ }
+ if (htSensor != null) {
+ if (htSensor.getUuid().equals(UuidUtils.STANDALONE_UUID)) {
+ break;
+ }
+ if (setHasHeadTracker(currentDevice)) {
+ break;
+ } else {
+ htSensor = null;
+ }
+ }
+ } else {
+ for (Sensor sensor : sensors) {
+ final UUID uuid = sensor.getUuid();
+ if (uuid.equals(routingDeviceUuid)) {
+ htSensor = sensor;
+ if (!setHasHeadTracker(currentDevice)) {
+ htSensor = null;
+ }
+ break;
+ }
+ if (uuid.equals(UuidUtils.STANDALONE_UUID)) {
+ htSensor = sensor;
+ // we do not break, perhaps we find a head tracker on device.
+ }
+ }
+ if (htSensor != null) {
break;
}
- if (uuid.equals(UuidUtils.STANDALONE_UUID)) {
- headHandle = sensor.getHandle();
- // we do not break, perhaps we find a head tracker on device.
- }
- }
- if (headHandle != -1) {
- break;
}
}
- return headHandle;
+ return htSensor != null ? htSensor.getHandle() : -1;
}
+ /**
+ * Contains the information parsed from the head tracker sensor version.
+ * See platform/hardware/libhardware/modules/sensors/dynamic_sensor/HidRawSensor.h
+ * for the definition of version and capability fields.
+ */
+ private static class HeadtrackerInfo {
+ private final int mVersion;
+ HeadtrackerInfo(Sensor sensor) {
+ mVersion = sensor.getVersion();
+ }
+ int getMajorVersion() {
+ return (mVersion & 0xFF000000) >> 24;
+ }
+ int getMinorVersion() {
+ return (mVersion & 0xFF0000) >> 16;
+ }
+ boolean hasAclTransport() {
+ return getMajorVersion() == 2 ? ((mVersion & 0x1) != 0) : false;
+ }
+ boolean hasIsoTransport() {
+ return getMajorVersion() == 2 ? ((mVersion & 0x2) != 0) : false;
+ }
+ };
+
private int getScreenSensorHandle() {
int screenHandle = -1;
Sensor screenSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index c629b2b..be78ea2 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -157,4 +157,10 @@
* @see VirtualDevice#getPersistentDeviceId()
*/
public abstract @Nullable String getPersistentIdForDevice(int deviceId);
+
+ /**
+ * Returns all current persistent device IDs, including the ones for which no virtual device
+ * exists, as long as one may have existed or can be created.
+ */
+ public abstract @NonNull Set<String> getAllPersistentDeviceIds();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0492f43..c2b5964 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -184,6 +184,7 @@
import android.companion.ICompanionDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.LoggingOnly;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
@@ -555,7 +556,7 @@
* creation and activation of an implicit {@link android.app.AutomaticZenRule}.
*/
@ChangeId
- @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
static final long MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES = 308670109L;
private static final Duration POST_WAKE_LOCK_TIMEOUT = Duration.ofSeconds(30);
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
index 28f656e..8b282dd3 100644
--- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java
+++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
@@ -58,6 +58,23 @@
}
/**
+ * Similar to {@link #scheduleTransactionItem}, but is called without WM lock.
+ *
+ * @see WindowProcessController#setReportedProcState(int)
+ */
+ void scheduleTransactionItemUnlocked(@NonNull IApplicationThread client,
+ @NonNull ClientTransactionItem transactionItem) throws RemoteException {
+ // Immediately dispatching to client, and must not access WMS.
+ final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
+ if (transactionItem.isActivityLifecycleItem()) {
+ clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem);
+ } else {
+ clientTransaction.addCallback(transactionItem);
+ }
+ scheduleTransaction(clientTransaction);
+ }
+
+ /**
* Schedules a single transaction item, either a callback or a lifecycle request, delivery to
* client application.
* @throws RemoteException
@@ -65,6 +82,7 @@
*/
void scheduleTransactionItem(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem transactionItem) throws RemoteException {
+ // TODO(b/260873529): queue the transaction items.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
if (transactionItem.isActivityLifecycleItem()) {
clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem);
@@ -82,6 +100,7 @@
void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem transactionItem,
@NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException {
+ // TODO(b/260873529): replace with #scheduleTransactionItem after launch for cleanup.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
clientTransaction.addCallback(transactionItem);
clientTransaction.setLifecycleStateRequest(lifecycleItem);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 558bf9d..2b18f07 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -388,13 +388,22 @@
final IApplicationThread thread = mThread;
if (prevProcState >= CACHED_CONFIG_PROC_STATE && repProcState < CACHED_CONFIG_PROC_STATE
&& thread != null && mHasCachedConfiguration) {
- final Configuration config;
+ final ConfigurationChangeItem configurationChangeItem;
synchronized (mLastReportedConfiguration) {
- config = new Configuration(mLastReportedConfiguration);
+ onConfigurationChangePreScheduled(mLastReportedConfiguration);
+ configurationChangeItem = ConfigurationChangeItem.obtain(
+ mLastReportedConfiguration, mLastTopActivityDeviceId);
}
// Schedule immediately to make sure the app component (e.g. receiver, service) can get
// the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate).
- scheduleConfigurationChange(thread, config);
+ try {
+ // No WM lock here.
+ mAtm.getLifecycleManager().scheduleTransactionItemUnlocked(
+ thread, configurationChangeItem);
+ } catch (Exception e) {
+ Slog.e(TAG_CONFIGURATION, "Failed to schedule ConfigurationChangeItem="
+ + configurationChangeItem + " owner=" + mOwner, e);
+ }
}
}
@@ -1634,11 +1643,12 @@
}
}
- scheduleConfigurationChange(thread, config);
+ onConfigurationChangePreScheduled(config);
+ scheduleClientTransactionItem(thread, ConfigurationChangeItem.obtain(
+ config, mLastTopActivityDeviceId));
}
- private void scheduleConfigurationChange(@NonNull IApplicationThread thread,
- @NonNull Configuration config) {
+ private void onConfigurationChangePreScheduled(@NonNull Configuration config) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName,
config);
if (Build.IS_DEBUGGABLE && mHasImeService) {
@@ -1646,8 +1656,6 @@
Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
}
mHasCachedConfiguration = false;
- scheduleClientTransactionItem(thread, ConfigurationChangeItem.obtain(
- config, mLastTopActivityDeviceId));
}
@VisibleForTesting
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index d87b8d1..b5ba322 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -773,6 +773,30 @@
}
@Test
+ public void getAllPersistentDeviceIds_respectsCurrentAssociations() {
+ mVdms.onCdmAssociationsChanged(List.of(mAssociationInfo));
+ TestableLooper.get(this).processAllMessages();
+
+ assertThat(mLocalService.getAllPersistentDeviceIds())
+ .containsExactly(mDeviceImpl.getPersistentDeviceId());
+
+ mVdms.onCdmAssociationsChanged(List.of(
+ createAssociationInfo(2, AssociationRequest.DEVICE_PROFILE_APP_STREAMING),
+ createAssociationInfo(3, AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION),
+ createAssociationInfo(4, AssociationRequest.DEVICE_PROFILE_WATCH)));
+ TestableLooper.get(this).processAllMessages();
+
+ assertThat(mLocalService.getAllPersistentDeviceIds()).containsExactly(
+ VirtualDeviceImpl.createPersistentDeviceId(2),
+ VirtualDeviceImpl.createPersistentDeviceId(3));
+
+ mVdms.onCdmAssociationsChanged(Collections.emptyList());
+ TestableLooper.get(this).processAllMessages();
+
+ assertThat(mLocalService.getAllPersistentDeviceIds()).isEmpty();
+ }
+
+ @Test
public void onAppsOnVirtualDeviceChanged_singleVirtualDevice_listenersNotified() {
ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2));
mLocalService.registerAppsOnVirtualDeviceListener(mAppsOnVirtualDeviceListener);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index e152feb..e31ee11 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -306,7 +306,7 @@
@Test
public void testCachedStateConfigurationChange() throws RemoteException {
- doNothing().when(mClientLifecycleManager).scheduleTransactionItem(any(), any());
+ doNothing().when(mClientLifecycleManager).scheduleTransactionItemUnlocked(any(), any());
final IApplicationThread thread = mWpc.getThread();
final Configuration newConfig = new Configuration(mWpc.getConfiguration());
newConfig.densityDpi += 100;
@@ -322,18 +322,17 @@
newConfig.densityDpi += 100;
mWpc.onConfigurationChanged(newConfig);
verify(mClientLifecycleManager, never()).scheduleTransactionItem(eq(thread), any());
+ verify(mClientLifecycleManager, never()).scheduleTransactionItemUnlocked(eq(thread), any());
// Cached -> non-cached will send the previous deferred config immediately.
mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER);
final ArgumentCaptor<ConfigurationChangeItem> captor =
ArgumentCaptor.forClass(ConfigurationChangeItem.class);
- verify(mClientLifecycleManager).scheduleTransactionItem(eq(thread), captor.capture());
+ verify(mClientLifecycleManager).scheduleTransactionItemUnlocked(
+ eq(thread), captor.capture());
final ClientTransactionHandler client = mock(ClientTransactionHandler.class);
captor.getValue().preExecute(client);
- final ArgumentCaptor<Configuration> configCaptor =
- ArgumentCaptor.forClass(Configuration.class);
- verify(client).updatePendingConfiguration(configCaptor.capture());
- assertEquals(newConfig, configCaptor.getValue());
+ verify(client).updatePendingConfiguration(newConfig);
}
@Test
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
index b44f1a6..c49f8fe 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
@@ -23,10 +23,13 @@
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.device.traces.parsers.toFlickerComponent
import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_FINISH_ACTIVITY
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,7 +56,12 @@
testApp.launchViaIntent(wmHelper)
testApp.openIME(wmHelper)
}
- transitions { testApp.finishActivity(wmHelper) }
+ transitions {
+ broadcastActionTrigger.doAction(ACTION_FINISH_ACTIVITY)
+ wmHelper.StateSyncBuilder()
+ .withActivityRemoved(ActivityOptions.Ime.Default.COMPONENT.toFlickerComponent())
+ .waitForAndVerify()
+ }
teardown { simpleApp.exit(wmHelper) }
}
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
index 976ac82..994edc5 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
@@ -28,6 +28,7 @@
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
+import com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_TOGGLE_ORIENTATION
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,7 +54,11 @@
// Enable letterbox when the app calls setRequestedOrientation
device.executeShellCommand("cmd window set-ignore-orientation-request true")
}
- transitions { testApp.toggleFixPortraitOrientation(wmHelper) }
+ transitions {
+ broadcastActionTrigger.doAction(ACTION_TOGGLE_ORIENTATION)
+ // Ensure app relaunching transition finished and the IME was shown
+ testApp.waitIMEShown(wmHelper)
+ }
teardown {
testApp.exit()
device.executeShellCommand("cmd window set-ignore-orientation-request false")
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
index aff8e65..6ee5a9a 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
@@ -104,7 +104,7 @@
@Presubmit
@Test
- open fun imeLayerIsVisibleWhenSwitchingToImeApp() {
+ fun imeLayerIsVisibleWhenSwitchingToImeApp() {
flicker.assertLayersStart { isVisible(ComponentNameMatcher.IME) }
flicker.assertLayersTag(TAG_IME_VISIBLE) { isVisible(ComponentNameMatcher.IME) }
flicker.assertLayersEnd { isVisible(ComponentNameMatcher.IME) }
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
index 4ffdcea..1ad5c0d 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
@@ -93,7 +93,7 @@
}
transitions {
testApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder().withImeShown().waitForAndVerify()
+ testApp.waitIMEShown(wmHelper)
}
}
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
index 6ad235c..181a2a2 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
@@ -23,11 +23,14 @@
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.device.traces.parsers.toFlickerComponent
import android.view.WindowInsets.Type.ime
import android.view.WindowInsets.Type.navigationBars
import android.view.WindowInsets.Type.statusBars
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_START_DIALOG_THEMED_ACTIVITY
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.FixMethodOrder
@@ -50,8 +53,12 @@
override val transition: FlickerBuilder.() -> Unit = {
setup {
testApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder().withImeShown().waitForAndVerify()
- testApp.startDialogThemedActivity(wmHelper)
+ testApp.waitIMEShown(wmHelper)
+ broadcastActionTrigger.doAction(ACTION_START_DIALOG_THEMED_ACTIVITY)
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(
+ ActivityOptions.DialogThemedActivity.COMPONENT.toFlickerComponent())
+ .waitForAndVerify()
// Verify IME insets isn't visible on dialog since it's non-IME focusable window
assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
index 7c9c05d..ad272a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker
import android.app.Instrumentation
+import android.content.Intent
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerBuilderProvider
@@ -50,6 +51,19 @@
/** Specification of the test transition to execute */
abstract val transition: FlickerBuilder.() -> Unit
+ protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation)
+
+ // Helper class to process test actions by broadcast.
+ protected class BroadcastActionTrigger(private val instrumentation: Instrumentation) {
+ private fun createIntentWithAction(broadcastAction: String): Intent {
+ return Intent(broadcastAction).setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ }
+
+ fun doAction(broadcastAction: String) {
+ instrumentation.context.sendBroadcast(createIntentWithAction(broadcastAction))
+ }
+ }
+
/**
* Entry point for the test runner. It will use this method to initialize and cache flicker
* executions
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 252f7d3..cb1aab0 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -50,7 +50,7 @@
waitIMEShown(wmHelper)
}
- protected fun waitIMEShown(wmHelper: WindowManagerStateHelper) {
+ fun waitIMEShown(wmHelper: WindowManagerStateHelper) {
wmHelper.StateSyncBuilder().withImeShown().waitForAndVerify()
}
@@ -63,17 +63,4 @@
uiDevice.pressBack()
wmHelper.StateSyncBuilder().withImeGone().waitForAndVerify()
}
-
- open fun finishActivity(wmHelper: WindowManagerStateHelper) {
- val finishButton =
- uiDevice.wait(
- Until.findObject(By.res(packageName, "finish_activity_btn")),
- FIND_TIMEOUT
- )
- requireNotNull(finishButton) {
- "Finish activity button not found, probably IME activity is not on the screen?"
- }
- finishButton.click()
- wmHelper.StateSyncBuilder().withActivityRemoved(this).waitForAndVerify()
- }
}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
index d3cee64..0ee7aee 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
@@ -74,24 +74,6 @@
open(expectedPackage)
}
- fun startDialogThemedActivity(wmHelper: WindowManagerStateHelper) {
- val button =
- uiDevice.wait(
- Until.findObject(By.res(packageName, "start_dialog_themed_activity_btn")),
- FIND_TIMEOUT
- )
-
- requireNotNull(button) {
- "Button not found, this usually happens when the device " +
- "was left in an unknown state (e.g. Screen turned off)"
- }
- button.click()
- wmHelper
- .StateSyncBuilder()
- .withFullScreenApp(ActivityOptions.DialogThemedActivity.COMPONENT.toFlickerComponent())
- .waitForAndVerify()
- }
-
fun dismissDialog(wmHelper: WindowManagerStateHelper) {
val dialog = uiDevice.wait(Until.findObject(By.text("Dialog for test")), FIND_TIMEOUT)
@@ -126,20 +108,4 @@
}
return false
}
-
- fun toggleFixPortraitOrientation(wmHelper: WindowManagerStateHelper) {
- val button =
- uiDevice.wait(
- Until.findObject(By.res(packageName, "toggle_fixed_portrait_btn")),
- FIND_TIMEOUT
- )
- require(button != null) {
- "Button not found, this usually happens when the device " +
- "was left in an unknown state (e.g. Screen turned off)"
- }
- button.click()
- instrumentation.waitForIdleSync()
- // Ensure app relaunching transition finish and the IME has shown
- waitIMEShown(wmHelper)
- }
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
index fa73e2c..507c1b6 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,39 +13,17 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
+ android:background="@android:color/holo_green_light"
android:focusableInTouchMode="true"
- android:background="@android:color/holo_green_light">
- <EditText android:id="@+id/plain_text_input"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:imeOptions="flagNoExtractUi"
- android:inputType="text"/>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/plain_text_input"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <Button
- android:id="@+id/finish_activity_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Finish activity" />
- <Button
- android:id="@+id/start_dialog_themed_activity_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Dialog themed activity" />
- <ToggleButton
- android:id="@+id/toggle_fixed_portrait_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textOn="Portrait (On)"
- android:textOff="Portrait (Off)"
- />
- </LinearLayout>
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:inputType="text" />
</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index 8b334c0..80c1dd0 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -40,6 +40,18 @@
public static final String LABEL = "ImeActivity";
public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
FLICKER_APP_PACKAGE + ".ImeActivity");
+
+ /** Intent action used to finish the test activity. */
+ public static final String ACTION_FINISH_ACTIVITY =
+ FLICKER_APP_PACKAGE + ".ImeActivity.FINISH_ACTIVITY";
+
+ /** Intent action used to start a {@link DialogThemedActivity}. */
+ public static final String ACTION_START_DIALOG_THEMED_ACTIVITY =
+ FLICKER_APP_PACKAGE + ".ImeActivity.START_DIALOG_THEMED_ACTIVITY";
+
+ /** Intent action used to toggle activity orientation. */
+ public static final String ACTION_TOGGLE_ORIENTATION =
+ FLICKER_APP_PACKAGE + ".ImeActivity.TOGGLE_ORIENTATION";
}
public static class AutoFocusActivity {
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
index d7ee2af..4418b5a 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
@@ -16,12 +16,51 @@
package com.android.server.wm.flicker.testapp;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_FINISH_ACTIVITY;
+import static com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_START_DIALOG_THEMED_ACTIVITY;
+import static com.android.server.wm.flicker.testapp.ActivityOptions.Ime.Default.ACTION_TOGGLE_ORIENTATION;
+
import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
+import android.util.Log;
import android.view.WindowManager;
-import android.widget.Button;
public class ImeActivity extends Activity {
+
+ private static final String TAG = "ImeActivity";
+
+ /** Receiver used to handle actions coming from the test helper methods. */
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case ACTION_FINISH_ACTIVITY -> finish();
+ case ACTION_START_DIALOG_THEMED_ACTIVITY -> startActivity(
+ new Intent(context, DialogThemedActivity.class));
+ case ACTION_TOGGLE_ORIENTATION -> {
+ mIsPortrait = !mIsPortrait;
+ setRequestedOrientation(mIsPortrait
+ ? SCREEN_ORIENTATION_PORTRAIT
+ : SCREEN_ORIENTATION_UNSPECIFIED);
+ }
+ default -> Log.w(TAG, "Unhandled action=" + intent.getAction());
+ }
+ }
+ };
+
+ /**
+ * Used to toggle activity orientation between portrait when {@code true} and
+ * unspecified otherwise.
+ */
+ private boolean mIsPortrait = false;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -30,9 +69,17 @@
.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(p);
setContentView(R.layout.activity_ime);
- Button button = findViewById(R.id.finish_activity_btn);
- button.setOnClickListener(view -> {
- finish();
- });
+
+ final var filter = new IntentFilter();
+ filter.addAction(ACTION_FINISH_ACTIVITY);
+ filter.addAction(ACTION_START_DIALOG_THEMED_ACTIVITY);
+ filter.addAction(ACTION_TOGGLE_ORIENTATION);
+ registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED);
+ }
+
+ @Override
+ protected void onDestroy() {
+ unregisterReceiver(mBroadcastReceiver);
+ super.onDestroy();
}
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
index 7ee8deb..cd711f7 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
@@ -16,29 +16,12 @@
package com.android.server.wm.flicker.testapp;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
-import android.content.Intent;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ToggleButton;
-
public class ImeActivityAutoFocus extends ImeActivity {
@Override
protected void onStart() {
super.onStart();
- Button startThemedActivityButton = findViewById(R.id.start_dialog_themed_activity_btn);
- startThemedActivityButton.setOnClickListener(
- button -> startActivity(new Intent(this, DialogThemedActivity.class)));
-
- ToggleButton toggleFixedPortraitButton = findViewById(R.id.toggle_fixed_portrait_btn);
- toggleFixedPortraitButton.setOnCheckedChangeListener(
- (button, isChecked) -> setRequestedOrientation(
- isChecked ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_UNSPECIFIED));
-
- EditText editTextField = findViewById(R.id.plain_text_input);
+ final var editTextField = findViewById(R.id.plain_text_input);
editTextField.requestFocus();
}
}