Camera.java revision a1b653d41df9a7999e1dba2a508295671ff6771d
1/* 2 * Copyright (C) 2008 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 17package android.hardware; 18 19import java.lang.ref.WeakReference; 20import java.util.HashMap; 21import java.util.StringTokenizer; 22import java.io.IOException; 23 24import android.util.Log; 25import android.view.Surface; 26import android.view.SurfaceHolder; 27import android.graphics.PixelFormat; 28import android.os.Handler; 29import android.os.Looper; 30import android.os.Message; 31 32/** 33 * The Camera class is used to connect/disconnect with the camera service, 34 * set capture settings, start/stop preview, snap a picture, and retrieve 35 * frames for encoding for video. 36 * <p>There is no default constructor for this class. Use {@link #open()} to 37 * get a Camera object.</p> 38 */ 39public class Camera { 40 private static final String TAG = "Camera"; 41 42 // These match the enums in frameworks/base/include/ui/Camera.h 43 private static final int CAMERA_MSG_ERROR = 0; 44 private static final int CAMERA_MSG_SHUTTER = 1; 45 private static final int CAMERA_MSG_FOCUS = 2; 46 private static final int CAMERA_MSG_ZOOM = 3; 47 private static final int CAMERA_MSG_PREVIEW_FRAME = 4; 48 private static final int CAMERA_MSG_VIDEO_FRAME = 5; 49 private static final int CAMERA_MSG_POSTVIEW_FRAME = 6; 50 private static final int CAMERA_MSG_RAW_IMAGE = 7; 51 private static final int CAMERA_MSG_COMPRESSED_IMAGE = 8; 52 53 private int mNativeContext; // accessed by native methods 54 private EventHandler mEventHandler; 55 private ShutterCallback mShutterCallback; 56 private PictureCallback mRawImageCallback; 57 private PictureCallback mJpegCallback; 58 private PreviewCallback mPreviewCallback; 59 private AutoFocusCallback mAutoFocusCallback; 60 private ErrorCallback mErrorCallback; 61 private boolean mOneShot; 62 63 /** 64 * Returns a new Camera object. 65 */ 66 public static Camera open() { 67 return new Camera(); 68 } 69 70 Camera() { 71 mShutterCallback = null; 72 mRawImageCallback = null; 73 mJpegCallback = null; 74 mPreviewCallback = null; 75 76 Looper looper; 77 if ((looper = Looper.myLooper()) != null) { 78 mEventHandler = new EventHandler(this, looper); 79 } else if ((looper = Looper.getMainLooper()) != null) { 80 mEventHandler = new EventHandler(this, looper); 81 } else { 82 mEventHandler = null; 83 } 84 85 native_setup(new WeakReference<Camera>(this)); 86 } 87 88 protected void finalize() { 89 native_release(); 90 } 91 92 private native final void native_setup(Object camera_this); 93 private native final void native_release(); 94 95 96 /** 97 * Disconnects and releases the Camera object resources. 98 * <p>It is recommended that you call this as soon as you're done with the 99 * Camera object.</p> 100 */ 101 public final void release() { 102 native_release(); 103 } 104 105 /** 106 * Reconnect to the camera after passing it to MediaRecorder. To save 107 * setup/teardown time, a client of Camera can pass an initialized Camera 108 * object to a MediaRecorder to use for video recording. Once the 109 * MediaRecorder is done with the Camera, this method can be used to 110 * re-establish a connection with the camera hardware. NOTE: The Camera 111 * object must first be unlocked by the process that owns it before it 112 * can be connected to another proces. 113 * 114 * @throws IOException if the method fails. 115 * 116 * FIXME: Unhide after approval 117 * @hide 118 */ 119 public native final void reconnect() throws IOException; 120 121 /** 122 * Lock the camera to prevent other processes from accessing it. To save 123 * setup/teardown time, a client of Camera can pass an initialized Camera 124 * object to another process. This method is used to re-lock the Camera 125 * object prevent other processes from accessing it. By default, the 126 * Camera object is locked. Locking it again from the same process will 127 * have no effect. Attempting to lock it from another process if it has 128 * not been unlocked will fail. 129 * Returns 0 if lock was successful. 130 * 131 * FIXME: Unhide after approval 132 * @hide 133 */ 134 public native final int lock(); 135 136 /** 137 * Unlock the camera to allow aother process to access it. To save 138 * setup/teardown time, a client of Camera can pass an initialized Camera 139 * object to another process. This method is used to unlock the Camera 140 * object before handing off the Camera object to the other process. 141 142 * Returns 0 if unlock was successful. 143 * 144 * FIXME: Unhide after approval 145 * @hide 146 */ 147 public native final int unlock(); 148 149 /** 150 * Sets the SurfaceHolder to be used for a picture preview. If the surface 151 * changed since the last call, the screen will blank. Nothing happens 152 * if the same surface is re-set. 153 * 154 * @param holder the SurfaceHolder upon which to place the picture preview 155 * @throws IOException if the method fails. 156 */ 157 public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { 158 if (holder != null) { 159 setPreviewDisplay(holder.getSurface()); 160 } else { 161 setPreviewDisplay((Surface)null); 162 } 163 } 164 165 private native final void setPreviewDisplay(Surface surface); 166 167 /** 168 * Used to get a copy of each preview frame. 169 */ 170 public interface PreviewCallback 171 { 172 /** 173 * The callback that delivers the preview frames. 174 * 175 * @param data The contents of the preview frame in getPreviewFormat() 176 * format. 177 * @param camera The Camera service object. 178 */ 179 void onPreviewFrame(byte[] data, Camera camera); 180 }; 181 182 /** 183 * Start drawing preview frames to the surface. 184 */ 185 public native final void startPreview(); 186 187 /** 188 * Stop drawing preview frames to the surface. 189 */ 190 public native final void stopPreview(); 191 192 /** 193 * Return current preview state. 194 * 195 * FIXME: Unhide before release 196 * @hide 197 */ 198 public native final boolean previewEnabled(); 199 200 /** 201 * Can be called at any time to instruct the camera to use a callback for 202 * each preview frame in addition to displaying it. 203 * 204 * @param cb A callback object that receives a copy of each preview frame. 205 * Pass null to stop receiving callbacks at any time. 206 */ 207 public final void setPreviewCallback(PreviewCallback cb) { 208 mPreviewCallback = cb; 209 mOneShot = false; 210 setHasPreviewCallback(cb != null, false); 211 } 212 213 /** 214 * Installs a callback to retrieve a single preview frame, after which the 215 * callback is cleared. 216 * 217 * @param cb A callback object that receives a copy of the preview frame. 218 */ 219 public final void setOneShotPreviewCallback(PreviewCallback cb) { 220 if (cb != null) { 221 mPreviewCallback = cb; 222 mOneShot = true; 223 setHasPreviewCallback(true, true); 224 } 225 } 226 227 private native final void setHasPreviewCallback(boolean installed, boolean oneshot); 228 229 private class EventHandler extends Handler 230 { 231 private Camera mCamera; 232 233 public EventHandler(Camera c, Looper looper) { 234 super(looper); 235 mCamera = c; 236 } 237 238 @Override 239 public void handleMessage(Message msg) { 240 switch(msg.what) { 241 case CAMERA_MSG_SHUTTER: 242 if (mShutterCallback != null) { 243 mShutterCallback.onShutter(); 244 } 245 return; 246 247 case CAMERA_MSG_RAW_IMAGE: 248 if (mRawImageCallback != null) 249 mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera); 250 return; 251 252 case CAMERA_MSG_COMPRESSED_IMAGE: 253 if (mJpegCallback != null) 254 mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera); 255 return; 256 257 case CAMERA_MSG_PREVIEW_FRAME: 258 if (mPreviewCallback != null) { 259 mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera); 260 if (mOneShot) { 261 mPreviewCallback = null; 262 } 263 } 264 return; 265 266 case CAMERA_MSG_FOCUS: 267 if (mAutoFocusCallback != null) 268 mAutoFocusCallback.onAutoFocus(msg.arg1 == 0 ? false : true, mCamera); 269 return; 270 271 case CAMERA_MSG_ERROR : 272 Log.e(TAG, "Error " + msg.arg1); 273 if (mErrorCallback != null) 274 mErrorCallback.onError(msg.arg1, mCamera); 275 return; 276 277 default: 278 Log.e(TAG, "Unknown message type " + msg.what); 279 return; 280 } 281 } 282 } 283 284 private static void postEventFromNative(Object camera_ref, 285 int what, int arg1, int arg2, Object obj) 286 { 287 Camera c = (Camera)((WeakReference)camera_ref).get(); 288 if (c == null) 289 return; 290 291 if (c.mEventHandler != null) { 292 Message m = c.mEventHandler.obtainMessage(what, arg1, arg2, obj); 293 c.mEventHandler.sendMessage(m); 294 } 295 } 296 297 /** 298 * Handles the callback for the camera auto focus. 299 */ 300 public interface AutoFocusCallback 301 { 302 /** 303 * Callback for the camera auto focus. 304 * 305 * @param success true if focus was successful, false if otherwise 306 * @param camera the Camera service object 307 */ 308 void onAutoFocus(boolean success, Camera camera); 309 }; 310 311 /** 312 * Starts auto-focus function and registers a callback function to 313 * run when camera is focused. Only valid after startPreview() has 314 * been called. 315 * 316 * @param cb the callback to run 317 */ 318 public final void autoFocus(AutoFocusCallback cb) 319 { 320 mAutoFocusCallback = cb; 321 native_autoFocus(); 322 } 323 private native final void native_autoFocus(); 324 325 /** 326 * An interface which contains a callback for the shutter closing after taking a picture. 327 */ 328 public interface ShutterCallback 329 { 330 /** 331 * Can be used to play a shutter sound as soon as the image has been captured, but before 332 * the data is available. 333 */ 334 void onShutter(); 335 } 336 337 /** 338 * Handles the callback for when a picture is taken. 339 */ 340 public interface PictureCallback { 341 /** 342 * Callback for when a picture is taken. 343 * 344 * @param data a byte array of the picture data 345 * @param camera the Camera service object 346 */ 347 void onPictureTaken(byte[] data, Camera camera); 348 }; 349 350 /** 351 * Triggers an asynchronous image capture. The camera service 352 * will initiate a series of callbacks to the application as the 353 * image capture progresses. The shutter callback occurs after 354 * the image is captured. This can be used to trigger a sound 355 * to let the user know that image has been captured. The raw 356 * callback occurs when the raw image data is available. The jpeg 357 * callback occurs when the compressed image is available. If the 358 * application does not need a particular callback, a null can be 359 * passed instead of a callback method. 360 * 361 * @param shutter callback after the image is captured, may be null 362 * @param raw callback with raw image data, may be null 363 * @param jpeg callback with jpeg image data, may be null 364 */ 365 public final void takePicture(ShutterCallback shutter, PictureCallback raw, 366 PictureCallback jpeg) { 367 mShutterCallback = shutter; 368 mRawImageCallback = raw; 369 mJpegCallback = jpeg; 370 native_takePicture(); 371 } 372 private native final void native_takePicture(); 373 374 // These match the enum in include/ui/Camera.h 375 /** Unspecified camerar error. @see #ErrorCallback */ 376 public static final int CAMERA_ERROR_UNKNOWN = 1; 377 /** Media server died. In this case, the application must release the 378 * Camera object and instantiate a new one. @see #ErrorCallback */ 379 public static final int CAMERA_ERROR_SERVER_DIED = 100; 380 381 /** 382 * Handles the camera error callback. 383 */ 384 public interface ErrorCallback 385 { 386 /** 387 * Callback for camera errors. 388 * @param error error code: 389 * <ul> 390 * <li>{@link #CAMERA_ERROR_UNKNOWN} 391 * <li>{@link #CAMERA_ERROR_SERVER_DIED} 392 * </ul> 393 * @param camera the Camera service object 394 */ 395 void onError(int error, Camera camera); 396 }; 397 398 /** 399 * Registers a callback to be invoked when an error occurs. 400 * @param cb the callback to run 401 */ 402 public final void setErrorCallback(ErrorCallback cb) 403 { 404 mErrorCallback = cb; 405 } 406 407 private native final void native_setParameters(String params); 408 private native final String native_getParameters(); 409 410 /** 411 * Sets the Parameters for pictures from this Camera service. 412 * 413 * @param params the Parameters to use for this Camera service 414 */ 415 public void setParameters(Parameters params) { 416 native_setParameters(params.flatten()); 417 } 418 419 /** 420 * Returns the picture Parameters for this Camera service. 421 */ 422 public Parameters getParameters() { 423 Parameters p = new Parameters(); 424 String s = native_getParameters(); 425 p.unflatten(s); 426 return p; 427 } 428 429 /** 430 * Handles the picture size (dimensions). 431 */ 432 public class Size { 433 /** 434 * Sets the dimensions for pictures. 435 * 436 * @param w the photo width (pixels) 437 * @param h the photo height (pixels) 438 */ 439 public Size(int w, int h) { 440 width = w; 441 height = h; 442 } 443 /** width of the picture */ 444 public int width; 445 /** height of the picture */ 446 public int height; 447 }; 448 449 /** 450 * Handles the parameters for pictures created by a Camera service. 451 */ 452 public class Parameters { 453 private HashMap<String, String> mMap; 454 455 private Parameters() { 456 mMap = new HashMap<String, String>(); 457 } 458 459 /** 460 * Writes the current Parameters to the log. 461 * @hide 462 * @deprecated 463 */ 464 public void dump() { 465 Log.e(TAG, "dump: size=" + mMap.size()); 466 for (String k : mMap.keySet()) { 467 Log.e(TAG, "dump: " + k + "=" + mMap.get(k)); 468 } 469 } 470 471 /** 472 * Creates a single string with all the parameters set in 473 * this Parameters object. 474 * <p>The {@link #unflatten(String)} method does the reverse.</p> 475 * 476 * @return a String with all values from this Parameters object, in 477 * semi-colon delimited key-value pairs 478 */ 479 public String flatten() { 480 StringBuilder flattened = new StringBuilder(); 481 for (String k : mMap.keySet()) { 482 flattened.append(k); 483 flattened.append("="); 484 flattened.append(mMap.get(k)); 485 flattened.append(";"); 486 } 487 // chop off the extra semicolon at the end 488 flattened.deleteCharAt(flattened.length()-1); 489 return flattened.toString(); 490 } 491 492 /** 493 * Takes a flattened string of parameters and adds each one to 494 * this Parameters object. 495 * <p>The {@link #flatten()} method does the reverse.</p> 496 * 497 * @param flattened a String of parameters (key-value paired) that 498 * are semi-colon delimited 499 */ 500 public void unflatten(String flattened) { 501 mMap.clear(); 502 503 StringTokenizer tokenizer = new StringTokenizer(flattened, ";"); 504 while (tokenizer.hasMoreElements()) { 505 String kv = tokenizer.nextToken(); 506 int pos = kv.indexOf('='); 507 if (pos == -1) { 508 continue; 509 } 510 String k = kv.substring(0, pos); 511 String v = kv.substring(pos + 1); 512 mMap.put(k, v); 513 } 514 } 515 516 public void remove(String key) { 517 mMap.remove(key); 518 } 519 520 /** 521 * Sets a String parameter. 522 * 523 * @param key the key name for the parameter 524 * @param value the String value of the parameter 525 */ 526 public void set(String key, String value) { 527 if (key.indexOf('=') != -1 || key.indexOf(';') != -1) { 528 Log.e(TAG, "Key \"" + key + "\" contains invalid character (= or ;)"); 529 return; 530 } 531 if (value.indexOf('=') != -1 || value.indexOf(';') != -1) { 532 Log.e(TAG, "Value \"" + value + "\" contains invalid character (= or ;)"); 533 return; 534 } 535 536 mMap.put(key, value); 537 } 538 539 /** 540 * Sets an integer parameter. 541 * 542 * @param key the key name for the parameter 543 * @param value the int value of the parameter 544 */ 545 public void set(String key, int value) { 546 mMap.put(key, Integer.toString(value)); 547 } 548 549 /** 550 * Returns the value of a String parameter. 551 * 552 * @param key the key name for the parameter 553 * @return the String value of the parameter 554 */ 555 public String get(String key) { 556 return mMap.get(key); 557 } 558 559 /** 560 * Returns the value of an integer parameter. 561 * 562 * @param key the key name for the parameter 563 * @return the int value of the parameter 564 */ 565 public int getInt(String key) { 566 return Integer.parseInt(mMap.get(key)); 567 } 568 569 /** 570 * Sets the dimensions for preview pictures. 571 * 572 * @param width the width of the pictures, in pixels 573 * @param height the height of the pictures, in pixels 574 */ 575 public void setPreviewSize(int width, int height) { 576 String v = Integer.toString(width) + "x" + Integer.toString(height); 577 set("preview-size", v); 578 } 579 580 /** 581 * Returns the dimensions setting for preview pictures. 582 * 583 * @return a Size object with the height and width setting 584 * for the preview picture 585 */ 586 public Size getPreviewSize() { 587 String pair = get("preview-size"); 588 if (pair == null) 589 return null; 590 String[] dims = pair.split("x"); 591 if (dims.length != 2) 592 return null; 593 594 return new Size(Integer.parseInt(dims[0]), 595 Integer.parseInt(dims[1])); 596 597 } 598 599 /** 600 * Sets the dimensions for EXIF thumbnails. 601 * 602 * @param width the width of the thumbnail, in pixels 603 * @param height the height of the thumbnail, in pixels 604 * 605 * FIXME: unhide before release 606 * @hide 607 */ 608 public void setThumbnailSize(int width, int height) { 609 set("jpeg-thumbnail-width", width); 610 set("jpeg-thumbnail-height", height); 611 } 612 613 /** 614 * Returns the dimensions for EXIF thumbnail 615 * 616 * @return a Size object with the height and width setting 617 * for the EXIF thumbnails 618 * 619 * FIXME: unhide before release 620 * @hide 621 */ 622 public Size getThumbnailSize() { 623 return new Size(getInt("jpeg-thumbnail-width"), 624 getInt("jpeg-thumbnail-height")); 625 } 626 627 /** 628 * Sets the quality of the EXIF thumbnail 629 * 630 * @param quality the JPEG quality of the EXIT thumbnail 631 * 632 * FIXME: unhide before release 633 * @hide 634 */ 635 public void setThumbnailQuality(int quality) { 636 set("jpeg-thumbnail-quality", quality); 637 } 638 639 /** 640 * Returns the quality setting for the EXIF thumbnail 641 * 642 * @return the JPEG quality setting of the EXIF thumbnail 643 * 644 * FIXME: unhide before release 645 * @hide 646 */ 647 public int getThumbnailQuality() { 648 return getInt("jpeg-thumbnail-quality"); 649 } 650 651 /** 652 * Sets the rate at which preview frames are received. 653 * 654 * @param fps the frame rate (frames per second) 655 */ 656 public void setPreviewFrameRate(int fps) { 657 set("preview-frame-rate", fps); 658 } 659 660 /** 661 * Returns the setting for the rate at which preview frames 662 * are received. 663 * 664 * @return the frame rate setting (frames per second) 665 */ 666 public int getPreviewFrameRate() { 667 return getInt("preview-frame-rate"); 668 } 669 670 /** 671 * Sets the image format for preview pictures. 672 * 673 * @param pixel_format the desired preview picture format 674 * (<var>PixelFormat.YCbCr_420_SP</var>, 675 * <var>PixelFormat.RGB_565</var>, or 676 * <var>PixelFormat.JPEG</var>) 677 * @see android.graphics.PixelFormat 678 */ 679 public void setPreviewFormat(int pixel_format) { 680 String s = cameraFormatForPixelFormat(pixel_format); 681 if (s == null) { 682 throw new IllegalArgumentException(); 683 } 684 685 set("preview-format", s); 686 } 687 688 /** 689 * Returns the image format for preview pictures. 690 * 691 * @return the PixelFormat int representing the preview picture format 692 */ 693 public int getPreviewFormat() { 694 return pixelFormatForCameraFormat(get("preview-format")); 695 } 696 697 /** 698 * Sets the dimensions for pictures. 699 * 700 * @param width the width for pictures, in pixels 701 * @param height the height for pictures, in pixels 702 */ 703 public void setPictureSize(int width, int height) { 704 String v = Integer.toString(width) + "x" + Integer.toString(height); 705 set("picture-size", v); 706 } 707 708 /** 709 * Returns the dimension setting for pictures. 710 * 711 * @return a Size object with the height and width setting 712 * for pictures 713 */ 714 public Size getPictureSize() { 715 String pair = get("picture-size"); 716 if (pair == null) 717 return null; 718 String[] dims = pair.split("x"); 719 if (dims.length != 2) 720 return null; 721 722 return new Size(Integer.parseInt(dims[0]), 723 Integer.parseInt(dims[1])); 724 725 } 726 727 /** 728 * Sets the image format for pictures. 729 * 730 * @param pixel_format the desired picture format 731 * (<var>PixelFormat.YCbCr_420_SP</var>, 732 * <var>PixelFormat.RGB_565</var>, or 733 * <var>PixelFormat.JPEG</var>) 734 * @see android.graphics.PixelFormat 735 */ 736 public void setPictureFormat(int pixel_format) { 737 String s = cameraFormatForPixelFormat(pixel_format); 738 if (s == null) { 739 throw new IllegalArgumentException(); 740 } 741 742 set("picture-format", s); 743 } 744 745 /** 746 * Returns the image format for pictures. 747 * 748 * @return the PixelFormat int representing the picture format 749 */ 750 public int getPictureFormat() { 751 return pixelFormatForCameraFormat(get("picture-format")); 752 } 753 754 private String cameraFormatForPixelFormat(int pixel_format) { 755 switch(pixel_format) { 756 case PixelFormat.YCbCr_422_SP: return "yuv422sp"; 757 case PixelFormat.YCbCr_420_SP: return "yuv420sp"; 758 case PixelFormat.RGB_565: return "rgb565"; 759 case PixelFormat.JPEG: return "jpeg"; 760 default: return null; 761 } 762 } 763 764 private int pixelFormatForCameraFormat(String format) { 765 if (format == null) 766 return PixelFormat.UNKNOWN; 767 768 if (format.equals("yuv422sp")) 769 return PixelFormat.YCbCr_422_SP; 770 771 if (format.equals("yuv420sp")) 772 return PixelFormat.YCbCr_420_SP; 773 774 if (format.equals("rgb565")) 775 return PixelFormat.RGB_565; 776 777 if (format.equals("jpeg")) 778 return PixelFormat.JPEG; 779 780 return PixelFormat.UNKNOWN; 781 } 782 783 }; 784} 785 786 787