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