summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/InputMethodManagerService.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /services/java/com/android/server/InputMethodManagerService.java
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
auto import from //depot/cupcake/@135843
Diffstat (limited to 'services/java/com/android/server/InputMethodManagerService.java')
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java1564
1 files changed, 0 insertions, 1564 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
deleted file mode 100644
index 4b458284a392..000000000000
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ /dev/null
@@ -1,1564 +0,0 @@
-/*
- * Copyright (C) 2006-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.server;
-
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethod;
-import com.android.internal.view.IInputMethodCallback;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.IInputMethodSession;
-import com.android.internal.view.InputBindResult;
-
-import com.android.server.status.IconData;
-import com.android.server.status.StatusBarService;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.IntentFilter;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.PrintWriterPrinter;
-import android.util.Printer;
-import android.view.IWindowManager;
-import android.view.WindowManager;
-import android.view.inputmethod.InputBinding;
-import android.view.inputmethod.InputMethod;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.EditorInfo;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This class provides a system service that manages input methods.
- */
-public class InputMethodManagerService extends IInputMethodManager.Stub
- implements ServiceConnection, Handler.Callback {
- static final boolean DEBUG = false;
- static final String TAG = "InputManagerService";
-
- static final int MSG_SHOW_IM_PICKER = 1;
-
- static final int MSG_UNBIND_INPUT = 1000;
- static final int MSG_BIND_INPUT = 1010;
- static final int MSG_SHOW_SOFT_INPUT = 1020;
- static final int MSG_HIDE_SOFT_INPUT = 1030;
- static final int MSG_ATTACH_TOKEN = 1040;
- static final int MSG_CREATE_SESSION = 1050;
-
- static final int MSG_START_INPUT = 2000;
- static final int MSG_RESTART_INPUT = 2010;
-
- static final int MSG_UNBIND_METHOD = 3000;
- static final int MSG_BIND_METHOD = 3010;
-
- static final long TIME_TO_RECONNECT = 10*1000;
-
- static final int LOG_IMF_FORCE_RECONNECT_IME = 32000;
-
- final Context mContext;
- final Handler mHandler;
- final SettingsObserver mSettingsObserver;
- final StatusBarService mStatusBar;
- final IBinder mInputMethodIcon;
- final IconData mInputMethodData;
- final IWindowManager mIWindowManager;
- final HandlerCaller mCaller;
-
- final InputBindResult mNoBinding = new InputBindResult(null, null, -1);
-
- // All known input methods. mMethodMap also serves as the global
- // lock for this class.
- final ArrayList<InputMethodInfo> mMethodList
- = new ArrayList<InputMethodInfo>();
- final HashMap<String, InputMethodInfo> mMethodMap
- = new HashMap<String, InputMethodInfo>();
-
- final TextUtils.SimpleStringSplitter mStringColonSplitter
- = new TextUtils.SimpleStringSplitter(':');
-
- class SessionState {
- final ClientState client;
- final IInputMethod method;
- final IInputMethodSession session;
-
- @Override
- public String toString() {
- return "SessionState{uid " + client.uid + " pid " + client.pid
- + " method " + Integer.toHexString(
- System.identityHashCode(method))
- + " session " + Integer.toHexString(
- System.identityHashCode(session))
- + "}";
- }
-
- SessionState(ClientState _client, IInputMethod _method,
- IInputMethodSession _session) {
- client = _client;
- method = _method;
- session = _session;
- }
- }
-
- class ClientState {
- final IInputMethodClient client;
- final IInputContext inputContext;
- final int uid;
- final int pid;
- final InputBinding binding;
-
- boolean sessionRequested;
- SessionState curSession;
-
- @Override
- public String toString() {
- return "ClientState{" + Integer.toHexString(
- System.identityHashCode(this)) + " uid " + uid
- + " pid " + pid + "}";
- }
-
- ClientState(IInputMethodClient _client, IInputContext _inputContext,
- int _uid, int _pid) {
- client = _client;
- inputContext = _inputContext;
- uid = _uid;
- pid = _pid;
- binding = new InputBinding(null, inputContext.asBinder(), uid, pid);
- }
- }
-
- final HashMap<IBinder, ClientState> mClients
- = new HashMap<IBinder, ClientState>();
-
- /**
- * Id of the currently selected input method.
- */
- String mCurMethodId;
-
- /**
- * The current binding sequence number, incremented every time there is
- * a new bind performed.
- */
- int mCurSeq;
-
- /**
- * The client that is currently bound to an input method.
- */
- ClientState mCurClient;
-
- /**
- * The input context last provided by the current client.
- */
- IInputContext mCurInputContext;
-
- /**
- * The attributes last provided by the current client.
- */
- EditorInfo mCurAttribute;
-
- /**
- * The input method ID of the input method service that we are currently
- * connected to or in the process of connecting to.
- */
- String mCurId;
-
- /**
- * Set to true if our ServiceConnection is currently actively bound to
- * a service (whether or not we have gotten its IBinder back yet).
- */
- boolean mHaveConnection;
-
- /**
- * Set if the client has asked for the input method to be shown.
- */
- boolean mShowRequested;
-
- /**
- * Set if we were explicitly told to show the input method.
- */
- boolean mShowExplicitlyRequested;
-
- /**
- * Set if we were forced to be shown.
- */
- boolean mShowForced;
-
- /**
- * Set if we last told the input method to show itself.
- */
- boolean mInputShown;
-
- /**
- * The Intent used to connect to the current input method.
- */
- Intent mCurIntent;
-
- /**
- * The token we have made for the currently active input method, to
- * identify it in the future.
- */
- IBinder mCurToken;
-
- /**
- * If non-null, this is the input method service we are currently connected
- * to.
- */
- IInputMethod mCurMethod;
-
- /**
- * Time that we last initiated a bind to the input method, to determine
- * if we should try to disconnect and reconnect to it.
- */
- long mLastBindTime;
-
- /**
- * Have we called mCurMethod.bindInput()?
- */
- boolean mBoundToMethod;
-
- /**
- * Currently enabled session. Only touched by service thread, not
- * protected by a lock.
- */
- SessionState mEnabledSession;
-
- /**
- * True if the screen is on. The value is true initially.
- */
- boolean mScreenOn = true;
-
- AlertDialog.Builder mDialogBuilder;
- AlertDialog mSwitchingDialog;
- InputMethodInfo[] mIms;
- CharSequence[] mItems;
-
- class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
- super(handler);
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
- }
-
- @Override public void onChange(boolean selfChange) {
- synchronized (mMethodMap) {
- updateFromSettingsLocked();
- }
- }
- }
-
- class ScreenOnOffReceiver extends android.content.BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
- mScreenOn = true;
- } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
- mScreenOn = false;
- } else {
- Log.w(TAG, "Unexpected intent " + intent);
- }
-
- // Inform the current client of the change in active status
- try {
- if (mCurClient != null && mCurClient.client != null) {
- mCurClient.client.setActive(mScreenOn);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Got RemoteException sending 'screen on/off' notification to pid "
- + mCurClient.pid + " uid " + mCurClient.uid);
- }
- }
- }
-
- class PackageReceiver extends android.content.BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (mMethodMap) {
- buildInputMethodListLocked(mMethodList, mMethodMap);
-
- InputMethodInfo curIm = null;
- String curInputMethodId = Settings.Secure.getString(context
- .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- final int N = mMethodList.size();
- if (curInputMethodId != null) {
- for (int i=0; i<N; i++) {
- if (mMethodList.get(i).getId().equals(curInputMethodId)) {
- curIm = mMethodList.get(i);
- }
- }
- }
-
- boolean changed = false;
-
- Uri uri = intent.getData();
- String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
- if (curIm != null && curIm.getPackageName().equals(pkg)) {
- ServiceInfo si = null;
- try {
- si = mContext.getPackageManager().getServiceInfo(
- curIm.getComponent(), 0);
- } catch (PackageManager.NameNotFoundException ex) {
- }
- if (si == null) {
- // Uh oh, current input method is no longer around!
- // Pick another one...
- Log.i(TAG, "Current input method removed: " + curInputMethodId);
- List<InputMethodInfo> enabled = getEnabledInputMethodListLocked();
- if (enabled != null && enabled.size() > 0) {
- changed = true;
- curIm = enabled.get(0);
- curInputMethodId = curIm.getId();
- Log.i(TAG, "Switching to: " + curInputMethodId);
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- curInputMethodId);
- } else if (curIm != null) {
- changed = true;
- curIm = null;
- curInputMethodId = "";
- Log.i(TAG, "Unsetting current input method");
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- curInputMethodId);
- }
- }
-
- } else if (curIm == null) {
- // We currently don't have a default input method... is
- // one now available?
- List<InputMethodInfo> enabled = getEnabledInputMethodListLocked();
- if (enabled != null && enabled.size() > 0) {
- changed = true;
- curIm = enabled.get(0);
- curInputMethodId = curIm.getId();
- Log.i(TAG, "New default input method: " + curInputMethodId);
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- curInputMethodId);
- }
- }
-
- if (changed) {
- updateFromSettingsLocked();
- }
- }
- }
- }
-
- class MethodCallback extends IInputMethodCallback.Stub {
- final IInputMethod mMethod;
-
- MethodCallback(IInputMethod method) {
- mMethod = method;
- }
-
- public void finishedEvent(int seq, boolean handled) throws RemoteException {
- }
-
- public void sessionCreated(IInputMethodSession session) throws RemoteException {
- onSessionCreated(mMethod, session);
- }
- }
-
- public InputMethodManagerService(Context context, StatusBarService statusBar) {
- mContext = context;
- mHandler = new Handler(this);
- mIWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
- mCaller = new HandlerCaller(context, new HandlerCaller.Callback() {
- public void executeMessage(Message msg) {
- handleMessage(msg);
- }
- });
-
- IntentFilter packageFilt = new IntentFilter();
- packageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
- packageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
- packageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
- packageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- packageFilt.addDataScheme("package");
- mContext.registerReceiver(new PackageReceiver(), packageFilt);
-
- IntentFilter screenOnOffFilt = new IntentFilter();
- screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON);
- screenOnOffFilt.addAction(Intent.ACTION_SCREEN_OFF);
- mContext.registerReceiver(new ScreenOnOffReceiver(), screenOnOffFilt);
-
- buildInputMethodListLocked(mMethodList, mMethodMap);
-
- final String enabledStr = Settings.Secure.getString(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS);
- Log.i(TAG, "Enabled input methods: " + enabledStr);
- if (enabledStr == null) {
- Log.i(TAG, "Enabled input methods has not been set, enabling all");
- InputMethodInfo defIm = null;
- StringBuilder sb = new StringBuilder(256);
- final int N = mMethodList.size();
- for (int i=0; i<N; i++) {
- InputMethodInfo imi = mMethodList.get(i);
- Log.i(TAG, "Adding: " + imi.getId());
- if (i > 0) sb.append(':');
- sb.append(imi.getId());
- if (defIm == null && imi.getIsDefaultResourceId() != 0) {
- try {
- Resources res = mContext.createPackageContext(
- imi.getPackageName(), 0).getResources();
- if (res.getBoolean(imi.getIsDefaultResourceId())) {
- defIm = imi;
- Log.i(TAG, "Selected default: " + imi.getId());
- }
- } catch (PackageManager.NameNotFoundException ex) {
- } catch (Resources.NotFoundException ex) {
- }
- }
- }
- if (defIm == null && N > 0) {
- defIm = mMethodList.get(0);
- Log.i(TAG, "No default found, using " + defIm.getId());
- }
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, sb.toString());
- if (defIm != null) {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId());
- }
- }
-
- mStatusBar = statusBar;
- mInputMethodData = IconData.makeIcon("ime", null, 0, 0, 0);
- mInputMethodIcon = statusBar.addIcon(mInputMethodData, null);
- statusBar.setIconVisibility(mInputMethodIcon, false);
-
- mSettingsObserver = new SettingsObserver(mHandler);
- updateFromSettingsLocked();
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- return super.onTransact(code, data, reply, flags);
- } catch (RuntimeException e) {
- // The input method manager only throws security exceptions, so let's
- // log all others.
- if (!(e instanceof SecurityException)) {
- Log.e(TAG, "Input Method Manager Crash", e);
- }
- throw e;
- }
- }
-
- public void systemReady() {
- }
-
- public List<InputMethodInfo> getInputMethodList() {
- synchronized (mMethodMap) {
- return new ArrayList<InputMethodInfo>(mMethodList);
- }
- }
-
- public List<InputMethodInfo> getEnabledInputMethodList() {
- synchronized (mMethodMap) {
- return getEnabledInputMethodListLocked();
- }
- }
-
- List<InputMethodInfo> getEnabledInputMethodListLocked() {
- final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>();
-
- final String enabledStr = Settings.Secure.getString(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS);
- if (enabledStr != null) {
- final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(enabledStr);
-
- while (splitter.hasNext()) {
- InputMethodInfo info = mMethodMap.get(splitter.next());
- if (info != null) {
- res.add(info);
- }
- }
- }
-
- return res;
- }
-
- public void addClient(IInputMethodClient client,
- IInputContext inputContext, int uid, int pid) {
- synchronized (mMethodMap) {
- mClients.put(client.asBinder(), new ClientState(client,
- inputContext, uid, pid));
- }
- }
-
- public void removeClient(IInputMethodClient client) {
- synchronized (mMethodMap) {
- mClients.remove(client.asBinder());
- }
- }
-
- void executeOrSendMessage(IInterface target, Message msg) {
- if (target.asBinder() instanceof Binder) {
- mCaller.sendMessage(msg);
- } else {
- handleMessage(msg);
- msg.recycle();
- }
- }
-
- void unbindCurrentInputLocked() {
- if (mCurClient != null) {
- if (DEBUG) Log.v(TAG, "unbindCurrentInputLocked: client = "
- + mCurClient.client.asBinder());
- if (mBoundToMethod) {
- mBoundToMethod = false;
- if (mCurMethod != null) {
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
- MSG_UNBIND_INPUT, mCurMethod));
- }
- }
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
- mCurClient.sessionRequested = false;
-
- // Call setActive(false) on the old client
- try {
- mCurClient.client.setActive(false);
- } catch (RemoteException e) {
- Log.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
- + mCurClient.pid + " uid " + mCurClient.uid);
- }
- mCurClient = null;
- }
- }
-
- private int getImeShowFlags() {
- int flags = 0;
- if (mShowForced) {
- flags |= InputMethod.SHOW_FORCED
- | InputMethod.SHOW_EXPLICIT;
- } else if (mShowExplicitlyRequested) {
- flags |= InputMethod.SHOW_EXPLICIT;
- }
- return flags;
- }
-
- private int getAppShowFlags() {
- int flags = 0;
- if (mShowForced) {
- flags |= InputMethodManager.SHOW_FORCED;
- } else if (!mShowExplicitlyRequested) {
- flags |= InputMethodManager.SHOW_IMPLICIT;
- }
- return flags;
- }
-
- InputBindResult attachNewInputLocked(boolean initial, boolean needResult) {
- if (!mBoundToMethod) {
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
- MSG_BIND_INPUT, mCurMethod, mCurClient.binding));
- mBoundToMethod = true;
- }
- final SessionState session = mCurClient.curSession;
- if (initial) {
- executeOrSendMessage(session.method, mCaller.obtainMessageOOO(
- MSG_START_INPUT, session, mCurInputContext, mCurAttribute));
- } else {
- executeOrSendMessage(session.method, mCaller.obtainMessageOOO(
- MSG_RESTART_INPUT, session, mCurInputContext, mCurAttribute));
- }
- if (mShowRequested) {
- if (DEBUG) Log.v(TAG, "Attach new input asks to show input");
- showCurrentInputLocked(getAppShowFlags());
- }
- return needResult
- ? new InputBindResult(session.session, mCurId, mCurSeq)
- : null;
- }
-
- InputBindResult startInputLocked(IInputMethodClient client,
- IInputContext inputContext, EditorInfo attribute,
- boolean initial, boolean needResult) {
- // If no method is currently selected, do nothing.
- if (mCurMethodId == null) {
- return mNoBinding;
- }
-
- ClientState cs = mClients.get(client.asBinder());
- if (cs == null) {
- throw new IllegalArgumentException("unknown client "
- + client.asBinder());
- }
-
- try {
- if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
- // Check with the window manager to make sure this client actually
- // has a window with focus. If not, reject. This is thread safe
- // because if the focus changes some time before or after, the
- // next client receiving focus that has any interest in input will
- // be calling through here after that change happens.
- Log.w(TAG, "Starting input on non-focused client " + cs.client
- + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
- return null;
- }
- } catch (RemoteException e) {
- }
-
- if (mCurClient != cs) {
- // If the client is changing, we need to switch over to the new
- // one.
- unbindCurrentInputLocked();
- if (DEBUG) Log.v(TAG, "switching to client: client = "
- + cs.client.asBinder());
-
- // If the screen is on, inform the new client it is active
- if (mScreenOn) {
- try {
- cs.client.setActive(mScreenOn);
- } catch (RemoteException e) {
- Log.w(TAG, "Got RemoteException sending setActive notification to pid "
- + cs.pid + " uid " + cs.uid);
- }
- }
- }
-
- // Bump up the sequence for this client and attach it.
- mCurSeq++;
- if (mCurSeq <= 0) mCurSeq = 1;
- mCurClient = cs;
- mCurInputContext = inputContext;
- mCurAttribute = attribute;
-
- // Check if the input method is changing.
- if (mCurId != null && mCurId.equals(mCurMethodId)) {
- if (cs.curSession != null) {
- // Fast case: if we are already connected to the input method,
- // then just return it.
- return attachNewInputLocked(initial, needResult);
- }
- if (mHaveConnection) {
- if (mCurMethod != null) {
- if (!cs.sessionRequested) {
- cs.sessionRequested = true;
- if (DEBUG) Log.v(TAG, "Creating new session for client " + cs);
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
- MSG_CREATE_SESSION, mCurMethod,
- new MethodCallback(mCurMethod)));
- }
- // Return to client, and we will get back with it when
- // we have had a session made for it.
- return new InputBindResult(null, mCurId, mCurSeq);
- } else if (SystemClock.uptimeMillis()
- < (mLastBindTime+TIME_TO_RECONNECT)) {
- // In this case we have connected to the service, but
- // don't yet have its interface. If it hasn't been too
- // long since we did the connection, we'll return to
- // the client and wait to get the service interface so
- // we can report back. If it has been too long, we want
- // to fall through so we can try a disconnect/reconnect
- // to see if we can get back in touch with the service.
- return new InputBindResult(null, mCurId, mCurSeq);
- } else {
- EventLog.writeEvent(LOG_IMF_FORCE_RECONNECT_IME, mCurMethodId,
- SystemClock.uptimeMillis()-mLastBindTime, 0);
- }
- }
- }
-
- InputMethodInfo info = mMethodMap.get(mCurMethodId);
- if (info == null) {
- throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
- }
-
- if (mHaveConnection) {
- mContext.unbindService(this);
- mHaveConnection = false;
- }
-
- if (mCurToken != null) {
- try {
- if (DEBUG) Log.v(TAG, "Removing window token: " + mCurToken);
- mIWindowManager.removeWindowToken(mCurToken);
- } catch (RemoteException e) {
- }
- mCurToken = null;
- }
-
- clearCurMethod();
-
- mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
- mCurIntent.setComponent(info.getComponent());
- if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE)) {
- mLastBindTime = SystemClock.uptimeMillis();
- mHaveConnection = true;
- mCurId = info.getId();
- mCurToken = new Binder();
- try {
- if (DEBUG) Log.v(TAG, "Adding window token: " + mCurToken);
- mIWindowManager.addWindowToken(mCurToken,
- WindowManager.LayoutParams.TYPE_INPUT_METHOD);
- } catch (RemoteException e) {
- }
- return new InputBindResult(null, mCurId, mCurSeq);
- } else {
- mCurIntent = null;
- Log.w(TAG, "Failure connecting to input method service: "
- + mCurIntent);
- }
- return null;
- }
-
- public InputBindResult startInput(IInputMethodClient client,
- IInputContext inputContext, EditorInfo attribute,
- boolean initial, boolean needResult) {
- synchronized (mMethodMap) {
- final long ident = Binder.clearCallingIdentity();
- try {
- return startInputLocked(client, inputContext, attribute,
- initial, needResult);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void finishInput(IInputMethodClient client) {
- }
-
- public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized (mMethodMap) {
- if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
- mCurMethod = IInputMethod.Stub.asInterface(service);
- if (mCurClient != null) {
- if (DEBUG) Log.v(TAG, "Initiating attach with token: " + mCurToken);
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
- MSG_ATTACH_TOKEN, mCurMethod, mCurToken));
- if (mCurClient != null) {
- if (DEBUG) Log.v(TAG, "Creating first session while with client "
- + mCurClient);
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
- MSG_CREATE_SESSION, mCurMethod,
- new MethodCallback(mCurMethod)));
- }
- }
- }
- }
- }
-
- void onSessionCreated(IInputMethod method, IInputMethodSession session) {
- synchronized (mMethodMap) {
- if (mCurMethod != null && method != null
- && mCurMethod.asBinder() == method.asBinder()) {
- if (mCurClient != null) {
- mCurClient.curSession = new SessionState(mCurClient,
- method, session);
- mCurClient.sessionRequested = false;
- InputBindResult res = attachNewInputLocked(true, true);
- if (res.method != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
- MSG_BIND_METHOD, mCurClient.client, res));
- }
- }
- }
- }
- }
-
- void clearCurMethod() {
- if (mCurMethod != null) {
- for (ClientState cs : mClients.values()) {
- cs.sessionRequested = false;
- cs.curSession = null;
- }
- mCurMethod = null;
- }
- mStatusBar.setIconVisibility(mInputMethodIcon, false);
- }
-
- public void onServiceDisconnected(ComponentName name) {
- synchronized (mMethodMap) {
- if (DEBUG) Log.v(TAG, "Service disconnected: " + name
- + " mCurIntent=" + mCurIntent);
- if (mCurMethod != null && mCurIntent != null
- && name.equals(mCurIntent.getComponent())) {
- clearCurMethod();
- // We consider this to be a new bind attempt, since the system
- // should now try to restart the service for us.
- mLastBindTime = SystemClock.uptimeMillis();
- mShowRequested = mInputShown;
- mInputShown = false;
- if (mCurClient != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
- }
- }
- }
- }
-
- public void updateStatusIcon(IBinder token, String packageName, int iconId) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (token == null || mCurToken != token) {
- Log.w(TAG, "Ignoring setInputMethod of token: " + token);
- return;
- }
-
- synchronized (mMethodMap) {
- if (iconId == 0) {
- if (DEBUG) Log.d(TAG, "hide the small icon for the input method");
- mStatusBar.setIconVisibility(mInputMethodIcon, false);
- } else if (packageName != null) {
- if (DEBUG) Log.d(TAG, "show a small icon for the input method");
- mInputMethodData.iconId = iconId;
- mInputMethodData.iconPackage = packageName;
- mStatusBar.updateIcon(mInputMethodIcon, mInputMethodData, null);
- mStatusBar.setIconVisibility(mInputMethodIcon, true);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- void updateFromSettingsLocked() {
- String id = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
- if (id != null) {
- try {
- setInputMethodLocked(id);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Unknown input method from prefs: " + id, e);
- }
- }
- }
-
- void setInputMethodLocked(String id) {
- InputMethodInfo info = mMethodMap.get(id);
- if (info == null) {
- throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
- }
-
- if (id.equals(mCurMethodId)) {
- return;
- }
-
- final long ident = Binder.clearCallingIdentity();
- try {
- mCurMethodId = id;
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD, id);
-
- if (ActivityManagerNative.isSystemReady()) {
- Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
- intent.putExtra("input_method_id", id);
- mContext.sendBroadcast(intent);
- }
- unbindCurrentInputLocked();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- public void showSoftInput(IInputMethodClient client, int flags) {
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mMethodMap) {
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- try {
- // We need to check if this is the current client with
- // focus in the window manager, to allow this call to
- // be made before input is started in it.
- if (!mIWindowManager.inputMethodClientHasFocus(client)) {
- Log.w(TAG, "Ignoring showSoftInput of: " + client);
- return;
- }
- } catch (RemoteException e) {
- }
- }
-
- if (DEBUG) Log.v(TAG, "Client requesting input be shown");
- showCurrentInputLocked(flags);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- void showCurrentInputLocked(int flags) {
- mShowRequested = true;
- if ((flags&InputMethodManager.SHOW_IMPLICIT) == 0) {
- mShowExplicitlyRequested = true;
- }
- if ((flags&InputMethodManager.SHOW_FORCED) != 0) {
- mShowExplicitlyRequested = true;
- mShowForced = true;
- }
- if (mCurMethod != null) {
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageIO(
- MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod));
- mInputShown = true;
- } else if (mHaveConnection && SystemClock.uptimeMillis()
- < (mLastBindTime+TIME_TO_RECONNECT)) {
- // The client has asked to have the input method shown, but
- // we have been sitting here too long with a connection to the
- // service and no interface received, so let's disconnect/connect
- // to try to prod things along.
- EventLog.writeEvent(LOG_IMF_FORCE_RECONNECT_IME, mCurMethodId,
- SystemClock.uptimeMillis()-mLastBindTime,1);
- mContext.unbindService(this);
- mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE);
- }
- }
-
- public void hideSoftInput(IInputMethodClient client, int flags) {
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mMethodMap) {
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- try {
- // We need to check if this is the current client with
- // focus in the window manager, to allow this call to
- // be made before input is started in it.
- if (!mIWindowManager.inputMethodClientHasFocus(client)) {
- Log.w(TAG, "Ignoring hideSoftInput of: " + client);
- return;
- }
- } catch (RemoteException e) {
- }
- }
-
- if (DEBUG) Log.v(TAG, "Client requesting input be hidden");
- hideCurrentInputLocked(flags);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- void hideCurrentInputLocked(int flags) {
- if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
- && (mShowExplicitlyRequested || mShowForced)) {
- if (DEBUG) Log.v(TAG,
- "Not hiding: explicit show not cancelled by non-explicit hide");
- return;
- }
- if (mShowForced && (flags&InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
- if (DEBUG) Log.v(TAG,
- "Not hiding: forced show not cancelled by not-always hide");
- return;
- }
- if (mInputShown && mCurMethod != null) {
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
- MSG_HIDE_SOFT_INPUT, mCurMethod));
- }
- mInputShown = false;
- mShowRequested = false;
- mShowExplicitlyRequested = false;
- mShowForced = false;
- }
-
- public void windowGainedFocus(IInputMethodClient client,
- boolean viewHasFocus, boolean isTextEditor, int softInputMode,
- boolean first, int windowFlags) {
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mMethodMap) {
- if (DEBUG) Log.v(TAG, "windowGainedFocus: " + client.asBinder()
- + " viewHasFocus=" + viewHasFocus
- + " isTextEditor=" + isTextEditor
- + " softInputMode=#" + Integer.toHexString(softInputMode)
- + " first=" + first + " flags=#"
- + Integer.toHexString(windowFlags));
-
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- try {
- // We need to check if this is the current client with
- // focus in the window manager, to allow this call to
- // be made before input is started in it.
- if (!mIWindowManager.inputMethodClientHasFocus(client)) {
- Log.w(TAG, "Ignoring focus gain of: " + client);
- return;
- }
- } catch (RemoteException e) {
- }
- }
-
- switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
- if (!isTextEditor || (softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
- != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
- if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) {
- // There is no focus view, and this window will
- // be behind any soft input window, so hide the
- // soft input window if it is shown.
- if (DEBUG) Log.v(TAG, "Unspecified window will hide input");
- hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS);
- }
- } else if (isTextEditor && (softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
- == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
- && (softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
- // There is a focus view, and we are navigating forward
- // into the window, so show the input window for the user.
- if (DEBUG) Log.v(TAG, "Unspecified window will show input");
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
- }
- break;
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
- // Do nothing.
- break;
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
- if ((softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
- if (DEBUG) Log.v(TAG, "Window asks to hide input going forward");
- hideCurrentInputLocked(0);
- }
- break;
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
- if (DEBUG) Log.v(TAG, "Window asks to hide input");
- hideCurrentInputLocked(0);
- break;
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
- if ((softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
- if (DEBUG) Log.v(TAG, "Window asks to show input going forward");
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
- }
- break;
- case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
- if (DEBUG) Log.v(TAG, "Window asks to always show input");
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
- break;
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- public void showInputMethodPickerFromClient(IInputMethodClient client) {
- synchronized (mMethodMap) {
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- Log.w(TAG, "Ignoring showInputMethodDialogFromClient of: " + client);
- }
-
- mHandler.sendEmptyMessage(MSG_SHOW_IM_PICKER);
- }
- }
-
- public void setInputMethod(IBinder token, String id) {
- synchronized (mMethodMap) {
- if (token == null) {
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Using null token requires permission "
- + android.Manifest.permission.WRITE_SECURE_SETTINGS);
- }
- } else if (mCurToken != token) {
- Log.w(TAG, "Ignoring setInputMethod of token: " + token);
- return;
- }
-
- long ident = Binder.clearCallingIdentity();
- try {
- setInputMethodLocked(id);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void hideMySoftInput(IBinder token, int flags) {
- synchronized (mMethodMap) {
- if (token == null || mCurToken != token) {
- Log.w(TAG, "Ignoring hideInputMethod of token: " + token);
- return;
- }
-
- long ident = Binder.clearCallingIdentity();
- try {
- hideCurrentInputLocked(flags);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- void setEnabledSessionInMainThread(SessionState session) {
- if (mEnabledSession != session) {
- if (mEnabledSession != null) {
- try {
- if (DEBUG) Log.v(TAG, "Disabling: " + mEnabledSession);
- mEnabledSession.method.setSessionEnabled(
- mEnabledSession.session, false);
- } catch (RemoteException e) {
- }
- }
- mEnabledSession = session;
- try {
- if (DEBUG) Log.v(TAG, "Enabling: " + mEnabledSession);
- session.method.setSessionEnabled(
- session.session, true);
- } catch (RemoteException e) {
- }
- }
- }
-
- public boolean handleMessage(Message msg) {
- HandlerCaller.SomeArgs args;
- switch (msg.what) {
- case MSG_SHOW_IM_PICKER:
- showInputMethodMenu();
- return true;
-
- // ---------------------------------------------------------
-
- case MSG_UNBIND_INPUT:
- try {
- ((IInputMethod)msg.obj).unbindInput();
- } catch (RemoteException e) {
- // There is nothing interesting about the method dying.
- }
- return true;
- case MSG_BIND_INPUT:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- ((IInputMethod)args.arg1).bindInput((InputBinding)args.arg2);
- } catch (RemoteException e) {
- }
- return true;
- case MSG_SHOW_SOFT_INPUT:
- try {
- ((IInputMethod)msg.obj).showSoftInput(msg.arg1);
- } catch (RemoteException e) {
- }
- return true;
- case MSG_HIDE_SOFT_INPUT:
- try {
- ((IInputMethod)msg.obj).hideSoftInput();
- } catch (RemoteException e) {
- }
- return true;
- case MSG_ATTACH_TOKEN:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- if (DEBUG) Log.v(TAG, "Sending attach of token: " + args.arg2);
- ((IInputMethod)args.arg1).attachToken((IBinder)args.arg2);
- } catch (RemoteException e) {
- }
- return true;
- case MSG_CREATE_SESSION:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- ((IInputMethod)args.arg1).createSession(
- (IInputMethodCallback)args.arg2);
- } catch (RemoteException e) {
- }
- return true;
-
- // ---------------------------------------------------------
-
- case MSG_START_INPUT:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- SessionState session = (SessionState)args.arg1;
- setEnabledSessionInMainThread(session);
- session.method.startInput((IInputContext)args.arg2,
- (EditorInfo)args.arg3);
- } catch (RemoteException e) {
- }
- return true;
- case MSG_RESTART_INPUT:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- SessionState session = (SessionState)args.arg1;
- setEnabledSessionInMainThread(session);
- session.method.restartInput((IInputContext)args.arg2,
- (EditorInfo)args.arg3);
- } catch (RemoteException e) {
- }
- return true;
-
- // ---------------------------------------------------------
-
- case MSG_UNBIND_METHOD:
- try {
- ((IInputMethodClient)msg.obj).onUnbindMethod(msg.arg1);
- } catch (RemoteException e) {
- // There is nothing interesting about the last client dying.
- }
- return true;
- case MSG_BIND_METHOD:
- args = (HandlerCaller.SomeArgs)msg.obj;
- try {
- ((IInputMethodClient)args.arg1).onBindMethod(
- (InputBindResult)args.arg2);
- } catch (RemoteException e) {
- Log.w(TAG, "Client died receiving input method " + args.arg2);
- }
- return true;
- }
- return false;
- }
-
- void buildInputMethodListLocked(ArrayList<InputMethodInfo> list,
- HashMap<String, InputMethodInfo> map) {
- list.clear();
- map.clear();
-
- PackageManager pm = mContext.getPackageManager();
-
- List<ResolveInfo> services = pm.queryIntentServices(
- new Intent(InputMethod.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
-
- for (int i = 0; i < services.size(); ++i) {
- ResolveInfo ri = services.get(i);
- ServiceInfo si = ri.serviceInfo;
- ComponentName compName = new ComponentName(si.packageName, si.name);
- if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(
- si.permission)) {
- Log.w(TAG, "Skipping input method " + compName
- + ": it does not require the permission "
- + android.Manifest.permission.BIND_INPUT_METHOD);
- continue;
- }
-
- if (DEBUG) Log.d(TAG, "Checking " + compName);
-
- try {
- InputMethodInfo p = new InputMethodInfo(mContext, ri);
- list.add(p);
- map.put(p.getId(), p);
-
- if (DEBUG) {
- Log.d(TAG, "Found a third-party input method " + p);
- }
-
- } catch (XmlPullParserException e) {
- Log.w(TAG, "Unable to load input method " + compName, e);
- } catch (IOException e) {
- Log.w(TAG, "Unable to load input method " + compName, e);
- }
- }
- }
-
- // ----------------------------------------------------------------------
-
- void showInputMethodMenu() {
- if (DEBUG) Log.v(TAG, "Show switching menu");
-
- hideInputMethodMenu();
-
- final Context context = mContext;
-
- final PackageManager pm = context.getPackageManager();
-
- String lastInputMethodId = Settings.Secure.getString(context
- .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- if (DEBUG) Log.v(TAG, "Current IME: " + lastInputMethodId);
-
- final List<InputMethodInfo> immis = getEnabledInputMethodList();
-
- int N = (immis == null ? 0 : immis.size());
-
- mItems = new CharSequence[N];
- mIms = new InputMethodInfo[N];
-
- for (int i = 0; i < N; ++i) {
- InputMethodInfo property = immis.get(i);
- mItems[i] = property.loadLabel(pm);
- mIms[i] = property;
- }
-
- int checkedItem = 0;
- for (int i = 0; i < N; ++i) {
- if (mIms[i].getId().equals(lastInputMethodId)) {
- checkedItem = i;
- break;
- }
- }
-
- AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- hideInputMethodMenu();
- }
- };
-
- TypedArray a = context.obtainStyledAttributes(null,
- com.android.internal.R.styleable.DialogPreference,
- com.android.internal.R.attr.alertDialogStyle, 0);
- mDialogBuilder = new AlertDialog.Builder(context)
- .setTitle(com.android.internal.R.string.select_input_method)
- .setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- hideInputMethodMenu();
- }
- })
- .setIcon(a.getDrawable(
- com.android.internal.R.styleable.DialogPreference_dialogTitle));
- a.recycle();
-
- mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- synchronized (mMethodMap) {
- InputMethodInfo im = mIms[which];
- hideInputMethodMenu();
- setInputMethodLocked(im.getId());
- }
- }
- });
-
- synchronized (mMethodMap) {
- mSwitchingDialog = mDialogBuilder.create();
- mSwitchingDialog.getWindow().setType(
- WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
- mSwitchingDialog.show();
- }
- }
-
- void hideInputMethodMenu() {
- if (DEBUG) Log.v(TAG, "Hide switching menu");
-
- synchronized (mMethodMap) {
- if (mSwitchingDialog != null) {
- mSwitchingDialog.dismiss();
- mSwitchingDialog = null;
- }
-
- mDialogBuilder = null;
- mItems = null;
- mIms = null;
- }
- }
-
- // ----------------------------------------------------------------------
-
- public boolean setInputMethodEnabled(String id, boolean enabled) {
- synchronized (mMethodMap) {
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires permission "
- + android.Manifest.permission.WRITE_SECURE_SETTINGS);
- }
-
- long ident = Binder.clearCallingIdentity();
- try {
- // Make sure this is a valid input method.
- InputMethodInfo imm = mMethodMap.get(id);
- if (imm == null) {
- if (imm == null) {
- throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
- }
- }
-
- StringBuilder builder = new StringBuilder(256);
-
- boolean removed = false;
- String firstId = null;
-
- // Look through the currently enabled input methods.
- String enabledStr = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS);
- if (enabledStr != null) {
- final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(enabledStr);
- while (splitter.hasNext()) {
- String curId = splitter.next();
- if (curId.equals(id)) {
- if (enabled) {
- // We are enabling this input method, but it is
- // already enabled. Nothing to do. The previous
- // state was enabled.
- return true;
- }
- // We are disabling this input method, and it is
- // currently enabled. Skip it to remove from the
- // new list.
- removed = true;
- } else if (!enabled) {
- // We are building a new list of input methods that
- // doesn't contain the given one.
- if (firstId == null) firstId = curId;
- if (builder.length() > 0) builder.append(':');
- builder.append(curId);
- }
- }
- }
-
- if (!enabled) {
- if (!removed) {
- // We are disabling the input method but it is already
- // disabled. Nothing to do. The previous state was
- // disabled.
- return false;
- }
- // Update the setting with the new list of input methods.
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
- // We the disabled input method is currently selected, switch
- // to another one.
- String selId = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
- if (id.equals(selId)) {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- firstId != null ? firstId : "");
- }
- // Previous state was enabled.
- return true;
- }
-
- // Add in the newly enabled input method.
- if (enabledStr == null || enabledStr.length() == 0) {
- enabledStr = id;
- } else {
- enabledStr = enabledStr + ':' + id;
- }
-
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, enabledStr);
-
- // Previous state was disabled.
- return false;
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- // ----------------------------------------------------------------------
-
- @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 InputMethodManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- IInputMethod method;
- ClientState client;
-
- final Printer p = new PrintWriterPrinter(pw);
-
- synchronized (mMethodMap) {
- p.println("Current Input Method Manager state:");
- int N = mMethodList.size();
- p.println(" Input Methods:");
- for (int i=0; i<N; i++) {
- InputMethodInfo info = mMethodList.get(i);
- p.println(" InputMethod #" + i + ":");
- info.dump(p, " ");
- }
- p.println(" Clients:");
- for (ClientState ci : mClients.values()) {
- p.println(" Client " + ci + ":");
- p.println(" client=" + ci.client);
- p.println(" inputContext=" + ci.inputContext);
- p.println(" sessionRequested=" + ci.sessionRequested);
- p.println(" curSession=" + ci.curSession);
- }
- p.println(" mInputMethodIcon=" + mInputMethodIcon);
- p.println(" mInputMethodData=" + mInputMethodData);
- p.println(" mCurrentMethod=" + mCurMethodId);
- client = mCurClient;
- p.println(" mCurSeq=" + mCurSeq + " mCurClient=" + client);
- p.println(" mCurId=" + mCurId + " mHaveConnect=" + mHaveConnection
- + " mBoundToMethod=" + mBoundToMethod);
- p.println(" mCurToken=" + mCurToken);
- p.println(" mCurIntent=" + mCurIntent);
- method = mCurMethod;
- p.println(" mCurMethod=" + mCurMethod);
- p.println(" mEnabledSession=" + mEnabledSession);
- p.println(" mShowRequested=" + mShowRequested
- + " mShowExplicitlyRequested=" + mShowExplicitlyRequested
- + " mShowForced=" + mShowForced
- + " mInputShown=" + mInputShown);
- p.println(" mScreenOn=" + mScreenOn);
- }
-
- if (client != null) {
- p.println(" ");
- pw.flush();
- try {
- client.client.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- p.println("Input method client dead: " + e);
- }
- }
-
- if (method != null) {
- p.println(" ");
- pw.flush();
- try {
- method.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- p.println("Input method service dead: " + e);
- }
- }
- }
-}