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 17package com.android.camera.one.v2.photo; 18 19import static com.android.camera.one.v2.core.ResponseListeners.forFrameExposure; 20 21import android.hardware.camera2.CameraAccessException; 22import android.hardware.camera2.CameraDevice; 23 24import com.android.camera.async.BufferQueue; 25import com.android.camera.async.Updatable; 26import com.android.camera.async.UpdatableCountDownLatch; 27import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException; 28import com.android.camera.one.v2.camera2proxy.ImageProxy; 29import com.android.camera.one.v2.core.FrameServer; 30import com.android.camera.one.v2.core.RequestBuilder; 31import com.android.camera.one.v2.core.ResourceAcquisitionFailedException; 32import com.android.camera.one.v2.imagesaver.ImageSaver; 33import com.android.camera.one.v2.sharedimagereader.ManagedImageReader; 34import com.android.camera.one.v2.sharedimagereader.imagedistributor.ImageStream; 35 36import java.util.Arrays; 37 38import javax.annotation.ParametersAreNonnullByDefault; 39 40/** 41 * Captures single images. 42 */ 43@ParametersAreNonnullByDefault 44class SimpleImageCaptureCommand implements ImageCaptureCommand { 45 private final FrameServer mFrameServer; 46 private final RequestBuilder.Factory mBuilderFactory; 47 private final ManagedImageReader mImageReader; 48 49 public SimpleImageCaptureCommand(FrameServer frameServer, RequestBuilder.Factory builder, 50 ManagedImageReader imageReader) { 51 mFrameServer = frameServer; 52 mBuilderFactory = builder; 53 mImageReader = imageReader; 54 } 55 56 /** 57 * Sends a request to take a picture and blocks until it completes. 58 */ 59 @Override 60 public void run(Updatable<Void> imageExposureUpdatable, ImageSaver imageSaver) throws 61 InterruptedException, CameraAccessException, CameraCaptureSessionClosedException, 62 ResourceAcquisitionFailedException { 63 try (FrameServer.Session session = mFrameServer.createExclusiveSession(); 64 ImageStream imageStream = mImageReader.createStream(1)) { 65 UpdatableCountDownLatch<Void> exposureLatch = new UpdatableCountDownLatch<>(1); 66 RequestBuilder photoRequest = mBuilderFactory.create(CameraDevice 67 .TEMPLATE_STILL_CAPTURE); 68 photoRequest.addStream(imageStream); 69 MetadataFuture metadataFuture = new MetadataFuture(); 70 photoRequest.addResponseListener(metadataFuture); 71 photoRequest.addResponseListener(forFrameExposure(imageExposureUpdatable)); 72 photoRequest.addResponseListener(forFrameExposure(exposureLatch)); 73 session.submitRequest(Arrays.asList(photoRequest.build()), 74 FrameServer.RequestType.NON_REPEATING); 75 76 // Release the FrameServer session (allowing subsequent camera 77 // operations to occur) as soon as the image is exposed. 78 exposureLatch.await(); 79 session.close(); 80 81 ImageProxy image = imageStream.getNext(); 82 imageSaver.addFullSizeImage(image, metadataFuture.getMetadata()); 83 } catch (BufferQueue.BufferQueueClosedException e) { 84 // If we get here, the request was submitted, but the image 85 // never arrived. 86 // TODO Log failure and notify the caller 87 } finally { 88 imageSaver.close(); 89 } 90 } 91} 92