1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/*
2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright 2013 The Android Open Source Project
3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License");
5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License.
6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at
7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *      http://www.apache.org/licenses/LICENSE-2.0
9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software
11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS,
12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and
14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License.
15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw.samples.simplecamera;
18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.ConditionVariable;
20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Handler;
21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Looper;
22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.util.Log;
23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.concurrent.TimeoutException;
25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/**
27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Camera test thread wrapper for handling camera callbacks
28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class CameraTestThread implements AutoCloseable {
30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final String TAG = "CameraTestThread";
31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    // Timeout for initializing looper and opening camera in Milliseconds.
33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final long WAIT_FOR_COMMAND_TO_COMPLETE = 5000;
34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private Looper mLooper = null;
35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private Handler mHandler = null;
36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Create and start a looper thread, return the Handler
39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public synchronized Handler start() throws Exception {
41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final ConditionVariable startDone = new ConditionVariable();
42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mLooper != null || mHandler !=null) {
43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            Log.w(TAG, "Looper thread already started");
44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return mHandler;
45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        new Thread() {
48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            @Override
49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            public void run() {
50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                if (VERBOSE) Log.v(TAG, "start loopRun");
51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                Looper.prepare();
52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                // Save the looper so that we can terminate this thread
53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                // after we are done with it.
54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                mLooper = Looper.myLooper();
55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                mHandler = new Handler();
56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                startDone.open();
57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                Looper.loop();
58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                if (VERBOSE) Log.v(TAG, "createLooperThread: finished");
59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }.start();
61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (VERBOSE) Log.v(TAG, "start waiting for looper");
63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            throw new TimeoutException("createLooperThread: start timeout");
65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mHandler;
67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Terminate the looper thread
71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public synchronized void close() throws Exception {
73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mLooper == null || mHandler == null) {
74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            Log.w(TAG, "Looper thread doesn't start yet");
75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return;
76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (VERBOSE) Log.v(TAG, "Terminate looper thread");
79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mLooper.quit();
80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mLooper.getThread().join();
81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mLooper = null;
82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mHandler = null;
83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Override
86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    protected void finalize() throws Throwable {
87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        try {
88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            close();
89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } finally {
90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            super.finalize();
91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks}
94