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 package android.hardware.camera2.utils; 17 18 import android.hardware.camera2.utils.TaskDrainer.DrainListener; 19 import android.os.Handler; 20 21 /** 22 * Keep track of a single concurrent task starting and finishing; 23 * allow draining the existing task and figuring out when the task has finished 24 * (and won't restart). 25 * 26 * <p>The initial state is to allow all tasks to be started and finished. A task may only be started 27 * once, after which it must be finished before starting again. Likewise, finishing a task 28 * that hasn't been started is also not allowed.</p> 29 * 30 * <p>When draining begins, the task cannot be started again. This guarantees that at some 31 * point the task will be finished forever, at which point the {@link DrainListener#onDrained} 32 * callback will be invoked.</p> 33 */ 34 public class TaskSingleDrainer { 35 36 private final TaskDrainer<Object> mTaskDrainer; 37 private final Object mSingleTask = new Object(); 38 39 /** 40 * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener 41 * via the {@code handler}. 42 * 43 * @param handler a non-{@code null} handler to use to post runnables to 44 * @param listener a non-{@code null} listener where {@code onDrained} will be called 45 */ 46 public TaskSingleDrainer(Handler handler, DrainListener listener) { 47 mTaskDrainer = new TaskDrainer<>(handler, listener); 48 } 49 50 /** 51 * Create a new task drainer; {@code onDrained} callbacks will be posted to the listener 52 * via the {@code handler}. 53 * 54 * @param handler a non-{@code null} handler to use to post runnables to 55 * @param listener a non-{@code null} listener where {@code onDrained} will be called 56 * @param name an optional name used for debug logging 57 */ 58 public TaskSingleDrainer(Handler handler, DrainListener listener, String name) { 59 mTaskDrainer = new TaskDrainer<>(handler, listener, name); 60 } 61 62 /** 63 * Mark this asynchronous task as having started. 64 * 65 * <p>The task cannot be started more than once without first having finished. Once 66 * draining begins with {@link #beginDrain}, no new tasks can be started.</p> 67 * 68 * @see #taskFinished 69 * @see #beginDrain 70 * 71 * @throws IllegalStateException 72 * If attempting to start a task which is already started (and not finished), 73 * or if attempting to start a task after draining has begun. 74 */ 75 public void taskStarted() { 76 mTaskDrainer.taskStarted(mSingleTask); 77 } 78 79 /** 80 * Do not allow any more task re-starts; once the existing task is finished, 81 * fire the {@link DrainListener#onDrained} callback asynchronously. 82 * 83 * <p>This operation is idempotent; calling it more than once has no effect.</p> 84 */ 85 public void beginDrain() { 86 mTaskDrainer.beginDrain(); 87 } 88 89 /** 90 * Mark this asynchronous task as having finished. 91 * 92 * <p>The task cannot be finished if it hasn't started. Once finished, a task 93 * cannot be finished again (unless it's started again).</p> 94 * 95 * @see #taskStarted 96 * @see #beginDrain 97 * 98 * @throws IllegalStateException 99 * If attempting to start a task which is already finished (and not re-started), 100 */ 101 public void taskFinished() { 102 mTaskDrainer.taskFinished(mSingleTask); 103 } 104 } 105