• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.inputmethodservice;
18 
19 import android.app.Service;
20 import android.content.Intent;
21 import android.os.IBinder;
22 import android.view.KeyEvent;
23 import android.view.MotionEvent;
24 import android.view.inputmethod.InputMethod;
25 import android.view.inputmethod.InputMethodSession;
26 
27 import java.io.FileDescriptor;
28 import 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  */
44 public abstract class AbstractInputMethodService extends Service
45         implements KeyEvent.Callback {
46     private InputMethod mInputMethod;
47 
48     final KeyEvent.DispatcherState mDispatcherState
49             = new KeyEvent.DispatcherState();
50 
51     /**
52      * Base class for derived classes to implement their {@link InputMethod}
53      * interface.  This takes care of basic maintenance of the input method,
54      * but most behavior must be implemented in a derived class.
55      */
56     public abstract class AbstractInputMethodImpl implements InputMethod {
57         /**
58          * Instantiate a new client session for the input method, by calling
59          * back to {@link AbstractInputMethodService#onCreateInputMethodSessionInterface()
60          * AbstractInputMethodService.onCreateInputMethodSessionInterface()}.
61          */
createSession(SessionCallback callback)62         public void createSession(SessionCallback callback) {
63             callback.sessionCreated(onCreateInputMethodSessionInterface());
64         }
65 
66         /**
67          * Take care of enabling or disabling an existing session by calling its
68          * {@link AbstractInputMethodSessionImpl#revokeSelf()
69          * AbstractInputMethodSessionImpl.setEnabled()} method.
70          */
setSessionEnabled(InputMethodSession session, boolean enabled)71         public void setSessionEnabled(InputMethodSession session, boolean enabled) {
72             ((AbstractInputMethodSessionImpl)session).setEnabled(enabled);
73         }
74 
75         /**
76          * Take care of killing an existing session by calling its
77          * {@link AbstractInputMethodSessionImpl#revokeSelf()
78          * AbstractInputMethodSessionImpl.revokeSelf()} method.
79          */
revokeSession(InputMethodSession session)80         public void revokeSession(InputMethodSession session) {
81             ((AbstractInputMethodSessionImpl)session).revokeSelf();
82         }
83     }
84 
85     /**
86      * Base class for derived classes to implement their {@link InputMethodSession}
87      * interface.  This takes care of basic maintenance of the session,
88      * but most behavior must be implemented in a derived class.
89      */
90     public abstract class AbstractInputMethodSessionImpl implements InputMethodSession {
91         boolean mEnabled = true;
92         boolean mRevoked;
93 
94         /**
95          * Check whether this session has been enabled by the system.  If not
96          * enabled, you should not execute any calls on to it.
97          */
isEnabled()98         public boolean isEnabled() {
99             return mEnabled;
100         }
101 
102         /**
103          * Check whether this session has been revoked by the system.  Revoked
104          * session is also always disabled, so there is generally no need to
105          * explicitly check for this.
106          */
isRevoked()107         public boolean isRevoked() {
108             return mRevoked;
109         }
110 
111         /**
112          * Change the enabled state of the session.  This only works if the
113          * session has not been revoked.
114          */
setEnabled(boolean enabled)115         public void setEnabled(boolean enabled) {
116             if (!mRevoked) {
117                 mEnabled = enabled;
118             }
119         }
120 
121         /**
122          * Revoke the session from the client.  This disabled the session, and
123          * prevents it from ever being enabled again.
124          */
revokeSelf()125         public void revokeSelf() {
126             mRevoked = true;
127             mEnabled = false;
128         }
129 
130         /**
131          * Take care of dispatching incoming key events to the appropriate
132          * callbacks on the service, and tell the client when this is done.
133          */
dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback)134         public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback) {
135             boolean handled = event.dispatch(AbstractInputMethodService.this,
136                     mDispatcherState, this);
137             if (callback != null) {
138                 callback.finishedEvent(seq, handled);
139             }
140         }
141 
142         /**
143          * Take care of dispatching incoming trackball events to the appropriate
144          * callbacks on the service, and tell the client when this is done.
145          */
dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback)146         public void dispatchTrackballEvent(int seq, MotionEvent event, EventCallback callback) {
147             boolean handled = onTrackballEvent(event);
148             if (callback != null) {
149                 callback.finishedEvent(seq, handled);
150             }
151         }
152 
153         /**
154          * Take care of dispatching incoming generic motion events to the appropriate
155          * callbacks on the service, and tell the client when this is done.
156          */
dispatchGenericMotionEvent(int seq, MotionEvent event, EventCallback callback)157         public void dispatchGenericMotionEvent(int seq, MotionEvent event, EventCallback callback) {
158             boolean handled = onGenericMotionEvent(event);
159             if (callback != null) {
160                 callback.finishedEvent(seq, handled);
161             }
162         }
163     }
164 
165     /**
166      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
167      * for used for processing events from the target application.
168      * Normally you will not need to use this directly, but
169      * just use the standard high-level event callbacks like {@link #onKeyDown}.
170      */
getKeyDispatcherState()171     public KeyEvent.DispatcherState getKeyDispatcherState() {
172         return mDispatcherState;
173     }
174 
175     /**
176      * Called by the framework during initialization, when the InputMethod
177      * interface for this service needs to be created.
178      */
onCreateInputMethodInterface()179     public abstract AbstractInputMethodImpl onCreateInputMethodInterface();
180 
181     /**
182      * Called by the framework when a new InputMethodSession interface is
183      * needed for a new client of the input method.
184      */
onCreateInputMethodSessionInterface()185     public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
186 
187     /**
188      * Implement this to handle {@link android.os.Binder#dump Binder.dump()}
189      * calls on your input method.
190      */
191     @Override
dump(FileDescriptor fd, PrintWriter fout, String[] args)192     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
193     }
194 
195     @Override
onBind(Intent intent)196     final public IBinder onBind(Intent intent) {
197         if (mInputMethod == null) {
198             mInputMethod = onCreateInputMethodInterface();
199         }
200         return new IInputMethodWrapper(this, mInputMethod);
201     }
202 
203     /**
204      * Implement this to handle trackball events on your input method.
205      *
206      * @param event The motion event being received.
207      * @return True if the event was handled in this function, false otherwise.
208      * @see View#onTrackballEvent
209      */
onTrackballEvent(MotionEvent event)210     public boolean onTrackballEvent(MotionEvent event) {
211         return false;
212     }
213 
214     /**
215      * Implement this to handle generic motion events on your input method.
216      *
217      * @param event The motion event being received.
218      * @return True if the event was handled in this function, false otherwise.
219      * @see View#onGenericMotionEvent
220      */
onGenericMotionEvent(MotionEvent event)221     public boolean onGenericMotionEvent(MotionEvent event) {
222         return false;
223     }
224 }
225