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

Commit 39acca1d authored by Felipe Leme's avatar Felipe Leme
Browse files

Fixed VIMS to postpone ASSISTANT rule change on pre-created users.

RoleService should not be calling onRoleHoldersChanged() on
pre-created users, but that behavior cannot be changed because its
implemented by a system app, and pre-created users APIs are hidden.

To test it:

$ adb shell pm create-user --pre-create-only  --guest
Success: created user id 12

$ adb shell pm create-user --guest ElGuesto
Success: created user id 12

$ adb shell cmd user list --all -v
4 users:

0: id=0, name=Driver, type=system.HEADLESS, flags=ADMIN|INITIALIZED|PRIMARY|SYSTEM (running)
1: id=10, name=Driver, type=full.SECONDARY, flags=ADMIN|FULL|INITIALIZED (running) (current)
2: id=11, name=null, type=full.SECONDARY, flags=FULL|INITIALIZED (pre-created)
3: id=12, name=ElGuesto, type=full.GUEST, flags=EPHEMERAL|FULL|GUEST|INITIALIZED (converted)

$ adb shell am switch-user 12

$ adb shell dumpsys voiceinteraction |egrep '(mBound|implementation)'
  mBound=true mService=android.service.voice.IVoiceInteractionService$Stub$Proxy@77da1bc

$ adb shell cmd voiceinteraction show

Test: see bove
Bug: 216141085
Bug: 226201975

Change-Id: I12d9bb32e144ecf91ee4b452affea0dcea546127
parent 39fcc26a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.service.voice;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.Bundle;
import android.os.IBinder;

@@ -64,6 +65,13 @@ public abstract class VoiceInteractionManagerInternal {
    @Nullable
    public abstract HotwordDetectionServiceIdentity getHotwordDetectionServiceIdentity();

    /**
     * Called by {@code UMS.convertPreCreatedUserIfPossible()} when a new user is not created from
     * scratched, but converted from the pool of existing pre-created users.
     */
    // TODO(b/226201975): remove method once RoleService supports pre-created users
    public abstract void onPreCreatedUserConversion(@UserIdInt int userId);

    /**
     * Provides the uids of the currently active
     * {@link android.service.voice.HotwordDetectionService} and its owning package. The
+6 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import android.os.storage.StorageManagerInternal;
import android.provider.Settings;
import android.security.GateKeeper;
import android.service.gatekeeper.IGateKeeperService;
import android.service.voice.VoiceInteractionManagerInternal;
import android.stats.devicepolicy.DevicePolicyEnums;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -4366,6 +4367,11 @@ public class UserManagerService extends IUserManager.Stub {
        Binder.withCleanCallingIdentity(() -> {
            mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true);
            dispatchUserAdded(preCreatedUser, token);
            VoiceInteractionManagerInternal vimi = LocalServices
                    .getService(VoiceInteractionManagerInternal.class);
            if (vimi != null) {
                vimi.onPreCreatedUserConversion(preCreatedUser.id);
            }
        });
        return preCreatedUser;
    }
+46 −3
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ import com.android.server.UiThread;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
import com.android.server.soundtrigger.SoundTriggerInternal;
import com.android.server.utils.Slogf;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.ActivityTaskManagerInternal;

@@ -134,18 +135,21 @@ public class VoiceInteractionManagerService extends SystemService {
    private final RemoteCallbackList<IVoiceInteractionSessionListener>
            mVoiceInteractionSessionListeners = new RemoteCallbackList<>();

    // TODO(b/226201975): remove once RoleService supports pre-created users
    private final ArrayList<UserHandle> mIgnoredPreCreatedUsers = new ArrayList<>();

    public VoiceInteractionManagerService(Context context) {
        super(context);
        mContext = context;
        mResolver = context.getContentResolver();
        mUserManagerInternal = Objects.requireNonNull(
                LocalServices.getService(UserManagerInternal.class));
        mDbHelper = new DatabaseHelper(context);
        mServiceStub = new VoiceInteractionManagerServiceStub();
        mAmInternal = Objects.requireNonNull(
                LocalServices.getService(ActivityManagerInternal.class));
        mAtmInternal = Objects.requireNonNull(
                LocalServices.getService(ActivityTaskManagerInternal.class));
        mUserManagerInternal = Objects.requireNonNull(
                LocalServices.getService(UserManagerInternal.class));

        LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService(
                LegacyPermissionManagerInternal.class);
@@ -300,6 +304,25 @@ public class VoiceInteractionManagerService extends SystemService {
            }
            return hotwordDetectionConnection.mIdentity;
        }

        @Override
        public void onPreCreatedUserConversion(int userId) {
            Slogf.d(TAG, "onPreCreatedUserConversion(%d)", userId);

            for (int i = 0; i < mIgnoredPreCreatedUsers.size(); i++) {
                UserHandle preCreatedUser = mIgnoredPreCreatedUsers.get(i);
                if (preCreatedUser.getIdentifier() == userId) {
                    Slogf.d(TAG, "Updating role on pre-created user %d", userId);
                    mServiceStub.mRoleObserver.onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT,
                            preCreatedUser);
                    mIgnoredPreCreatedUsers.remove(i);
                    return;
                }
            }
            Slogf.w(TAG, "onPreCreatedUserConversion(%d): not available on "
                    + "mIgnoredPreCreatedUserIds (%s)", userId, mIgnoredPreCreatedUsers);
        }

    }

    // implementation entry point and binder service
@@ -317,10 +340,12 @@ public class VoiceInteractionManagerService extends SystemService {
        private boolean mTemporarilyDisabled;

        private final boolean mEnableService;
        // TODO(b/226201975): remove reference once RoleService supports pre-created users
        private final RoleObserver mRoleObserver;

        VoiceInteractionManagerServiceStub() {
            mEnableService = shouldEnableService(mContext);
            new RoleObserver(mContext.getMainExecutor());
            mRoleObserver = new RoleObserver(mContext.getMainExecutor());
        }

        void handleUserStop(String packageName, int userHandle) {
@@ -1882,6 +1907,7 @@ public class VoiceInteractionManagerService extends SystemService {
                pw.println("  mTemporarilyDisabled: " + mTemporarilyDisabled);
                pw.println("  mCurUser: " + mCurUser);
                pw.println("  mCurUserSupported: " + mCurUserSupported);
                pw.println("  mIgnoredPreCreatedUsers: " + mIgnoredPreCreatedUsers);
                dumpSupportedUsers(pw, "  ");
                mDbHelper.dump(pw);
                if (mImpl == null) {
@@ -1995,6 +2021,23 @@ public class VoiceInteractionManagerService extends SystemService {

                List<String> roleHolders = mRm.getRoleHoldersAsUser(roleName, user);

                // TODO(b/226201975): this method is beling called when a pre-created user is added,
                // at which point it doesn't have any role holders. But it's not called again when
                // the actual user is added (i.e., when the  pre-created user is converted), so we
                // need to save the user id and call this method again when it's converted
                // (at onPreCreatedUserConversion()).
                // Once RoleService properly handles pre-created users, this workaround should be
                // removed.
                if (roleHolders.isEmpty()) {
                    UserInfo userInfo = mUserManagerInternal.getUserInfo(user.getIdentifier());
                    if (userInfo != null && userInfo.preCreated) {
                        Slogf.d(TAG, "onRoleHoldersChanged(): ignoring pre-created user %s for now",
                                userInfo.toFullString());
                        mIgnoredPreCreatedUsers.add(user);
                        return;
                    }
                }

                int userId = user.getIdentifier();
                if (roleHolders.isEmpty()) {
                    Settings.Secure.putStringForUser(getContext().getContentResolver(),