CameraAgent.java revision a0842b40441db5332a5290f941021636b1182761
1/* 2 * Copyright (C) 2012 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 com.android.ex.camera2.portability; 18 19import android.annotation.TargetApi; 20import android.graphics.SurfaceTexture; 21import android.hardware.Camera; 22import android.hardware.Camera.OnZoomChangeListener; 23import android.os.Build; 24import android.os.Handler; 25import android.os.Looper; 26import android.view.SurfaceHolder; 27 28import com.android.ex.camera2.portability.debug.Log; 29 30/** 31 * An interface which provides possible camera device operations. 32 * 33 * The client should call {@code CameraAgent.openCamera} to get an instance 34 * of {@link CameraAgent.CameraProxy} to control the camera. Classes 35 * implementing this interface should have its own one unique {@code Thread} 36 * other than the main thread for camera operations. Camera device callbacks 37 * are wrapped since the client should not deal with 38 * {@code android.hardware.Camera} directly. 39 * 40 * TODO: provide callback interfaces for: 41 * {@code android.hardware.Camera.ErrorCallback}, 42 * {@code android.hardware.Camera.OnZoomChangeListener}, and 43 */ 44public abstract class CameraAgent { 45 public static final long CAMERA_OPERATION_TIMEOUT_MS = 2500; 46 47 private static final Log.Tag TAG = new Log.Tag("CamAgnt"); 48 49 public static class CameraStartPreviewCallbackForward 50 implements CameraStartPreviewCallback { 51 private final Handler mHandler; 52 private final CameraStartPreviewCallback mCallback; 53 54 public static CameraStartPreviewCallbackForward getNewInstance( 55 Handler handler, CameraStartPreviewCallback cb) { 56 if (handler == null || cb == null) { 57 return null; 58 } 59 return new CameraStartPreviewCallbackForward(handler, cb); 60 } 61 62 private CameraStartPreviewCallbackForward(Handler h, 63 CameraStartPreviewCallback cb) { 64 mHandler = h; 65 mCallback = cb; 66 } 67 68 @Override 69 public void onPreviewStarted() { 70 mHandler.post(new Runnable() { 71 @Override 72 public void run() { 73 mCallback.onPreviewStarted(); 74 }}); 75 } 76 } 77 78 /** 79 * A callback helps to invoke the original callback on another 80 * {@link android.os.Handler}. 81 */ 82 public static class CameraOpenCallbackForward implements CameraOpenCallback { 83 private final Handler mHandler; 84 private final CameraOpenCallback mCallback; 85 86 /** 87 * Returns a new instance of {@link FaceDetectionCallbackForward}. 88 * 89 * @param handler The handler in which the callback will be invoked in. 90 * @param cb The callback to be invoked. 91 * @return The instance of the {@link FaceDetectionCallbackForward}, or 92 * null if any parameter is null. 93 */ 94 public static CameraOpenCallbackForward getNewInstance( 95 Handler handler, CameraOpenCallback cb) { 96 if (handler == null || cb == null) { 97 return null; 98 } 99 return new CameraOpenCallbackForward(handler, cb); 100 } 101 102 private CameraOpenCallbackForward(Handler h, CameraOpenCallback cb) { 103 // Given that we are using the main thread handler, we can create it 104 // here instead of holding onto the PhotoModule objects. In this 105 // way, we can avoid memory leak. 106 mHandler = new Handler(Looper.getMainLooper()); 107 mCallback = cb; 108 } 109 110 @Override 111 public void onCameraOpened(final CameraProxy camera) { 112 mHandler.post(new Runnable() { 113 @Override 114 public void run() { 115 mCallback.onCameraOpened(camera); 116 }}); 117 } 118 119 @Override 120 public void onCameraDisabled(final int cameraId) { 121 mHandler.post(new Runnable() { 122 @Override 123 public void run() { 124 mCallback.onCameraDisabled(cameraId); 125 }}); 126 } 127 128 @Override 129 public void onDeviceOpenFailure(final int cameraId, final String info) { 130 mHandler.post(new Runnable() { 131 @Override 132 public void run() { 133 mCallback.onDeviceOpenFailure(cameraId, info); 134 }}); 135 } 136 137 @Override 138 public void onDeviceOpenedAlready(final int cameraId, final String info) { 139 mHandler.post(new Runnable() { 140 @Override 141 public void run() { 142 mCallback.onDeviceOpenedAlready(cameraId, info); 143 }}); 144 } 145 146 @Override 147 public void onReconnectionFailure(final CameraAgent mgr, final String info) { 148 mHandler.post(new Runnable() { 149 @Override 150 public void run() { 151 mCallback.onReconnectionFailure(mgr, info); 152 }}); 153 } 154 } 155 156 /** 157 * A handler for all camera api runtime exceptions. 158 * The default behavior is to throw the runtime exception. 159 */ 160 public static interface CameraExceptionCallback { 161 public void onCameraException(RuntimeException e); 162 } 163 164 /** 165 * An interface which wraps 166 * {@link android.hardware.Camera.ErrorCallback} 167 */ 168 public static interface CameraErrorCallback { 169 public void onError(int error, CameraProxy camera); 170 } 171 172 /** 173 * An interface which wraps 174 * {@link android.hardware.Camera.AutoFocusCallback}. 175 */ 176 public static interface CameraAFCallback { 177 public void onAutoFocus(boolean focused, CameraProxy camera); 178 } 179 180 /** 181 * An interface which wraps 182 * {@link android.hardware.Camera.AutoFocusMoveCallback}. 183 */ 184 public static interface CameraAFMoveCallback { 185 public void onAutoFocusMoving(boolean moving, CameraProxy camera); 186 } 187 188 /** 189 * An interface which wraps 190 * {@link android.hardware.Camera.ShutterCallback}. 191 */ 192 public static interface CameraShutterCallback { 193 public void onShutter(CameraProxy camera); 194 } 195 196 /** 197 * An interface which wraps 198 * {@link android.hardware.Camera.PictureCallback}. 199 */ 200 public static interface CameraPictureCallback { 201 public void onPictureTaken(byte[] data, CameraProxy camera); 202 } 203 204 /** 205 * An interface which wraps 206 * {@link android.hardware.Camera.PreviewCallback}. 207 */ 208 public static interface CameraPreviewDataCallback { 209 public void onPreviewFrame(byte[] data, CameraProxy camera); 210 } 211 212 /** 213 * An interface which wraps 214 * {@link android.hardware.Camera.FaceDetectionListener}. 215 */ 216 public static interface CameraFaceDetectionCallback { 217 /** 218 * Callback for face detection. 219 * 220 * @param faces Recognized face in the preview. 221 * @param camera The camera which the preview image comes from. 222 */ 223 public void onFaceDetection(Camera.Face[] faces, CameraProxy camera); 224 } 225 226 /** 227 * An interface to be called when the camera preview has started. 228 */ 229 public static interface CameraStartPreviewCallback { 230 /** 231 * Callback when the preview starts. 232 */ 233 public void onPreviewStarted(); 234 } 235 236 /** 237 * An interface to be called for any events when opening or closing the 238 * camera device. This error callback is different from the one defined 239 * in the framework, {@link android.hardware.Camera.ErrorCallback}, which 240 * is used after the camera is opened. 241 */ 242 public static interface CameraOpenCallback { 243 /** 244 * Callback when camera open succeeds. 245 */ 246 public void onCameraOpened(CameraProxy camera); 247 248 /** 249 * Callback when {@link com.android.camera.CameraDisabledException} is 250 * caught. 251 * 252 * @param cameraId The disabled camera. 253 */ 254 public void onCameraDisabled(int cameraId); 255 256 /** 257 * Callback when {@link com.android.camera.CameraHardwareException} is 258 * caught. 259 * 260 * @param cameraId The camera with the hardware failure. 261 * @param info The extra info regarding this failure. 262 */ 263 public void onDeviceOpenFailure(int cameraId, String info); 264 265 /** 266 * Callback when trying to open the camera which is already opened. 267 * 268 * @param cameraId The camera which is causing the open error. 269 */ 270 public void onDeviceOpenedAlready(int cameraId, String info); 271 272 /** 273 * Callback when {@link java.io.IOException} is caught during 274 * {@link android.hardware.Camera#reconnect()}. 275 * 276 * @param mgr The {@link CameraAgent} 277 * with the reconnect failure. 278 */ 279 public void onReconnectionFailure(CameraAgent mgr, String info); 280 } 281 282 /** 283 * Opens the camera of the specified ID asynchronously. The camera device 284 * will be opened in the camera handler thread and will be returned through 285 * the {@link CameraAgent.CameraOpenCallback# 286 * onCameraOpened(com.android.camera.cameradevice.CameraAgent.CameraProxy)}. 287 * 288 * @param handler The {@link android.os.Handler} in which the callback 289 * was handled. 290 * @param callback The callback for the result. 291 * @param cameraId The camera ID to open. 292 */ 293 public void openCamera(final Handler handler, final int cameraId, 294 final CameraOpenCallback callback) { 295 getDispatchThread().runJob(new Runnable() { 296 @Override 297 public void run() { 298 getCameraHandler().obtainMessage(CameraActions.OPEN_CAMERA, cameraId, 0, 299 CameraOpenCallbackForward.getNewInstance(handler, callback)).sendToTarget(); 300 }}); 301 } 302 303 /** 304 * Closes the camera device. 305 * 306 * @param camera The camera to close. {@code null} means all. 307 * @param synced Whether this call should be synchronous. 308 */ 309 public void closeCamera(CameraProxy camera, boolean synced) { 310 if (synced) { 311 final WaitDoneBundle bundle = new WaitDoneBundle(); 312 313 getDispatchThread().runJobSync(new Runnable() { 314 @Override 315 public void run() { 316 getCameraHandler().obtainMessage(CameraActions.RELEASE).sendToTarget(); 317 getCameraHandler().post(bundle.mUnlockRunnable); 318 }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera release"); 319 } else { 320 getDispatchThread().runJob(new Runnable() { 321 @Override 322 public void run() { 323 getCameraHandler().removeCallbacksAndMessages(null); 324 getCameraHandler().obtainMessage(CameraActions.RELEASE).sendToTarget(); 325 }}); 326 } 327 } 328 329 /** 330 * Sets a callback for handling camera api runtime exceptions on 331 * a handler. 332 */ 333 public abstract void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 334 Handler handler); 335 336 /** 337 * Recycles the resources used by this instance. CameraAgent will be in 338 * an unusable state after calling this. 339 */ 340 public abstract void recycle(); 341 342 /** 343 * @return The camera devices info. 344 */ 345 public abstract CameraDeviceInfo getCameraDeviceInfo(); 346 347 /** 348 * @return The handler to which camera tasks should be posted. 349 */ 350 protected abstract Handler getCameraHandler(); 351 352 /** 353 * @return The thread used on which client callbacks are served. 354 */ 355 protected abstract DispatchThread getDispatchThread(); 356 357 /** 358 * An interface that takes camera operation requests and post messages to the 359 * camera handler thread. All camera operations made through this interface is 360 * asynchronous by default except those mentioned specifically. 361 */ 362 public static abstract class CameraProxy { 363 364 /** 365 * Returns the underlying {@link android.hardware.Camera} object used 366 * by this proxy. This method should only be used when handing the 367 * camera device over to {@link android.media.MediaRecorder} for 368 * recording. 369 */ 370 @Deprecated 371 public abstract android.hardware.Camera getCamera(); 372 373 /** 374 * @return The camera ID associated to by this 375 * {@link CameraAgent.CameraProxy}. 376 */ 377 public abstract int getCameraId(); 378 379 /** 380 * @return The camera characteristics. 381 */ 382 public abstract CameraDeviceInfo.Characteristics getCharacteristics(); 383 384 /** 385 * @return The camera capabilities. 386 */ 387 public abstract CameraCapabilities getCapabilities(); 388 389 /** 390 * Reconnects to the camera device. On success, the camera device will 391 * be returned through {@link CameraAgent 392 * .CameraOpenCallback#onCameraOpened(com.android.camera.cameradevice.CameraAgent 393 * .CameraProxy)}. 394 * @see android.hardware.Camera#reconnect() 395 * 396 * @param handler The {@link android.os.Handler} in which the callback 397 * was handled. 398 * @param cb The callback when any error happens. 399 */ 400 public void reconnect(final Handler handler, final CameraOpenCallback cb) { 401 getDispatchThread().runJob(new Runnable() { 402 @Override 403 public void run() { 404 getCameraHandler().obtainMessage(CameraActions.RECONNECT, getCameraId(), 0, 405 CameraOpenCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 406 }}); 407 } 408 409 /** 410 * Unlocks the camera device. 411 * 412 * @see android.hardware.Camera#unlock() 413 */ 414 public void unlock() { 415 final WaitDoneBundle bundle = new WaitDoneBundle(); 416 getDispatchThread().runJobSync(new Runnable() { 417 @Override 418 public void run() { 419 getCameraHandler().sendEmptyMessage(CameraActions.UNLOCK); 420 getCameraHandler().post(bundle.mUnlockRunnable); 421 }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera unlock"); 422 } 423 424 /** 425 * Locks the camera device. 426 * @see android.hardware.Camera#lock() 427 */ 428 public void lock() { 429 getDispatchThread().runJob(new Runnable() { 430 @Override 431 public void run() { 432 getCameraHandler().sendEmptyMessage(CameraActions.LOCK); 433 }}); 434 } 435 436 /** 437 * Sets the {@link android.graphics.SurfaceTexture} for preview. 438 * 439 * @param surfaceTexture The {@link SurfaceTexture} for preview. 440 */ 441 public void setPreviewTexture(final SurfaceTexture surfaceTexture) { 442 getDispatchThread().runJob(new Runnable() { 443 @Override 444 public void run() { 445 getCameraHandler() 446 .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 447 .sendToTarget(); 448 }}); 449 } 450 451 /** 452 * Blocks until a {@link android.graphics.SurfaceTexture} has been set 453 * for preview. 454 * 455 * @param surfaceTexture The {@link SurfaceTexture} for preview. 456 */ 457 public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) { 458 final WaitDoneBundle bundle = new WaitDoneBundle(); 459 getDispatchThread().runJobSync(new Runnable() { 460 @Override 461 public void run() { 462 getCameraHandler() 463 .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 464 .sendToTarget(); 465 getCameraHandler().post(bundle.mUnlockRunnable); 466 }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "set preview texture"); 467 } 468 469 /** 470 * Sets the {@link android.view.SurfaceHolder} for preview. 471 * 472 * @param surfaceHolder The {@link SurfaceHolder} for preview. 473 */ 474 public void setPreviewDisplay(final SurfaceHolder surfaceHolder) { 475 getDispatchThread().runJob(new Runnable() { 476 @Override 477 public void run() { 478 getCameraHandler() 479 .obtainMessage(CameraActions.SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder) 480 .sendToTarget(); 481 }}); 482 } 483 484 /** 485 * Starts the camera preview. 486 */ 487 public void startPreview() { 488 getDispatchThread().runJob(new Runnable() { 489 @Override 490 public void run() { 491 getCameraHandler() 492 .obtainMessage(CameraActions.START_PREVIEW_ASYNC, null).sendToTarget(); 493 }}); 494 } 495 496 /** 497 * Starts the camera preview and executes a callback on a handler once 498 * the preview starts. 499 */ 500 public void startPreviewWithCallback(final Handler h, final CameraStartPreviewCallback cb) { 501 getDispatchThread().runJob(new Runnable() { 502 @Override 503 public void run() { 504 getCameraHandler().obtainMessage(CameraActions.START_PREVIEW_ASYNC, 505 CameraStartPreviewCallbackForward.getNewInstance(h, cb)) 506 .sendToTarget(); 507 }}); 508 } 509 510 /** 511 * Stops the camera preview synchronously. 512 * {@code stopPreview()} must be synchronous to ensure that the caller can 513 * continues to release resources related to camera preview. 514 */ 515 public void stopPreview() { 516 final WaitDoneBundle bundle = new WaitDoneBundle(); 517 getDispatchThread().runJobSync(new Runnable() { 518 @Override 519 public void run() { 520 getCameraHandler().sendEmptyMessage(CameraActions.STOP_PREVIEW); 521 getCameraHandler().post(bundle.mUnlockRunnable); 522 }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "stop preview"); 523 } 524 525 /** 526 * Sets the callback for preview data. 527 * 528 * @param handler The {@link android.os.Handler} in which the callback was handled. 529 * @param cb The callback to be invoked when the preview data is available. 530 * @see android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback) 531 */ 532 public abstract void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb); 533 534 /** 535 * Sets the one-time callback for preview data. 536 * 537 * @param handler The {@link android.os.Handler} in which the callback was handled. 538 * @param cb The callback to be invoked when the preview data for 539 * next frame is available. 540 * @see android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback) 541 */ 542 public abstract void setOneShotPreviewCallback(Handler handler, 543 CameraPreviewDataCallback cb); 544 545 /** 546 * Sets the callback for preview data. 547 * 548 * @param handler The handler in which the callback will be invoked. 549 * @param cb The callback to be invoked when the preview data is available. 550 * @see android.hardware.Camera#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback) 551 */ 552 public abstract void setPreviewDataCallbackWithBuffer(Handler handler, 553 CameraPreviewDataCallback cb); 554 555 /** 556 * Adds buffer for the preview callback. 557 * 558 * @param callbackBuffer The buffer allocated for the preview data. 559 */ 560 public void addCallbackBuffer(final byte[] callbackBuffer) { 561 getDispatchThread().runJob(new Runnable() { 562 @Override 563 public void run() { 564 getCameraHandler() 565 .obtainMessage(CameraActions.ADD_CALLBACK_BUFFER, callbackBuffer) 566 .sendToTarget(); 567 } 568 }); 569 } 570 571 /** 572 * Starts the auto-focus process. The result will be returned through the callback. 573 * 574 * @param handler The handler in which the callback will be invoked. 575 * @param cb The auto-focus callback. 576 */ 577 public abstract void autoFocus(Handler handler, CameraAFCallback cb); 578 579 /** 580 * Cancels the auto-focus process. 581 */ 582 public void cancelAutoFocus() { 583 getDispatchThread().runJob(new Runnable() { 584 @Override 585 public void run() { 586 getCameraHandler().removeMessages(CameraActions.AUTO_FOCUS); 587 getCameraHandler().sendEmptyMessage(CameraActions.CANCEL_AUTO_FOCUS); 588 }}); 589 } 590 591 /** 592 * Sets the auto-focus callback 593 * 594 * @param handler The handler in which the callback will be invoked. 595 * @param cb The callback to be invoked when the preview data is available. 596 */ 597 @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 598 public abstract void setAutoFocusMoveCallback(Handler handler, CameraAFMoveCallback cb); 599 600 /** 601 * Instrument the camera to take a picture. 602 * 603 * @param handler The handler in which the callback will be invoked. 604 * @param shutter The callback for shutter action, may be null. 605 * @param raw The callback for uncompressed data, may be null. 606 * @param postview The callback for postview image data, may be null. 607 * @param jpeg The callback for jpeg image data, may be null. 608 * @see android.hardware.Camera#takePicture( 609 * android.hardware.Camera.ShutterCallback, 610 * android.hardware.Camera.PictureCallback, 611 * android.hardware.Camera.PictureCallback) 612 */ 613 public abstract void takePicture( 614 Handler handler, 615 CameraShutterCallback shutter, 616 CameraPictureCallback raw, 617 CameraPictureCallback postview, 618 CameraPictureCallback jpeg); 619 620 /** 621 * Sets the display orientation for camera to adjust the preview orientation. 622 * 623 * @param degrees The rotation in degrees. Should be 0, 90, 180 or 270. 624 */ 625 public void setDisplayOrientation(final int degrees) { 626 getDispatchThread().runJob(new Runnable() { 627 @Override 628 public void run() { 629 getCameraHandler() 630 .obtainMessage(CameraActions.SET_DISPLAY_ORIENTATION, degrees, 0) 631 .sendToTarget(); 632 }}); 633 } 634 635 /** 636 * Sets the listener for zoom change. 637 * 638 * @param listener The listener. 639 */ 640 public abstract void setZoomChangeListener(OnZoomChangeListener listener); 641 642 /** 643 * Sets the face detection listener. 644 * 645 * @param handler The handler in which the callback will be invoked. 646 * @param callback The callback for face detection results. 647 */ 648 public abstract void setFaceDetectionCallback(Handler handler, 649 CameraFaceDetectionCallback callback); 650 651 /** 652 * Starts the face detection. 653 */ 654 public void startFaceDetection() { 655 getDispatchThread().runJob(new Runnable() { 656 @Override 657 public void run() { 658 getCameraHandler().sendEmptyMessage(CameraActions.START_FACE_DETECTION); 659 }}); 660 } 661 662 /** 663 * Stops the face detection. 664 */ 665 public void stopFaceDetection() { 666 getDispatchThread().runJob(new Runnable() { 667 @Override 668 public void run() { 669 getCameraHandler().sendEmptyMessage(CameraActions.STOP_FACE_DETECTION); 670 }}); 671 } 672 673 /** 674 * Registers an error callback. 675 * 676 * @param handler The handler on which the callback will be invoked. 677 * @param cb The error callback. 678 * @see android.hardware.Camera#setErrorCallback(android.hardware.Camera.ErrorCallback) 679 */ 680 public abstract void setErrorCallback(Handler handler, CameraErrorCallback cb); 681 682 /** 683 * Sets the camera parameters. 684 * 685 * @param params The camera parameters to use. 686 */ 687 @Deprecated 688 public abstract void setParameters(Camera.Parameters params); 689 690 /** 691 * Gets the current camera parameters synchronously. This method is 692 * synchronous since the caller has to wait for the camera to return 693 * the parameters. If the parameters are already cached, it returns 694 * immediately. 695 */ 696 @Deprecated 697 public abstract Camera.Parameters getParameters(); 698 699 /** 700 * Gets the current camera settings synchronously. 701 * <p>This method is synchronous since the caller has to wait for the 702 * camera to return the parameters. If the parameters are already 703 * cached, it returns immediately.</p> 704 */ 705 public abstract CameraSettings getSettings(); 706 707 /** 708 * Default implementation of {@link #applySettings(CameraSettings)} 709 * that is only missing the set of states it needs to wait for 710 * before applying the settings. 711 * 712 * @param settings The settings to use on the device. 713 * @param statesToAwait Bitwise OR of the required camera states. 714 * @return Whether the settings can be applied. 715 */ 716 protected boolean applySettingsHelper(final CameraSettings settings, 717 final int statesToAwait) { 718 if (settings == null) { 719 Log.v(TAG, "null parameters in applySettings()"); 720 return false; 721 } 722 if (!getCapabilities().supports(settings)) { 723 return false; 724 } 725 726 final CameraSettings copyOfSettings = new CameraSettings(settings); 727 getDispatchThread().runJob(new Runnable() { 728 @Override 729 public void run() { 730 getCameraState().waitForStates(statesToAwait); 731 getCameraHandler().obtainMessage(CameraActions.APPLY_SETTINGS, copyOfSettings) 732 .sendToTarget(); 733 } 734 }); 735 return true; 736 } 737 738 /** 739 * Applies the settings to the camera device. 740 * 741 * @param settings The settings to use on the device. 742 * @return Whether the settings can be applied. 743 */ 744 public abstract boolean applySettings(CameraSettings settings); 745 746 /** 747 * Forces {@code CameraProxy} to update the cached version of the camera 748 * settings regardless of the dirty bit. 749 */ 750 public void refreshSettings() { 751 getDispatchThread().runJob(new Runnable() { 752 @Override 753 public void run() { 754 getCameraHandler().sendEmptyMessage(CameraActions.REFRESH_PARAMETERS); 755 }}); 756 } 757 758 /** 759 * Enables/Disables the camera shutter sound. 760 * 761 * @param enable {@code true} to enable the shutter sound, 762 * {@code false} to disable it. 763 */ 764 public void enableShutterSound(final boolean enable) { 765 getDispatchThread().runJob(new Runnable() { 766 @Override 767 public void run() { 768 getCameraHandler() 769 .obtainMessage(CameraActions.ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0) 770 .sendToTarget(); 771 }}); 772 } 773 774 /** 775 * Dumps the current settings of the camera device. 776 * 777 * <p>The content varies based on the underlying camera API settings 778 * implementation.</p> 779 * 780 * @return The content of the device settings represented by a string. 781 */ 782 public abstract String dumpDeviceSettings(); 783 784 /** 785 * @return The handler to which camera tasks should be posted. 786 */ 787 public abstract Handler getCameraHandler(); 788 789 /** 790 * @return The thread used on which client callbacks are served. 791 */ 792 public abstract DispatchThread getDispatchThread(); 793 794 /** 795 * @return The state machine tracking the camera API's current mode. 796 */ 797 public abstract CameraStateHolder getCameraState(); 798 } 799 800 public static class WaitDoneBundle { 801 public final Runnable mUnlockRunnable; 802 public final Object mWaitLock; 803 804 WaitDoneBundle() { 805 mWaitLock = new Object(); 806 mUnlockRunnable = new Runnable() { 807 @Override 808 public void run() { 809 synchronized (mWaitLock) { 810 mWaitLock.notifyAll(); 811 } 812 }}; 813 } 814 } 815} 816