PageRenderTime 51ms CodeModel.GetById 19ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/ocr/ocrservice/src/com/googlecode/eyesfree/ocr/service/OcrService.java

http://eyes-free.googlecode.com/
Java | 318 lines | 209 code | 58 blank | 51 comment | 30 complexity | 1cfed3a196b3771ff3b574562303f97a MD5 | raw file
  1/*
  2 * Copyright (C) 2011 Google Inc.
  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 com.googlecode.eyesfree.ocr.service;
 18
 19import android.app.Service;
 20import android.content.BroadcastReceiver;
 21import android.content.Context;
 22import android.content.Intent;
 23import android.content.IntentFilter;
 24import android.content.pm.PackageInfo;
 25import android.content.pm.PackageManager;
 26import android.content.pm.PackageManager.NameNotFoundException;
 27import android.os.IBinder;
 28import android.os.RemoteCallbackList;
 29import android.os.RemoteException;
 30import android.util.Log;
 31
 32import com.googlecode.eyesfree.ocr.client.IOcr;
 33import com.googlecode.eyesfree.ocr.client.IOcrCallback;
 34import com.googlecode.eyesfree.ocr.client.Intents;
 35import com.googlecode.eyesfree.ocr.client.Language;
 36import com.googlecode.eyesfree.ocr.client.Ocr;
 37import com.googlecode.eyesfree.ocr.client.OcrResult;
 38import com.googlecode.eyesfree.ocr.client.Ocr.Parameters;
 39import com.googlecode.eyesfree.ocr.service.OcrTaskProcessor.OcrTaskListener;
 40
 41import java.io.File;
 42import java.util.ArrayList;
 43import java.util.HashMap;
 44import java.util.List;
 45
 46/**
 47 * Provides services for recognizing text in images. Specifically handles
 48 * binding the service to clients.
 49 *
 50 * @author alanv@google.com (Alan Viverette)
 51 */
 52public class OcrService extends Service {
 53    private static final String TAG = "OcrService";
 54
 55    private final OcrService mSelf = this;
 56
 57    private RemoteCallbackList<IOcrCallback> mCallbacks;
 58    private HashMap<Integer, IOcrCallback> mCallbacksMap;
 59    private LanguageManager mLanguageManager;
 60    private OcrTaskProcessor mOcrTaskProcessor;
 61
 62    @Override
 63    public void onCreate() {
 64        super.onCreate();
 65
 66        Log.i(TAG, "Service starting...");
 67
 68        mCallbacks = new RemoteCallbackList<IOcrCallback>();
 69        mCallbacksMap = new HashMap<Integer, IOcrCallback>();
 70
 71        mLanguageManager = new LanguageManager(this);
 72        mLanguageManager.loadLanguages();
 73
 74        mOcrTaskProcessor = new OcrTaskProcessor(mLanguageManager.getDatapath());
 75        mOcrTaskProcessor.setListener(mOcrTaskListener);
 76
 77        IntentFilter filter = new IntentFilter();
 78        filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
 79        filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
 80        filter.addAction(Intent.ACTION_MEDIA_EJECT);
 81        filter.addDataScheme("file");
 82
 83        registerReceiver(mBroadcastReceiver, filter);
 84    }
 85
 86    @Override
 87    public void onDestroy() {
 88        Log.i(TAG, "Service is shutting down...");
 89
 90        unregisterReceiver(mBroadcastReceiver);
 91
 92        mCallbacks.kill();
 93
 94        super.onDestroy();
 95    }
 96
 97    private void applyDefaults(Ocr.Parameters params) {
 98        // TODO(alanv): Make sure language choice is valid
 99        /*
100         * boolean override = mPrefs.getBoolean("override_pref", false); if
101         * (override || config.language == null) { config.language =
102         * mPrefs.getString("lang_pref", "eng"); } if (override ||
103         * !config.variables.containsKey(Config.VAR_ACCURACYVSPEED)) {
104         * config.variables.put(Config.VAR_ACCURACYVSPEED,
105         * mPrefs.getString("speed_pref", "0")); } if (override ||
106         * !config.debug) { config.debug = mPrefs.getBoolean("debug_pref",
107         * false); }
108         */
109    }
110
111    @Override
112    public IBinder onBind(Intent intent) {
113        if (Intents.Service.ACTION.equals(intent.getAction())) {
114            for (String category : intent.getCategories()) {
115                if (Intents.Service.CATEGORY.equals(category)) {
116                    return mBinder;
117                }
118            }
119        }
120
121        return null;
122    }
123
124    /**
125     * Attempts to cancel the OCR processor job with the specified token
126     * belonging to the specified process ID.
127     *
128     * @param pid
129     * @param token
130     */
131    private boolean cancel(int pid, long token) {
132        return mOcrTaskProcessor.cancel(pid, token);
133    }
134
135    /**
136     * Attempts to cancel all OCR processor jobs belonging to the specified
137     * process ID.
138     *
139     * @param pid
140     */
141    private boolean stop(int pid) {
142        return mOcrTaskProcessor.cancelAll(pid);
143    }
144
145    /**
146     * Returns the version number of the OCR package. This version number is the
147     * versionCode from the AndroidManifest.xml
148     *
149     * @return The version number of the OCR package
150     */
151    private int getVersion() {
152        PackageManager manager = mSelf.getPackageManager();
153        PackageInfo info = new PackageInfo();
154
155        try {
156            info = manager.getPackageInfo(mSelf.getPackageName(), 0);
157        } catch (NameNotFoundException e) {
158            e.printStackTrace();
159
160            return -1;
161        }
162
163        return info.versionCode;
164    }
165
166    private long enqueueData(int pid, byte[] data, Parameters params) {
167        if (data == null || data.length == 0) {
168            Log.e(TAG, "Attempted to enqueue null or empty data");
169            return Ocr.INVALID_TOKEN;
170        }
171
172        if (params == null) {
173            Log.e(TAG, "Attempted to enqueue null params");
174            return Ocr.INVALID_TOKEN;
175        }
176
177        applyDefaults(params);
178
179        return mOcrTaskProcessor.enqueueData(pid, data, params);
180    }
181
182    private long enqueueFile(int pid, String filename, Parameters params) {
183        if (filename == null) {
184            Log.e(TAG, "Attempted to enqueue null filename");
185            return Ocr.INVALID_TOKEN;
186        }
187
188        if (params == null) {
189            Log.e(TAG, "Attempted to enqueue null params");
190            return Ocr.INVALID_TOKEN;
191        }
192
193        final File file = new File(filename);
194
195        if (!file.exists() || !file.canRead()) {
196            Log.e(TAG, "Attempted to enqueue unreadable file");
197            return Ocr.INVALID_TOKEN;
198        }
199
200        applyDefaults(params);
201
202        return mOcrTaskProcessor.enqueueFile(pid, file, params);
203    }
204
205    private void setCallback(int pid, IOcrCallback callback) {
206        if (callback != null) {
207            mCallbacks.register(callback);
208            mCallbacksMap.put(pid, callback);
209        } else {
210            callback = mCallbacksMap.get(pid);
211
212            if (callback != null) {
213                mCallbacks.unregister(callback);
214            }
215        }
216    }
217
218    private final IOcr.Stub mBinder = new IOcr.Stub() {
219        @Override
220        public void setCallback(IOcrCallback cb) {
221            mSelf.setCallback(getCallingPid(), cb);
222        }
223
224        @Override
225        public long enqueueData(byte[] data, Parameters params) {
226            return mSelf.enqueueData(getCallingPid(), data, params);
227        }
228
229        @Override
230        public long enqueueFile(String filename, Parameters params) {
231            return mSelf.enqueueFile(getCallingPid(), filename, params);
232        }
233
234        @Override
235        public boolean cancel(long token) {
236            return mSelf.cancel(getCallingPid(), token);
237        }
238
239        @Override
240        public boolean stop() {
241            return mSelf.stop(getCallingPid());
242        }
243
244        @Override
245        public int getVersion() {
246            return mSelf.getVersion();
247        }
248
249        @Override
250        public boolean reloadLanguages() {
251            return mLanguageManager.loadLanguages();
252        }
253
254        @Override
255        public List<Language> getAvailableLanguages() {
256            return mLanguageManager.getAvailable();
257        }
258
259        @Override
260        public String getDatapath() {
261            File datapath = mLanguageManager.getDatapath();
262
263            return datapath == null ? null : datapath.getAbsolutePath();
264        }
265
266        @Override
267        public String getTessdata() {
268            File tessdata = mLanguageManager.getTessdata();
269
270            return tessdata == null ? null : tessdata.getAbsolutePath();
271        }
272    };
273
274    private final OcrTaskListener mOcrTaskListener = new OcrTaskListener() {
275        @Override
276        public void onResult(int pid, long token, OcrResult result) {
277            final IOcrCallback callback = mCallbacksMap.get(pid);
278
279            if (callback == null) {
280                return;
281            }
282
283            try {
284                callback.onResult(token, result);
285            } catch (RemoteException e) {
286                e.printStackTrace();
287            }
288        }
289
290        @Override
291        public void onCompleted(int pid, long token, ArrayList<OcrResult> results) {
292            IOcrCallback callback = mCallbacksMap.get(pid);
293
294            if (callback == null) {
295                return;
296            }
297
298            try {
299                callback.onCompleted(token, results);
300            } catch (RemoteException e) {
301                e.printStackTrace();
302            }
303        }
304    };
305
306    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
307        @Override
308        public void onReceive(Context context, Intent intent) {
309            if (Intent.ACTION_MEDIA_MOUNTED.equals(intent.getAction())
310                    || Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())) {
311                mLanguageManager.loadLanguages();
312            } else if (Intent.ACTION_MEDIA_EJECT.equals(intent.getAction())) {
313                mOcrTaskProcessor.abort();
314                Log.i(TAG, "Preparing for media eject");
315            }
316        }
317    };
318}