Home | History | Annotate | Download | only in core
      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