SpellCheckerService.java revision 6be6d7548fb7c29a4d46dc985318ab2adf69f95f
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.IBinder;
26import android.os.RemoteException;
27import android.util.Log;
28import android.view.textservice.SuggestionsInfo;
29import android.view.textservice.TextInfo;
30
31import java.lang.ref.WeakReference;
32
33/**
34 * SpellCheckerService provides an abstract base class for a spell checker.
35 * This class combines a service to the system with the spell checker service interface that
36 * spell checker must implement.
37 */
38public abstract class SpellCheckerService extends Service {
39    private static final String TAG = SpellCheckerService.class.getSimpleName();
40    private static final boolean DBG = false;
41    public static final String SERVICE_INTERFACE =
42            "android.service.textservice.SpellCheckerService";
43
44    private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);
45
46    /**
47     * Get suggestions for specified text in TextInfo.
48     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
49     * but will be called in series on another thread.
50     * @param textInfo the text metadata
51     * @param suggestionsLimit the number of limit of suggestions returned
52     * @param locale the locale for getting suggestions
53     * @return SuggestionInfo which contains suggestions for textInfo
54     */
55    public abstract SuggestionsInfo getSuggestions(
56            TextInfo textInfo, int suggestionsLimit, String locale);
57
58    /**
59     * A batch process of onGetSuggestions.
60     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
61     * but will be called in series on another thread.
62     * @param textInfos an array of the text metadata
63     * @param locale the locale for getting suggestions
64     * @param suggestionsLimit the number of limit of suggestions returned
65     * @param sequentialWords true if textInfos can be treated as sequential words.
66     * @return an array of SuggestionInfo of onGetSuggestions
67     */
68    public SuggestionsInfo[] getSuggestionsMultiple(
69            TextInfo[] textInfos, String locale, int suggestionsLimit, boolean sequentialWords) {
70        final int length = textInfos.length;
71        final SuggestionsInfo[] retval = new SuggestionsInfo[length];
72        for (int i = 0; i < length; ++i) {
73            retval[i] = getSuggestions(textInfos[i], suggestionsLimit, locale);
74            retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
75        }
76        return retval;
77    }
78
79    /**
80     * Request to abort all tasks executed in SpellChecker.
81     * This function will run on the incoming IPC thread. So, this is not called on the main thread,
82     * but will be called in series on another thread.
83     */
84    public void cancel() {}
85
86    /**
87     * Implement to return the implementation of the internal spell checker
88     * service interface. Subclasses should not override.
89     */
90    @Override
91    public final IBinder onBind(final Intent intent) {
92        if (DBG) {
93            Log.w(TAG, "onBind");
94        }
95        return mBinder;
96    }
97
98    private static class SpellCheckerSessionImpl extends ISpellCheckerSession.Stub {
99        private final WeakReference<SpellCheckerService> mInternalServiceRef;
100        private final String mLocale;
101        private final ISpellCheckerSessionListener mListener;
102
103        public SpellCheckerSessionImpl(
104                SpellCheckerService service, String locale, ISpellCheckerSessionListener listener) {
105            mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
106            mLocale = locale;
107            mListener = listener;
108        }
109
110        @Override
111        public void getSuggestionsMultiple(
112                TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
113            final SpellCheckerService service = mInternalServiceRef.get();
114            if (service == null) return;
115            try {
116                mListener.onGetSuggestions(
117                        service.getSuggestionsMultiple(textInfos, mLocale,
118                                suggestionsLimit, sequentialWords));
119            } catch (RemoteException e) {
120            }
121        }
122
123        @Override
124        public void cancel() {
125            final SpellCheckerService service = mInternalServiceRef.get();
126            if (service == null) return;
127            service.cancel();
128        }
129    }
130
131    private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub {
132        private final WeakReference<SpellCheckerService> mInternalServiceRef;
133
134        public SpellCheckerServiceBinder(SpellCheckerService service) {
135            mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
136        }
137
138        @Override
139        public ISpellCheckerSession getISpellCheckerSession(
140                String locale, ISpellCheckerSessionListener listener) {
141            final SpellCheckerService service = mInternalServiceRef.get();
142            if (service == null) return null;
143            return new SpellCheckerSessionImpl(service, locale, listener);
144        }
145    }
146}
147