165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.filterfw.core; 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.os.AsyncTask; 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.os.Handler; 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.Log; 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.InterruptedException; 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.Runnable; 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.concurrent.CancellationException; 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.concurrent.ExecutionException; 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.concurrent.TimeoutException; 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.concurrent.TimeUnit; 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/** 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @hide 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic class AsyncRunner extends GraphRunner{ 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Class mSchedulerClass; 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private SyncRunner mRunner; 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private AsyncRunnerTask mRunTask; 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private OnRunnerDoneListener mDoneListener; 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private boolean isProcessing; 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Exception mException; 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private class RunnerResult { 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public int status = RESULT_UNKNOWN; 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public Exception exception; 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private class AsyncRunnerTask extends AsyncTask<SyncRunner, Void, RunnerResult> { 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private static final String TAG = "AsyncRunnerTask"; 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected RunnerResult doInBackground(SyncRunner... runner) { 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn RunnerResult result = new RunnerResult(); 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (runner.length > 1) { 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("More than one runner received!"); 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn runner[0].assertReadyToStep(); 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Preparation 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Starting background graph processing."); 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn activateGlContext(); 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Preparing filter graph for processing."); 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn runner[0].beginProcessing(); 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Running graph."); 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Run loop 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_RUNNING; 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn while (!isCancelled() && result.status == RESULT_RUNNING) { 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!runner[0].performStep()) { 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = runner[0].determinePostRunState(); 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result.status == GraphRunner.RESULT_SLEEPING) { 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn runner[0].waitUntilWake(); 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_RUNNING; 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Cleanup 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (isCancelled()) { 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_STOPPED; 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (Exception exception) { 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.exception = exception; 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_ERROR; 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Deactivate context. 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn deactivateGlContext(); 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (Exception exception) { 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.exception = exception; 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_ERROR; 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Done with background graph processing."); 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void onCancelled(RunnerResult result) { 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn onPostExecute(result); 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void onPostExecute(RunnerResult result) { 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Starting post-execute."); 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setRunning(false); 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == null) { 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Cancelled before got to doInBackground 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = new RunnerResult(); 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_STOPPED; 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setException(result.exception); 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result.status == RESULT_STOPPED || result.status == RESULT_ERROR) { 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Closing filters."); 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunner.close(); 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (Exception exception) { 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result.status = RESULT_ERROR; 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setException(exception); 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mDoneListener != null) { 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Calling graph done callback."); 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDoneListener.onRunnerDone(result.status); 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Completed post-execute."); 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private boolean mLogVerbose; 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private static final String TAG = "AsyncRunner"; 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Create a new asynchronous graph runner with the given filter 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * context, and the given scheduler class. 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Must be created on the UI thread. 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public AsyncRunner(FilterContext context, Class schedulerClass) { 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn super(context); 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mSchedulerClass = schedulerClass; 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Create a new asynchronous graph runner with the given filter 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * context. Uses a default scheduler. 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Must be created on the UI thread. 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public AsyncRunner(FilterContext context) { 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn super(context); 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mSchedulerClass = SimpleScheduler.class; 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Set a callback to be called in the UI thread once the AsyncRunner 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * completes running a graph, whether the completion is due to a stop() call 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * or the filters running out of data to process. 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void setDoneCallback(OnRunnerDoneListener listener) { 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDoneListener = listener; 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Sets the graph to be run. Will call prepare() on graph. Cannot be called 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * when a graph is already running. 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public void setGraph(FilterGraph graph) { 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (isRunning()) { 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Graph is already running!"); 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunner = new SyncRunner(mFilterContext, graph, mSchedulerClass); 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public FilterGraph getGraph() { 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mRunner != null ? mRunner.getGraph() : null; 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Execute the graph in a background thread. */ 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public void run() { 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Running graph."); 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setException(null); 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (isRunning()) { 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Graph is already running!"); 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mRunner == null) { 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Cannot run before a graph is set!"); 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunTask = this.new AsyncRunnerTask(); 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setRunning(true); 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunTask.execute(mRunner); 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Stop graph execution. This is an asynchronous call; register a callback 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * with setDoneCallback to be notified of when the background processing has 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * been completed. Calling stop will close the filter graph. */ 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public void stop() { 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mRunTask != null && !mRunTask.isCancelled() ) { 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Stopping graph."); 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunTask.cancel(false); 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public void close() { 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (isRunning()) { 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Cannot close graph while it is running!"); 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Closing filters."); 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mRunner.close(); 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Check if background processing is happening */ 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public boolean isRunning() { 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return isProcessing; 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized public Exception getError() { 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mException; 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized private void setRunning(boolean running) { 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn isProcessing = running; 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized private void setException(Exception exception) { 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mException = exception; 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 248