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

Commit 4e481c55 authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Revert "Add UserData to store user related information"

This reverts commit 4eb3b97c.

This fixes a lock contention that created a regression in boot time.

Fix: 329414077
Bug: 325515685
Test: n/a
Change-Id: Ibe8602a4e0810ffaa923cdee48981e6051e74f5f
parent 789423c3
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ final class InputMethodBindingController {
    @GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
    @GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
    @GuardedBy("ImfLock.class") @Nullable private IBinder mCurToken;
    @GuardedBy("ImfLock.class") private int mCurSeq;
    @GuardedBy("ImfLock.class") private boolean mVisibleBound;
    @GuardedBy("ImfLock.class") private boolean mSupportsStylusHw;
    @GuardedBy("ImfLock.class") private boolean mSupportsConnectionlessStylusHw;
@@ -193,6 +194,27 @@ final class InputMethodBindingController {
        return mCurIntent;
    }

    /**
     * The current binding sequence number, incremented every time there is
     * a new bind performed.
     */
    @GuardedBy("ImfLock.class")
    int getSequenceNumber() {
        return mCurSeq;
    }

    /**
     * Increase the current binding sequence number by one.
     * Reset to 1 on overflow.
     */
    @GuardedBy("ImfLock.class")
    void advanceSequenceNumber() {
        mCurSeq += 1;
        if (mCurSeq <= 0) {
            mCurSeq = 1;
        }
    }

    /**
     * If non-null, this is the input method service we are currently connected
     * to.
@@ -413,11 +435,9 @@ final class InputMethodBindingController {
            mLastBindTime = SystemClock.uptimeMillis();

            addFreshWindowToken();
            final UserData monitor = UserData.getOrCreate(
                    mService.getCurrentImeUserIdLocked());
            return new InputBindResult(
                    InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
                    null, null, null, mCurId, monitor.mSequence.getSequenceNumber(), false);
                    null, null, null, mCurId, mCurSeq, false);
        }

        Slog.w(InputMethodManagerService.TAG,
+2 −5
Original line number Diff line number Diff line
@@ -479,8 +479,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private int getSequenceNumberLocked() {
        final UserData monitor = UserData.getOrCreate(mCurrentUserId);
        return monitor.mSequence.getSequenceNumber();
        return mBindingController.getSequenceNumber();
    }

    /**
@@ -489,8 +488,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private void advanceSequenceNumberLocked() {
        final UserData monitor = UserData.getOrCreate(mCurrentUserId);
        monitor.mSequence.advanceSequenceNumber();
        mBindingController.advanceSequenceNumber();
    }

    @GuardedBy("ImfLock.class")
@@ -1379,7 +1377,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked
        InputMethodSettingsRepository.initialize(mHandler, mContext);
        AdditionalSubtypeMapRepository.initialize(mHandler, mContext);
        UserData.initialize(mHandler);

        mCurrentUserId = mActivityManagerInternal.getCurrentUserId();

+0 −45
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.inputmethod;

import com.android.internal.annotations.GuardedBy;

/**
 * A sequence number utility class that only generate positive numbers.
 */
final class Sequence {

    private final Object mLock = new Object();

    private int mSequence;

    int getSequenceNumber() {
        synchronized (mLock) {
            return mSequence;
        }
    }

    @GuardedBy("ImfLock.class")
    void advanceSequenceNumber() {
        synchronized (mLock) {
            mSequence++;
            if (mSequence <= 0) {
                mSequence = 1;
            }
        }
    }
}
+0 −88
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.inputmethod;

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

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

final class UserData {

    @NonNull
    private static final SparseArray<UserData> sPerUserMonitor = new SparseArray<>();

    @UserIdInt
    final int mUserId;

    @GuardedBy("ImfLock.class")
    final Sequence mSequence = new Sequence();

    /**
     * Not intended to be instantiated.
     */
    private UserData(int userId) {
        mUserId = userId;
    }

    @GuardedBy("ImfLock.class")
    static UserData getOrCreate(@UserIdInt int userId) {
        UserData monitor = sPerUserMonitor.get(userId);
        if (monitor == null) {
            monitor = new UserData(userId);
            sPerUserMonitor.put(userId, monitor);
        }
        return monitor;
    }

    static void initialize(Handler handler) {
        final UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        userManagerInternal.addUserLifecycleListener(
                new UserManagerInternal.UserLifecycleListener() {
                    @Override
                    public void onUserRemoved(UserInfo user) {
                        final int userId = user.id;
                        handler.post(() -> {
                            synchronized (ImfLock.class) {
                                sPerUserMonitor.remove(userId);
                            }
                        });
                    }

                    @Override
                    public void onUserCreated(UserInfo user, Object unusedToken) {
                        final int userId = user.id;
                        handler.post(() -> {
                            synchronized (ImfLock.class) {
                                getOrCreate(userId);
                            }
                        });
                    }
                });
        synchronized (ImfLock.class) {
            for (int userId : userManagerInternal.getUserIds()) {
                getOrCreate(userId);
            }
        }
    }
}