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.photo; 18 19 import static com.android.camera.one.v2.core.ResponseListeners.forFrameExposure; 20 21 import android.hardware.camera2.CameraAccessException; 22 import android.hardware.camera2.CameraDevice; 23 24 import com.android.camera.async.BufferQueue; 25 import com.android.camera.async.Updatable; 26 import com.android.camera.async.UpdatableCountDownLatch; 27 import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException; 28 import com.android.camera.one.v2.camera2proxy.ImageProxy; 29 import com.android.camera.one.v2.core.FrameServer; 30 import com.android.camera.one.v2.core.RequestBuilder; 31 import com.android.camera.one.v2.core.ResourceAcquisitionFailedException; 32 import com.android.camera.one.v2.imagesaver.ImageSaver; 33 import com.android.camera.one.v2.sharedimagereader.ManagedImageReader; 34 import com.android.camera.one.v2.sharedimagereader.imagedistributor.ImageStream; 35 36 import java.util.Arrays; 37 38 import javax.annotation.ParametersAreNonnullByDefault; 39 40 /** 41 * Captures single images. 42 */ 43 @ParametersAreNonnullByDefault 44 class SimpleImageCaptureCommand implements ImageCaptureCommand { 45 private final FrameServer mFrameServer; 46 private final RequestBuilder.Factory mBuilderFactory; 47 private final ManagedImageReader mImageReader; 48 SimpleImageCaptureCommand(FrameServer frameServer, RequestBuilder.Factory builder, ManagedImageReader imageReader)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 run(Updatable<Void> imageExposureUpdatable, ImageSaver imageSaver)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