1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.inputmethod; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.UserIdInt; 22 import android.util.Pair; 23 import android.util.SparseArray; 24 import android.view.inputmethod.EditorInfo; 25 import android.view.inputmethod.ImeTracker; 26 import android.view.inputmethod.InputMethodSubtype; 27 import android.window.ImeOnBackInvokedDispatcher; 28 29 import com.android.internal.annotations.GuardedBy; 30 import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; 31 import com.android.internal.inputmethod.IRemoteInputConnection; 32 import com.android.internal.inputmethod.InputMethodSubtypeHandle; 33 34 import java.util.concurrent.CountDownLatch; 35 import java.util.concurrent.atomic.AtomicBoolean; 36 import java.util.concurrent.atomic.AtomicReference; 37 38 /** Placeholder for all IMMS user specific fields */ 39 final class UserData { 40 @UserIdInt 41 final int mUserId; 42 43 /** 44 * Tells whether {@link InputMethodManagerService.Lifecycle#initializeUsersAsync(int[])} is 45 * completed for this user or not. 46 */ 47 @NonNull 48 final CountDownLatch mBackgroundLoadLatch = new CountDownLatch(1); 49 50 /** 51 * Contains non-null {@link RawInputMethodMap}, which represents the latest collections of 52 * {@link android.view.inputmethod.InputMethodInfo} for both direct-boot aware and unaware IMEs 53 * before taking {@link AdditionalSubtypeMap} into account. 54 * 55 * <p>See {@link RawInputMethodMap} for details on when to use this.</p> 56 */ 57 @NonNull 58 final AtomicReference<RawInputMethodMap> mRawInputMethodMap = 59 new AtomicReference<>(RawInputMethodMap.emptyMap()); 60 61 @NonNull 62 final InputMethodBindingController mBindingController; 63 64 @NonNull 65 final InputMethodSubtypeSwitchingController mSwitchingController = 66 new InputMethodSubtypeSwitchingController(); 67 68 @NonNull 69 final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController = 70 new HardwareKeyboardShortcutController(); 71 72 @NonNull 73 final ImeVisibilityStateComputer mVisibilityStateComputer; 74 75 /** 76 * Have we called mCurMethod.bindInput()? 77 */ 78 @GuardedBy("ImfLock.class") 79 boolean mBoundToMethod = false; 80 81 /** 82 * Have we called bindInput() for accessibility services? 83 */ 84 @GuardedBy("ImfLock.class") 85 boolean mBoundToAccessibility; 86 87 @GuardedBy("ImfLock.class") 88 @NonNull 89 ImeBindingState mImeBindingState = ImeBindingState.newEmptyState(); 90 91 @GuardedBy("ImfLock.class") 92 @Nullable 93 ClientState mCurClient = null; 94 95 @GuardedBy("ImfLock.class") 96 boolean mInFullscreenMode; 97 98 /** 99 * The {@link IRemoteInputConnection} last provided by the current client. 100 */ 101 @GuardedBy("ImfLock.class") 102 @Nullable 103 IRemoteInputConnection mCurInputConnection; 104 105 /** 106 * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to 107 * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME. 108 */ 109 @GuardedBy("ImfLock.class") 110 @Nullable 111 ImeOnBackInvokedDispatcher mCurImeDispatcher; 112 113 /** 114 * The {@link IRemoteAccessibilityInputConnection} last provided by the current client. 115 */ 116 @GuardedBy("ImfLock.class") 117 @Nullable 118 IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection; 119 120 /** 121 * The {@link EditorInfo} last provided by the current client. 122 */ 123 @GuardedBy("ImfLock.class") 124 @Nullable 125 EditorInfo mCurEditorInfo; 126 127 /** 128 * The token tracking the current IME show request that is waiting for a connection to an 129 * IME, otherwise {@code null}. 130 */ 131 @GuardedBy("ImfLock.class") 132 @Nullable 133 ImeTracker.Token mCurStatsToken; 134 135 /** 136 * Currently enabled session. 137 */ 138 @GuardedBy("ImfLock.class") 139 @Nullable 140 InputMethodManagerService.SessionState mEnabledSession; 141 142 @GuardedBy("ImfLock.class") 143 @NonNull 144 SparseArray<InputMethodManagerService.AccessibilitySessionState> mEnabledAccessibilitySessions = 145 new SparseArray<>(); 146 147 /** 148 * A per-user cache of {@link InputMethodSettings#getEnabledInputMethodsStr()}. 149 */ 150 @GuardedBy("ImfLock.class") 151 @NonNull 152 String mLastEnabledInputMethodsStr = ""; 153 154 /** 155 * A temporary solution to Bug 356879517, where we need to emulate the previous single-user mode 156 * behavior for KeyboardLayoutManager. 157 * 158 * <p>TODO(b/357663774): Remove this workaround</p> 159 */ 160 @GuardedBy("ImfLock.class") 161 @Nullable 162 Pair<InputMethodSubtypeHandle, InputMethodSubtype> mSubtypeForKeyboardLayoutMapping; 163 164 /** 165 * {@code true} when the IME is responsible for drawing the navigation bar and its buttons. 166 */ 167 @NonNull 168 final AtomicBoolean mImeDrawsNavBar = new AtomicBoolean(); 169 170 171 /** 172 * {@code true} if the user storage is considered to be unlocked. 173 * 174 * @see com.android.server.pm.UserManagerInternal#isUserUnlockingOrUnlocked(int) 175 */ 176 @NonNull 177 final AtomicBoolean mIsUnlockingOrUnlocked = new AtomicBoolean(false); 178 179 /** 180 * Intended to be instantiated only from this file. 181 */ UserData(@serIdInt int userId, @NonNull InputMethodBindingController bindingController, @NonNull ImeVisibilityStateComputer stateComputer)182 UserData(@UserIdInt int userId, 183 @NonNull InputMethodBindingController bindingController, 184 @NonNull ImeVisibilityStateComputer stateComputer) { 185 mUserId = userId; 186 mBindingController = bindingController; 187 mVisibilityStateComputer = stateComputer; 188 } 189 190 @Override toString()191 public String toString() { 192 return "UserData{" + "mUserId=" + mUserId + '}'; 193 } 194 } 195