-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: added more information about thermals, exit reasons etc...
- Loading branch information
CraZyLegenD
committed
Jun 21, 2020
1 parent
dd5f314
commit bb13384
Showing
7 changed files
with
205 additions
and
10 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
165 changes: 165 additions & 0 deletions
165
crashyreporter/src/main/java/com/crazylegend/crashyreporter/extensions/ExtensionFunctions.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,165 @@ | ||
package com.crazylegend.crashyreporter.extensions | ||
|
||
import android.app.ActivityManager | ||
import android.app.ActivityManager.RunningAppProcessInfo.* | ||
import android.app.ApplicationExitInfo.* | ||
import android.content.Context | ||
import android.os.Build | ||
import android.os.PowerManager | ||
import android.os.PowerManager.* | ||
import androidx.annotation.RequiresApi | ||
import com.crazylegend.crashyreporter.CrashyReporter | ||
import java.util.* | ||
|
||
|
||
/** | ||
* Created by crazy on 6/21/20 to long live and prosper ! | ||
*/ | ||
|
||
internal data class AppDeathInfo( | ||
val description: String?, | ||
val importance: String, | ||
val reason: String, | ||
val timestamp: String | ||
) | ||
|
||
private inline val Context.powerManager | ||
get() = getSystemService(Context.POWER_SERVICE) as PowerManager? | ||
|
||
private inline val Context.activityManager: ActivityManager | ||
get() = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager | ||
|
||
internal val Context.isSustainedPerformanceModeSupported | ||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||
powerManager?.isSustainedPerformanceModeSupported.booleanAsYesOrNo() | ||
} else { | ||
notAvailableString | ||
} | ||
|
||
internal val Context.isInPowerSaveMode | ||
get() = powerManager?.isPowerSaveMode.booleanAsYesOrNo() | ||
|
||
internal val Context.isInInteractiveState | ||
get() = powerManager?.isInteractive.booleanAsYesOrNo() | ||
|
||
internal val Context.isIgnoringBatteryOptimization | ||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
powerManager?.isIgnoringBatteryOptimizations(packageName).booleanAsYesOrNo() | ||
} else { | ||
notAvailableString | ||
} | ||
|
||
private fun Boolean?.booleanAsYesOrNo() = | ||
when (this) { | ||
true -> "Yes" | ||
false -> "No" | ||
null -> notAvailableString | ||
} | ||
|
||
|
||
/** | ||
* THERMAL_STATUS_NONE if device in not under thermal throttling. Value is | ||
* THERMAL_STATUS_NONE, THERMAL_STATUS_LIGHT, | ||
* THERMAL_STATUS_MODERATE, THERMAL_STATUS_SEVERE, THERMAL_STATUS_CRITICAL, THERMAL_STATUS_EMERGENCY, or THERMAL_STATUS_SHUTDOWN | ||
*/ | ||
internal val Context.getThermalStatus: String | ||
@RequiresApi(Build.VERSION_CODES.Q) | ||
get() { | ||
return when (powerManager?.currentThermalStatus) { | ||
THERMAL_STATUS_NONE -> "STATUS_NONE" | ||
THERMAL_STATUS_LIGHT -> "STATUS_LIGHT" | ||
THERMAL_STATUS_MODERATE -> "STATUS_MODERATE" | ||
THERMAL_STATUS_SEVERE -> "STATUS_SEVERE" | ||
THERMAL_STATUS_CRITICAL -> "STATUS_CRITICAL" | ||
THERMAL_STATUS_EMERGENCY -> "STATUS_EMERGENCY" | ||
THERMAL_STATUS_SHUTDOWN -> "STATUS_SHUTDOWN" | ||
|
||
else -> notAvailableString | ||
} | ||
} | ||
|
||
/** | ||
* Value is LOCATION_MODE_NO_CHANGE, LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF, | ||
* LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF, | ||
* LOCATION_MODE_FOREGROUND_ONLY, or LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF | ||
*/ | ||
internal val Context.locationPowerSaveMode: String | ||
get() { | ||
|
||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
when (powerManager?.locationPowerSaveMode) { | ||
LOCATION_MODE_NO_CHANGE -> "MODE_NO_CHANGE" | ||
LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF -> "MODE_GPS_DISABLED_WHEN_SCREEN_OFF" | ||
LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF -> "MODE_ALL_DISABLED_WHEN_SCREEN_OFF" | ||
LOCATION_MODE_FOREGROUND_ONLY -> "MODE_FOREGROUND_ONLY" | ||
LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF -> "MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF" | ||
else -> notAvailableString | ||
} | ||
} else { | ||
notAvailableString | ||
} | ||
} | ||
|
||
internal val Context.isDeviceIdle | ||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
powerManager?.isDeviceIdleMode.booleanAsYesOrNo() | ||
} else { | ||
notAvailableString | ||
} | ||
|
||
|
||
private fun buildExitReason(reason: Int) = when (reason) { | ||
REASON_ANR -> "ANR" | ||
REASON_CRASH -> "CRASH" | ||
REASON_CRASH_NATIVE -> "CRASH_NATIVE" | ||
REASON_DEPENDENCY_DIED -> "DEPENDENCY_DIED" | ||
REASON_EXCESSIVE_RESOURCE_USAGE -> "EXCESSIVE_RESOURCE_USAGE" | ||
REASON_EXIT_SELF -> "EXIT_SELF" | ||
REASON_INITIALIZATION_FAILURE -> "INITIALIZATION_FAILURE" | ||
REASON_LOW_MEMORY -> "LOW_MEMORY" | ||
REASON_OTHER -> "OTHER" | ||
REASON_PERMISSION_CHANGE -> "PERMISSION_CHANGE" | ||
REASON_SIGNALED -> "SIGNALED" | ||
REASON_USER_REQUESTED -> "USER_REQUESTED" | ||
REASON_USER_STOPPED -> "USER_STOPPED" | ||
android.app.ApplicationExitInfo.REASON_UNKNOWN -> "UNKNOWN" | ||
else -> notAvailableString | ||
} | ||
|
||
internal fun Context.getExitReasons(pid: Int = 0, maxRes: Int = 1) = | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { | ||
activityManager.getHistoricalProcessExitReasons(packageName, pid, maxRes).mapIndexed { index, it -> | ||
"~~~~~~~~~~~ Exit reason #${index+1} ~~~~~~~~~~~\n" + | ||
"\n" + | ||
"Description: ${it.description}\n" + | ||
"Importance: ${buildImportance(it.importance)}\n" + | ||
"Importance: ${buildExitReason(it.reason)}\n" + | ||
"Timestamp: ${CrashyReporter.dateFormat.format(Date(it.timestamp))}\n" + | ||
"\n" + | ||
"~~~~~~~~~~~ END of exit reason #${index+1} ~~~~~~~~~~~" + | ||
"\n" + | ||
"\n" | ||
} | ||
} else { | ||
emptyList() | ||
} | ||
|
||
fun buildImportance(importance: Int): String { | ||
return when(importance){ | ||
IMPORTANCE_FOREGROUND-> "FOREGROUND" | ||
IMPORTANCE_FOREGROUND_SERVICE-> "FOREGROUND_SERVICE" | ||
IMPORTANCE_TOP_SLEEPING-> "TOP_SLEEPING" | ||
IMPORTANCE_VISIBLE-> "VISIBLE" | ||
IMPORTANCE_PERCEPTIBLE-> "PERCEPTIBLE" | ||
IMPORTANCE_CANT_SAVE_STATE-> "CANT_SAVE_STATE" | ||
IMPORTANCE_SERVICE-> "SERVICE" | ||
IMPORTANCE_CACHED-> "CACHED" | ||
IMPORTANCE_GONE -> "GONE" | ||
else-> notAvailableString | ||
} | ||
} | ||
|
||
internal const val notAvailableString = "N/A" | ||
|
||
internal fun <T> Collection<T>?.notAvailableIfNullNewLine(): String = if (this.isNullOrEmpty()) "N/A" else "\n${this}" | ||
internal fun <T> Collection<T>?.notAvailableIfNull(): String = if (this.isNullOrEmpty()) "N/A" else "$this" |
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.