Have IMMS report IME UID to AudioService
This is a follow up CL to our previous CL [1], which enabled
AudioService to be notified about the UID of the currently used IME.
Although there is no change in the overall approach, with the help
from InputMethodManagerService AuditoService can be notified new IME
UIDs more quickly especially when IMEs are switching to other ones
(e.g. due to user switching or profile switching).
[1]: I11e17b13513627c88ccb8e4db66c5359e9ee7f7b
ed4e8c3fab
Bug: 147037345
Test: use voice input with Gboard 9.5.0 during a simulated RTT call.
Change-Id: I44e3331a7bad6d36227f7e2d0523dd14d933b6a1
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
package android.media;
|
||||
|
||||
import android.util.IntArray;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,18 @@ public abstract class AudioManagerInternal {
|
||||
|
||||
public abstract void setAccessibilityServiceUids(IntArray uids);
|
||||
|
||||
/**
|
||||
* Called by {@link com.android.server.inputmethod.InputMethodManagerService} to notify the UID
|
||||
* of the currently used {@link android.inputmethodservice.InputMethodService}.
|
||||
*
|
||||
* <p>The caller is expected to take care of any performance implications, e.g. by using a
|
||||
* background thread to call this method.</p>
|
||||
*
|
||||
* @param uid UID of the currently used {@link android.inputmethodservice.InputMethodService}.
|
||||
* {@link android.os.Process#INVALID_UID} if no IME is active.
|
||||
*/
|
||||
public abstract void setInputMethodServiceUid(int uid);
|
||||
|
||||
public interface RingerModeDelegate {
|
||||
/** Called when external ringer mode is evaluated, returns the new internal ringer mode */
|
||||
int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
|
||||
|
||||
@@ -52,7 +52,6 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -570,6 +569,10 @@ public class AudioService extends IAudioService.Stub
|
||||
private int[] mAccessibilityServiceUids;
|
||||
private final Object mAccessibilityServiceUidsLock = new Object();
|
||||
|
||||
// Uid of the active input method service to check if caller is the one or not.
|
||||
private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
|
||||
private final Object mInputMethodServiceUidLock = new Object();
|
||||
|
||||
private int mEncodedSurroundMode;
|
||||
private String mEnabledSurroundFormats;
|
||||
private boolean mSurroundModeChanged;
|
||||
@@ -1078,12 +1081,14 @@ public class AudioService extends IAudioService.Stub
|
||||
sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
|
||||
sendEnabledSurroundFormats(mContentResolver, true);
|
||||
updateAssistantUId(true);
|
||||
updateCurrentImeUid(true);
|
||||
AudioSystem.setRttEnabled(mRttEnabled);
|
||||
}
|
||||
synchronized (mAccessibilityServiceUidsLock) {
|
||||
AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
|
||||
}
|
||||
synchronized (mInputMethodServiceUidLock) {
|
||||
mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
|
||||
}
|
||||
synchronized (mHdmiClientLock) {
|
||||
if (mHdmiManager != null && mHdmiTvClient != null) {
|
||||
setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
|
||||
@@ -1629,37 +1634,6 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mSettingsLock")
|
||||
private void updateCurrentImeUid(boolean forceUpdate) {
|
||||
String imeId = Settings.Secure.getStringForUser(
|
||||
mContentResolver,
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT);
|
||||
if (TextUtils.isEmpty(imeId)) {
|
||||
Log.e(TAG, "updateCurrentImeUid() could not find current IME");
|
||||
return;
|
||||
}
|
||||
ComponentName componentName = ComponentName.unflattenFromString(imeId);
|
||||
if (componentName == null) {
|
||||
Log.e(TAG, "updateCurrentImeUid() got invalid service name for "
|
||||
+ Settings.Secure.DEFAULT_INPUT_METHOD + ": " + imeId);
|
||||
return;
|
||||
}
|
||||
String packageName = componentName.getPackageName();
|
||||
int currentUserId = LocalServices.getService(ActivityManagerInternal.class)
|
||||
.getCurrentUserId();
|
||||
int currentImeUid = LocalServices.getService(PackageManagerInternal.class)
|
||||
.getPackageUidInternal(packageName, 0 /* flags */, currentUserId);
|
||||
if (currentImeUid < 0) {
|
||||
Log.e(TAG, "updateCurrentImeUid() could not find UID for package: " + packageName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentImeUid != mCurrentImeUid || forceUpdate) {
|
||||
mAudioSystem.setCurrentImeUid(currentImeUid);
|
||||
mCurrentImeUid = currentImeUid;
|
||||
}
|
||||
}
|
||||
|
||||
private void readPersistedSettings() {
|
||||
if (!mSystemServer.isPrivileged()) {
|
||||
return;
|
||||
@@ -1707,7 +1681,6 @@ public class AudioService extends IAudioService.Stub
|
||||
sendEncodedSurroundMode(cr, "readPersistedSettings");
|
||||
sendEnabledSurroundFormats(cr, true);
|
||||
updateAssistantUId(true);
|
||||
updateCurrentImeUid(true);
|
||||
AudioSystem.setRttEnabled(mRttEnabled);
|
||||
}
|
||||
|
||||
@@ -6217,8 +6190,6 @@ public class AudioService extends IAudioService.Stub
|
||||
|
||||
mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
|
||||
mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -6242,7 +6213,6 @@ public class AudioService extends IAudioService.Stub
|
||||
updateEncodedSurroundOutput();
|
||||
sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
|
||||
updateAssistantUId(false);
|
||||
updateCurrentImeUid(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7584,6 +7554,19 @@ public class AudioService extends IAudioService.Stub
|
||||
AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setInputMethodServiceUid(int uid) {
|
||||
synchronized (mInputMethodServiceUidLock) {
|
||||
if (mInputMethodServiceUid != uid) {
|
||||
mAudioSystem.setCurrentImeUid(uid);
|
||||
mInputMethodServiceUid = uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================================
|
||||
|
||||
@@ -56,6 +56,7 @@ import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -67,6 +68,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.input.InputManagerInternal;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.media.AudioManagerInternal;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -223,6 +225,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
|
||||
|
||||
static final int MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE = 7000;
|
||||
|
||||
static final long TIME_TO_RECONNECT = 3 * 1000;
|
||||
|
||||
static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20;
|
||||
@@ -308,6 +312,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
final SettingsObserver mSettingsObserver;
|
||||
final IWindowManager mIWindowManager;
|
||||
final WindowManagerInternal mWindowManagerInternal;
|
||||
final PackageManagerInternal mPackageManagerInternal;
|
||||
final InputManagerInternal mInputManagerInternal;
|
||||
private final DisplayManagerInternal mDisplayManagerInternal;
|
||||
final HandlerCaller mCaller;
|
||||
@@ -320,6 +325,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
private final UserManager mUserManager;
|
||||
private final UserManagerInternal mUserManagerInternal;
|
||||
|
||||
/**
|
||||
* Cache the result of {@code LocalServices.getService(AudioManagerInternal.class)}.
|
||||
*
|
||||
* <p>This field is used only within {@link #handleMessage(Message)} hence synchronization is
|
||||
* not necessary.</p>
|
||||
*/
|
||||
@Nullable
|
||||
private AudioManagerInternal mAudioManagerInternal = null;
|
||||
|
||||
|
||||
// All known input methods. mMethodMap also serves as the global
|
||||
// lock for this class.
|
||||
final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
|
||||
@@ -642,6 +657,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
*/
|
||||
IInputMethod mCurMethod;
|
||||
|
||||
/**
|
||||
* If not {@link Process#INVALID_UID}, then the UID of {@link #mCurIntent}.
|
||||
*/
|
||||
int mCurMethodUid = Process.INVALID_UID;
|
||||
|
||||
/**
|
||||
* Time that we last initiated a bind to the input method, to determine
|
||||
* if we should try to disconnect and reconnect to it.
|
||||
@@ -1625,6 +1645,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mIWindowManager = IWindowManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.WINDOW_SERVICE));
|
||||
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
|
||||
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
|
||||
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
|
||||
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
|
||||
mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
|
||||
@@ -2521,11 +2542,26 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private void scheduleNotifyImeUidToAudioService(int uid) {
|
||||
mCaller.removeMessages(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE);
|
||||
mCaller.obtainMessageI(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
synchronized (mMethodMap) {
|
||||
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
|
||||
mCurMethod = IInputMethod.Stub.asInterface(service);
|
||||
final String curMethodPackage = mCurIntent.getComponent().getPackageName();
|
||||
final int curMethodUid = mPackageManagerInternal.getPackageUidInternal(
|
||||
curMethodPackage, 0 /* flags */, mSettings.getCurrentUserId());
|
||||
if (curMethodUid < 0) {
|
||||
Slog.e(TAG, "Failed to get UID for package=" + curMethodPackage);
|
||||
mCurMethodUid = Process.INVALID_UID;
|
||||
} else {
|
||||
mCurMethodUid = curMethodUid;
|
||||
}
|
||||
if (mCurToken == null) {
|
||||
Slog.w(TAG, "Service connected without a token!");
|
||||
unbindCurrentMethodLocked();
|
||||
@@ -2535,6 +2571,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
// Dispatch display id for InputMethodService to update context display.
|
||||
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
|
||||
MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
|
||||
scheduleNotifyImeUidToAudioService(mCurMethodUid);
|
||||
if (mCurClient != null) {
|
||||
clearClientSessionLocked(mCurClient);
|
||||
requestClientSessionLocked(mCurClient);
|
||||
@@ -2656,6 +2693,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
finishSessionLocked(mEnabledSession);
|
||||
mEnabledSession = null;
|
||||
mCurMethod = null;
|
||||
mCurMethodUid = Process.INVALID_UID;
|
||||
scheduleNotifyImeUidToAudioService(mCurMethodUid);
|
||||
}
|
||||
if (mStatusBar != null) {
|
||||
mStatusBar.setIconVisibility(mSlotIme, false);
|
||||
@@ -4277,6 +4316,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
args.recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
case MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE: {
|
||||
if (mAudioManagerInternal == null) {
|
||||
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
|
||||
}
|
||||
if (mAudioManagerInternal != null) {
|
||||
mAudioManagerInternal.setInputMethodServiceUid(msg.arg1 /* uid */);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user