• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.systemui.shared.system
2 
3 import android.util.Log
4 import java.lang.Thread.UncaughtExceptionHandler
5 import java.util.concurrent.CopyOnWriteArrayList
6 import javax.inject.Inject
7 import javax.inject.Singleton
8 
9 /**
10  * Sets the global (static var in Thread) uncaught exception pre-handler to an implementation that
11  * delegates to each item in a list of registered UncaughtExceptionHandlers.
12  */
13 @Singleton
14 class UncaughtExceptionPreHandlerManager @Inject constructor() {
15     private val handlers: MutableList<UncaughtExceptionHandler> = CopyOnWriteArrayList()
16     private val globalUncaughtExceptionPreHandler = GlobalUncaughtExceptionHandler()
17 
18     /**
19      * Adds an exception pre-handler to the list of handlers. If this has not yet set the global
20      * (static var in Thread) uncaught exception pre-handler yet, it will do so.
21      */
registerHandlernull22     fun registerHandler(handler: UncaughtExceptionHandler) {
23         checkGlobalHandlerSetup()
24         addHandler(handler)
25     }
26 
27     /**
28      * Verifies that the global handler is set in Thread. If not, sets is up.
29      */
checkGlobalHandlerSetupnull30     private fun checkGlobalHandlerSetup() {
31         val currentHandler = Thread.getUncaughtExceptionPreHandler()
32         if (currentHandler != globalUncaughtExceptionPreHandler) {
33             if (currentHandler is GlobalUncaughtExceptionHandler) {
34                 throw IllegalStateException("Two UncaughtExceptionPreHandlerManagers created")
35             }
36             currentHandler?.let { addHandler(it) }
37             Thread.setUncaughtExceptionPreHandler(globalUncaughtExceptionPreHandler)
38         }
39     }
40 
41     /**
42      * Adds a handler if it has not already been added, preserving order.
43      */
addHandlernull44     private fun addHandler(it: UncaughtExceptionHandler) {
45         if (it !in handlers) {
46             handlers.add(it)
47         }
48     }
49 
50     /**
51      * Calls uncaughtException on all registered handlers, catching and logging any new exceptions.
52      */
handleUncaughtExceptionnull53     fun handleUncaughtException(thread: Thread?, throwable: Throwable?) {
54         for (handler in handlers) {
55             try {
56                 handler.uncaughtException(thread, throwable)
57             } catch (e: Exception) {
58                 Log.wtf("Uncaught exception pre-handler error", e)
59             }
60         }
61     }
62 
63     /**
64      * UncaughtExceptionHandler impl that will be set as Thread's pre-handler static variable.
65      */
66     inner class GlobalUncaughtExceptionHandler : UncaughtExceptionHandler {
uncaughtExceptionnull67         override fun uncaughtException(thread: Thread?, throwable: Throwable?) {
68             handleUncaughtException(thread, throwable)
69         }
70     }
71 }