Search in sources :

Example 56 with SpellCheckerInfo

use of android.view.textservice.SpellCheckerInfo in project android_frameworks_base by DirtyUnicorns.

the class TextServicesManagerService method getSpellCheckerService.

@Override
public void getSpellCheckerService(String sciId, String locale, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, Bundle bundle) {
    if (!calledFromValidUser()) {
        return;
    }
    if (!mSystemReady) {
        return;
    }
    if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
        Slog.e(TAG, "getSpellCheckerService: Invalid input.");
        return;
    }
    synchronized (mSpellCheckerMap) {
        if (!mSpellCheckerMap.containsKey(sciId)) {
            return;
        }
        final SpellCheckerInfo sci = mSpellCheckerMap.get(sciId);
        final int uid = Binder.getCallingUid();
        if (mSpellCheckerBindGroups.containsKey(sciId)) {
            final SpellCheckerBindGroup bindGroup = mSpellCheckerBindGroups.get(sciId);
            if (bindGroup != null) {
                final InternalDeathRecipient recipient = mSpellCheckerBindGroups.get(sciId).addListener(tsListener, locale, scListener, uid, bundle);
                if (recipient == null) {
                    if (DBG) {
                        Slog.w(TAG, "Didn't create a death recipient.");
                    }
                    return;
                }
                if (bindGroup.mSpellChecker == null & bindGroup.mConnected) {
                    Slog.e(TAG, "The state of the spell checker bind group is illegal.");
                    bindGroup.removeAll();
                } else if (bindGroup.mSpellChecker != null) {
                    if (DBG) {
                        Slog.w(TAG, "Existing bind found. Return a spell checker session now. " + "Listeners count = " + bindGroup.mListeners.size());
                    }
                    try {
                        final ISpellCheckerSession session = bindGroup.mSpellChecker.getISpellCheckerSession(recipient.mScLocale, recipient.mScListener, bundle);
                        if (session != null) {
                            tsListener.onServiceConnected(session);
                            return;
                        } else {
                            if (DBG) {
                                Slog.w(TAG, "Existing bind already expired. ");
                            }
                            bindGroup.removeAll();
                        }
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Exception in getting spell checker session: " + e);
                        bindGroup.removeAll();
                    }
                }
            }
        }
        final long ident = Binder.clearCallingIdentity();
        try {
            startSpellCheckerServiceInnerLocked(sci, locale, tsListener, scListener, uid, bundle);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }
    return;
}
Also used : ISpellCheckerSession(com.android.internal.textservice.ISpellCheckerSession) RemoteException(android.os.RemoteException) SpellCheckerInfo(android.view.textservice.SpellCheckerInfo)

Example 57 with SpellCheckerInfo

use of android.view.textservice.SpellCheckerInfo in project android_frameworks_base by DirtyUnicorns.

the class TextServicesManagerService method getCurrentSpellCheckerSubtype.

// TODO: Respect allowImplicitlySelectedSubtype
// TODO: Save SpellCheckerSubtype by supported languages by looking at "locale".
@Override
public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String locale, boolean allowImplicitlySelectedSubtype) {
    // TODO: Make this work even for non-current users?
    if (!calledFromValidUser()) {
        return null;
    }
    final int subtypeHashCode;
    final SpellCheckerInfo sci;
    final Locale systemLocale;
    synchronized (mSpellCheckerMap) {
        subtypeHashCode = mSettings.getSelectedSpellCheckerSubtype(SpellCheckerSubtype.SUBTYPE_ID_NONE);
        if (DBG) {
            Slog.w(TAG, "getCurrentSpellCheckerSubtype: " + subtypeHashCode);
        }
        sci = getCurrentSpellChecker(null);
        systemLocale = mContext.getResources().getConfiguration().locale;
    }
    if (sci == null || sci.getSubtypeCount() == 0) {
        if (DBG) {
            Slog.w(TAG, "Subtype not found.");
        }
        return null;
    }
    if (subtypeHashCode == SpellCheckerSubtype.SUBTYPE_ID_NONE && !allowImplicitlySelectedSubtype) {
        return null;
    }
    String candidateLocale = null;
    if (subtypeHashCode == 0) {
        // Spell checker language settings == "auto"
        final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
        if (imm != null) {
            final InputMethodSubtype currentInputMethodSubtype = imm.getCurrentInputMethodSubtype();
            if (currentInputMethodSubtype != null) {
                final String localeString = currentInputMethodSubtype.getLocale();
                if (!TextUtils.isEmpty(localeString)) {
                    // 1. Use keyboard locale if available in the spell checker
                    candidateLocale = localeString;
                }
            }
        }
        if (candidateLocale == null) {
            // 2. Use System locale if available in the spell checker
            candidateLocale = systemLocale.toString();
        }
    }
    SpellCheckerSubtype candidate = null;
    for (int i = 0; i < sci.getSubtypeCount(); ++i) {
        final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
        if (subtypeHashCode == 0) {
            final String scsLocale = scs.getLocale();
            if (candidateLocale.equals(scsLocale)) {
                return scs;
            } else if (candidate == null) {
                if (candidateLocale.length() >= 2 && scsLocale.length() >= 2 && candidateLocale.startsWith(scsLocale)) {
                    // Fall back to the applicable language
                    candidate = scs;
                }
            }
        } else if (scs.hashCode() == subtypeHashCode) {
            if (DBG) {
                Slog.w(TAG, "Return subtype " + scs.hashCode() + ", input= " + locale + ", " + scs.getLocale());
            }
            // 3. Use the user specified spell check language
            return scs;
        }
    }
    // spell check languages
    return candidate;
}
Also used : Locale(java.util.Locale) SpellCheckerSubtype(android.view.textservice.SpellCheckerSubtype) InputMethodSubtype(android.view.inputmethod.InputMethodSubtype) InputMethodManager(android.view.inputmethod.InputMethodManager) SpellCheckerInfo(android.view.textservice.SpellCheckerInfo)

Example 58 with SpellCheckerInfo

use of android.view.textservice.SpellCheckerInfo in project android_frameworks_base by DirtyUnicorns.

the class TextServicesManagerService method buildSpellCheckerMapLocked.

private static void buildSpellCheckerMapLocked(Context context, ArrayList<SpellCheckerInfo> list, HashMap<String, SpellCheckerInfo> map, TextServicesSettings settings) {
    list.clear();
    map.clear();
    final PackageManager pm = context.getPackageManager();
    // Note: We do not specify PackageManager.MATCH_ENCRYPTION_* flags here because the default
    // behavior of PackageManager is exactly what we want.  It by default picks up appropriate
    // services depending on the unlock state for the specified user.
    final List<ResolveInfo> services = pm.queryIntentServicesAsUser(new Intent(SpellCheckerService.SERVICE_INTERFACE), PackageManager.GET_META_DATA, settings.getCurrentUserId());
    final int N = services.size();
    for (int i = 0; i < N; ++i) {
        final ResolveInfo ri = services.get(i);
        final ServiceInfo si = ri.serviceInfo;
        final ComponentName compName = new ComponentName(si.packageName, si.name);
        if (!android.Manifest.permission.BIND_TEXT_SERVICE.equals(si.permission)) {
            Slog.w(TAG, "Skipping text service " + compName + ": it does not require the permission " + android.Manifest.permission.BIND_TEXT_SERVICE);
            continue;
        }
        if (DBG)
            Slog.d(TAG, "Add: " + compName);
        try {
            final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri);
            if (sci.getSubtypeCount() <= 0) {
                Slog.w(TAG, "Skipping text service " + compName + ": it does not contain subtypes.");
                continue;
            }
            list.add(sci);
            map.put(sci.getId(), sci);
        } catch (XmlPullParserException e) {
            Slog.w(TAG, "Unable to load the spell checker " + compName, e);
        } catch (IOException e) {
            Slog.w(TAG, "Unable to load the spell checker " + compName, e);
        }
    }
    if (DBG) {
        Slog.d(TAG, "buildSpellCheckerMapLocked: " + list.size() + "," + map.size());
    }
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) ServiceInfo(android.content.pm.ServiceInfo) PackageManager(android.content.pm.PackageManager) Intent(android.content.Intent) ComponentName(android.content.ComponentName) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) IOException(java.io.IOException) SpellCheckerInfo(android.view.textservice.SpellCheckerInfo)

Example 59 with SpellCheckerInfo

use of android.view.textservice.SpellCheckerInfo in project android_frameworks_base by DirtyUnicorns.

the class TextServicesManagerService method calledFromValidUser.

// ---------------------------------------------------------------------------------------
// Check whether or not this is a valid IPC. Assumes an IPC is valid when either
// 1) it comes from the system process
// 2) the calling process' user id is identical to the current user id TSMS thinks.
private boolean calledFromValidUser() {
    final int uid = Binder.getCallingUid();
    final int userId = UserHandle.getUserId(uid);
    if (DBG) {
        Slog.d(TAG, "--- calledFromForegroundUserOrSystemProcess ? " + "calling uid = " + uid + " system uid = " + Process.SYSTEM_UID + " calling userId = " + userId + ", foreground user id = " + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid());
        try {
            final String[] packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid);
            for (int i = 0; i < packageNames.length; ++i) {
                if (DBG) {
                    Slog.d(TAG, "--- process name for " + uid + " = " + packageNames[i]);
                }
            }
        } catch (RemoteException e) {
        }
    }
    if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
        return true;
    }
    // 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;
            }
        }
    }
    // support is implemented.
    if (DBG) {
        Slog.d(TAG, "--- IPC from userId:" + userId + " is being ignored. \n" + getStackTrace());
    }
    return false;
}
Also used : ServiceInfo(android.content.pm.ServiceInfo) RemoteException(android.os.RemoteException) SpellCheckerInfo(android.view.textservice.SpellCheckerInfo)

Example 60 with SpellCheckerInfo

use of android.view.textservice.SpellCheckerInfo in project android_frameworks_base by DirtyUnicorns.

the class TextServicesManagerService method dump.

@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
        pw.println("Permission Denial: can't dump TextServicesManagerService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
        return;
    }
    synchronized (mSpellCheckerMap) {
        pw.println("Current Text Services Manager state:");
        pw.println("  Spell Checkers:");
        int spellCheckerIndex = 0;
        for (final SpellCheckerInfo info : mSpellCheckerMap.values()) {
            pw.println("  Spell Checker #" + spellCheckerIndex);
            info.dump(pw, "    ");
            ++spellCheckerIndex;
        }
        pw.println("");
        pw.println("  Spell Checker Bind Groups:");
        for (final Map.Entry<String, SpellCheckerBindGroup> ent : mSpellCheckerBindGroups.entrySet()) {
            final SpellCheckerBindGroup grp = ent.getValue();
            pw.println("    " + ent.getKey() + " " + grp + ":");
            pw.println("      " + "mInternalConnection=" + grp.mInternalConnection);
            pw.println("      " + "mSpellChecker=" + grp.mSpellChecker);
            pw.println("      " + "mBound=" + grp.mBound + " mConnected=" + grp.mConnected);
            final int N = grp.mListeners.size();
            for (int i = 0; i < N; i++) {
                final InternalDeathRecipient listener = grp.mListeners.get(i);
                pw.println("      " + "Listener #" + i + ":");
                pw.println("        " + "mTsListener=" + listener.mTsListener);
                pw.println("        " + "mScListener=" + listener.mScListener);
                pw.println("        " + "mGroup=" + listener.mGroup);
                pw.println("        " + "mScLocale=" + listener.mScLocale + " mUid=" + listener.mUid);
            }
        }
        pw.println("");
        pw.println("  mSettings:");
        mSettings.dumpLocked(pw, "    ");
    }
}
Also used : Map(java.util.Map) HashMap(java.util.HashMap) SpellCheckerInfo(android.view.textservice.SpellCheckerInfo)

Aggregations

SpellCheckerInfo (android.view.textservice.SpellCheckerInfo)87 SpellCheckerSubtype (android.view.textservice.SpellCheckerSubtype)19 RemoteException (android.os.RemoteException)16 Intent (android.content.Intent)13 ServiceInfo (android.content.pm.ServiceInfo)11 Locale (java.util.Locale)10 DialogInterface (android.content.DialogInterface)7 Test (org.junit.Test)7 AlertDialog (android.app.AlertDialog)6 ComponentName (android.content.ComponentName)6 ApplicationInfo (android.content.pm.ApplicationInfo)6 PackageManager (android.content.pm.PackageManager)6 ResolveInfo (android.content.pm.ResolveInfo)6 InputMethodInfo (android.view.inputmethod.InputMethodInfo)6 InputMethodManager (android.view.inputmethod.InputMethodManager)6 InputMethodSubtype (android.view.inputmethod.InputMethodSubtype)6 ISpellCheckerSession (com.android.internal.textservice.ISpellCheckerSession)6 IOException (java.io.IOException)6 HashMap (java.util.HashMap)6 Map (java.util.Map)6