SpellCheckerService.java revision 117999d1f44ec3423369385495ae207898b7b73e
1/* 2 * Copyright (C) 2011 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.service.textservice; 18 19import com.android.internal.textservice.ISpellCheckerService; 20import com.android.internal.textservice.ISpellCheckerSession; 21import com.android.internal.textservice.ISpellCheckerSessionListener; 22 23import android.app.Service; 24import android.content.Intent; 25import android.os.Bundle; 26import android.os.IBinder; 27import android.os.RemoteException; 28import android.util.Log; 29import android.view.textservice.SuggestionsInfo; 30import android.view.textservice.TextInfo; 31 32import java.lang.ref.WeakReference; 33 34/** 35 * SpellCheckerService provides an abstract base class for a spell checker. 36 * This class combines a service to the system with the spell checker service interface that 37 * spell checker must implement. 38 */ 39public abstract class SpellCheckerService extends Service { 40 private static final String TAG = SpellCheckerService.class.getSimpleName(); 41 private static final boolean DBG = false; 42 public static final String SERVICE_INTERFACE = 43 "android.service.textservice.SpellCheckerService"; 44 45 private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this); 46 47 48 /** 49 * Implement to return the implementation of the internal spell checker 50 * service interface. Subclasses should not override. 51 */ 52 @Override 53 public final IBinder onBind(final Intent intent) { 54 if (DBG) { 55 Log.w(TAG, "onBind"); 56 } 57 return mBinder; 58 } 59 60 /** 61 * Factory method to create a spell checker session impl 62 * @return SpellCheckerSessionImpl which should be overridden by a concrete implementation. 63 */ 64 public abstract Session createSession(); 65 66 /** 67 * This abstract class should be overridden by a concrete implementation of a spell checker. 68 */ 69 public static abstract class Session { 70 private InternalISpellCheckerSession mInternalSession; 71 72 /** 73 * @hide 74 */ 75 public final void setInternalISpellCheckerSession(InternalISpellCheckerSession session) { 76 mInternalSession = session; 77 } 78 79 /** 80 * This is called after the class is initialized, at which point it knows it can call 81 * getLocale() etc... 82 */ 83 public abstract void onCreate(); 84 85 /** 86 * Get suggestions for specified text in TextInfo. 87 * This function will run on the incoming IPC thread. 88 * So, this is not called on the main thread, 89 * but will be called in series on another thread. 90 * @param textInfo the text metadata 91 * @param suggestionsLimit the number of limit of suggestions returned 92 * @return SuggestionInfo which contains suggestions for textInfo 93 */ 94 public abstract SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit); 95 96 /** 97 * A batch process of onGetSuggestions. 98 * This function will run on the incoming IPC thread. 99 * So, this is not called on the main thread, 100 * but will be called in series on another thread. 101 * @param textInfos an array of the text metadata 102 * @param suggestionsLimit the number of limit of suggestions returned 103 * @param sequentialWords true if textInfos can be treated as sequential words. 104 * @return an array of SuggestionInfo of onGetSuggestions 105 */ 106 public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos, 107 int suggestionsLimit, boolean sequentialWords) { 108 final int length = textInfos.length; 109 final SuggestionsInfo[] retval = new SuggestionsInfo[length]; 110 for (int i = 0; i < length; ++i) { 111 retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit); 112 retval[i].setCookieAndSequence( 113 textInfos[i].getCookie(), textInfos[i].getSequence()); 114 } 115 return retval; 116 } 117 118 /** 119 * Request to abort all tasks executed in SpellChecker. 120 * This function will run on the incoming IPC thread. 121 * So, this is not called on the main thread, 122 * but will be called in series on another thread. 123 */ 124 public void onCancel() {} 125 126 /** 127 * @return Locale for this session 128 */ 129 public String getLocale() { 130 return mInternalSession.getLocale(); 131 } 132 133 /** 134 * @return Bundle for this session 135 */ 136 public Bundle getBundle() { 137 return mInternalSession.getBundle(); 138 } 139 } 140 141 // Preventing from exposing ISpellCheckerSession.aidl, create an internal class. 142 private static class InternalISpellCheckerSession extends ISpellCheckerSession.Stub { 143 private final ISpellCheckerSessionListener mListener; 144 private final Session mSession; 145 private final String mLocale; 146 private final Bundle mBundle; 147 148 public InternalISpellCheckerSession(String locale, ISpellCheckerSessionListener listener, 149 Bundle bundle, Session session) { 150 mListener = listener; 151 mSession = session; 152 mLocale = locale; 153 mBundle = bundle; 154 session.setInternalISpellCheckerSession(this); 155 } 156 157 @Override 158 public void onGetSuggestionsMultiple( 159 TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) { 160 try { 161 mListener.onGetSuggestions( 162 mSession.onGetSuggestionsMultiple( 163 textInfos, suggestionsLimit, sequentialWords)); 164 } catch (RemoteException e) { 165 } 166 } 167 168 @Override 169 public void onCancel() { 170 mSession.onCancel(); 171 } 172 173 public String getLocale() { 174 return mLocale; 175 } 176 177 public Bundle getBundle() { 178 return mBundle; 179 } 180 } 181 182 private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub { 183 private final WeakReference<SpellCheckerService> mInternalServiceRef; 184 185 public SpellCheckerServiceBinder(SpellCheckerService service) { 186 mInternalServiceRef = new WeakReference<SpellCheckerService>(service); 187 } 188 189 @Override 190 public ISpellCheckerSession getISpellCheckerSession( 191 String locale, ISpellCheckerSessionListener listener, Bundle bundle) { 192 final SpellCheckerService service = mInternalServiceRef.get(); 193 if (service == null) return null; 194 final Session session = service.createSession(); 195 final InternalISpellCheckerSession internalSession = 196 new InternalISpellCheckerSession(locale, listener, bundle, session); 197 session.onCreate(); 198 return internalSession; 199 } 200 } 201} 202