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

Commit 53706a28 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Offload IMMS#mImeDrawsImeNavBarRes initialization

This is a follow up CL to my previous CL [1], which was needed to
propagate an overlayable resource config_imeDrawsImeNavBar value from
profile owner user to other profile users.

With this CL, the first initialization of

  InputMethodManagerService#mImeDrawsImeNavBarRes

will be moved from

  InputMethodManagerService#systemRunning()

to a background thread to minimize its impact on the device boot time.

Other than that, there should be no observable behavior difference.

 [1]: Id3d6a71d8ba1bfa49131350b68aa8d3424eca381
      f93769b1

Bug: 219820813
Fix: 223591305
Test: Manually verified as follows
  1. Build aosp_coral-userdebug then flash it.
  2. adb install -r TestDPC-normalv8001.apk
  3. adb shell am start -n com.afwsamples.testdpc/.SetupManagementLaunchActivity
  4. Set up work-profile
  5. adb shell am start --user 0 -n \
   com.android.documentsui/com.android.documentsui.files.FilesActivity
  6. adb shell dumpsys input_method | grep mNavigation
      -> "mNavigationBarController={mImeDrawsImeNavBar=false, ..."
  7. Enable gesture navigation
  8. adb shell dumpsys input_method | grep mNavigation
      -> "mNavigationBarController={mImeDrawsImeNavBar=true, ..."
  9. adb shell am start --user 10 -n \
   com.android.documentsui/com.android.documentsui.files.FilesActivity
 10. adb shell dumpsys input_method | grep mNavigation
      -> "mNavigationBarController={mImeDrawsImeNavBar=true, ..."
Change-Id: I20f6be5d676b9e61ea3077aeaa2eadc5dbbdcd0c
parent 521df749
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.IInlineSuggestionsResponseCallback;
@@ -178,6 +179,7 @@ import com.android.server.AccessibilityManagerInternal;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
@@ -203,6 +205,7 @@ import java.util.Objects;
import java.util.OptionalInt;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

/**
@@ -339,6 +342,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    private OverlayableSystemBooleanResourceWrapper mImeDrawsImeNavBarRes;
    @GuardedBy("ImfLock.class")
    @Nullable
    Future<?> mImeDrawsImeNavBarResLazyInitFuture;

    static class SessionState {
        final ClientState client;
@@ -1728,7 +1734,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    }

    @GuardedBy("ImfLock.class")
    private void recreateImeDrawsImeNavBarResIfNecessary(@UserIdInt int targetUserId) {
    private void maybeInitImeNavbarConfigLocked(@UserIdInt int targetUserId) {
        // Currently, com.android.internal.R.bool.config_imeDrawsImeNavBar is overlaid only for the
        // profile parent user.
        // TODO(b/221443458): See if we can make OverlayManager be aware of profile groups.
@@ -1772,7 +1778,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
                + " currentUserId=" + mSettings.getCurrentUserId());

        recreateImeDrawsImeNavBarResIfNecessary(newUserId);
        maybeInitImeNavbarConfigLocked(newUserId);

        // ContentObserver should be registered again when the user is changed
        mSettingsObserver.registerContentObserverLocked(newUserId);
@@ -1878,7 +1884,22 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    });
                }

                recreateImeDrawsImeNavBarResIfNecessary(currentUserId);
                // TODO(b/32343335): The entire systemRunning() method needs to be revisited.
                mImeDrawsImeNavBarResLazyInitFuture = SystemServerInitThreadPool.submit(() -> {
                    // Note that the synchronization block below guarantees that the task
                    // can never be completed before the returned Future<?> object is assigned to
                    // the "mImeDrawsImeNavBarResLazyInitFuture" field.
                    synchronized (ImfLock.class) {
                        mImeDrawsImeNavBarResLazyInitFuture = null;
                        if (currentUserId != mSettings.getCurrentUserId()) {
                            // This means that the current user is already switched to other user
                            // before the background task is executed. In this scenario the relevant
                            // field should already be initialized.
                            return;
                        }
                        maybeInitImeNavbarConfigLocked(currentUserId);
                    }
                }, "Lazily initialize IMMS#mImeDrawsImeNavBarRes");

                mMyPackageMonitor.register(mContext, null, UserHandle.ALL, true);
                mSettingsObserver.registerContentObserverLocked(currentUserId);
@@ -2988,6 +3009,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @InputMethodNavButtonFlags
    private int getInputMethodNavButtonFlagsLocked() {
        if (mImeDrawsImeNavBarResLazyInitFuture != null) {
            // TODO(b/225366708): Avoid Future.get(), which is internally used here.
            ConcurrentUtils.waitForFutureNoInterrupt(mImeDrawsImeNavBarResLazyInitFuture,
                    "Waiting for the lazy init of mImeDrawsImeNavBarRes");
        }
        final boolean canImeDrawsImeNavBar =
                mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get();
        final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(