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

Commit 464060da authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove remaining UserLifecycleListener deps from IMMS utils" into main

parents 68d7a156 cf9acd88
Loading
Loading
Loading
Loading
+4 −47
Original line number Diff line number Diff line
@@ -18,20 +18,14 @@ package com.android.server.inputmethod;

import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Handler;
import android.os.Process;
import android.util.IntArray;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.DirectBootAwareness;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;

import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
@@ -225,37 +219,8 @@ final class AdditionalSubtypeMapRepository {
        sWriter.startThread();
    }

    static void initialize(@NonNull Handler ioHandler, @NonNull Context context) {
        final UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        ioHandler.post(() -> {
            userManagerInternal.addUserLifecycleListener(
                    new UserManagerInternal.UserLifecycleListener() {
                        @Override
                        public void onUserCreated(UserInfo user, @Nullable Object token) {
                            final int userId = user.id;
                            sWriter.onUserCreated(userId);
                            ioHandler.post(() -> {
                                synchronized (ImfLock.class) {
                                    if (!sPerUserMap.contains(userId)) {
                                        final AdditionalSubtypeMap additionalSubtypeMap =
                                                AdditionalSubtypeUtils.load(userId);
                                        sPerUserMap.put(userId, additionalSubtypeMap);
                                        final InputMethodSettings settings =
                                                InputMethodManagerService
                                                        .queryInputMethodServicesInternal(context,
                                                                userId,
                                                                additionalSubtypeMap,
                                                                DirectBootAwareness.AUTO);
                                        InputMethodSettingsRepository.put(userId, settings);
                                    }
                                }
                            });
                        }

                        @Override
                        public void onUserRemoved(UserInfo user) {
                            final int userId = user.id;
    @AnyThread
    static void remove(@UserIdInt int userId, @NonNull Handler ioHandler) {
        sWriter.onUserRemoved(userId);
        ioHandler.post(() -> {
            synchronized (ImfLock.class) {
@@ -263,12 +228,4 @@ final class AdditionalSubtypeMapRepository {
            }
        });
    }
                    });
            synchronized (ImfLock.class) {
                for (int userId : userManagerInternal.getUserIds()) {
                    sPerUserMap.put(userId, AdditionalSubtypeUtils.load(userId));
                }
            }
        });
    }
}
+36 −10
Original line number Diff line number Diff line
@@ -933,6 +933,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.

            // For production code, hook up user lifecycle
            mService.mUserManagerInternal.addUserLifecycleListener(this);

            // Also schedule user init tasks onto an I/O thread.
            initializeUsersAsync(context, mService.mIoHandler,
                    mService.mUserManagerInternal.getUserIds());
        }

        @VisibleForTesting
@@ -1015,6 +1019,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        @Override
        public void onUserCreated(UserInfo user, @Nullable Object token) {
            // Called directly from UserManagerService. Do not block the calling thread.
            initializeUsersAsync(mService.mContext, mService.mIoHandler, new int[user.id]);
        }

        @Override
@@ -1022,6 +1027,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            // Called directly from UserManagerService. Do not block the calling thread.
            final int userId = user.id;
            SecureSettingsWrapper.onUserRemoved(userId);
            AdditionalSubtypeMapRepository.remove(userId, mService.mIoHandler);
            InputMethodSettingsRepository.remove(userId);
            mService.mUserDataRepository.remove(userId);
        }

@@ -1049,6 +1056,35 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            });
        }

        @AnyThread
        private static void initializeUsersAsync(
                @NonNull Context context, @NonNull Handler ioHandler, @UserIdInt int[] userIds) {
            ioHandler.post(() -> {
                // We first create InputMethodMap for each user without loading AdditionalSubtypes.
                final int numUsers = userIds.length;
                final InputMethodMap[] rawMethodMaps = new InputMethodMap[numUsers];
                for (int i = 0; i < numUsers; ++i) {
                    final int userId = userIds[i];
                    rawMethodMaps[i] = InputMethodManagerService.queryInputMethodServicesInternal(
                            context, userId, AdditionalSubtypeMap.EMPTY_MAP,
                            DirectBootAwareness.AUTO).getMethodMap();
                }

                // Then create full InputMethodMap for each user. Note that
                // AdditionalSubtypeMapRepository#get() and InputMethodSettingsRepository#put()
                // need to be called with ImfLock held (b/352387655).
                // TODO(b/343601565): Avoid ImfLock after fixing b/352387655.
                synchronized (ImfLock.class) {
                    for (int i = 0; i < numUsers; ++i) {
                        final int userId = userIds[i];
                        final var map = AdditionalSubtypeMapRepository.get(userId);
                        final var methodMap = rawMethodMaps[i].applyAdditionalSubtypes(map);
                        final var settings = InputMethodSettings.create(methodMap, userId);
                        InputMethodSettingsRepository.put(userId, settings);
                    }
                }
            });
        }
    }

    void onUnlockUser(@UserIdInt int userId) {
@@ -1121,16 +1157,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.

            mShowOngoingImeSwitcherForPhones = false;

            // Executing InputMethodSettingsRepository.initialize() does not mean that it
            // immediately becomes ready to return the up-to-date InputMethodSettings for each
            // running user, because we want to return from the constructor as early as possible so
            // as not to delay the system boot process.
            // Search for InputMethodSettingsRepository.put() to find where and when it's actually
            // being updated. In general IMMS should refrain from exposing the existence of IMEs
            // until systemReady().
            InputMethodSettingsRepository.initialize(mIoHandler, mContext);
            AdditionalSubtypeMapRepository.initialize(mIoHandler, mContext);

            mCurrentUserId = mActivityManagerInternal.getCurrentUserId();
            @SuppressWarnings("GuardedBy") final IntFunction<InputMethodBindingController>
                    bindingControllerFactory = userId -> new InputMethodBindingController(userId,
+6 −34
Original line number Diff line number Diff line
@@ -16,17 +16,12 @@

package com.android.server.inputmethod;

import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Handler;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.DirectBootAwareness;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;

final class InputMethodSettingsRepository {
    @GuardedBy("ImfLock.class")
@@ -54,33 +49,10 @@ final class InputMethodSettingsRepository {
        sPerUserMap.put(userId, obj);
    }

    static void initialize(@NonNull Handler ioHandler, @NonNull Context context) {
        final UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        ioHandler.post(() -> {
            userManagerInternal.addUserLifecycleListener(
                    new UserManagerInternal.UserLifecycleListener() {
                        @Override
                        public void onUserRemoved(UserInfo user) {
                            final int userId = user.id;
                            ioHandler.post(() -> {
    @AnyThread
    static void remove(@UserIdInt int userId) {
        synchronized (ImfLock.class) {
            sPerUserMap.remove(userId);
        }
                            });
                        }
                    });
            synchronized (ImfLock.class) {
                for (int userId : userManagerInternal.getUserIds()) {
                    final InputMethodSettings settings =
                            InputMethodManagerService.queryInputMethodServicesInternal(
                                    context,
                                    userId,
                                    AdditionalSubtypeMapRepository.get(userId),
                                    DirectBootAwareness.AUTO);
                    put(userId, settings);
                }
            }
        });
    }
}