Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f705e27 authored by Felipe Leme's avatar Felipe Leme
Browse files

Fixed display id on Instrumentation.sendKeySync().

By default, the displayId in the KeyEvents is always 0, which would
cause CTS tests to fail when they are running on background
users visible in different displays.

Bug: 266851112
Fixes: 268103680

Test: adb shell am start-user --display 2 13 && adb shell am instrument --user 13 -e class "android.app.cts.LauncherActivityTest" -w "android.app.cts/androidx.test.runner.AndroidJUnitRunner"

Change-Id: Ie9a68319f47c45f0a6b035ddcda13e8c5627f34f
parent 5bc4f546
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -43,8 +43,10 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.TestLooperManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
@@ -93,6 +95,8 @@ public class Instrumentation {

    private static final long CONNECT_TIMEOUT_MILLIS = 5000;

    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);

    /**
     * @hide
     */
@@ -1124,10 +1128,44 @@ public class Instrumentation {
        newEvent.setTime(downTime, eventTime);
        newEvent.setSource(source);
        newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM);
        setDisplayIfNeeded(newEvent);

        InputManager.getInstance().injectInputEvent(newEvent,
                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
    }

    private void setDisplayIfNeeded(KeyEvent event) {
        if (!UserManager.isVisibleBackgroundUsersEnabled()) {
            return;
        }
        // In devices that support visible background users visible, the display id must be set to
        // reflect the display the user was started visible on, otherwise the event would be sent to
        // the main display (which would most likely fail the test).
        int eventDisplayId = event.getDisplayId();
        if (eventDisplayId != Display.INVALID_DISPLAY) {
            if (VERBOSE) {
                Log.v(TAG, "setDisplayIfNeeded(" + event + "): not changing display id as it's "
                        + "explicitly set to " + eventDisplayId);
            }
            return;
        }

        UserManager userManager = mInstrContext.getSystemService(UserManager.class);
        int userDisplayId = userManager.getDisplayIdAssignedToUser();
        if (VERBOSE) {
            Log.v(TAG, "setDisplayIfNeeded(" + event + "): eventDisplayId=" + eventDisplayId
                    + ", user=" + mInstrContext.getUser() + ", userDisplayId=" + userDisplayId);
        }
        if (userDisplayId == Display.INVALID_DISPLAY) {
            Log.e(TAG, "setDisplayIfNeeded(" + event + "): UserManager returned INVALID_DISPLAY as "
                    + "display assigned to user " + mInstrContext.getUser());
            return;

        }

        event.setDisplayId(userDisplayId);
    }

    /**
     * Sends up and down key events with the given key code to the currently focused window, and
     * waits for it to be processed.
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ interface IUserManager {
    boolean isUserForeground(int userId);
    boolean isUserVisible(int userId);
    int[] getVisibleUsers();
    int getDisplayIdAssignedToUser();
    boolean isUserNameSet(int userId);
    boolean hasRestrictedProfiles(int userId);
    boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags);
+13 −0
Original line number Diff line number Diff line
@@ -3051,6 +3051,19 @@ public class UserManager {
        return result;
    }

    /**
     * See {@link com.android.server.pm.UserManagerInternal#getDisplayAssignedToUser(int)}.
     *
     * @hide
     */
    public int getDisplayIdAssignedToUser() {
        try {
            return mService.getDisplayIdAssignedToUser();
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Return whether the context user is running in an "unlocked" state.
     * <p>
+8 −0
Original line number Diff line number Diff line
@@ -1903,6 +1903,14 @@ public class UserManagerService extends IUserManager.Stub {
        }
    }

    @Override
    public int getDisplayIdAssignedToUser() {
        // Not checking for any permission as it returns info about calling user
        int userId = UserHandle.getUserId(Binder.getCallingUid());
        int displayId = mUserVisibilityMediator.getDisplayAssignedToUser(userId);
        return displayId;
    }

    @Override
    public @NonNull String getUserName() {
        final int callingUid = Binder.getCallingUid();