From 53706a2899887c1a08876d54ae230e1ceff20980 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 18 Mar 2022 09:53:06 -0700 Subject: [PATCH] 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 f93769b1ae390d4dc38bccb01627f5f7189cd075 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 --- .../InputMethodManagerService.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 77dcbd3e92773..d1ee17c73344c 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -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(