Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-20202] Android: Camera.open() can throw a RuntimeException. #7616

Merged
merged 1 commit into from Jan 8, 2016

Conversation

collinprice
Copy link
Contributor

Issue: Added try catch block to prevent crashes when Camera.open() fails at Runtime.

camera = Camera.open(cameraId);
}
} catch (Exception e) {
Log.e(TAG, "Could not open camera. Camera may be in use by another process or device policy manager has disabled the camera.", e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be good to have camera = null in the catch statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if statement before the try ensures camera will be null.

@ashcoding ashcoding changed the title [TC-5825] Android: Camera.open() can throw a RuntimeException. [TIMOB-20202] Android: Camera.open() can throw a RuntimeException. Jan 7, 2016
@ashcoding
Copy link
Contributor

Code reviewed. Everything looks good. 👍

@ashcoding
Copy link
Contributor

Is there a sample code you can provide to make this crash to test this?

@collinprice
Copy link
Contributor Author

I have been unable to reproduce the issue on my available devices but I am getting crash reports from Crittercism that relate to this. See example stack trace:

Stack Trace
_________________________________
0   java.lang.RuntimeException: Unable to resume activity {com.meridian.android/ti.modules.titanium.media.TiCameraActivity}: java.lang.RuntimeException: Fail to connect to camera service
1       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3103)
2       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
3       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
4       at android.app.ActivityThread.-wrap11(ActivityThread.java)
5       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
6       at android.os.Handler.dispatchMessage(Handler.java:102)
7       at android.os.Looper.loop(Looper.java:148)
8       at android.app.ActivityThread.main(ActivityThread.java:5417)
9       at java.lang.reflect.Method.invoke(Native Method)
10      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12  Caused by: java.lang.RuntimeException: Fail to connect to camera service
13      at android.hardware.Camera.<init>(Camera.java:495)
14      at android.hardware.Camera.open(Camera.java:356)
15      at ti.modules.titanium.media.TiCameraActivity.openCamera(TiCameraActivity.java:633)
16      at ti.modules.titanium.media.TiCameraActivity.openCamera(TiCameraActivity.java:618)
17      at ti.modules.titanium.media.TiCameraActivity.onResume(TiCameraActivity.java:203)
18      at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
19      at android.app.Activity.performResume(Activity.java:6327)
20      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
21      ... 10 more
22  java.lang.RuntimeException: Fail to connect to camera service
23      at android.hardware.Camera.<init>(Camera.java:495)
24      at android.hardware.Camera.open(Camera.java:356)
25      at ti.modules.titanium.media.TiCameraActivity.openCamera(TiCameraActivity.java:633)
26      at ti.modules.titanium.media.TiCameraActivity.openCamera(TiCameraActivity.java:618)
27      at ti.modules.titanium.media.TiCameraActivity.onResume(TiCameraActivity.java:203)
28      at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
29      at android.app.Activity.performResume(Activity.java:6327)
30      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
31      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
32      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
33      at android.app.ActivityThread.-wrap11(ActivityThread.java)
34      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
35      at android.os.Handler.dispatchMessage(Handler.java:102)
36      at android.os.Looper.loop(Looper.java:148)
37      at android.app.ActivityThread.main(ActivityThread.java:5417)
38      at java.lang.reflect.Method.invoke(Native Method)
39      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
40      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)


Threads
_________________________________
Thread: pool-3-thread-1
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2013)
5   java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
6   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
7   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
8   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
9   java.lang.Thread.run(Thread.java:818)

Thread: Signal Catcher

Thread: AsyncTask #2
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2013)
5   java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
6   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
7   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
8   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
9   java.lang.Thread.run(Thread.java:818)

Thread: TXN Thread
0   java.lang.Object.wait(Native Method)
1   android.os.ConditionVariable.block(ConditionVariable.java:97)
2   crittercism.android.ba.a(Unknown Source)
3   crittercism.android.dc.run(Unknown Source)
4   crittercism.android.cy.a(Unknown Source)
5   crittercism.android.dc.run(Unknown Source)
6   java.lang.Thread.run(Thread.java:818)

Thread: Binder_3

Thread: FinalizerDaemon
0   java.lang.Object.wait(Native Method)
1   java.lang.Object.wait(Object.java:423)
2   java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101)
3   java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72)
4   java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
5   java.lang.Thread.run(Thread.java:818)

Thread: pool-3-thread-2
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2013)
5   java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
6   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
7   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
8   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
9   java.lang.Thread.run(Thread.java:818)

Thread: AsyncTask #1
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2013)
5   java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
6   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
7   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
8   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
9   java.lang.Thread.run(Thread.java:818)

Thread: FinalizerWatchdogDaemon
0   java.lang.Object.wait(Native Method)
1   java.lang.Daemons$FinalizerWatchdogDaemon.waitForObject(Daemons.java:255)
2   java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:227)
3   java.lang.Thread.run(Thread.java:818)

Thread: RenderThread

Thread: pool-1-thread-1
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2053)
5   java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
6   java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1071)
7   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
8   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
9   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10  java.lang.Thread.run(Thread.java:818)

Thread: Binder_2

Thread: Thread-495
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2013)
5   java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
6   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
7   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
8   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
9   crittercism.android.cy.a(Unknown Source)
10  crittercism.android.dc.run(Unknown Source)
11  java.lang.Thread.run(Thread.java:818)

Thread: hwuiTask1

Thread: HeapTaskDaemon
0   dalvik.system.VMRuntime.runHeapTasks(Native Method)
1   java.lang.Daemons$HeapTaskDaemon.run(Daemons.java:355)
2   java.lang.Thread.run(Thread.java:818)

Thread: OkHttp ConnectionPool
0   java.lang.Object.wait(Native Method)
1   com.android.okhttp.ConnectionPool.performCleanup(ConnectionPool.java:305)
2   com.android.okhttp.ConnectionPool.runCleanupUntilPoolIsEmpty(ConnectionPool.java:242)
3   com.android.okhttp.ConnectionPool.-wrap0(ConnectionPool.java)
4   com.android.okhttp.ConnectionPool$1.run(ConnectionPool.java:97)
5   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
6   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
7   java.lang.Thread.run(Thread.java:818)

Thread: KrollRuntimeThread
0   android.os.MessageQueue.nativePollOnce(Native Method)
1   android.os.MessageQueue.next(MessageQueue.java:323)
2   android.os.Looper.loop(Looper.java:135)
3   org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:112)

Thread: Thread-496
0   java.lang.Object.wait(Native Method)
1   java.lang.Thread.parkFor$(Thread.java:1220)
2   sun.misc.Unsafe.park(Unsafe.java:299)
3   java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
4   java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2053)
5   java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
6   java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1071)
7   java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1038)
8   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1098)
9   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10  crittercism.android.cy.a(Unknown Source)
11  crittercism.android.dc.run(Unknown Source)
12  java.lang.Thread.run(Thread.java:818)

Thread: Binder_1

Thread: OPTMZ
0   java.lang.Object.wait(Native Method)
1   android.os.ConditionVariable.block(ConditionVariable.java:97)
2   crittercism.android.h.run(Unknown Source)
3   crittercism.android.cy.a(Unknown Source)
4   crittercism.android.dc.run(Unknown Source)
5   java.lang.Thread.run(Thread.java:818)

Thread: ReferenceQueueDaemon
0   java.lang.Object.wait(Native Method)
1   java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:147)
2   java.lang.Thread.run(Thread.java:818)

Thread: hwuiTask2

Thread: Okio Watchdog
0   java.lang.Object.wait(Native Method)
1   com.android.okhttp.okio.AsyncTimeout.awaitTimeout(AsyncTimeout.java:323)
2   com.android.okhttp.okio.AsyncTimeout.-wrap0(AsyncTimeout.java)
3   com.android.okhttp.okio.AsyncTimeout$Watchdog.run(AsyncTimeout.java:286)


@ashcoding
Copy link
Contributor

Understood.

Code reviewed. Tested with Kitchen Sink to ensure Camera is okay. PR approved. Merging

ashcoding added a commit that referenced this pull request Jan 8, 2016
[TIMOB-20202] Android: Camera.open() can throw a RuntimeException.
@ashcoding ashcoding merged commit 0b4f4a9 into tidev:master Jan 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants