AbstractInputMethodService.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
1/*
2 * Copyright (C) 2007-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package android.inputmethodservice;
18
19import android.app.Service;
20import android.content.Intent;
21import android.os.IBinder;
22import android.view.KeyEvent;
23import android.view.MotionEvent;
24import android.view.inputmethod.InputMethod;
25import android.view.inputmethod.InputMethodSession;
26
27/**
28 * AbstractInputMethodService provides a abstract base class for input methods.
29 * Normal input method implementations will not derive from this directly,
30 * instead building on top of {@link InputMethodService} or another more
31 * complete base class.  Be sure to read {@link InputMethod} for more
32 * information on the basics of writing input methods.
33 *
34 * <p>This class combines a Service (representing the input method component
35 * to the system with the InputMethod interface that input methods must
36 * implement.  This base class takes care of reporting your InputMethod from
37 * the service when clients bind to it, but provides no standard implementation
38 * of the InputMethod interface itself.  Derived classes must implement that
39 * interface.
40 */
41public abstract class AbstractInputMethodService extends Service
42        implements KeyEvent.Callback {
43    private InputMethod mInputMethod;
44
45    /**
46     * Base class for derived classes to implement their {@link InputMethod}
47     * interface.  This takes care of basic maintenance of the input method,
48     * but most behavior must be implemented in a derived class.
49     */
50    public abstract class AbstractInputMethodImpl implements InputMethod {
51        /**
52         * Instantiate a new client session for the input method, by calling
53         * back to {@link AbstractInputMethodService#onCreateInputMethodSessionInterface()
54         * AbstractInputMethodService.onCreateInputMethodSessionInterface()}.
55         */
56        public void createSession(SessionCallback callback) {
57            callback.sessionCreated(onCreateInputMethodSessionInterface());
58        }
59
60        /**
61         * Take care of enabling or disabling an existing session by calling its
62         * {@link AbstractInputMethodSessionImpl#revokeSelf()
63         * AbstractInputMethodSessionImpl.setEnabled()} method.
64         */
65        public void setSessionEnabled(InputMethodSession session, boolean enabled) {
66            ((AbstractInputMethodSessionImpl)session).setEnabled(enabled);
67        }
68
69        /**
70         * Take care of killing an existing session by calling its
71         * {@link AbstractInputMethodSessionImpl#revokeSelf()
72         * AbstractInputMethodSessionImpl.revokeSelf()} method.
73         */
74        public void revokeSession(InputMethodSession session) {
75            ((AbstractInputMethodSessionImpl)session).revokeSelf();
76        }
77    }
78
79    /**
80     * Base class for derived classes to implement their {@link InputMethodSession}
81     * interface.  This takes care of basic maintenance of the session,
82     * but most behavior must be implemented in a derived class.
83     */
84    public abstract class AbstractInputMethodSessionImpl implements InputMethodSession {
85        boolean mEnabled = true;
86        boolean mRevoked;
87
88        /**
89         * Check whether this session has been enabled by the system.  If not
90         * enabled, you should not execute any calls on to it.
91         */
92        public boolean isEnabled() {
93            return mEnabled;
94        }
95
96        /**
97         * Check whether this session has been revoked by the system.  Revoked
98         * session is also always disabled, so there is generally no need to
99         * explicitly check for this.
100         */
101        public boolean isRevoked() {
102            return mRevoked;
103        }
104
105        /**
106         * Change the enabled state of the session.  This only works if the
107         * session has not been revoked.
108         */
109        public void setEnabled(boolean enabled) {
110            if (!mRevoked) {
111                mEnabled = enabled;
112            }
113        }
114
115        /**
116         * Revoke the session from the client.  This disabled the session, and
117         * prevents it from ever being enabled again.
118         */
119        public void revokeSelf() {
120            mRevoked = true;
121            mEnabled = false;
122        }
123
124        /**
125         * Take care of dispatching incoming key events to the appropriate
126         * callbacks on the service, and tell the client when this is done.
127         */
128        public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback) {
129            boolean handled = event.dispatch(AbstractInputMethodService.this);
130            if (callback != null) {
131                callback.finishedEvent(seq, handled);
132            }
133        }
134
135        /**
136         * Take care of dispatching incoming trackball events to the appropriate
137         * callbacks on the service, and tell the client when this is done.
138         */
139        public void dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback) {
140            boolean handled = onTrackballEvent(event);
141            if (callback != null) {
142                callback.finishedEvent(seq, handled);
143            }
144        }
145    }
146
147    /**
148     * Called by the framework during initialization, when the InputMethod
149     * interface for this service needs to be created.
150     */
151    public abstract AbstractInputMethodImpl onCreateInputMethodInterface();
152
153    /**
154     * Called by the framework when a new InputMethodSession interface is
155     * needed for a new client of the input method.
156     */
157    public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
158
159    @Override
160    final public IBinder onBind(Intent intent) {
161        if (mInputMethod == null) {
162            mInputMethod = onCreateInputMethodInterface();
163        }
164        return new IInputMethodWrapper(this, mInputMethod);
165    }
166
167    public boolean onTrackballEvent(MotionEvent event) {
168        return false;
169    }
170}
171