Initialized merge tracking via "svnmerge" with revisions "1-319" from
[zxing.git] / android / src / com / google / zxing / client / android / WorkerThread.java
1 /*
2  * Copyright (C) 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.android;
18
19 import android.graphics.Bitmap;
20 import android.os.Handler;
21 import android.os.Message;
22 import com.google.zxing.MonochromeBitmapSource;
23 import com.google.zxing.MultiFormatReader;
24 import com.google.zxing.ReaderException;
25 import com.google.zxing.Result;
26
27 /**
28  * This thread does all the heavy lifting, both during preview and for the final capture and
29  * decoding. That leaves the main thread free to handle UI tasks.
30  *
31  * @author dswitkin@google.com (Daniel Switkin)
32  */
33 final class WorkerThread extends Thread {
34
35   private final CameraSurfaceView surfaceView;
36   private final CameraManager cameraManager;
37   private final Handler handler;
38   private final Object idleLock;
39   private State state;
40
41   private enum State {
42     IDLE,
43     PREVIEW_LOOP,
44     STILL_AND_DECODE,
45     DONE
46   }
47
48   WorkerThread(CameraSurfaceView surfaceView, CameraManager cameraManager, Handler handler) {
49     this.surfaceView = surfaceView;
50     this.cameraManager = cameraManager;
51     this.handler = handler;
52     this.idleLock = new Object();
53     state = State.IDLE;
54   }
55
56   @Override
57   public void run() {
58     while (true) {
59       switch (state) {
60         case IDLE:
61           idle();
62           break;
63         case PREVIEW_LOOP:
64           surfaceView.capturePreviewAndDraw();
65           break;
66         case STILL_AND_DECODE:
67           Bitmap bitmap = cameraManager.captureStill();
68           Result rawResult;
69           try {
70             MonochromeBitmapSource source = new RGBMonochromeBitmapSource(bitmap);
71             rawResult = new MultiFormatReader().decode(source);
72           } catch (ReaderException e) {
73             Message message = Message.obtain(handler, R.id.decoding_failed_message);
74             message.sendToTarget();
75             state = State.PREVIEW_LOOP;
76             break;
77           }
78           Message message = Message.obtain(handler, R.id.decoding_succeeded_message, rawResult);
79           message.sendToTarget();
80           state = State.IDLE;
81           break;
82         case DONE:
83           return;
84       }
85     }
86   }
87
88   public void requestPreviewLoop() {
89     state = State.PREVIEW_LOOP;
90     wakeFromIdle();
91   }
92
93   public void requestStillAndDecode() {
94     state = State.STILL_AND_DECODE;
95     wakeFromIdle();
96   }
97
98   public void requestExitAndWait() {
99     state = State.DONE;
100     wakeFromIdle();
101     try {
102       join();
103     } catch (InterruptedException e) {
104     }
105   }
106
107   private void idle() {
108     try {
109       synchronized (idleLock) {
110         idleLock.wait();
111       }
112     } catch (InterruptedException ie) {
113       // continue
114     }
115   }
116
117   private void wakeFromIdle() {
118     synchronized (idleLock) {
119       idleLock.notifyAll();
120     }
121   }
122
123 }