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

Commit 734983ff authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Allow related users to show activities on primary user

Make ActivityManager and WindowManager understand related users.

Task stack will now contain interleaved tasks for related users,
but still group regular users separately from groups of related users.

InputMethodManagerService permits related users to invoke IME and receive
key events.

Change-Id: I3bd87b32aec69c3f8d470c8b29b144f4e849c808
parent 16340670
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -504,6 +504,7 @@ public class InputMethodUtils {

        private String mEnabledInputMethodsStrCache;
        private int mCurrentUserId;
        private int[] mRelatedUserIds = new int[0];

        private static void buildEnabledInputMethodsSettingString(
                StringBuilder builder, Pair<String, ArrayList<String>> pair) {
@@ -536,6 +537,22 @@ public class InputMethodUtils {
            mCurrentUserId = userId;
        }

        public void setRelatedUserIds(int[] relatedUserIds) {
            synchronized (this) {
                mRelatedUserIds = relatedUserIds;
            }
        }

        public boolean isRelatedToOrCurrentUser(int userId) {
            synchronized (this) {
                if (userId == mCurrentUserId) return true;
                for (int i = 0; i < mRelatedUserIds.length; i++) {
                    if (userId == mRelatedUserIds[i]) return true;
                }
                return false;
            }
        }

        public List<InputMethodInfo> getEnabledInputMethodListLocked() {
            return createEnabledInputMethodListLocked(
                    getEnabledInputMethodsAndSubtypeListLocked());
+21 −1
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -78,6 +79,7 @@ import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
@@ -441,6 +443,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                hideInputMethodMenu();
                // No need to updateActive
                return;
            } else if (Intent.ACTION_USER_ADDED.equals(action)
                    || Intent.ACTION_USER_REMOVED.equals(action)) {
                updateRelatedUserIds();
                return;
            } else {
                Slog.w(TAG, "Unexpected intent " + intent);
            }
@@ -642,6 +648,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        broadcastFilter.addAction(Intent.ACTION_SCREEN_ON);
        broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF);
        broadcastFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        broadcastFilter.addAction(Intent.ACTION_USER_ADDED);
        broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
        mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);

        mNotificationShown = false;
@@ -675,6 +683,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        // mSettings should be created before buildInputMethodListLocked
        mSettings = new InputMethodSettings(
                mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
        updateRelatedUserIds();
        mFileManager = new InputMethodFileManager(mMethodMap, userId);
        mSwitchingController = new InputMethodSubtypeSwitchingController(mSettings);
        mSwitchingController.resetCircularListLocked(context);
@@ -790,6 +799,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

    private void switchUserLocked(int newUserId) {
        mSettings.setCurrentUserId(newUserId);
        updateRelatedUserIds();
        // InputMethodFileManager should be reset when the user is changed
        mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
        final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -810,6 +820,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    void updateRelatedUserIds() {
        List<UserInfo> relatedUsers =
                UserManager.get(mContext).getRelatedUsers(mSettings.getCurrentUserId());
        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
        for (int i = 0; i < relatedUserIds.length; i++) {
            relatedUserIds[i] = relatedUsers.get(i).id;
        }
        mSettings.setRelatedUserIds(relatedUserIds);
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
@@ -905,7 +925,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                    + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()
                    + InputMethodUtils.getApiCallStack());
        }
        if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
        if (uid == Process.SYSTEM_UID || mSettings.isRelatedToOrCurrentUser(userId)) {
            return true;
        }

+19 −1
Original line number Diff line number Diff line
@@ -1015,6 +1015,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    final ActivityThread mSystemThread;
    int mCurrentUserId = 0;
    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
    private UserManagerService mUserManager;
    private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -16097,6 +16098,20 @@ public final class ActivityManagerService extends ActivityManagerNative
        return startUser(userId, /* foreground */ false);
    }
    /**
     * Refreshes the list of users related to the current user when either a
     * user switch happens or when a new related user is started in the
     * background.
     */
    private void updateRelatedUserIdsLocked() {
        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
        for (int i = 0; i < relatedUserIds.length; i++) {
            relatedUserIds[i] = relatedUsers.get(i).id;
        }
        mRelatedUserIds = relatedUserIds;
    }
    @Override
    public boolean switchUser(final int userId) {
        return startUser(userId, /* foregound */ true);
@@ -16150,12 +16165,15 @@ public final class ActivityManagerService extends ActivityManagerNative
                if (foreground) {
                    mCurrentUserId = userId;
                    mWindowManager.setCurrentUser(userId);
                    updateRelatedUserIdsLocked();
                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
                    // Once the internal notion of the active user has switched, we lock the device
                    // with the option to show the user switcher on the keyguard.
                    mWindowManager.lockNow(null);
                } else {
                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
                    updateRelatedUserIdsLocked();
                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
                    mUserLru.remove(currentUserIdInt);
                    mUserLru.add(currentUserIdInt);
                }
+19 −8
Original line number Diff line number Diff line
@@ -341,8 +341,19 @@ final class ActivityStack {
        mCurrentUser = mService.mCurrentUserId;
    }

    boolean okToShow(ActivityRecord r) {
        return r.userId == mCurrentUser
    /**
     * Checks whether the userid is either the current user or a related user.
     */
    private boolean isRelatedToOrCurrentUserLocked(int userId) {
        if (mCurrentUser == userId) return true;
        for (int i = 0; i < mService.mRelatedUserIds.length; i++) {
            if (mService.mRelatedUserIds[i] == userId) return true;
        }
        return false;
    }

    boolean okToShowLocked(ActivityRecord r) {
        return isRelatedToOrCurrentUserLocked(r.userId)
                || (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0;
    }

@@ -362,7 +373,7 @@ final class ActivityStack {
            final ArrayList<ActivityRecord> activities = task.mActivities;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                ActivityRecord r = activities.get(activityNdx);
                if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
                if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
                    return r;
                }
            }
@@ -389,7 +400,7 @@ final class ActivityStack {
            for (int i = activities.size() - 1; i >= 0; --i) {
                final ActivityRecord r = activities.get(i);
                // Note: the taskId check depends on real taskId fields being non-zero
                if (!r.finishing && (token != r.appToken) && okToShow(r)) {
                if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
                    return r;
                }
            }
@@ -542,7 +553,7 @@ final class ActivityStack {

        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.userId != mCurrentUser) {
            if (!isRelatedToOrCurrentUserLocked(task.userId)) {
                return null;
            }
            final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -573,7 +584,7 @@ final class ActivityStack {
        int index = mTaskHistory.size();
        for (int i = 0; i < index; ) {
            TaskRecord task = mTaskHistory.get(i);
            if (task.userId == userId) {
            if (isRelatedToOrCurrentUserLocked(task.userId)) {
                if (DEBUG_TASKS) Slog.d(TAG, "switchUserLocked: stack=" + getStackId() +
                        " moving " + task + " to top");
                mTaskHistory.remove(i);
@@ -1728,10 +1739,10 @@ final class ActivityStack {
        mTaskHistory.remove(task);
        // Now put task at top.
        int stackNdx = mTaskHistory.size();
        if (task.userId != mCurrentUser) {
        if (!isRelatedToOrCurrentUserLocked(task.userId)) {
            // Put non-current user tasks below current user tasks.
            while (--stackNdx >= 0) {
                if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
                if (!isRelatedToOrCurrentUserLocked(mTaskHistory.get(stackNdx).userId)) {
                    break;
                }
            }
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ final class TaskRecord extends ThumbnailHolder {
    ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
        for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
            ActivityRecord r = mActivities.get(activityNdx);
            if (!r.finishing && r != notTop && stack.okToShow(r)) {
            if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
                return r;
            }
        }
Loading