@@ -155,7 +155,7 @@ public class Camera {
155155 private boolean mOneShot ;
156156 private boolean mWithBuffer ;
157157 private boolean mFaceDetectionRunning = false ;
158- private ReentrantLock mFocusLock = new ReentrantLock ();
158+ private Object mAutoFocusCallbackLock = new Object ();
159159
160160 /**
161161 * Broadcast Action: A new picture is taken by the camera, and the entry of
@@ -513,7 +513,9 @@ public final void stopPreview() {
513513 mRawImageCallback = null ;
514514 mPostviewCallback = null ;
515515 mJpegCallback = null ;
516- mAutoFocusCallback = null ;
516+ synchronized (mAutoFocusCallbackLock ) {
517+ mAutoFocusCallback = null ;
518+ }
517519 mAutoFocusMoveCallback = null ;
518520 }
519521
@@ -758,14 +760,13 @@ public void handleMessage(Message msg) {
758760 return ;
759761
760762 case CAMERA_MSG_FOCUS :
761- mFocusLock .lock ();
762- try {
763- if (mAutoFocusCallback != null ) {
764- boolean success = msg .arg1 == 0 ? false : true ;
765- mAutoFocusCallback .onAutoFocus (success , mCamera );
766- }
767- } finally {
768- mFocusLock .unlock ();
763+ AutoFocusCallback cb = null ;
764+ synchronized (mAutoFocusCallbackLock ) {
765+ cb = mAutoFocusCallback ;
766+ }
767+ if (cb != null ) {
768+ boolean success = msg .arg1 == 0 ? false : true ;
769+ cb .onAutoFocus (success , mCamera );
769770 }
770771 return ;
771772
@@ -890,13 +891,10 @@ public interface AutoFocusCallback
890891 */
891892 public final void autoFocus (AutoFocusCallback cb )
892893 {
893- mFocusLock .lock ();
894- try {
894+ synchronized (mAutoFocusCallbackLock ) {
895895 mAutoFocusCallback = cb ;
896- native_autoFocus ();
897- } finally {
898- mFocusLock .unlock ();
899896 }
897+ native_autoFocus ();
900898 }
901899 private native final void native_autoFocus ();
902900
@@ -910,14 +908,26 @@ public final void autoFocus(AutoFocusCallback cb)
910908 */
911909 public final void cancelAutoFocus ()
912910 {
913- mFocusLock .lock ();
914- try {
911+ synchronized (mAutoFocusCallbackLock ) {
915912 mAutoFocusCallback = null ;
916- native_cancelAutoFocus ();
917- removePendingAFCompletionMessages ();
918- } finally {
919- mFocusLock .unlock ();
920913 }
914+ native_cancelAutoFocus ();
915+ // CAMERA_MSG_FOCUS should be removed here because the following
916+ // scenario can happen:
917+ // - An application uses the same thread for autoFocus, cancelAutoFocus
918+ // and looper thread.
919+ // - The application calls autoFocus.
920+ // - HAL sends CAMERA_MSG_FOCUS, which enters the looper message queue.
921+ // Before event handler's handleMessage() is invoked, the application
922+ // calls cancelAutoFocus and autoFocus.
923+ // - The application gets the old CAMERA_MSG_FOCUS and thinks autofocus
924+ // has been completed. But in fact it is not.
925+ //
926+ // As documented in the beginning of the file, apps should not use
927+ // multiple threads to call autoFocus and cancelAutoFocus at the same
928+ // time. It is HAL's responsibility not to send a CAMERA_MSG_FOCUS
929+ // message after native_cancelAutoFocus is called.
930+ mEventHandler .removeMessages (CAMERA_MSG_FOCUS );
921931 }
922932 private native final void native_cancelAutoFocus ();
923933
@@ -3640,13 +3650,4 @@ private boolean same(String s1, String s2) {
36403650 return false ;
36413651 }
36423652 };
3643-
3644- /*
3645- * At any time, there should be at most one pending auto focus completion
3646- * message, but we simply remove all pending AF completion messages in
3647- * the looper's queue.
3648- */
3649- private void removePendingAFCompletionMessages () {
3650- mEventHandler .removeMessages (CAMERA_MSG_FOCUS );
3651- }
36523653}
0 commit comments