Home | History | Annotate | Download | only in inputmethodservice
      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          */
     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          */
     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          */
     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          */
     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          */
    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          */
    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          */
    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          */
    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          */
    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     /**
    155      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
    156      * for used for processing events from the target application.
    157      * Normally you will not need to use this directly, but
    158      * just use the standard high-level event callbacks like {@link #onKeyDown}.
    159      */
    160     public KeyEvent.DispatcherState getKeyDispatcherState() {
    161         return mDispatcherState;
    162     }
    163 
    164     /**
    165      * Called by the framework during initialization, when the InputMethod
    166      * interface for this service needs to be created.
    167      */
    168     public abstract AbstractInputMethodImpl onCreateInputMethodInterface();
    169 
    170     /**
    171      * Called by the framework when a new InputMethodSession interface is
    172      * needed for a new client of the input method.
    173      */
    174     public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
    175 
    176     /**
    177      * Implement this to handle {@link android.os.Binder#dump Binder.dump()}
    178      * calls on your input method.
    179      */
    180     @Override
    181     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
    182     }
    183 
    184     @Override
    185     final public IBinder onBind(Intent intent) {
    186         if (mInputMethod == null) {
    187             mInputMethod = onCreateInputMethodInterface();
    188         }
    189         return new IInputMethodWrapper(this, mInputMethod);
    190     }
    191 
    192     public boolean onTrackballEvent(MotionEvent event) {
    193         return false;
    194     }
    195 }
    196