106 lines
3.9 KiB
Java
106 lines
3.9 KiB
Java
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package android.hardware.camera2.utils;
|
|
|
|
import android.hardware.camera2.utils.TaskDrainer.DrainListener;
|
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
/**
|
|
* Keep track of a single concurrent task starting and finishing;
|
|
* allow draining the existing task and figuring out when the task has finished
|
|
* (and won't restart).
|
|
*
|
|
* <p>The initial state is to allow all tasks to be started and finished. A task may only be started
|
|
* once, after which it must be finished before starting again. Likewise, finishing a task
|
|
* that hasn't been started is also not allowed.</p>
|
|
*
|
|
* <p>When draining begins, the task cannot be started again. This guarantees that at some
|
|
* point the task will be finished forever, at which point the {@link DrainListener#onDrained}
|
|
* callback will be invoked.</p>
|
|
*/
|
|
public class TaskSingleDrainer {
|
|
|
|
private final TaskDrainer<Object> mTaskDrainer;
|
|
private final Object mSingleTask = new Object();
|
|
|
|
/**
|
|
* Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
|
|
* via the {@code executor}.
|
|
*
|
|
* @param executor a non-{@code null} executor to use for listener execution
|
|
* @param listener a non-{@code null} listener where {@code onDrained} will be called
|
|
*/
|
|
public TaskSingleDrainer(Executor executor, DrainListener listener) {
|
|
mTaskDrainer = new TaskDrainer<>(executor, listener);
|
|
}
|
|
|
|
/**
|
|
* Create a new task drainer; {@code onDrained} callbacks will be posted to the listener
|
|
* via the {@code executor}.
|
|
*
|
|
* @param executor a non-{@code null} executor to use for listener execution
|
|
* @param listener a non-{@code null} listener where {@code onDrained} will be called
|
|
* @param name an optional name used for debug logging
|
|
*/
|
|
public TaskSingleDrainer(Executor executor, DrainListener listener, String name) {
|
|
mTaskDrainer = new TaskDrainer<>(executor, listener, name);
|
|
}
|
|
|
|
/**
|
|
* Mark this asynchronous task as having started.
|
|
*
|
|
* <p>The task cannot be started more than once without first having finished. Once
|
|
* draining begins with {@link #beginDrain}, no new tasks can be started.</p>
|
|
*
|
|
* @see #taskFinished
|
|
* @see #beginDrain
|
|
*
|
|
* @throws IllegalStateException
|
|
* If attempting to start a task which is already started (and not finished),
|
|
* or if attempting to start a task after draining has begun.
|
|
*/
|
|
public void taskStarted() {
|
|
mTaskDrainer.taskStarted(mSingleTask);
|
|
}
|
|
|
|
/**
|
|
* Do not allow any more task re-starts; once the existing task is finished,
|
|
* fire the {@link DrainListener#onDrained} callback asynchronously.
|
|
*
|
|
* <p>This operation is idempotent; calling it more than once has no effect.</p>
|
|
*/
|
|
public void beginDrain() {
|
|
mTaskDrainer.beginDrain();
|
|
}
|
|
|
|
/**
|
|
* Mark this asynchronous task as having finished.
|
|
*
|
|
* <p>The task cannot be finished if it hasn't started. Once finished, a task
|
|
* cannot be finished again (unless it's started again).</p>
|
|
*
|
|
* @see #taskStarted
|
|
* @see #beginDrain
|
|
*
|
|
* @throws IllegalStateException
|
|
* If attempting to start a task which is already finished (and not re-started),
|
|
*/
|
|
public void taskFinished() {
|
|
mTaskDrainer.taskFinished(mSingleTask);
|
|
}
|
|
}
|