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;
18 
19 import android.app.Activity;
20 import android.location.Location;
21 import android.net.Uri;
22 import android.view.Surface;
23 
24 import com.android.camera.session.CaptureSession;
25 import com.android.camera.settings.SettingsManager;
26 import com.android.camera.ui.motion.LinearScale;
27 import com.android.camera.util.Size;
28 
29 import java.io.File;
30 
31 import javax.annotation.Nonnull;
32 
33 /**
34  * OneCamera is a camera API tailored around our Google Camera application
35  * needs. It's not a general purpose API but instead offers an API with exactly
36  * what's needed from the app's side.
37  */
38 public interface OneCamera {
39 
40     /** Which way the camera is facing. */
41     public static enum Facing {
42         FRONT, BACK;
43     }
44 
45     /**
46      * Auto focus system status; 1:1 mapping from camera2 AF_STATE.
47      * <ul>
48      * <li>{@link #INACTIVE}</li>
49      * <li>{@link #ACTIVE_SCAN}</li>
50      * <li>{@link #ACTIVE_FOCUSED}</li>
51      * <li>{@link #ACTIVE_UNFOCUSED}</li>
52      * <li>{@link #PASSIVE_SCAN}</li>
53      * <li>{@link #PASSIVE_FOCUSED}</li>
54      * <li>{@link #PASSIVE_UNFOCUSED}</li>
55      * </ul>
56      */
57     public static enum AutoFocusState {
58         /** Indicates AF system is inactive for some reason (could be an error). */
59         INACTIVE,
60         /** Indicates active scan in progress. */
61         ACTIVE_SCAN,
62         /** Indicates active scan success (in focus). */
63         ACTIVE_FOCUSED,
64         /** Indicates active scan failure (not in focus). */
65         ACTIVE_UNFOCUSED,
66         /** Indicates passive scan in progress. */
67         PASSIVE_SCAN,
68         /** Indicates passive scan success (in focus). */
69         PASSIVE_FOCUSED,
70         /** Indicates passive scan failure (not in focus). */
71         PASSIVE_UNFOCUSED
72     }
73 
74     /**
75      * Classes implementing this interface will be called when the camera was
76      * opened or failed to open.
77      */
78     public static interface OpenCallback {
79         /**
80          * Called when the camera was opened successfully.
81          *
82          * @param camera the camera instance that was successfully opened
83          */
onCameraOpened(@onnull OneCamera camera)84         public void onCameraOpened(@Nonnull OneCamera camera);
85 
86         /**
87          * Called if opening the camera failed.
88          */
onFailure()89         public void onFailure();
90 
91         /**
92          * Called if the camera is currently being used by a higher priority application.
93          **/
onCameraInUse()94         public void onCameraInUse();
95 
96         /**
97          * Called if the camera is closed or disconnected while attempting to
98          * open.
99          */
onCameraClosed()100         public void onCameraClosed();
101 
102         /**
103          * Called if the camera is disconnected after successfully opening
104          */
onCameraInterrupted()105         public void onCameraInterrupted();
106     }
107 
108     /**
109      * Classes implementing this interface can be informed when we're ready to
110      * take a picture of if setting up the capture pipeline failed.
111      */
112     public static interface CaptureReadyCallback {
113         /** After this is called, the system is ready for capture requests. */
onReadyForCapture()114         public void onReadyForCapture();
115 
116         /**
117          * Indicates that something went wrong during setup and the system is
118          * not ready for capture requests.
119          */
onSetupFailed()120         public void onSetupFailed();
121     }
122 
123     /**
124      * Classes implementing this interface can be informed when the state of
125      * capture changes.
126      */
127     public static interface ReadyStateChangedListener {
128         /**
129          * Called when the camera is either ready or not ready to take a picture
130          * right now.
131          */
onReadyStateChanged(boolean readyForCapture)132         public void onReadyStateChanged(boolean readyForCapture);
133     }
134 
135     /**
136      * A class implementing this interface can be passed into the call to take a
137      * picture in order to receive the resulting image or updated about the
138      * progress.
139      */
140     public static interface PictureCallback {
141         /**
142          * Called near the the when an image is being exposed for cameras which
143          * are exposing a single frame, so that a UI can be presented for the
144          * capture.
145          */
onQuickExpose()146         public void onQuickExpose();
147 
148         /**
149          * Called when a thumbnail image is provided before the final image is
150          * finished.
151          */
onThumbnailResult(byte[] jpegData)152         public void onThumbnailResult(byte[] jpegData);
153 
154         /**
155          * Called when the final picture is done taking
156          *
157          * @param session the capture session
158          */
onPictureTaken(CaptureSession session)159         public void onPictureTaken(CaptureSession session);
160 
161         /**
162          * Called when the picture has been saved to disk.
163          *
164          * @param uri the URI of the stored data.
165          */
onPictureSaved(Uri uri)166         public void onPictureSaved(Uri uri);
167 
168         /**
169          * Called when picture taking failed.
170          */
onPictureTakingFailed()171         public void onPictureTakingFailed();
172 
173         /**
174          * Called when capture session is reporting a processing update. This
175          * should only be called by capture sessions that require the user to
176          * hold still for a while.
177          *
178          * @param progress a value from 0...1, indicating the current processing
179          *            progress.
180          */
onTakePictureProgress(float progress)181         public void onTakePictureProgress(float progress);
182     }
183 
184     /**
185      * A class implementing this interface can be passed to a picture saver in
186      * order to receive image processing events.
187      */
188     public static interface PictureSaverCallback {
189         /**
190          * Called when compressed data for Thumbnail on a remote device (such as
191          * Android wear) is available.
192          */
onRemoteThumbnailAvailable(byte[] jpegImage)193         public void onRemoteThumbnailAvailable(byte[] jpegImage);
194     }
195 
196     /**
197      * Classes implementing this interface will be called when the state of the
198      * focus changes. Guaranteed not to stay stuck in scanning state past some
199      * reasonable timeout even if Camera API is stuck.
200      */
201     public static interface FocusStateListener {
202         /**
203          * Called when state of auto focus system changes.
204          *
205          * @param state Current auto focus state.
206          * @param frameNumber Frame number if available.
207          */
onFocusStatusUpdate(AutoFocusState state, long frameNumber)208         public void onFocusStatusUpdate(AutoFocusState state, long frameNumber);
209     }
210 
211     /**
212      * Classes implementing this interface will be called when the focus
213      * distance of the physical lens changes.
214      */
215     public static interface FocusDistanceListener {
216         /**
217          * Called when physical lens distance on the camera changes.
218          */
onFocusDistance(float distance, LinearScale lensRange)219         public void onFocusDistance(float distance, LinearScale lensRange);
220     }
221 
222     /**
223      * Single instance of the current camera AF state.
224      */
225     public static class FocusState {
226         public final float lensDistance;
227         public final boolean isActive;
228 
229         /**
230          * @param lensDistance The current focal distance.
231          * @param isActive Whether the lens is moving, e.g. because of either an
232          *            "active scan" or a "passive scan".
233          */
FocusState(float lensDistance, boolean isActive)234         public FocusState(float lensDistance, boolean isActive) {
235             this.lensDistance = lensDistance;
236             this.isActive = isActive;
237         }
238 
239         @Override
equals(Object o)240         public boolean equals(Object o) {
241             if (this == o)
242                 return true;
243             if (o == null || getClass() != o.getClass())
244                 return false;
245 
246             FocusState that = (FocusState) o;
247 
248             if (Float.compare(that.lensDistance, lensDistance) != 0)
249                 return false;
250             if (isActive != that.isActive)
251                 return false;
252 
253             return true;
254         }
255 
256         @Override
hashCode()257         public int hashCode() {
258             int result = (lensDistance != +0.0f ? Float.floatToIntBits(lensDistance) : 0);
259             result = 31 * result + (isActive ? 1 : 0);
260             return result;
261         }
262 
263         @Override
toString()264         public String toString() {
265             return "FocusState{" +
266                   "lensDistance=" + lensDistance +
267                   ", isActive=" + isActive +
268                   '}';
269         }
270     }
271 
272     /**
273      * Parameters to be given to capture requests.
274      */
275     public static abstract class CaptureParameters {
276         /** The title/filename (without suffix) for this capture. */
277         public final String title;
278 
279         /** The device orientation so we can compute the right JPEG rotation. */
280         public final int orientation;
281 
282         /** The location of this capture. */
283         public final Location location;
284 
285         /** Set this to provide a debug folder for this capture. */
286         public final File debugDataFolder;
287 
CaptureParameters(String title, int orientation, Location location, File debugDataFolder)288         public CaptureParameters(String title, int orientation, Location location, File
289                 debugDataFolder) {
290             this.title = title;
291             this.orientation = orientation;
292             this.location = location;
293             this.debugDataFolder = debugDataFolder;
294         }
295     }
296 
297     /**
298      * Parameters to be given to photo capture requests.
299      */
300     public static class PhotoCaptureParameters extends CaptureParameters {
301         /**
302          * Flash modes.
303          * <p>
304          */
305         public static enum Flash {
306             AUTO("auto"), OFF("off"), ON("on");
307 
308             /**
309              * The machine-readable (via {@link #encodeSettingsString} and
310              * {@link #decodeSettingsString} string used to represent this flash
311              * mode in {@link SettingsManager}.
312              * <p>
313              * This must be in sync with R.arrays.pref_camera_flashmode_entryvalues.
314              */
315             private final String mSettingsString;
316 
Flash(@onnull String settingsString)317             Flash(@Nonnull String settingsString) {
318                 mSettingsString = settingsString;
319             }
320 
321             @Nonnull
encodeSettingsString()322             public String encodeSettingsString() {
323                 return mSettingsString;
324             }
325 
326             @Nonnull
decodeSettingsString(@onnull String setting)327             public static Flash decodeSettingsString(@Nonnull String setting) {
328                 if (AUTO.encodeSettingsString().equals(setting)) {
329                     return AUTO;
330                 } else if (OFF.encodeSettingsString().equals(setting)) {
331                     return OFF;
332                 } else if (ON.encodeSettingsString().equals(setting)) {
333                     return ON;
334                 }
335                 throw new IllegalArgumentException("Not a valid setting");
336             }
337         }
338 
339         /** Called when the capture is completed or failed. */
340         public final PictureCallback callback;
341         public final PictureSaverCallback saverCallback;
342         /** The heading of the device at time of capture. In degrees. */
343         public final int heading;
344         /** Zoom value. */
345         public final float zoom;
346         /** Timer duration in seconds or 0 for no timer. */
347         public final float timerSeconds;
348 
PhotoCaptureParameters(String title, int orientation, Location location, File debugDataFolder, PictureCallback callback, PictureSaverCallback saverCallback, int heading, float zoom, float timerSeconds)349         public PhotoCaptureParameters(String title, int orientation, Location location, File
350                 debugDataFolder, PictureCallback callback, PictureSaverCallback saverCallback,
351                 int heading, float zoom, float timerSeconds) {
352             super(title, orientation, location, debugDataFolder);
353             this.callback = callback;
354             this.saverCallback = saverCallback;
355             this.heading = heading;
356             this.zoom = zoom;
357             this.timerSeconds = timerSeconds;
358         }
359     }
360 
361 
362     /**
363      * Meters and triggers auto focus scan with ROI around tap point.
364      * <p/>
365      * Normalized coordinates are referenced to portrait preview window with (0,
366      * 0) top left and (1, 1) bottom right. Rotation has no effect.
367      *
368      * @param nx normalized x coordinate.
369      * @param ny normalized y coordinate.
370      */
triggerFocusAndMeterAtPoint(float nx, float ny)371     public void triggerFocusAndMeterAtPoint(float nx, float ny);
372 
373     /**
374      * Call this to take a picture.
375      *
376      * @param params parameters for taking pictures.
377      * @param session the capture session for this picture.
378      */
takePicture(PhotoCaptureParameters params, CaptureSession session)379     public void takePicture(PhotoCaptureParameters params, CaptureSession session);
380 
381     /**
382      * Sets or replaces a listener that is called whenever the focus state of
383      * the camera changes.
384      */
setFocusStateListener(FocusStateListener listener)385     public void setFocusStateListener(FocusStateListener listener);
386 
387     /**
388      * Sets or replaces a listener that is called whenever the focus state of
389      * the camera changes.
390      */
setFocusDistanceListener(FocusDistanceListener listener)391     public void setFocusDistanceListener(FocusDistanceListener listener);
392 
393     /**
394      * Sets or replaces a listener that is called whenever the state of the
395      * camera changes to be either ready or not ready to take another picture.
396      */
setReadyStateChangedListener(ReadyStateChangedListener listener)397     public void setReadyStateChangedListener(ReadyStateChangedListener listener);
398 
399     /**
400      * Starts a preview stream and renders it to the given surface.
401      *
402      * @param surface the surface on which to render preview frames
403      * @param listener
404      */
startPreview(Surface surface, CaptureReadyCallback listener)405     public void startPreview(Surface surface, CaptureReadyCallback listener);
406 
407     /**
408      * Closes the camera.
409      */
close()410     public void close();
411 
412     /**
413      * @return The direction of the camera.
414      */
getDirection()415     public Facing getDirection();
416 
417     /**
418      * Get the maximum zoom value.
419      *
420      * @return A float number to represent the maximum zoom value(>= 1.0).
421      */
getMaxZoom()422     public float getMaxZoom();
423 
424     /**
425      * This function sets the current zoom ratio value.
426      * <p>
427      * The zoom range must be [1.0, maxZoom]. The maxZoom can be queried by
428      * {@link #getMaxZoom}.
429      *
430      * @param zoom Zoom ratio value passed to scaler.
431      */
setZoom(float zoom)432     public void setZoom(float zoom);
433 
434     /**
435      * Based on the selected picture size, this returns the best preview size.
436      *
437      * @param pictureSize the picture size as selected by the user. A camera
438      *            might choose not to obey these and therefore the returned
439      *            preview size might not match the aspect ratio of the given
440      *            size.
441      * @param context the android activity context
442      * @return The preview size that best matches the picture aspect ratio that
443      *         will be taken.
444      */
pickPreviewSize(Size pictureSize, Activity context)445     public Size pickPreviewSize(Size pictureSize, Activity context);
446 }
447