1 /* 2 * Copyright (C) 2015 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 17 package com.android.camera.device; 18 19 import com.android.camera.async.Lifetime; 20 import com.android.camera.async.SafeCloseable; 21 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.SettableFuture; 23 24 import java.util.concurrent.atomic.AtomicBoolean; 25 26 import javax.annotation.concurrent.ThreadSafe; 27 28 /** 29 * ThreadSafe class to deal with the combined future and lifetime 30 * for a single device request. 31 */ 32 @ThreadSafe 33 public class SingleDeviceRequest<TDevice> implements SafeCloseable { 34 private final SettableFuture<TDevice> mFuture; 35 private final Lifetime mLifetime; 36 private final AtomicBoolean mIsClosed; 37 SingleDeviceRequest(Lifetime lifetime)38 public SingleDeviceRequest(Lifetime lifetime) { 39 mLifetime = lifetime; 40 mFuture = SettableFuture.create(); 41 mIsClosed = new AtomicBoolean(false); 42 } 43 44 /** 45 * Return the future instance for this request. 46 */ getFuture()47 public ListenableFuture<TDevice> getFuture() { 48 return mFuture; 49 } 50 51 /** 52 * Return the lifetime instance for this request. 53 */ getLifetime()54 public Lifetime getLifetime() { 55 return mLifetime; 56 } 57 58 /** 59 * If the future has not been set, set the value. 60 */ set(TDevice device)61 public boolean set(TDevice device) { 62 if (!mIsClosed.get()) { 63 return mFuture.set(device); 64 } else { 65 return false; 66 } 67 } 68 isClosed()69 public boolean isClosed() { 70 return mIsClosed.get(); 71 } 72 closeWithException(Throwable throwable)73 public void closeWithException(Throwable throwable) { 74 if (!mIsClosed.getAndSet(true)) { 75 mFuture.setException(throwable); 76 mLifetime.close(); 77 } 78 } 79 80 @Override close()81 public void close() { 82 if (!mIsClosed.getAndSet(true)) { 83 mFuture.cancel(true /* mayInterruptIfRunning */); 84 mLifetime.close(); 85 } 86 } 87 } 88