19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.inputmethodservice;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Service;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodSession;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AbstractInputMethodService provides a abstract base class for input methods.
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Normal input method implementations will not derive from this directly,
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead building on top of {@link InputMethodService} or another more
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * complete base class.  Be sure to read {@link InputMethod} for more
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information on the basics of writing input methods.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This class combines a Service (representing the input method component
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the system with the InputMethod interface that input methods must
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implement.  This base class takes care of reporting your InputMethod from
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the service when clients bind to it, but provides no standard implementation
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the InputMethod interface itself.  Derived classes must implement that
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interface.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class AbstractInputMethodService extends Service
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements KeyEvent.Callback {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private InputMethod mInputMethod;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    final KeyEvent.DispatcherState mDispatcherState
4983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            = new KeyEvent.DispatcherState();
5083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Base class for derived classes to implement their {@link InputMethod}
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interface.  This takes care of basic maintenance of the input method,
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but most behavior must be implemented in a derived class.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract class AbstractInputMethodImpl implements InputMethod {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Instantiate a new client session for the input method, by calling
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * back to {@link AbstractInputMethodService#onCreateInputMethodSessionInterface()
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * AbstractInputMethodService.onCreateInputMethodSessionInterface()}.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void createSession(SessionCallback callback) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback.sessionCreated(onCreateInputMethodSessionInterface());
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Take care of enabling or disabling an existing session by calling its
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link AbstractInputMethodSessionImpl#revokeSelf()
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * AbstractInputMethodSessionImpl.setEnabled()} method.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setSessionEnabled(InputMethodSession session, boolean enabled) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((AbstractInputMethodSessionImpl)session).setEnabled(enabled);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Take care of killing an existing session by calling its
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link AbstractInputMethodSessionImpl#revokeSelf()
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * AbstractInputMethodSessionImpl.revokeSelf()} method.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void revokeSession(InputMethodSession session) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((AbstractInputMethodSessionImpl)session).revokeSelf();
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Base class for derived classes to implement their {@link InputMethodSession}
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interface.  This takes care of basic maintenance of the session,
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but most behavior must be implemented in a derived class.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract class AbstractInputMethodSessionImpl implements InputMethodSession {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean mEnabled = true;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean mRevoked;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Check whether this session has been enabled by the system.  If not
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * enabled, you should not execute any calls on to it.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isEnabled() {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mEnabled;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Check whether this session has been revoked by the system.  Revoked
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * session is also always disabled, so there is generally no need to
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * explicitly check for this.
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isRevoked() {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mRevoked;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Change the enabled state of the session.  This only works if the
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * session has not been revoked.
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setEnabled(boolean enabled) {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mRevoked) {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mEnabled = enabled;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Revoke the session from the client.  This disabled the session, and
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * prevents it from ever being enabled again.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void revokeSelf() {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRevoked = true;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEnabled = false;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Take care of dispatching incoming key events to the appropriate
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * callbacks on the service, and tell the client when this is done.
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback) {
13583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            boolean handled = event.dispatch(AbstractInputMethodService.this,
13683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                    mDispatcherState, this);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (callback != null) {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.finishedEvent(seq, handled);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Take care of dispatching incoming trackball events to the appropriate
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * callbacks on the service, and tell the client when this is done.
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean handled = onTrackballEvent(event);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (callback != null) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.finishedEvent(seq, handled);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
15683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * for used for processing events from the target application.
15783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * Normally you will not need to use this directly, but
15883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * just use the standard high-level event callbacks like {@link #onKeyDown}.
15983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     */
16083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    public KeyEvent.DispatcherState getKeyDispatcherState() {
16183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        return mDispatcherState;
16283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    }
16383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
16483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    /**
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by the framework during initialization, when the InputMethod
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interface for this service needs to be created.
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract AbstractInputMethodImpl onCreateInputMethodInterface();
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by the framework when a new InputMethodSession interface is
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * needed for a new client of the input method.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this to handle {@link android.os.Binder#dump Binder.dump()}
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * calls on your input method.
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final public IBinder onBind(Intent intent) {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputMethod == null) {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputMethod = onCreateInputMethodInterface();
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new IInputMethodWrapper(this, mInputMethod);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTrackballEvent(MotionEvent event) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
195