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 */ 84 public void onCameraOpened(@Nonnull OneCamera camera); 85 86 /** 87 * Called if opening the camera failed. 88 */ 89 public void onFailure(); 90 91 /** 92 * Called if the camera is closed or disconnected while attempting to 93 * open. 94 */ 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. */ 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 */ 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 */ 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 */ 136 public void onQuickExpose(); 137 138 /** 139 * Called when a thumbnail image is provided before the final image is 140 * finished. 141 */ 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 */ 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 */ 156 public void onPictureSaved(Uri uri); 157 158 /** 159 * Called when picture taking failed. 160 */ 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 */ 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 */ 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 */ 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 */ 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 */ 224 public FocusState(float lensDistance, boolean isActive) { 225 this.lensDistance = lensDistance; 226 this.isActive = isActive; 227 } 228 229 @Override 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 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 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 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 307 Flash(@Nonnull String settingsString) { 308 mSettingsString = settingsString; 309 } 310 311 @Nonnull 312 public String encodeSettingsString() { 313 return mSettingsString; 314 } 315 316 @Nonnull 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 395 public void startPreview(Surface surface, CaptureReadyCallback listener); 396 397 /** 398 * Closes the camera. 399 */ 400 public void close(); 401 402 /** 403 * @return The direction of the camera. 404 */ 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 */ 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 */ 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 */ 435 public Size pickPreviewSize(Size pictureSize, Context context); 436 } 437