Loading core/java/android/app/SystemServiceRegistry.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -439,10 +439,11 @@ final class SystemServiceRegistry { }}); }}); registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class, registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class, new StaticServiceFetcher<TextServicesManager>() { new CachedServiceFetcher<TextServicesManager>() { @Override @Override public TextServicesManager createService() { public TextServicesManager createService(ContextImpl ctx) return TextServicesManager.getInstance(); throws ServiceNotFoundException { return TextServicesManager.createInstance(ctx); }}); }}); registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, Loading core/java/android/view/textservice/SpellCheckerSession.java +4 −9 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.util.Log; import com.android.internal.textservice.ISpellCheckerSession; import com.android.internal.textservice.ISpellCheckerSession; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; import com.android.internal.textservice.ITextServicesSessionListener; import com.android.internal.textservice.ITextServicesSessionListener; import dalvik.system.CloseGuard; import dalvik.system.CloseGuard; Loading Loading @@ -96,7 +95,7 @@ public class SpellCheckerSession { private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2; private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2; private final InternalListener mInternalListener; private final InternalListener mInternalListener; private final ITextServicesManager mTextServicesManager; private final TextServicesManager mTextServicesManager; private final SpellCheckerInfo mSpellCheckerInfo; private final SpellCheckerInfo mSpellCheckerInfo; @UnsupportedAppUsage @UnsupportedAppUsage private final SpellCheckerSessionListener mSpellCheckerSessionListener; private final SpellCheckerSessionListener mSpellCheckerSessionListener; Loading Loading @@ -124,7 +123,7 @@ public class SpellCheckerSession { * @hide * @hide */ */ public SpellCheckerSession( public SpellCheckerSession( SpellCheckerInfo info, ITextServicesManager tsm, SpellCheckerSessionListener listener) { SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener) { if (info == null || listener == null || tsm == null) { if (info == null || listener == null || tsm == null) { throw new NullPointerException(); throw new NullPointerException(); } } Loading Loading @@ -166,12 +165,8 @@ public class SpellCheckerSession { */ */ public void close() { public void close() { mGuard.close(); mGuard.close(); try { mSpellCheckerSessionListenerImpl.close(); mSpellCheckerSessionListenerImpl.close(); mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl); mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl); } catch (RemoteException e) { // do nothing } } } /** /** Loading core/java/android/view/textservice/TextServicesManager.java +46 −10 Original line number Original line Diff line number Diff line Loading @@ -16,16 +16,20 @@ package android.view.textservice; package android.view.textservice; import android.annotation.NonNull; import android.annotation.SystemService; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.content.Context; import android.content.Context; import android.os.Bundle; import android.os.Bundle; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.ServiceManager.ServiceNotFoundException; import android.os.UserHandle; import android.util.Log; import android.util.Log; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; import com.android.internal.textservice.ITextServicesManager; import java.util.Locale; import java.util.Locale; Loading Loading @@ -67,17 +71,41 @@ public final class TextServicesManager { private static final String TAG = TextServicesManager.class.getSimpleName(); private static final String TAG = TextServicesManager.class.getSimpleName(); private static final boolean DBG = false; private static final boolean DBG = false; /** * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in * {@link #getInstance()}. */ @Deprecated private static TextServicesManager sInstance; private static TextServicesManager sInstance; private final ITextServicesManager mService; private final ITextServicesManager mService; private TextServicesManager() throws ServiceNotFoundException { @UserIdInt private final int mUserId; private TextServicesManager(@UserIdInt int userId) throws ServiceNotFoundException { mService = ITextServicesManager.Stub.asInterface( mService = ITextServicesManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE)); ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE)); mUserId = userId; } } /** /** * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist. * The factory method of {@link TextServicesManager}. * * @param context {@link Context} from which {@link TextServicesManager} should be instantiated. * @return {@link TextServicesManager} that is associated with {@link Context#getUserId()}. * @throws ServiceNotFoundException When {@link TextServicesManager} is not available. * @hide */ @NonNull public static TextServicesManager createInstance(@NonNull Context context) throws ServiceNotFoundException { return new TextServicesManager(context.getUserId()); } /** * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in * {@link #getInstance()}. * @hide * @hide */ */ @UnsupportedAppUsage @UnsupportedAppUsage Loading @@ -85,7 +113,7 @@ public final class TextServicesManager { synchronized (TextServicesManager.class) { synchronized (TextServicesManager.class) { if (sInstance == null) { if (sInstance == null) { try { try { sInstance = new TextServicesManager(); sInstance = new TextServicesManager(UserHandle.myUserId()); } catch (ServiceNotFoundException e) { } catch (ServiceNotFoundException e) { throw new IllegalStateException(e); throw new IllegalStateException(e); } } Loading Loading @@ -136,7 +164,7 @@ public final class TextServicesManager { final SpellCheckerInfo sci; final SpellCheckerInfo sci; try { try { sci = mService.getCurrentSpellChecker(null); sci = mService.getCurrentSpellChecker(mUserId, null); } catch (RemoteException e) { } catch (RemoteException e) { return null; return null; } } Loading Loading @@ -174,9 +202,9 @@ public final class TextServicesManager { if (subtypeInUse == null) { if (subtypeInUse == null) { return null; return null; } } final SpellCheckerSession session = new SpellCheckerSession(sci, mService, listener); final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener); try { try { mService.getSpellCheckerService(sci.getId(), subtypeInUse.getLocale(), mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(), session.getTextServicesSessionListener(), session.getTextServicesSessionListener(), session.getSpellCheckerSessionListener(), bundle); session.getSpellCheckerSessionListener(), bundle); } catch (RemoteException e) { } catch (RemoteException e) { Loading @@ -191,7 +219,7 @@ public final class TextServicesManager { @UnsupportedAppUsage @UnsupportedAppUsage public SpellCheckerInfo[] getEnabledSpellCheckers() { public SpellCheckerInfo[] getEnabledSpellCheckers() { try { try { final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(); final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(mUserId); if (DBG) { if (DBG) { Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null")); Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null")); } } Loading @@ -208,7 +236,7 @@ public final class TextServicesManager { public SpellCheckerInfo getCurrentSpellChecker() { public SpellCheckerInfo getCurrentSpellChecker() { try { try { // Passing null as a locale for ICS // Passing null as a locale for ICS return mService.getCurrentSpellChecker(null); return mService.getCurrentSpellChecker(mUserId, null); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading @@ -221,7 +249,7 @@ public final class TextServicesManager { public SpellCheckerSubtype getCurrentSpellCheckerSubtype( public SpellCheckerSubtype getCurrentSpellCheckerSubtype( boolean allowImplicitlySelectedSubtype) { boolean allowImplicitlySelectedSubtype) { try { try { return mService.getCurrentSpellCheckerSubtype(allowImplicitlySelectedSubtype); return mService.getCurrentSpellCheckerSubtype(mUserId, allowImplicitlySelectedSubtype); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading @@ -233,7 +261,15 @@ public final class TextServicesManager { @UnsupportedAppUsage @UnsupportedAppUsage public boolean isSpellCheckerEnabled() { public boolean isSpellCheckerEnabled() { try { try { return mService.isSpellCheckerEnabled(); return mService.isSpellCheckerEnabled(mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } void finishSpellCheckerService(ISpellCheckerSessionListener listener) { try { mService.finishSpellCheckerService(mUserId, listener); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading core/java/com/android/internal/textservice/ITextServicesManager.aidl +7 −6 Original line number Original line Diff line number Diff line Loading @@ -29,12 +29,13 @@ import android.view.textservice.SpellCheckerSubtype; * @hide * @hide */ */ interface ITextServicesManager { interface ITextServicesManager { SpellCheckerInfo getCurrentSpellChecker(String locale); SpellCheckerInfo getCurrentSpellChecker(int userId, String locale); SpellCheckerSubtype getCurrentSpellCheckerSubtype(boolean allowImplicitlySelectedSubtype); SpellCheckerSubtype getCurrentSpellCheckerSubtype(int userId, oneway void getSpellCheckerService(String sciId, in String locale, boolean allowImplicitlySelectedSubtype); oneway void getSpellCheckerService(int userId, String sciId, in String locale, in ITextServicesSessionListener tsListener, in ITextServicesSessionListener tsListener, in ISpellCheckerSessionListener scListener, in Bundle bundle); in ISpellCheckerSessionListener scListener, in Bundle bundle); oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener); oneway void finishSpellCheckerService(int userId, in ISpellCheckerSessionListener listener); boolean isSpellCheckerEnabled(); boolean isSpellCheckerEnabled(int userId); SpellCheckerInfo[] getEnabledSpellCheckers(); SpellCheckerInfo[] getEnabledSpellCheckers(int userId); } } services/core/java/com/android/server/textservices/TextServicesManagerService.java +27 −14 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.textservices; package com.android.server.textservices; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; Loading Loading @@ -513,8 +515,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { // TODO: Save SpellCheckerService by supported languages. Currently only one spell // TODO: Save SpellCheckerService by supported languages. Currently only one spell // checker is saved. // checker is saved. @Override @Override public SpellCheckerInfo getCurrentSpellChecker(String locale) { public SpellCheckerInfo getCurrentSpellChecker(@UserIdInt int userId, String locale) { int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return null; if (tsd == null) return null; Loading @@ -527,11 +529,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale". // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale". @Override @Override public SpellCheckerSubtype getCurrentSpellCheckerSubtype( public SpellCheckerSubtype getCurrentSpellCheckerSubtype( boolean allowImplicitlySelectedSubtype) { @UserIdInt int userId, boolean allowImplicitlySelectedSubtype) { verifyUser(userId); final int subtypeHashCode; final int subtypeHashCode; final SpellCheckerInfo sci; final SpellCheckerInfo sci; final Locale systemLocale; final Locale systemLocale; final int userId = UserHandle.getCallingUserId(); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading Loading @@ -591,17 +594,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public void getSpellCheckerService(String sciId, String locale, public void getSpellCheckerService(@UserIdInt int userId, String sciId, String locale, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, Bundle bundle) { Bundle bundle) { verifyUser(userId); if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) { if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) { Slog.e(TAG, "getSpellCheckerService: Invalid input."); Slog.e(TAG, "getSpellCheckerService: Invalid input."); return; return; } } int callingUserId = UserHandle.getCallingUserId(); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return; if (tsd == null) return; HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap; HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap; Loading Loading @@ -634,8 +637,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public boolean isSpellCheckerEnabled() { public boolean isSpellCheckerEnabled(@UserIdInt int userId) { int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading Loading @@ -671,11 +674,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public SpellCheckerInfo[] getEnabledSpellCheckers() { public SpellCheckerInfo[] getEnabledSpellCheckers(@UserIdInt int userId) { int callingUserId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return null; if (tsd == null) return null; ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList; ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList; Loading @@ -691,11 +694,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public void finishSpellCheckerService(ISpellCheckerSessionListener listener) { public void finishSpellCheckerService(@UserIdInt int userId, ISpellCheckerSessionListener listener) { if (DBG) { if (DBG) { Slog.d(TAG, "FinishSpellCheckerService"); Slog.d(TAG, "FinishSpellCheckerService"); } } int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading @@ -716,6 +720,15 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } } } private void verifyUser(@UserIdInt int userId) { final int callingUserId = UserHandle.getCallingUserId(); if (userId != callingUserId) { mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, "Cross-user interaction requires INTERACT_ACROSS_USERS_FULL. userId=" + userId + " callingUserId=" + callingUserId); } } private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) { private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) { final String sciId = (sci != null) ? sci.getId() : ""; final String sciId = (sci != null) ? sci.getId() : ""; if (DBG) { if (DBG) { Loading Loading
core/java/android/app/SystemServiceRegistry.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -439,10 +439,11 @@ final class SystemServiceRegistry { }}); }}); registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class, registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class, new StaticServiceFetcher<TextServicesManager>() { new CachedServiceFetcher<TextServicesManager>() { @Override @Override public TextServicesManager createService() { public TextServicesManager createService(ContextImpl ctx) return TextServicesManager.getInstance(); throws ServiceNotFoundException { return TextServicesManager.createInstance(ctx); }}); }}); registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, Loading
core/java/android/view/textservice/SpellCheckerSession.java +4 −9 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.util.Log; import com.android.internal.textservice.ISpellCheckerSession; import com.android.internal.textservice.ISpellCheckerSession; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; import com.android.internal.textservice.ITextServicesSessionListener; import com.android.internal.textservice.ITextServicesSessionListener; import dalvik.system.CloseGuard; import dalvik.system.CloseGuard; Loading Loading @@ -96,7 +95,7 @@ public class SpellCheckerSession { private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2; private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2; private final InternalListener mInternalListener; private final InternalListener mInternalListener; private final ITextServicesManager mTextServicesManager; private final TextServicesManager mTextServicesManager; private final SpellCheckerInfo mSpellCheckerInfo; private final SpellCheckerInfo mSpellCheckerInfo; @UnsupportedAppUsage @UnsupportedAppUsage private final SpellCheckerSessionListener mSpellCheckerSessionListener; private final SpellCheckerSessionListener mSpellCheckerSessionListener; Loading Loading @@ -124,7 +123,7 @@ public class SpellCheckerSession { * @hide * @hide */ */ public SpellCheckerSession( public SpellCheckerSession( SpellCheckerInfo info, ITextServicesManager tsm, SpellCheckerSessionListener listener) { SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener) { if (info == null || listener == null || tsm == null) { if (info == null || listener == null || tsm == null) { throw new NullPointerException(); throw new NullPointerException(); } } Loading Loading @@ -166,12 +165,8 @@ public class SpellCheckerSession { */ */ public void close() { public void close() { mGuard.close(); mGuard.close(); try { mSpellCheckerSessionListenerImpl.close(); mSpellCheckerSessionListenerImpl.close(); mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl); mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl); } catch (RemoteException e) { // do nothing } } } /** /** Loading
core/java/android/view/textservice/TextServicesManager.java +46 −10 Original line number Original line Diff line number Diff line Loading @@ -16,16 +16,20 @@ package android.view.textservice; package android.view.textservice; import android.annotation.NonNull; import android.annotation.SystemService; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.content.Context; import android.content.Context; import android.os.Bundle; import android.os.Bundle; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.ServiceManager.ServiceNotFoundException; import android.os.UserHandle; import android.util.Log; import android.util.Log; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; import com.android.internal.textservice.ITextServicesManager; import java.util.Locale; import java.util.Locale; Loading Loading @@ -67,17 +71,41 @@ public final class TextServicesManager { private static final String TAG = TextServicesManager.class.getSimpleName(); private static final String TAG = TextServicesManager.class.getSimpleName(); private static final boolean DBG = false; private static final boolean DBG = false; /** * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in * {@link #getInstance()}. */ @Deprecated private static TextServicesManager sInstance; private static TextServicesManager sInstance; private final ITextServicesManager mService; private final ITextServicesManager mService; private TextServicesManager() throws ServiceNotFoundException { @UserIdInt private final int mUserId; private TextServicesManager(@UserIdInt int userId) throws ServiceNotFoundException { mService = ITextServicesManager.Stub.asInterface( mService = ITextServicesManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE)); ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE)); mUserId = userId; } } /** /** * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist. * The factory method of {@link TextServicesManager}. * * @param context {@link Context} from which {@link TextServicesManager} should be instantiated. * @return {@link TextServicesManager} that is associated with {@link Context#getUserId()}. * @throws ServiceNotFoundException When {@link TextServicesManager} is not available. * @hide */ @NonNull public static TextServicesManager createInstance(@NonNull Context context) throws ServiceNotFoundException { return new TextServicesManager(context.getUserId()); } /** * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in * {@link #getInstance()}. * @hide * @hide */ */ @UnsupportedAppUsage @UnsupportedAppUsage Loading @@ -85,7 +113,7 @@ public final class TextServicesManager { synchronized (TextServicesManager.class) { synchronized (TextServicesManager.class) { if (sInstance == null) { if (sInstance == null) { try { try { sInstance = new TextServicesManager(); sInstance = new TextServicesManager(UserHandle.myUserId()); } catch (ServiceNotFoundException e) { } catch (ServiceNotFoundException e) { throw new IllegalStateException(e); throw new IllegalStateException(e); } } Loading Loading @@ -136,7 +164,7 @@ public final class TextServicesManager { final SpellCheckerInfo sci; final SpellCheckerInfo sci; try { try { sci = mService.getCurrentSpellChecker(null); sci = mService.getCurrentSpellChecker(mUserId, null); } catch (RemoteException e) { } catch (RemoteException e) { return null; return null; } } Loading Loading @@ -174,9 +202,9 @@ public final class TextServicesManager { if (subtypeInUse == null) { if (subtypeInUse == null) { return null; return null; } } final SpellCheckerSession session = new SpellCheckerSession(sci, mService, listener); final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener); try { try { mService.getSpellCheckerService(sci.getId(), subtypeInUse.getLocale(), mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(), session.getTextServicesSessionListener(), session.getTextServicesSessionListener(), session.getSpellCheckerSessionListener(), bundle); session.getSpellCheckerSessionListener(), bundle); } catch (RemoteException e) { } catch (RemoteException e) { Loading @@ -191,7 +219,7 @@ public final class TextServicesManager { @UnsupportedAppUsage @UnsupportedAppUsage public SpellCheckerInfo[] getEnabledSpellCheckers() { public SpellCheckerInfo[] getEnabledSpellCheckers() { try { try { final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(); final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(mUserId); if (DBG) { if (DBG) { Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null")); Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null")); } } Loading @@ -208,7 +236,7 @@ public final class TextServicesManager { public SpellCheckerInfo getCurrentSpellChecker() { public SpellCheckerInfo getCurrentSpellChecker() { try { try { // Passing null as a locale for ICS // Passing null as a locale for ICS return mService.getCurrentSpellChecker(null); return mService.getCurrentSpellChecker(mUserId, null); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading @@ -221,7 +249,7 @@ public final class TextServicesManager { public SpellCheckerSubtype getCurrentSpellCheckerSubtype( public SpellCheckerSubtype getCurrentSpellCheckerSubtype( boolean allowImplicitlySelectedSubtype) { boolean allowImplicitlySelectedSubtype) { try { try { return mService.getCurrentSpellCheckerSubtype(allowImplicitlySelectedSubtype); return mService.getCurrentSpellCheckerSubtype(mUserId, allowImplicitlySelectedSubtype); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading @@ -233,7 +261,15 @@ public final class TextServicesManager { @UnsupportedAppUsage @UnsupportedAppUsage public boolean isSpellCheckerEnabled() { public boolean isSpellCheckerEnabled() { try { try { return mService.isSpellCheckerEnabled(); return mService.isSpellCheckerEnabled(mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } void finishSpellCheckerService(ISpellCheckerSessionListener listener) { try { mService.finishSpellCheckerService(mUserId, listener); } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } Loading
core/java/com/android/internal/textservice/ITextServicesManager.aidl +7 −6 Original line number Original line Diff line number Diff line Loading @@ -29,12 +29,13 @@ import android.view.textservice.SpellCheckerSubtype; * @hide * @hide */ */ interface ITextServicesManager { interface ITextServicesManager { SpellCheckerInfo getCurrentSpellChecker(String locale); SpellCheckerInfo getCurrentSpellChecker(int userId, String locale); SpellCheckerSubtype getCurrentSpellCheckerSubtype(boolean allowImplicitlySelectedSubtype); SpellCheckerSubtype getCurrentSpellCheckerSubtype(int userId, oneway void getSpellCheckerService(String sciId, in String locale, boolean allowImplicitlySelectedSubtype); oneway void getSpellCheckerService(int userId, String sciId, in String locale, in ITextServicesSessionListener tsListener, in ITextServicesSessionListener tsListener, in ISpellCheckerSessionListener scListener, in Bundle bundle); in ISpellCheckerSessionListener scListener, in Bundle bundle); oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener); oneway void finishSpellCheckerService(int userId, in ISpellCheckerSessionListener listener); boolean isSpellCheckerEnabled(); boolean isSpellCheckerEnabled(int userId); SpellCheckerInfo[] getEnabledSpellCheckers(); SpellCheckerInfo[] getEnabledSpellCheckers(int userId); } }
services/core/java/com/android/server/textservices/TextServicesManagerService.java +27 −14 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.textservices; package com.android.server.textservices; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; Loading Loading @@ -513,8 +515,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { // TODO: Save SpellCheckerService by supported languages. Currently only one spell // TODO: Save SpellCheckerService by supported languages. Currently only one spell // checker is saved. // checker is saved. @Override @Override public SpellCheckerInfo getCurrentSpellChecker(String locale) { public SpellCheckerInfo getCurrentSpellChecker(@UserIdInt int userId, String locale) { int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return null; if (tsd == null) return null; Loading @@ -527,11 +529,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale". // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale". @Override @Override public SpellCheckerSubtype getCurrentSpellCheckerSubtype( public SpellCheckerSubtype getCurrentSpellCheckerSubtype( boolean allowImplicitlySelectedSubtype) { @UserIdInt int userId, boolean allowImplicitlySelectedSubtype) { verifyUser(userId); final int subtypeHashCode; final int subtypeHashCode; final SpellCheckerInfo sci; final SpellCheckerInfo sci; final Locale systemLocale; final Locale systemLocale; final int userId = UserHandle.getCallingUserId(); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading Loading @@ -591,17 +594,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public void getSpellCheckerService(String sciId, String locale, public void getSpellCheckerService(@UserIdInt int userId, String sciId, String locale, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, Bundle bundle) { Bundle bundle) { verifyUser(userId); if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) { if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) { Slog.e(TAG, "getSpellCheckerService: Invalid input."); Slog.e(TAG, "getSpellCheckerService: Invalid input."); return; return; } } int callingUserId = UserHandle.getCallingUserId(); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return; if (tsd == null) return; HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap; HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap; Loading Loading @@ -634,8 +637,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public boolean isSpellCheckerEnabled() { public boolean isSpellCheckerEnabled(@UserIdInt int userId) { int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading Loading @@ -671,11 +674,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public SpellCheckerInfo[] getEnabledSpellCheckers() { public SpellCheckerInfo[] getEnabledSpellCheckers(@UserIdInt int userId) { int callingUserId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); if (tsd == null) return null; if (tsd == null) return null; ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList; ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList; Loading @@ -691,11 +694,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } @Override @Override public void finishSpellCheckerService(ISpellCheckerSessionListener listener) { public void finishSpellCheckerService(@UserIdInt int userId, ISpellCheckerSessionListener listener) { if (DBG) { if (DBG) { Slog.d(TAG, "FinishSpellCheckerService"); Slog.d(TAG, "FinishSpellCheckerService"); } } int userId = UserHandle.getCallingUserId(); verifyUser(userId); synchronized (mLock) { synchronized (mLock) { final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); final TextServicesData tsd = getDataFromCallingUserIdLocked(userId); Loading @@ -716,6 +720,15 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } } } private void verifyUser(@UserIdInt int userId) { final int callingUserId = UserHandle.getCallingUserId(); if (userId != callingUserId) { mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, "Cross-user interaction requires INTERACT_ACROSS_USERS_FULL. userId=" + userId + " callingUserId=" + callingUserId); } } private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) { private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) { final String sciId = (sci != null) ? sci.getId() : ""; final String sciId = (sci != null) ? sci.getId() : ""; if (DBG) { if (DBG) { Loading