OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2013 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 import java.io.StringWriter; | 22 import java.io.StringWriter; |
23 | 23 |
24 /** | 24 /** |
25 * Singleton helper: install a default unhandled exception handler which shows | 25 * Singleton helper: install a default unhandled exception handler which shows |
26 * an informative dialog and kills the app. Useful for apps whose | 26 * an informative dialog and kills the app. Useful for apps whose |
27 * error-handling consists of throwing RuntimeExceptions. | 27 * error-handling consists of throwing RuntimeExceptions. |
28 * NOTE: almost always more useful to | 28 * NOTE: almost always more useful to |
29 * Thread.setDefaultUncaughtExceptionHandler() rather than | 29 * Thread.setDefaultUncaughtExceptionHandler() rather than |
30 * Thread.setUncaughtExceptionHandler(), to apply to background threads as well. | 30 * Thread.setUncaughtExceptionHandler(), to apply to background threads as well. |
31 */ | 31 */ |
32 public class UnhandledExceptionHandler | 32 public class UnhandledExceptionHandler implements Thread.UncaughtExceptionHandle
r { |
33 implements Thread.UncaughtExceptionHandler { | |
34 private static final String TAG = "AppRTCMobileActivity"; | 33 private static final String TAG = "AppRTCMobileActivity"; |
35 private final Activity activity; | 34 private final Activity activity; |
36 | 35 |
37 public UnhandledExceptionHandler(final Activity activity) { | 36 public UnhandledExceptionHandler(final Activity activity) { |
38 this.activity = activity; | 37 this.activity = activity; |
39 } | 38 } |
40 | 39 |
41 public void uncaughtException(Thread unusedThread, final Throwable e) { | 40 public void uncaughtException(Thread unusedThread, final Throwable e) { |
42 activity.runOnUiThread(new Runnable() { | 41 activity.runOnUiThread(new Runnable() { |
43 @Override public void run() { | 42 @Override |
44 String title = "Fatal error: " + getTopLevelCauseMessage(e); | 43 public void run() { |
45 String msg = getRecursiveStackTrace(e); | 44 String title = "Fatal error: " + getTopLevelCauseMessage(e); |
46 TextView errorView = new TextView(activity); | 45 String msg = getRecursiveStackTrace(e); |
47 errorView.setText(msg); | 46 TextView errorView = new TextView(activity); |
48 errorView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 8); | 47 errorView.setText(msg); |
49 ScrollView scrollingContainer = new ScrollView(activity); | 48 errorView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 8); |
50 scrollingContainer.addView(errorView); | 49 ScrollView scrollingContainer = new ScrollView(activity); |
51 Log.e(TAG, title + "\n\n" + msg); | 50 scrollingContainer.addView(errorView); |
52 DialogInterface.OnClickListener listener = | 51 Log.e(TAG, title + "\n\n" + msg); |
53 new DialogInterface.OnClickListener() { | 52 DialogInterface.OnClickListener listener = new DialogInterface.OnClickLi
stener() { |
54 @Override public void onClick( | 53 @Override |
55 DialogInterface dialog, int which) { | 54 public void onClick(DialogInterface dialog, int which) { |
56 dialog.dismiss(); | 55 dialog.dismiss(); |
57 System.exit(1); | 56 System.exit(1); |
58 } | 57 } |
59 }; | 58 }; |
60 AlertDialog.Builder builder = | 59 AlertDialog.Builder builder = new AlertDialog.Builder(activity); |
61 new AlertDialog.Builder(activity); | 60 builder.setTitle(title) |
62 builder | 61 .setView(scrollingContainer) |
63 .setTitle(title) | 62 .setPositiveButton("Exit", listener) |
64 .setView(scrollingContainer) | 63 .show(); |
65 .setPositiveButton("Exit", listener).show(); | 64 } |
66 } | 65 }); |
67 }); | |
68 } | 66 } |
69 | 67 |
70 // Returns the Message attached to the original Cause of |t|. | 68 // Returns the Message attached to the original Cause of |t|. |
71 private static String getTopLevelCauseMessage(Throwable t) { | 69 private static String getTopLevelCauseMessage(Throwable t) { |
72 Throwable topLevelCause = t; | 70 Throwable topLevelCause = t; |
73 while (topLevelCause.getCause() != null) { | 71 while (topLevelCause.getCause() != null) { |
74 topLevelCause = topLevelCause.getCause(); | 72 topLevelCause = topLevelCause.getCause(); |
75 } | 73 } |
76 return topLevelCause.getMessage(); | 74 return topLevelCause.getMessage(); |
77 } | 75 } |
78 | 76 |
79 // Returns a human-readable String of the stacktrace in |t|, recursively | 77 // Returns a human-readable String of the stacktrace in |t|, recursively |
80 // through all Causes that led to |t|. | 78 // through all Causes that led to |t|. |
81 private static String getRecursiveStackTrace(Throwable t) { | 79 private static String getRecursiveStackTrace(Throwable t) { |
82 StringWriter writer = new StringWriter(); | 80 StringWriter writer = new StringWriter(); |
83 t.printStackTrace(new PrintWriter(writer)); | 81 t.printStackTrace(new PrintWriter(writer)); |
84 return writer.toString(); | 82 return writer.toString(); |
85 } | 83 } |
86 } | 84 } |
OLD | NEW |