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