diff options
| author | Yohei Yukawa <yukawa@google.com> | 2014-11-01 02:19:02 +0000 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2014-11-01 02:19:02 +0000 |
| commit | f5051e9b6771de3558d2b8adf7ef233721dad1d6 (patch) | |
| tree | b23d80141f6415164db43b1afe36d50f5926dc2d | |
| parent | 28d51a39a1bed35855b0fe75a65ad4a6d43a4460 (diff) | |
| parent | b1f56430d38f9d6bab0a3512905daaf994ba134b (diff) | |
| download | frameworks_base-f5051e9b6771de3558d2b8adf7ef233721dad1d6.zip frameworks_base-f5051e9b6771de3558d2b8adf7ef233721dad1d6.tar.gz frameworks_base-f5051e9b6771de3558d2b8adf7ef233721dad1d6.tar.bz2 | |
am 22cbf54c: Merge "Conditionally allow non-primay profiles to use TextServices" into lmp-mr1-dev
automerge: b1f5643
* commit 'b1f56430d38f9d6bab0a3512905daaf994ba134b':
Conditionally allow non-primay profiles to use TextServices
| -rw-r--r-- | services/core/java/com/android/server/TextServicesManagerService.java | 98 |
1 files changed, 94 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java index d4c436f..5add88e 100644 --- a/services/core/java/com/android/server/TextServicesManagerService.java +++ b/services/core/java/com/android/server/TextServicesManagerService.java @@ -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; @@ -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; @@ -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; @@ -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( @@ -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); @@ -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(); @@ -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) { @@ -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) { @@ -237,10 +273,40 @@ 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( @@ -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) { @@ -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; @@ -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; } |
