@@ -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
@@ -508,7 +508,9 @@ public final void stopPreview() {
508508 mRawImageCallback = null ;
509509 mPostviewCallback = null ;
510510 mJpegCallback = null ;
511- mAutoFocusCallback = null ;
511+ synchronized (mAutoFocusCallbackLock ) {
512+ mAutoFocusCallback = null ;
513+ }
512514 mAutoFocusMoveCallback = null ;
513515 }
514516
@@ -748,14 +750,13 @@ public void handleMessage(Message msg) {
748750 return ;
749751
750752 case CAMERA_MSG_FOCUS :
751- mFocusLock .lock ();
752- try {
753- if (mAutoFocusCallback != null ) {
754- boolean success = msg .arg1 == 0 ? false : true ;
755- mAutoFocusCallback .onAutoFocus (success , mCamera );
756- }
757- } finally {
758- mFocusLock .unlock ();
753+ AutoFocusCallback cb = null ;
754+ synchronized (mAutoFocusCallbackLock ) {
755+ cb = mAutoFocusCallback ;
756+ }
757+ if (cb != null ) {
758+ boolean success = msg .arg1 == 0 ? false : true ;
759+ cb .onAutoFocus (success , mCamera );
759760 }
760761 return ;
761762
@@ -880,13 +881,10 @@ public interface AutoFocusCallback
880881 */
881882 public final void autoFocus (AutoFocusCallback cb )
882883 {
883- mFocusLock .lock ();
884- try {
884+ synchronized (mAutoFocusCallbackLock ) {
885885 mAutoFocusCallback = cb ;
886- native_autoFocus ();
887- } finally {
888- mFocusLock .unlock ();
889886 }
887+ native_autoFocus ();
890888 }
891889 private native final void native_autoFocus ();
892890
@@ -900,14 +898,26 @@ public final void autoFocus(AutoFocusCallback cb)
900898 */
901899 public final void cancelAutoFocus ()
902900 {
903- mFocusLock .lock ();
904- try {
901+ synchronized (mAutoFocusCallbackLock ) {
905902 mAutoFocusCallback = null ;
906- native_cancelAutoFocus ();
907- removePendingAFCompletionMessages ();
908- } finally {
909- mFocusLock .unlock ();
910903 }
904+ native_cancelAutoFocus ();
905+ // CAMERA_MSG_FOCUS should be removed here because the following
906+ // scenario can happen:
907+ // - An application uses the same thread for autoFocus, cancelAutoFocus
908+ // and looper thread.
909+ // - The application calls autoFocus.
910+ // - HAL sends CAMERA_MSG_FOCUS, which enters the looper message queue.
911+ // Before event handler's handleMessage() is invoked, the application
912+ // calls cancelAutoFocus and autoFocus.
913+ // - The application gets the old CAMERA_MSG_FOCUS and thinks autofocus
914+ // has been completed. But in fact it is not.
915+ //
916+ // As documented in the beginning of the file, apps should not use
917+ // multiple threads to call autoFocus and cancelAutoFocus at the same
918+ // time. It is HAL's responsibility not to send a CAMERA_MSG_FOCUS
919+ // message after native_cancelAutoFocus is called.
920+ mEventHandler .removeMessages (CAMERA_MSG_FOCUS );
911921 }
912922 private native final void native_cancelAutoFocus ();
913923
@@ -3596,13 +3606,4 @@ private boolean same(String s1, String s2) {
35963606 return false ;
35973607 }
35983608 };
3599-
3600- /*
3601- * At any time, there should be at most one pending auto focus completion
3602- * message, but we simply remove all pending AF completion messages in
3603- * the looper's queue.
3604- */
3605- private void removePendingAFCompletionMessages () {
3606- mEventHandler .removeMessages (CAMERA_MSG_FOCUS );
3607- }
36083609}
0 commit comments