SpellCheckerService.java revision 988323c57bd25a58f05dfa492d9b9c8ab62c5153
14a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner/*
24a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * Copyright (C) 2011 The Android Open Source Project
34a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner *
44a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * Licensed under the Apache License, Version 2.0 (the "License"); you may not
54a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * use this file except in compliance with the License. You may obtain a copy of
64a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * the License at
74a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner *
84a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * http://www.apache.org/licenses/LICENSE-2.0
94a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner *
104a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * Unless required by applicable law or agreed to in writing, software
114a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
124a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
134a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * License for the specific language governing permissions and limitations under
144a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner * the License.
154a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner */
164a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner
174a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautnerpackage android.service.textservice;
184a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner
194a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautnerimport com.android.internal.textservice.ISpellCheckerService;
204a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautnerimport com.android.internal.textservice.ISpellCheckerSession;
214a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautnerimport com.android.internal.textservice.ISpellCheckerSessionListener;
224a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautner
23e3a00d745fad479f560e96cec23e957f37d1c043Craig Mautnerimport android.app.Service;
24d94b47f3b671f5afbc79b061a9b8fa7aa8b22f87Craig Mautnerimport android.content.Intent;
254a1cb22056112f7ffd5f4fad8b7a092b96e7cc7bCraig Mautnerimport android.os.IBinder;
26import android.os.RemoteException;
27import android.view.textservice.SuggestionsInfo;
28import android.view.textservice.TextInfo;
29
30import java.lang.ref.WeakReference;
31
32/**
33 * SpellCheckerService provides an abstract base class for a spell checker.
34 * This class combines a service to the system with the spell checker service interface that
35 * spell checker must implement.
36 */
37public abstract class SpellCheckerService extends Service {
38    private static final String TAG = SpellCheckerService.class.getSimpleName();
39    public static final String SERVICE_INTERFACE = SpellCheckerService.class.getName();
40
41    private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);
42
43    /**
44     * Get suggestions for specified text in TextInfo.
45     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
46     * but will be called in series on another thread.
47     * @param textInfo the text metadata
48     * @param suggestionsLimit the number of limit of suggestions returned
49     * @param locale the locale for getting suggestions
50     * @return SuggestionInfo which contains suggestions for textInfo
51     */
52    public abstract SuggestionsInfo getSuggestions(
53            TextInfo textInfo, int suggestionsLimit, String locale);
54
55    /**
56     * A batch process of onGetSuggestions.
57     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
58     * but will be called in series on another thread.
59     * @param textInfos an array of the text metadata
60     * @param locale the locale for getting suggestions
61     * @param suggestionsLimit the number of limit of suggestions returned
62     * @param sequentialWords true if textInfos can be treated as sequential words.
63     * @return an array of SuggestionInfo of onGetSuggestions
64     */
65    public SuggestionsInfo[] getSuggestionsMultiple(
66            TextInfo[] textInfos, String locale, int suggestionsLimit, boolean sequentialWords) {
67        final int length = textInfos.length;
68        final SuggestionsInfo[] retval = new SuggestionsInfo[length];
69        for (int i = 0; i < length; ++i) {
70            retval[i] = getSuggestions(textInfos[i], suggestionsLimit, locale);
71            retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
72        }
73        return retval;
74    }
75
76    /**
77     * Request to abort all tasks executed in SpellChecker.
78     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
79     * but will be called in series on another thread.
80     */
81    public void cancel() {}
82
83    /**
84     * Implement to return the implementation of the internal spell checker
85     * service interface. Subclasses should not override.
86     */
87    @Override
88    public final IBinder onBind(final Intent intent) {
89        return mBinder;
90    }
91
92    private static class SpellCheckerSessionImpl extends ISpellCheckerSession.Stub {
93        private final WeakReference<SpellCheckerService> mInternalServiceRef;
94        private final String mLocale;
95        private final ISpellCheckerSessionListener mListener;
96
97        public SpellCheckerSessionImpl(
98                SpellCheckerService service, String locale, ISpellCheckerSessionListener listener) {
99            mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
100            mLocale = locale;
101            mListener = listener;
102        }
103
104        @Override
105        public void getSuggestionsMultiple(
106                TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
107            final SpellCheckerService service = mInternalServiceRef.get();
108            if (service == null) return;
109            try {
110                mListener.onGetSuggestions(
111                        service.getSuggestionsMultiple(textInfos, mLocale,
112                                suggestionsLimit, sequentialWords));
113            } catch (RemoteException e) {
114            }
115        }
116
117        @Override
118        public void cancel() {
119            final SpellCheckerService service = mInternalServiceRef.get();
120            if (service == null) return;
121            service.cancel();
122        }
123    }
124
125    private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub {
126        private final WeakReference<SpellCheckerService> mInternalServiceRef;
127
128        public SpellCheckerServiceBinder(SpellCheckerService service) {
129            mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
130        }
131
132        @Override
133        public ISpellCheckerSession getISpellCheckerSession(
134                String locale, ISpellCheckerSessionListener listener) {
135            final SpellCheckerService service = mInternalServiceRef.get();
136            if (service == null) return null;
137            return new SpellCheckerSessionImpl(service, locale, listener);
138        }
139    }
140}
141