AbstractInputMethodService.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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
27import java.io.FileDescriptor;
28import java.io.PrintWriter;
29
30/**
31 * AbstractInputMethodService provides a abstract base class for input methods.
32 * Normal input method implementations will not derive from this directly,
33 * instead building on top of {@link InputMethodService} or another more
34 * complete base class.  Be sure to read {@link InputMethod} for more
35 * information on the basics of writing input methods.
36 *
37 * <p>This class combines a Service (representing the input method component
38 * to the system with the InputMethod interface that input methods must
39 * implement.  This base class takes care of reporting your InputMethod from
40 * the service when clients bind to it, but provides no standard implementation
41 * of the InputMethod interface itself.  Derived classes must implement that
42 * interface.
43 */
44public abstract class AbstractInputMethodService extends Service
45        implements KeyEvent.Callback {
46    private InputMethod mInputMethod;
47
48    /**
49     * Base class for derived classes to implement their {@link InputMethod}
50     * interface.  This takes care of basic maintenance of the input method,
51     * but most behavior must be implemented in a derived class.
52     */
53    public abstract class AbstractInputMethodImpl implements InputMethod {
54        /**
55         * Instantiate a new client session for the input method, by calling
56         * back to {@link AbstractInputMethodService#onCreateInputMethodSessionInterface()
57         * AbstractInputMethodService.onCreateInputMethodSessionInterface()}.
58         */
59        public void createSession(SessionCallback callback) {
60            callback.sessionCreated(onCreateInputMethodSessionInterface());
61        }
62
63        /**
64         * Take care of enabling or disabling an existing session by calling its
65         * {@link AbstractInputMethodSessionImpl#revokeSelf()
66         * AbstractInputMethodSessionImpl.setEnabled()} method.
67         */
68        public void setSessionEnabled(InputMethodSession session, boolean enabled) {
69            ((AbstractInputMethodSessionImpl)session).setEnabled(enabled);
70        }
71
72        /**
73         * Take care of killing an existing session by calling its
74         * {@link AbstractInputMethodSessionImpl#revokeSelf()
75         * AbstractInputMethodSessionImpl.revokeSelf()} method.
76         */
77        public void revokeSession(InputMethodSession session) {
78            ((AbstractInputMethodSessionImpl)session).revokeSelf();
79        }
80    }
81
82    /**
83     * Base class for derived classes to implement their {@link InputMethodSession}
84     * interface.  This takes care of basic maintenance of the session,
85     * but most behavior must be implemented in a derived class.
86     */
87    public abstract class AbstractInputMethodSessionImpl implements InputMethodSession {
88        boolean mEnabled = true;
89        boolean mRevoked;
90
91        /**
92         * Check whether this session has been enabled by the system.  If not
93         * enabled, you should not execute any calls on to it.
94         */
95        public boolean isEnabled() {
96            return mEnabled;
97        }
98
99        /**
100         * Check whether this session has been revoked by the system.  Revoked
101         * session is also always disabled, so there is generally no need to
102         * explicitly check for this.
103         */
104        public boolean isRevoked() {
105            return mRevoked;
106        }
107
108        /**
109         * Change the enabled state of the session.  This only works if the
110         * session has not been revoked.
111         */
112        public void setEnabled(boolean enabled) {
113            if (!mRevoked) {
114                mEnabled = enabled;
115            }
116        }
117
118        /**
119         * Revoke the session from the client.  This disabled the session, and
120         * prevents it from ever being enabled again.
121         */
122        public void revokeSelf() {
123            mRevoked = true;
124            mEnabled = false;
125        }
126
127        /**
128         * Take care of dispatching incoming key events to the appropriate
129         * callbacks on the service, and tell the client when this is done.
130         */
131        public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback) {
132            boolean handled = event.dispatch(AbstractInputMethodService.this);
133            if (callback != null) {
134                callback.finishedEvent(seq, handled);
135            }
136        }
137
138        /**
139         * Take care of dispatching incoming trackball events to the appropriate
140         * callbacks on the service, and tell the client when this is done.
141         */
142        public void dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback) {
143            boolean handled = onTrackballEvent(event);
144            if (callback != null) {
145                callback.finishedEvent(seq, handled);
146            }
147        }
148    }
149
150    /**
151     * Called by the framework during initialization, when the InputMethod
152     * interface for this service needs to be created.
153     */
154    public abstract AbstractInputMethodImpl onCreateInputMethodInterface();
155
156    /**
157     * Called by the framework when a new InputMethodSession interface is
158     * needed for a new client of the input method.
159     */
160    public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
161
162    /**
163     * Implement this to handle {@link android.os.Binder#dump Binder.dump()}
164     * calls on your input method.
165     */
166    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
167    }
168
169    @Override
170    final public IBinder onBind(Intent intent) {
171        if (mInputMethod == null) {
172            mInputMethod = onCreateInputMethodInterface();
173        }
174        return new IInputMethodWrapper(this, mInputMethod);
175    }
176
177    public boolean onTrackballEvent(MotionEvent event) {
178        return false;
179    }
180}
181