Skip to content

Commit f05c1d6

Browse files
author
Wu-cheng Li
committed
Avoid deadlocks when calling autoFocus from onAutoFocus callback.
Applicatons may use different threads for calling autoFocus and onAutoFocus callback. bug:6026574 Change-Id: I114a60240e22af15ca469b591e080121367db8e2
1 parent 39f412d commit f05c1d6

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

core/java/android/hardware/Camera.java

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)