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 17 package com.android.camera.one.v2.core; 18 19 import static com.google.common.base.Preconditions.checkState; 20 21 import android.hardware.camera2.CameraAccessException; 22 23 import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException; 24 25 import java.util.List; 26 import java.util.concurrent.locks.ReentrantLock; 27 28 import javax.annotation.Nonnull; 29 import javax.annotation.Nullable; 30 31 /** 32 * Implements a FrameServer by managing exclusive access to a single 33 * {@link FrameServer.Session}. 34 */ 35 public final class FrameServerImpl implements FrameServer { 36 public class Session implements FrameServer.Session { 37 private final Object mLock; 38 private boolean mClosed; 39 40 private Session() { 41 mLock = new Object(); 42 mClosed = false; 43 } 44 45 @Override 46 public void submitRequest(List<Request> burstRequests, RequestType type) 47 throws CameraAccessException, InterruptedException, 48 CameraCaptureSessionClosedException, ResourceAcquisitionFailedException { 49 synchronized (mLock) { 50 try { 51 if (mClosed) { 52 throw new SessionClosedException(); 53 } 54 55 mCaptureSession.submitRequest(burstRequests, type); 56 } catch (Exception e) { 57 for (Request r : burstRequests) { 58 r.abort(); 59 } 60 throw e; 61 } 62 } 63 } 64 65 @Override 66 public void close() { 67 synchronized (mLock) { 68 if (!mClosed) { 69 mClosed = true; 70 mCameraLock.unlock(); 71 } 72 } 73 } 74 } 75 76 private final FrameServer.Session mCaptureSession; 77 private final ReentrantLock mCameraLock; 78 79 /** 80 * @param captureSession The underlying session to manage access to. Note 81 * that this will never close the session. 82 */ 83 public FrameServerImpl(FrameServer.Session captureSession) { 84 mCaptureSession = captureSession; 85 mCameraLock = new ReentrantLock(true); 86 } 87 88 @Override 89 @Nonnull 90 public Session createExclusiveSession() throws InterruptedException { 91 checkState(!mCameraLock.isHeldByCurrentThread(), "Cannot acquire another " + 92 "FrameServer.Session on the same thread."); 93 mCameraLock.lockInterruptibly(); 94 return new Session(); 95 } 96 97 @Override 98 @Nullable 99 public Session tryCreateExclusiveSession() { 100 if (mCameraLock.isHeldByCurrentThread()) { 101 return null; 102 } 103 if (mCameraLock.tryLock()) { 104 return new Session(); 105 } else { 106 return null; 107 } 108 } 109 } 110