Skip to content

Commit b737c2a

Browse files
committed
chore(analytics): Implement Shizuku logs
1 parent 89679eb commit b737c2a

File tree

3 files changed

+93
-8
lines changed

3 files changed

+93
-8
lines changed

app/src/main/java/dev/lexip/hecate/analytics/AnalyticsLogger.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,45 @@ object AnalyticsLogger {
138138
analytics(context).logEvent("in_app_update_installed") { }
139139
}
140140
}
141+
142+
fun logUnexpectedShizukuError(
143+
context: Context,
144+
operation: String,
145+
stage: String,
146+
throwable: Throwable,
147+
binderReady: Boolean,
148+
packageName: String? = null
149+
) {
150+
ifAllowed {
151+
analytics(context).logEvent("shizuku_unexpected_error") {
152+
param("operation", operation)
153+
param("stage", stage)
154+
param("exception_type", throwable.javaClass.simpleName)
155+
param("message", throwable.message ?: "no_message")
156+
param("binder_ready", if (binderReady) 1L else 0L)
157+
if (packageName != null) param("package_name", packageName)
158+
}
159+
}
160+
}
161+
162+
fun logShizukuGrantResult(
163+
context: Context,
164+
result: dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult,
165+
packageName: String
166+
) {
167+
ifAllowed {
168+
analytics(context).logEvent("shizuku_grant_result") {
169+
val (resultType, exitCode) = when (result) {
170+
is dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult.Success -> "success" to null
171+
is dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult.ServiceNotRunning -> "service_not_running" to null
172+
is dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult.NotAuthorized -> "not_authorized" to null
173+
is dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult.ShellCommandFailed -> "shell_command_failed" to result.exitCode
174+
is dev.lexip.hecate.util.shizuku.ShizukuManager.GrantResult.Unexpected -> "unexpected" to null
175+
}
176+
param("result_type", resultType)
177+
exitCode?.let { param("exit_code", it.toLong()) }
178+
param("package_name", packageName)
179+
}
180+
}
181+
}
141182
}

app/src/main/java/dev/lexip/hecate/ui/AdaptiveThemeViewModel.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ class AdaptiveThemeViewModel(
415415
return
416416
}
417417

418-
if (!ShizukuManager.hasPermission()) {
418+
if (!ShizukuManager.hasPermission(context)) {
419419
Toast.makeText(
420420
context,
421421
context.getString(R.string.shizuku_request_permission),
@@ -426,7 +426,8 @@ class AdaptiveThemeViewModel(
426426
}
427427

428428
viewModelScope.launch(ioDispatcher) {
429-
val result = ShizukuManager.executeGrantViaShizuku(packageName)
429+
val result = ShizukuManager.executeGrantViaShizuku(context, packageName)
430+
AnalyticsLogger.logShizukuGrantResult(context, result, packageName)
430431
withContext(mainDispatcher) {
431432
when (result) {
432433
is ShizukuManager.GrantResult.Success -> {
@@ -469,6 +470,7 @@ class AdaptiveThemeViewModel(
469470
Toast.LENGTH_LONG
470471
).show()
471472
}
473+
472474
}
473475
}
474476
}

app/src/main/java/dev/lexip/hecate/util/shizuku/ShizukuManager.kt

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import android.os.Binder
88
import android.os.IBinder
99
import android.os.Parcel
1010
import android.util.Log
11+
import dev.lexip.hecate.analytics.AnalyticsLogger
1112
import rikka.shizuku.Shizuku
1213

1314
object ShizukuManager {
@@ -45,19 +46,26 @@ object ShizukuManager {
4546

4647
fun isBinderReady(): Boolean = binderReady
4748

48-
fun hasPermission(): Boolean {
49+
fun hasPermission(context: Context): Boolean {
4950
if (Shizuku.isPreV11()) return false
5051
if (!binderReady) return false
5152

5253
return try {
5354
Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
5455
} catch (t: Throwable) {
5556
Log.w(TAG, "Failed to check Shizuku permission", t)
57+
AnalyticsLogger.logUnexpectedShizukuError(
58+
context = context,
59+
operation = "check_permission",
60+
stage = "check_self_permission",
61+
throwable = t,
62+
binderReady = binderReady
63+
)
5664
false
5765
}
5866
}
5967

60-
fun requestPermission(@Suppress("UNUSED_PARAMETER") context: Context) {
68+
fun requestPermission(context: Context) {
6169
if (Shizuku.isPreV11()) {
6270
Log.w(TAG, "Ignoring Shizuku.requestPermission on pre-v11")
6371
return
@@ -82,10 +90,10 @@ object ShizukuManager {
8290
fun buildGrantWriteSecureSettingsCommand(packageName: String): String =
8391
"pm grant $packageName android.permission.WRITE_SECURE_SETTINGS"
8492

85-
fun executeGrantViaShizuku(packageName: String): GrantResult {
93+
fun executeGrantViaShizuku(context: Context, packageName: String): GrantResult {
8694
if (Shizuku.isPreV11()) return GrantResult.ServiceNotRunning
8795
if (!binderReady) return GrantResult.ServiceNotRunning
88-
if (!hasPermission()) return GrantResult.NotAuthorized
96+
if (!hasPermission(context)) return GrantResult.NotAuthorized
8997

9098
val cmd = buildGrantWriteSecureSettingsCommand(packageName)
9199

@@ -94,7 +102,13 @@ object ShizukuManager {
94102
var result: GrantResult = GrantResult.Unexpected(IllegalStateException("No result"))
95103

96104
val args = createGrantServiceArgs()
97-
val connection = createGrantServiceConnection(args, cmd, monitor) { grantResult ->
105+
val connection = createGrantServiceConnection(
106+
context,
107+
args,
108+
cmd,
109+
monitor,
110+
packageName
111+
) { grantResult ->
98112
result = grantResult
99113
}
100114

@@ -104,6 +118,14 @@ object ShizukuManager {
104118
result
105119
} catch (t: Throwable) {
106120
Log.e(TAG, "Grant via Shizuku failed", t)
121+
AnalyticsLogger.logUnexpectedShizukuError(
122+
context = context,
123+
operation = "grant_write_secure_settings",
124+
stage = "execute_grant_via_shizuku",
125+
throwable = t,
126+
binderReady = binderReady,
127+
packageName = packageName
128+
)
107129
GrantResult.Unexpected(t)
108130
}
109131
}
@@ -118,9 +140,11 @@ object ShizukuManager {
118140
}
119141

120142
private fun createGrantServiceConnection(
143+
context: Context,
121144
args: Shizuku.UserServiceArgs,
122145
cmd: String,
123146
monitor: Object,
147+
packageName: String,
124148
onResult: (GrantResult) -> Unit
125149
): ServiceConnection {
126150
return object : ServiceConnection {
@@ -137,13 +161,31 @@ object ShizukuManager {
137161
} catch (t: Throwable) {
138162
when (t) {
139163
is SecurityException -> GrantResult.NotAuthorized
140-
else -> GrantResult.Unexpected(t)
164+
else -> {
165+
AnalyticsLogger.logUnexpectedShizukuError(
166+
context = context,
167+
operation = "grant_write_secure_settings",
168+
stage = "on_service_connected_execute",
169+
throwable = t,
170+
binderReady = binderReady,
171+
packageName = packageName
172+
)
173+
GrantResult.Unexpected(t)
174+
}
141175
}
142176
} finally {
143177
try {
144178
Shizuku.unbindUserService(args, this, true)
145179
} catch (t: Throwable) {
146180
Log.w(TAG, "Error while unbinding Shizuku user service", t)
181+
AnalyticsLogger.logUnexpectedShizukuError(
182+
context = context,
183+
operation = "grant_write_secure_settings",
184+
stage = "unbind_user_service",
185+
throwable = t,
186+
binderReady = binderReady,
187+
packageName = packageName
188+
)
147189
}
148190
synchronized(monitor) {
149191
monitor.notifyAll()

0 commit comments

Comments
 (0)