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