-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: register system callbacks on background thread
- Loading branch information
1 parent
361e2b5
commit c733178
Showing
5 changed files
with
159 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
196 changes: 0 additions & 196 deletions
196
bugsnag-android-core/src/main/java/com/bugsnag/android/SystemBroadcastReceiver.java
This file was deleted.
Oops, something went wrong.
130 changes: 130 additions & 0 deletions
130
bugsnag-android-core/src/main/java/com/bugsnag/android/SystemBroadcastReceiver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package com.bugsnag.android | ||
|
||
import android.content.BroadcastReceiver | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.content.IntentFilter | ||
import java.util.HashMap | ||
|
||
/** | ||
* Used to automatically create breadcrumbs for system events | ||
* Broadcast actions and categories can be found in text files in the android folder | ||
* e.g. ~/Library/Android/sdk/platforms/android-9/data/broadcast_actions.txt | ||
* See http://stackoverflow.com/a/27601497 | ||
*/ | ||
internal class SystemBroadcastReceiver( | ||
private val client: Client, | ||
private val logger: Logger | ||
) : BroadcastReceiver() { | ||
|
||
companion object { | ||
private const val INTENT_ACTION_KEY = "Intent Action" | ||
|
||
@JvmStatic | ||
fun register(ctx: Context, receiver: SystemBroadcastReceiver, logger: Logger) { | ||
if (receiver.actions.isNotEmpty()) { | ||
val filter = IntentFilter() | ||
receiver.actions.keys.forEach(filter::addAction) | ||
ctx.registerReceiverSafe(receiver, filter, logger) | ||
} | ||
} | ||
|
||
fun isAndroidKey(actionName: String): Boolean { | ||
return actionName.startsWith("android.") | ||
} | ||
|
||
fun shortenActionNameIfNeeded(action: String): String { | ||
return if (isAndroidKey(action)) { | ||
action.substring(action.lastIndexOf(".") + 1) | ||
} else { | ||
action | ||
} | ||
} | ||
} | ||
|
||
val actions: Map<String, BreadcrumbType> = buildActions() | ||
|
||
override fun onReceive(context: Context, intent: Intent) { | ||
try { | ||
val meta: MutableMap<String, Any> = HashMap() | ||
val fullAction = intent.action ?: return | ||
val shortAction = shortenActionNameIfNeeded(fullAction) | ||
meta[INTENT_ACTION_KEY] = fullAction // always add the Intent Action | ||
addExtrasToMetadata(intent, meta, shortAction) | ||
|
||
val type = actions[fullAction] ?: BreadcrumbType.STATE | ||
client.leaveBreadcrumb(shortAction, meta, type) | ||
} catch (ex: Exception) { | ||
logger.w("Failed to leave breadcrumb in SystemBroadcastReceiver: ${ex.message}") | ||
} | ||
} | ||
|
||
private fun addExtrasToMetadata( | ||
intent: Intent, | ||
meta: MutableMap<String, Any>, | ||
shortAction: String | ||
) { | ||
val extras = intent.extras | ||
extras?.keySet()?.forEach { key -> | ||
val valObj = extras[key] ?: return@forEach | ||
val strVal = valObj.toString() | ||
if (isAndroidKey(key)) { // shorten the Intent action | ||
meta["Extra"] = "$shortAction: $strVal" | ||
} else { | ||
meta[key] = strVal | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Builds a map of intent actions and their breadcrumb type (if enabled). | ||
* | ||
* Noisy breadcrumbs are omitted, along with anything that involves a state change. | ||
* @return the action map | ||
*/ | ||
private fun buildActions(): Map<String, BreadcrumbType> { | ||
val actions: MutableMap<String, BreadcrumbType> = HashMap() | ||
val config = client.config | ||
|
||
if (!config.shouldDiscardBreadcrumb(BreadcrumbType.USER)) { | ||
actions["android.appwidget.action.APPWIDGET_DELETED"] = BreadcrumbType.USER | ||
actions["android.appwidget.action.APPWIDGET_DISABLED"] = BreadcrumbType.USER | ||
actions["android.appwidget.action.APPWIDGET_ENABLED"] = BreadcrumbType.USER | ||
actions["android.intent.action.CAMERA_BUTTON"] = BreadcrumbType.USER | ||
actions["android.intent.action.CLOSE_SYSTEM_DIALOGS"] = BreadcrumbType.USER | ||
actions["android.intent.action.DOCK_EVENT"] = BreadcrumbType.USER | ||
} | ||
if (!config.shouldDiscardBreadcrumb(BreadcrumbType.STATE)) { | ||
actions["android.appwidget.action.APPWIDGET_HOST_RESTORED"] = BreadcrumbType.STATE | ||
actions["android.appwidget.action.APPWIDGET_RESTORED"] = BreadcrumbType.STATE | ||
actions["android.appwidget.action.APPWIDGET_UPDATE"] = BreadcrumbType.STATE | ||
actions["android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"] = BreadcrumbType.STATE | ||
actions["android.intent.action.ACTION_POWER_CONNECTED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.ACTION_POWER_DISCONNECTED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.ACTION_SHUTDOWN"] = BreadcrumbType.STATE | ||
actions["android.intent.action.AIRPLANE_MODE"] = BreadcrumbType.STATE | ||
actions["android.intent.action.BATTERY_LOW"] = BreadcrumbType.STATE | ||
actions["android.intent.action.BATTERY_OKAY"] = BreadcrumbType.STATE | ||
actions["android.intent.action.BOOT_COMPLETED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.CONFIGURATION_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.CONTENT_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.DATE_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.DEVICE_STORAGE_LOW"] = BreadcrumbType.STATE | ||
actions["android.intent.action.DEVICE_STORAGE_OK"] = BreadcrumbType.STATE | ||
actions["android.intent.action.INPUT_METHOD_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.LOCALE_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.REBOOT"] = BreadcrumbType.STATE | ||
actions["android.intent.action.SCREEN_OFF"] = BreadcrumbType.STATE | ||
actions["android.intent.action.SCREEN_ON"] = BreadcrumbType.STATE | ||
actions["android.intent.action.TIMEZONE_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.intent.action.TIME_SET"] = BreadcrumbType.STATE | ||
actions["android.os.action.DEVICE_IDLE_MODE_CHANGED"] = BreadcrumbType.STATE | ||
actions["android.os.action.POWER_SAVE_MODE_CHANGED"] = BreadcrumbType.STATE | ||
} | ||
if (!config.shouldDiscardBreadcrumb(BreadcrumbType.NAVIGATION)) { | ||
actions["android.intent.action.DREAMING_STARTED"] = BreadcrumbType.NAVIGATION | ||
actions["android.intent.action.DREAMING_STOPPED"] = BreadcrumbType.NAVIGATION | ||
} | ||
return actions | ||
} | ||
} |
Oops, something went wrong.