Loading services/core/java/com/android/server/TextServicesManagerService.java +94 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server; import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.textservice.ISpellCheckerService; import com.android.internal.textservice.ISpellCheckerSession; Loading @@ -28,14 +29,18 @@ import org.xmlpull.v1.XmlPullParserException; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.IUserSwitchObserver; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; Loading @@ -43,6 +48,7 @@ import android.os.IRemoteCallback; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.textservice.SpellCheckerService; import android.text.TextUtils; Loading Loading @@ -84,6 +90,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { public TextServicesManagerService(Context context) { mSystemReady = false; mContext = context; final IntentFilter broadcastFilter = new IntentFilter(); broadcastFilter.addAction(Intent.ACTION_USER_ADDED); broadcastFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiver(new TextServicesBroadcastReceiver(), broadcastFilter); int userId = UserHandle.USER_OWNER; try { ActivityManagerNative.getDefault().registerUserSwitchObserver( Loading Loading @@ -119,6 +131,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { private void switchUserLocked(int userId) { mSettings.setCurrentUserId(userId); updateCurrentProfileIds(); unbindServiceLocked(); buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap, mSettings); SpellCheckerInfo sci = getCurrentSpellChecker(null); Loading @@ -133,6 +146,16 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } void updateCurrentProfileIds() { List<UserInfo> profiles = UserManager.get(mContext).getProfiles(mSettings.getCurrentUserId()); int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null for (int i = 0; i < currentProfileIds.length; i++) { currentProfileIds[i] = profiles.get(i).id; } mSettings.setCurrentProfileIds(currentProfileIds); } private class TextServicesMonitor extends PackageMonitor { private boolean isChangingPackagesOfCurrentUser() { final int userId = getChangingUserId(); Loading Loading @@ -171,6 +194,19 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } class TextServicesBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_USER_ADDED.equals(action) || Intent.ACTION_USER_REMOVED.equals(action)) { updateCurrentProfileIds(); return; } Slog.w(TAG, "Unexpected intent " + intent); } } private static void buildSpellCheckerMapLocked(Context context, ArrayList<SpellCheckerInfo> list, HashMap<String, SpellCheckerInfo> map, TextServicesSettings settings) { Loading Loading @@ -223,7 +259,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.d(TAG, "--- calledFromForegroundUserOrSystemProcess ? " + "calling uid = " + uid + " system uid = " + Process.SYSTEM_UID + " calling userId = " + userId + ", foreground user id = " + mSettings.getCurrentUserId()); + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()); try { final String[] packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid); for (int i = 0; i < packageNames.length; ++i) { Loading @@ -237,12 +273,42 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) { return true; } else { Slog.w(TAG, "--- IPC called from background users. Ignore. \n" + getStackTrace()); return false; } // Permits current profile to use TSFM as long as the current text service is the system's // one. This is a tentative solution and should be replaced with fully functional multiuser // support. // TODO: Implement multiuser support in TSMS. final boolean isCurrentProfile = mSettings.isCurrentProfile(userId); if (DBG) { Slog.d(TAG, "--- userId = "+ userId + " isCurrentProfile = " + isCurrentProfile); } if (mSettings.isCurrentProfile(userId)) { final SpellCheckerInfo spellCheckerInfo = getCurrentSpellCheckerWithoutVerification(); if (spellCheckerInfo != null) { final ServiceInfo serviceInfo = spellCheckerInfo.getServiceInfo(); final boolean isSystemSpellChecker = (serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; if (DBG) { Slog.d(TAG, "--- current spell checker = "+ spellCheckerInfo.getPackageName() + " isSystem = " + isSystemSpellChecker); } if (isSystemSpellChecker) { return true; } } } // Unlike InputMethodManagerService#calledFromValidUser, INTERACT_ACROSS_USERS_FULL isn't // taken into account here. Anyway this method is supposed to be removed once multiuser // support is implemented. if (DBG) { Slog.d(TAG, "--- IPC from userId:" + userId + " is being ignored. \n" + getStackTrace()); } return false; } private boolean bindCurrentSpellCheckerService( Intent service, ServiceConnection conn, int flags) { if (service == null || conn == null) { Loading Loading @@ -292,6 +358,10 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { if (!calledFromValidUser()) { return null; } return getCurrentSpellCheckerWithoutVerification(); } private SpellCheckerInfo getCurrentSpellCheckerWithoutVerification() { synchronized (mSpellCheckerMap) { final String curSpellCheckerId = mSettings.getSelectedSpellChecker(); if (DBG) { Loading Loading @@ -914,6 +984,10 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { private static class TextServicesSettings { private final ContentResolver mResolver; private int mCurrentUserId; @GuardedBy("mLock") private int[] mCurrentProfileIds = new int[0]; private Object mLock = new Object(); public TextServicesSettings(ContentResolver resolver, int userId) { mResolver = resolver; mCurrentUserId = userId; Loading @@ -928,6 +1002,22 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { mCurrentUserId = userId; } public void setCurrentProfileIds(int[] currentProfileIds) { synchronized (mLock) { mCurrentProfileIds = currentProfileIds; } } public boolean isCurrentProfile(int userId) { synchronized (mLock) { if (userId == mCurrentUserId) return true; for (int i = 0; i < mCurrentProfileIds.length; i++) { if (userId == mCurrentProfileIds[i]) return true; } return false; } } public int getCurrentUserId() { return mCurrentUserId; } Loading Loading
services/core/java/com/android/server/TextServicesManagerService.java +94 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server; import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.textservice.ISpellCheckerService; import com.android.internal.textservice.ISpellCheckerSession; Loading @@ -28,14 +29,18 @@ import org.xmlpull.v1.XmlPullParserException; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.IUserSwitchObserver; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; Loading @@ -43,6 +48,7 @@ import android.os.IRemoteCallback; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.textservice.SpellCheckerService; import android.text.TextUtils; Loading Loading @@ -84,6 +90,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { public TextServicesManagerService(Context context) { mSystemReady = false; mContext = context; final IntentFilter broadcastFilter = new IntentFilter(); broadcastFilter.addAction(Intent.ACTION_USER_ADDED); broadcastFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiver(new TextServicesBroadcastReceiver(), broadcastFilter); int userId = UserHandle.USER_OWNER; try { ActivityManagerNative.getDefault().registerUserSwitchObserver( Loading Loading @@ -119,6 +131,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { private void switchUserLocked(int userId) { mSettings.setCurrentUserId(userId); updateCurrentProfileIds(); unbindServiceLocked(); buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap, mSettings); SpellCheckerInfo sci = getCurrentSpellChecker(null); Loading @@ -133,6 +146,16 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } void updateCurrentProfileIds() { List<UserInfo> profiles = UserManager.get(mContext).getProfiles(mSettings.getCurrentUserId()); int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null for (int i = 0; i < currentProfileIds.length; i++) { currentProfileIds[i] = profiles.get(i).id; } mSettings.setCurrentProfileIds(currentProfileIds); } private class TextServicesMonitor extends PackageMonitor { private boolean isChangingPackagesOfCurrentUser() { final int userId = getChangingUserId(); Loading Loading @@ -171,6 +194,19 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } class TextServicesBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_USER_ADDED.equals(action) || Intent.ACTION_USER_REMOVED.equals(action)) { updateCurrentProfileIds(); return; } Slog.w(TAG, "Unexpected intent " + intent); } } private static void buildSpellCheckerMapLocked(Context context, ArrayList<SpellCheckerInfo> list, HashMap<String, SpellCheckerInfo> map, TextServicesSettings settings) { Loading Loading @@ -223,7 +259,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.d(TAG, "--- calledFromForegroundUserOrSystemProcess ? " + "calling uid = " + uid + " system uid = " + Process.SYSTEM_UID + " calling userId = " + userId + ", foreground user id = " + mSettings.getCurrentUserId()); + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()); try { final String[] packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid); for (int i = 0; i < packageNames.length; ++i) { Loading @@ -237,12 +273,42 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) { return true; } else { Slog.w(TAG, "--- IPC called from background users. Ignore. \n" + getStackTrace()); return false; } // Permits current profile to use TSFM as long as the current text service is the system's // one. This is a tentative solution and should be replaced with fully functional multiuser // support. // TODO: Implement multiuser support in TSMS. final boolean isCurrentProfile = mSettings.isCurrentProfile(userId); if (DBG) { Slog.d(TAG, "--- userId = "+ userId + " isCurrentProfile = " + isCurrentProfile); } if (mSettings.isCurrentProfile(userId)) { final SpellCheckerInfo spellCheckerInfo = getCurrentSpellCheckerWithoutVerification(); if (spellCheckerInfo != null) { final ServiceInfo serviceInfo = spellCheckerInfo.getServiceInfo(); final boolean isSystemSpellChecker = (serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; if (DBG) { Slog.d(TAG, "--- current spell checker = "+ spellCheckerInfo.getPackageName() + " isSystem = " + isSystemSpellChecker); } if (isSystemSpellChecker) { return true; } } } // Unlike InputMethodManagerService#calledFromValidUser, INTERACT_ACROSS_USERS_FULL isn't // taken into account here. Anyway this method is supposed to be removed once multiuser // support is implemented. if (DBG) { Slog.d(TAG, "--- IPC from userId:" + userId + " is being ignored. \n" + getStackTrace()); } return false; } private boolean bindCurrentSpellCheckerService( Intent service, ServiceConnection conn, int flags) { if (service == null || conn == null) { Loading Loading @@ -292,6 +358,10 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { if (!calledFromValidUser()) { return null; } return getCurrentSpellCheckerWithoutVerification(); } private SpellCheckerInfo getCurrentSpellCheckerWithoutVerification() { synchronized (mSpellCheckerMap) { final String curSpellCheckerId = mSettings.getSelectedSpellChecker(); if (DBG) { Loading Loading @@ -914,6 +984,10 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { private static class TextServicesSettings { private final ContentResolver mResolver; private int mCurrentUserId; @GuardedBy("mLock") private int[] mCurrentProfileIds = new int[0]; private Object mLock = new Object(); public TextServicesSettings(ContentResolver resolver, int userId) { mResolver = resolver; mCurrentUserId = userId; Loading @@ -928,6 +1002,22 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { mCurrentUserId = userId; } public void setCurrentProfileIds(int[] currentProfileIds) { synchronized (mLock) { mCurrentProfileIds = currentProfileIds; } } public boolean isCurrentProfile(int userId) { synchronized (mLock) { if (userId == mCurrentUserId) return true; for (int i = 0; i < mCurrentProfileIds.length; i++) { if (userId == mCurrentProfileIds[i]) return true; } return false; } } public int getCurrentUserId() { return mCurrentUserId; } Loading