1 /*
2  * Copyright (C) 2014 The Android Open Source Project
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.android.server.telecom.testapps;
18 
19 import android.os.ConditionVariable;
20 import android.os.Handler;
21 import android.os.Looper;
22 import android.util.Log;
23 
24 import java.lang.AutoCloseable;
25 import java.lang.Exception;
26 import java.lang.Override;
27 import java.lang.String;
28 import java.lang.Thread;
29 import java.lang.Throwable;
30 import java.util.concurrent.TimeoutException;
31 
32 /**
33  * Camera thread class used for handling camera callbacks.
34  */
35 public class CameraThread implements AutoCloseable {
36     private static final String TAG = "CameraThread";
37     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
38 
39     // Timeout for initializing looper and opening camera in Milliseconds.
40     private static final long WAIT_FOR_COMMAND_TO_COMPLETE = 5000;
41     private Looper mLooper = null;
42     private Handler mHandler = null;
43 
44     /**
45      * Create and start a looper thread, return the Handler
46      */
start()47     public synchronized Handler start() throws Exception {
48         final ConditionVariable startDone = new ConditionVariable();
49         if (mHandler != null) {
50             Log.w(TAG, "Looper thread already started");
51             return mHandler;
52         }
53 
54         new Thread() {
55             @Override
56             public void run() {
57                 if (VERBOSE) Log.v(TAG, "start loopRun");
58                 Looper.prepare();
59                 // Save the looper so that we can terminate this thread
60                 // after we are done with it.
61                 mLooper = Looper.myLooper();
62                 mHandler = new Handler();
63                 startDone.open();
64                 Looper.loop();
65                 if (VERBOSE) Log.v(TAG, "createLooperThread: finished");
66             }
67         }.start();
68 
69         if (VERBOSE) Log.v(TAG, "start waiting for looper");
70         if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
71             throw new TimeoutException("createLooperThread: start timeout");
72         }
73         return mHandler;
74     }
75 
76     /**
77      * Terminate the looper thread
78      */
close()79     public synchronized void close() throws Exception {
80         if (mLooper == null || mHandler == null) {
81             Log.w(TAG, "Looper thread doesn't start yet");
82             return;
83         }
84 
85         if (VERBOSE) Log.v(TAG, "Terminate looper thread");
86         mLooper.quit();
87         mLooper.getThread().join();
88         mLooper = null;
89         mHandler = null;
90     }
91 
92     @Override
finalize()93     protected void finalize() throws Throwable {
94         try {
95             close();
96         } finally {
97             super.finalize();
98         }
99     }
100 }
101