/*
 * 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).

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.

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 DrainListener.onDrained callback will be invoked.

/** * 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; onDrained callbacks will be posted to the listener via the executor.
Params:
  • executor – a non-null executor to use for listener execution
  • listener – a non-null listener where onDrained will be called
/** * 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; onDrained callbacks will be posted to the listener via the executor.
Params:
  • executor – a non-null executor to use for listener execution
  • listener – a non-null listener where onDrained will be called
  • name – an optional name used for debug logging
/** * 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.

The task cannot be started more than once without first having finished. Once draining begins with beginDrain, no new tasks can be started.

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.
See Also:
/** * 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 DrainListener.onDrained callback asynchronously.

This operation is idempotent; calling it more than once has no effect.

/** * 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.

The task cannot be finished if it hasn't started. Once finished, a task cannot be finished again (unless it's started again).

Throws:
See Also:
/** * 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); } }