1bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde/* 2bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * Copyright (C) 2015 The Android Open Source Project 3bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * 4bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * Licensed under the Apache License, Version 2.0 (the "License"); 5bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * you may not use this file except in compliance with the License. 6bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * You may obtain a copy of the License at 7bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * 8bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * http://www.apache.org/licenses/LICENSE-2.0 9bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * 10bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * Unless required by applicable law or agreed to in writing, software 11bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * distributed under the License is distributed on an "AS IS" BASIS, 12bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * See the License for the specific language governing permissions and 14bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde * limitations under the License. 15bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde */ 16bb5cb5fa3d9e4ac18f4b4c9adaf237b804a09c56Paul Rohde 17b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdepackage com.android.camera.device; 18b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 19b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.async.Lifetime; 20b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.async.SafeCloseable; 21b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.google.common.util.concurrent.ListenableFuture; 22b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.google.common.util.concurrent.SettableFuture; 23b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 24b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport java.util.concurrent.atomic.AtomicBoolean; 25b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 26b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport javax.annotation.concurrent.ThreadSafe; 27b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 28b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde/** 29b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * ThreadSafe class to deal with the combined future and lifetime 30b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * for a single device request. 31b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 32b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde@ThreadSafe 33b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdepublic class SingleDeviceRequest<TDevice> implements SafeCloseable { 34b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final SettableFuture<TDevice> mFuture; 35b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Lifetime mLifetime; 36b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final AtomicBoolean mIsClosed; 37b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 38b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public SingleDeviceRequest(Lifetime lifetime) { 39b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLifetime = lifetime; 40b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mFuture = SettableFuture.create(); 41b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mIsClosed = new AtomicBoolean(false); 42b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 43b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 44b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 45b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Return the future instance for this request. 46b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 47b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public ListenableFuture<TDevice> getFuture() { 48b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde return mFuture; 49b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 50b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 51b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 52b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Return the lifetime instance for this request. 53b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 54b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public Lifetime getLifetime() { 55b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde return mLifetime; 56b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 57b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 58b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 59b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * If the future has not been set, set the value. 60b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 61b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public boolean set(TDevice device) { 62b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!mIsClosed.get()) { 63b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde return mFuture.set(device); 64b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } else { 65b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde return false; 66b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 67b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 68b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 69b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public boolean isClosed() { 70b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde return mIsClosed.get(); 71b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 72b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 73b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void closeWithException(Throwable throwable) { 74b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!mIsClosed.getAndSet(true)) { 75b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mFuture.setException(throwable); 76b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLifetime.close(); 77b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 78b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 79b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 80b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 81b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void close() { 82b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!mIsClosed.getAndSet(true)) { 83b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mFuture.cancel(true /* mayInterruptIfRunning */); 84b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLifetime.close(); 85b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 86b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 87b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde} 88