pakstr 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android-template/app/build.gradle.kts +71 -4
- package/android-template/app/proguard-rules.pro +21 -18
- package/android-template/app/src/debug/AndroidManifest.xml +11 -0
- package/android-template/app/src/main/AndroidManifest.xml +6 -0
- package/android-template/app/src/main/java/com/pakstr/app/ApplicationClass.kt +14 -0
- package/android-template/app/src/main/java/com/pakstr/app/MainActivity.kt +55 -5
- package/android-template/app/src/main/java/com/pakstr/app/ShellRuntime.kt +1 -1
- package/android-template/app/src/main/java/com/pakstr/app/WebViewController.kt +135 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/AppDebugLogger.kt +78 -5
- package/android-template/app/src/main/java/com/pakstr/app/debug/CrashHandler.kt +32 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugConfigProvider.kt +8 -3
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugLogStorage.kt +43 -11
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugPreferences.kt +85 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugReportExporter.kt +42 -32
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugRuntimeOverride.kt +30 -4
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugSession.kt +16 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DeveloperToolsActivity.kt +234 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DeveloperToolsManager.kt +42 -13
- package/android-template/app/src/main/java/com/pakstr/app/debug/WebViewDebugManager.kt +30 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/logging/PakstrLog.kt +16 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/logging/PakstrLogger.kt +154 -0
- package/android-template/app/src/main/java/com/pakstr/app/signer/NostrBridge.kt +1 -1
- package/android-template/app/src/main/res/layout/activity_developer_tools.xml +308 -0
- package/android-template/app/src/main/res/layout/activity_layout.xml +9 -0
- package/android-template/app/src/main/res/values/dimes.xml +1 -0
- package/android-template/app/src/main/res/values/strings.xml +43 -0
- package/android-template/gradle/libs.versions.toml +1 -0
- package/android-template/gradle.properties +2 -1
- package/package.json +1 -1
|
@@ -1,12 +1,59 @@
|
|
|
1
|
+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
2
|
+
import java.util.Properties
|
|
3
|
+
import java.io.File
|
|
4
|
+
|
|
1
5
|
plugins {
|
|
2
6
|
alias(libs.plugins.android.application)
|
|
3
7
|
alias(libs.plugins.kotlin.compose)
|
|
4
8
|
}
|
|
5
9
|
|
|
10
|
+
val keystoreProperties =
|
|
11
|
+
|
|
12
|
+
Properties()
|
|
13
|
+
|
|
14
|
+
val keystorePath =
|
|
15
|
+
providers.gradleProperty(
|
|
16
|
+
"releaseKeystoreConfig"
|
|
17
|
+
).orNull
|
|
18
|
+
|
|
19
|
+
val keystorePropertiesFile =
|
|
20
|
+
keystorePath?.let { rootProject.file(it) }
|
|
21
|
+
if (keystorePropertiesFile?.exists() == true) {
|
|
22
|
+
|
|
23
|
+
keystorePropertiesFile.inputStream()
|
|
24
|
+
.use {
|
|
25
|
+
keystoreProperties.load(it)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
6
29
|
android {
|
|
7
30
|
namespace = "com.pakstr.app"
|
|
8
31
|
compileSdk = 36
|
|
9
32
|
|
|
33
|
+
signingConfigs {
|
|
34
|
+
|
|
35
|
+
create("release") {
|
|
36
|
+
|
|
37
|
+
if (keystorePropertiesFile?.exists() == true) {
|
|
38
|
+
|
|
39
|
+
storeFile =
|
|
40
|
+
File(
|
|
41
|
+
keystorePropertiesFile.parentFile,
|
|
42
|
+
keystoreProperties["storeFile"] as String
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
storePassword =
|
|
46
|
+
keystoreProperties["storePassword"] as String
|
|
47
|
+
|
|
48
|
+
keyAlias =
|
|
49
|
+
keystoreProperties["keyAlias"] as String
|
|
50
|
+
|
|
51
|
+
keyPassword =
|
|
52
|
+
keystoreProperties["keyPassword"] as String
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
10
57
|
defaultConfig {
|
|
11
58
|
applicationId = "com.pakstr.app"
|
|
12
59
|
minSdk = 28
|
|
@@ -18,23 +65,43 @@ android {
|
|
|
18
65
|
}
|
|
19
66
|
|
|
20
67
|
buildTypes {
|
|
68
|
+
|
|
69
|
+
debug {
|
|
70
|
+
applicationIdSuffix = ".debug"
|
|
71
|
+
versionNameSuffix = "-debug"
|
|
72
|
+
}
|
|
73
|
+
|
|
21
74
|
release {
|
|
22
|
-
|
|
75
|
+
signingConfig =
|
|
76
|
+
signingConfigs.getByName("release")
|
|
77
|
+
isMinifyEnabled = true
|
|
78
|
+
isShrinkResources = true
|
|
23
79
|
proguardFiles(
|
|
24
|
-
getDefaultProguardFile(
|
|
80
|
+
getDefaultProguardFile(
|
|
81
|
+
"proguard-android-optimize.txt"
|
|
82
|
+
),
|
|
25
83
|
"proguard-rules.pro"
|
|
26
84
|
)
|
|
27
85
|
}
|
|
28
86
|
}
|
|
29
87
|
compileOptions {
|
|
30
|
-
sourceCompatibility = JavaVersion.
|
|
31
|
-
targetCompatibility = JavaVersion.
|
|
88
|
+
sourceCompatibility = JavaVersion.VERSION_17
|
|
89
|
+
targetCompatibility = JavaVersion.VERSION_17
|
|
32
90
|
}
|
|
91
|
+
|
|
33
92
|
buildFeatures {
|
|
34
93
|
compose = true
|
|
35
94
|
buildConfig = true
|
|
36
95
|
}
|
|
37
96
|
}
|
|
97
|
+
tasks.withType<KotlinCompile>()
|
|
98
|
+
.configureEach {
|
|
99
|
+
compilerOptions {
|
|
100
|
+
jvmTarget.set(
|
|
101
|
+
org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
38
105
|
|
|
39
106
|
dependencies {
|
|
40
107
|
implementation(libs.androidx.core.ktx)
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# For more details, see
|
|
6
|
-
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
1
|
+
# JavaScript bridge
|
|
2
|
+
-keepclassmembers class * {
|
|
3
|
+
@android.webkit.JavascriptInterface <methods>;
|
|
4
|
+
}
|
|
7
5
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
# class:
|
|
11
|
-
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
12
|
-
# public *;
|
|
13
|
-
#}
|
|
6
|
+
# Nostr signer
|
|
7
|
+
-keep class com.pakstr.app.signer.** { *; }
|
|
14
8
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
#-keepattributes SourceFile,LineNumberTable
|
|
9
|
+
# Crypto
|
|
10
|
+
-keep class com.pakstr.app.crypto.** { *; }
|
|
18
11
|
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
# BouncyCastle
|
|
13
|
+
-keep class org.bouncycastle.crypto.** { *; }
|
|
14
|
+
-keep class org.bouncycastle.math.** { *; }
|
|
15
|
+
-keep class org.bouncycastle.asn1.** { *; }
|
|
16
|
+
|
|
17
|
+
# Ignore unavailable Java SE classes
|
|
18
|
+
-dontwarn javax.naming.**
|
|
19
|
+
|
|
20
|
+
# Keep Application class
|
|
21
|
+
-keep class com.pakstr.app.ApplicationClass { *; }
|
|
22
|
+
|
|
23
|
+
# Keep model classes used through JSON
|
|
24
|
+
-keep class com.pakstr.app.signer.** { *; }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<application>
|
|
4
|
+
<activity-alias
|
|
5
|
+
android:name=".debug.DeveloperToolsDebugLauncher"
|
|
6
|
+
android:enabled="true"
|
|
7
|
+
android:exported="true"
|
|
8
|
+
android:label="@string/developer_tools_title"
|
|
9
|
+
android:targetActivity=".debug.DeveloperToolsActivity" />
|
|
10
|
+
</application>
|
|
11
|
+
</manifest>
|
|
@@ -28,6 +28,12 @@
|
|
|
28
28
|
android:supportsRtl="true"
|
|
29
29
|
android:usesCleartextTraffic="true">
|
|
30
30
|
|
|
31
|
+
<activity
|
|
32
|
+
android:name=".debug.DeveloperToolsActivity"
|
|
33
|
+
android:exported="false"
|
|
34
|
+
android:label="@string/developer_tools_title"
|
|
35
|
+
android:theme="@style/Theme.NostrAppShell" />
|
|
36
|
+
|
|
31
37
|
<activity
|
|
32
38
|
android:name=".MainActivity"
|
|
33
39
|
android:exported="true"
|
|
@@ -2,6 +2,9 @@ package com.pakstr.app
|
|
|
2
2
|
|
|
3
3
|
import android.app.Application
|
|
4
4
|
import com.pakstr.app.crypto.CryptoInitializer
|
|
5
|
+
import com.pakstr.app.debug.AppDebugLogger
|
|
6
|
+
import com.pakstr.app.debug.CrashHandler
|
|
7
|
+
import com.pakstr.app.debug.DebugSession
|
|
5
8
|
import com.pakstr.app.utils.AppPreferences
|
|
6
9
|
|
|
7
10
|
class ApplicationClass : Application() {
|
|
@@ -9,5 +12,16 @@ class ApplicationClass : Application() {
|
|
|
9
12
|
super.onCreate()
|
|
10
13
|
AppPreferences.init(this)
|
|
11
14
|
CryptoInitializer.init()
|
|
15
|
+
CrashHandler.install(this)
|
|
16
|
+
|
|
17
|
+
AppDebugLogger.log(
|
|
18
|
+
|
|
19
|
+
this,
|
|
20
|
+
|
|
21
|
+
"SESSION",
|
|
22
|
+
|
|
23
|
+
"Session started: ${DebugSession.sessionId}"
|
|
24
|
+
|
|
25
|
+
)
|
|
12
26
|
}
|
|
13
27
|
}
|
|
@@ -17,10 +17,14 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
|
17
17
|
import androidx.core.view.ViewCompat
|
|
18
18
|
import androidx.core.view.WindowInsetsCompat
|
|
19
19
|
import androidx.core.view.updatePadding
|
|
20
|
+
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
20
21
|
import com.pakstr.app.debug.AppDebugLogger
|
|
22
|
+
import com.pakstr.app.debug.CrashHandler
|
|
21
23
|
|
|
22
24
|
import com.pakstr.app.debug.DebugReportShare
|
|
25
|
+
import com.pakstr.app.debug.DeveloperToolsActivity
|
|
23
26
|
import com.pakstr.app.debug.DeveloperToolsManager
|
|
27
|
+
import com.pakstr.app.debug.WebViewDebugManager
|
|
24
28
|
|
|
25
29
|
import com.pakstr.app.permissions.PermissionManager
|
|
26
30
|
import com.pakstr.app.permissions.interfaces.PermissionHandler
|
|
@@ -41,6 +45,8 @@ class MainActivity : AppCompatActivity(), PermissionHandler {
|
|
|
41
45
|
private lateinit var amberLauncher:
|
|
42
46
|
ActivityResultLauncher<Intent>
|
|
43
47
|
|
|
48
|
+
private lateinit var fab: FloatingActionButton
|
|
49
|
+
|
|
44
50
|
override fun onCreate(
|
|
45
51
|
|
|
46
52
|
savedInstanceState: Bundle?
|
|
@@ -52,21 +58,32 @@ class MainActivity : AppCompatActivity(), PermissionHandler {
|
|
|
52
58
|
enableEdgeToEdge()
|
|
53
59
|
|
|
54
60
|
super.onCreate(savedInstanceState)
|
|
61
|
+
if (BuildConfig.DEBUG) {
|
|
62
|
+
|
|
63
|
+
DeveloperToolsManager.enableDebug(this)
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
WebViewDebugManager.enable(this)
|
|
68
|
+
|
|
55
69
|
AppDebugLogger.log(
|
|
56
70
|
|
|
57
71
|
this,
|
|
58
72
|
|
|
59
|
-
"
|
|
73
|
+
"TEST",
|
|
60
74
|
|
|
61
|
-
"
|
|
75
|
+
"Developer debug enabled"
|
|
62
76
|
|
|
63
77
|
)
|
|
78
|
+
AppDebugLogger.log(
|
|
64
79
|
|
|
65
|
-
|
|
80
|
+
this,
|
|
66
81
|
|
|
67
|
-
|
|
82
|
+
"SESSION",
|
|
68
83
|
|
|
69
|
-
|
|
84
|
+
"========== APP START =========="
|
|
85
|
+
|
|
86
|
+
)
|
|
70
87
|
|
|
71
88
|
setContentView(
|
|
72
89
|
|
|
@@ -75,6 +92,7 @@ class MainActivity : AppCompatActivity(), PermissionHandler {
|
|
|
75
92
|
)
|
|
76
93
|
|
|
77
94
|
initViews()
|
|
95
|
+
showDebugFab()
|
|
78
96
|
|
|
79
97
|
amberLauncher =
|
|
80
98
|
|
|
@@ -132,6 +150,34 @@ class MainActivity : AppCompatActivity(), PermissionHandler {
|
|
|
132
150
|
|
|
133
151
|
}
|
|
134
152
|
|
|
153
|
+
private fun showDebugFab() {
|
|
154
|
+
if (BuildConfig.DEBUG || RuntimeConfig.debugEnabled(this)) {
|
|
155
|
+
|
|
156
|
+
fab.visibility = View.VISIBLE
|
|
157
|
+
|
|
158
|
+
fab.setOnClickListener {
|
|
159
|
+
|
|
160
|
+
startActivity(
|
|
161
|
+
|
|
162
|
+
Intent(
|
|
163
|
+
|
|
164
|
+
this,
|
|
165
|
+
|
|
166
|
+
DeveloperToolsActivity::class.java
|
|
167
|
+
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
} else {
|
|
175
|
+
|
|
176
|
+
fab.visibility = View.GONE
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
135
181
|
private fun setupBackNavigation() {
|
|
136
182
|
onBackPressedDispatcher.addCallback(
|
|
137
183
|
this,
|
|
@@ -184,6 +230,10 @@ class MainActivity : AppCompatActivity(), PermissionHandler {
|
|
|
184
230
|
permissionManager =
|
|
185
231
|
PermissionManager(this)
|
|
186
232
|
|
|
233
|
+
fab = findViewById(
|
|
234
|
+
|
|
235
|
+
R.id.developerToolsFab)
|
|
236
|
+
|
|
187
237
|
}
|
|
188
238
|
|
|
189
239
|
private fun handleSignerSetup() {
|
|
@@ -95,6 +95,7 @@ class WebViewController(
|
|
|
95
95
|
nip07Injected = injectNip07()
|
|
96
96
|
|
|
97
97
|
}
|
|
98
|
+
injectDebugLogger()
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
override fun onReceivedHttpError(
|
|
@@ -343,4 +344,138 @@ class WebViewController(
|
|
|
343
344
|
false
|
|
344
345
|
}
|
|
345
346
|
}
|
|
347
|
+
|
|
348
|
+
private fun injectDebugLogger() {
|
|
349
|
+
|
|
350
|
+
val js = """
|
|
351
|
+
(function(){
|
|
352
|
+
|
|
353
|
+
if (!window.AndroidBridge) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
const oldLog = console.log;
|
|
359
|
+
const oldWarn = console.warn;
|
|
360
|
+
const oldError = console.error;
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
function send(level, args){
|
|
364
|
+
|
|
365
|
+
try {
|
|
366
|
+
|
|
367
|
+
const message =
|
|
368
|
+
Array.from(args)
|
|
369
|
+
.map(item => {
|
|
370
|
+
|
|
371
|
+
if(typeof item === 'object'){
|
|
372
|
+
return JSON.stringify(item);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return String(item);
|
|
376
|
+
|
|
377
|
+
})
|
|
378
|
+
.join(" ");
|
|
379
|
+
|
|
380
|
+
window.AndroidBridge.debugLog(
|
|
381
|
+
level,
|
|
382
|
+
message
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
} catch(e){
|
|
386
|
+
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
console.log = function(){
|
|
392
|
+
|
|
393
|
+
send(
|
|
394
|
+
"LOG",
|
|
395
|
+
arguments
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
oldLog.apply(
|
|
399
|
+
console,
|
|
400
|
+
arguments
|
|
401
|
+
);
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
console.warn = function(){
|
|
406
|
+
|
|
407
|
+
send(
|
|
408
|
+
"WARN",
|
|
409
|
+
arguments
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
oldWarn.apply(
|
|
413
|
+
console,
|
|
414
|
+
arguments
|
|
415
|
+
);
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
console.error = function(){
|
|
420
|
+
|
|
421
|
+
send(
|
|
422
|
+
"ERROR",
|
|
423
|
+
arguments
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
oldError.apply(
|
|
427
|
+
console,
|
|
428
|
+
arguments
|
|
429
|
+
);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
window.onerror =
|
|
434
|
+
function(
|
|
435
|
+
message,
|
|
436
|
+
source,
|
|
437
|
+
line,
|
|
438
|
+
column,
|
|
439
|
+
error
|
|
440
|
+
){
|
|
441
|
+
|
|
442
|
+
send(
|
|
443
|
+
"ERROR",
|
|
444
|
+
[
|
|
445
|
+
"JS ERROR:",
|
|
446
|
+
message,
|
|
447
|
+
source,
|
|
448
|
+
line,
|
|
449
|
+
column,
|
|
450
|
+
error?.stack
|
|
451
|
+
]
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
return false;
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
window.onunhandledrejection =
|
|
459
|
+
function(event){
|
|
460
|
+
|
|
461
|
+
send(
|
|
462
|
+
"ERROR",
|
|
463
|
+
[
|
|
464
|
+
"PROMISE ERROR:",
|
|
465
|
+
event.reason
|
|
466
|
+
]
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
})();
|
|
473
|
+
""".trimIndent()
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
webView.evaluateJavascript(
|
|
477
|
+
js,
|
|
478
|
+
null
|
|
479
|
+
)
|
|
480
|
+
}
|
|
346
481
|
}
|
|
@@ -5,6 +5,7 @@ import android.util.Log
|
|
|
5
5
|
import com.pakstr.app.BuildConfig
|
|
6
6
|
import com.pakstr.app.RuntimeConfig
|
|
7
7
|
import java.text.SimpleDateFormat
|
|
8
|
+
import java.util.Collections
|
|
8
9
|
import java.util.Date
|
|
9
10
|
import java.util.Locale
|
|
10
11
|
|
|
@@ -15,7 +16,12 @@ object AppDebugLogger {
|
|
|
15
16
|
private const val MAX_LOGS = 500
|
|
16
17
|
|
|
17
18
|
private val logs =
|
|
18
|
-
|
|
19
|
+
|
|
20
|
+
Collections.synchronizedList(
|
|
21
|
+
|
|
22
|
+
mutableListOf<String>()
|
|
23
|
+
|
|
24
|
+
)
|
|
19
25
|
|
|
20
26
|
fun log(
|
|
21
27
|
context: Context,
|
|
@@ -108,10 +114,14 @@ object AppDebugLogger {
|
|
|
108
114
|
|
|
109
115
|
}
|
|
110
116
|
|
|
111
|
-
fun clear(
|
|
117
|
+
fun clear(
|
|
118
|
+
context: Context
|
|
119
|
+
) {
|
|
112
120
|
|
|
113
121
|
logs.clear()
|
|
114
122
|
|
|
123
|
+
DebugLogStorage.clear(context)
|
|
124
|
+
|
|
115
125
|
}
|
|
116
126
|
|
|
117
127
|
private fun isDebugEnabled(
|
|
@@ -280,14 +290,77 @@ object AppDebugLogger {
|
|
|
280
290
|
}
|
|
281
291
|
|
|
282
292
|
private fun config(
|
|
293
|
+
context: Context
|
|
294
|
+
): DebugConfig {
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
val runtime =
|
|
298
|
+
DebugRuntimeOverride.get(context)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
if (runtime != null) {
|
|
302
|
+
return runtime
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
val stored =
|
|
307
|
+
DebugPreferences.load(
|
|
308
|
+
context
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
if (stored.enabled) {
|
|
313
|
+
return stored
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
return RuntimeConfig.debugConfig(
|
|
318
|
+
context
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
}
|
|
283
322
|
|
|
323
|
+
fun exportLogs(
|
|
284
324
|
context: Context
|
|
325
|
+
): String {
|
|
285
326
|
|
|
286
|
-
|
|
327
|
+
return buildString {
|
|
328
|
+
|
|
329
|
+
appendLine(
|
|
330
|
+
"===== PAKSTR DEBUG LOG ====="
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
appendLine(
|
|
334
|
+
"Version: ${BuildConfig.VERSION_NAME}"
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
appendLine(
|
|
338
|
+
"Debug: ${isDebugEnabled(context)}"
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
appendLine()
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
getLogs().forEach {
|
|
345
|
+
appendLine(it)
|
|
346
|
+
}
|
|
287
347
|
|
|
288
|
-
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
fun load(
|
|
352
|
+
|
|
353
|
+
context: Context
|
|
354
|
+
|
|
355
|
+
) {
|
|
356
|
+
|
|
357
|
+
logs.clear()
|
|
289
358
|
|
|
290
|
-
|
|
359
|
+
logs.addAll(
|
|
360
|
+
|
|
361
|
+
DebugLogStorage.read(context)
|
|
362
|
+
|
|
363
|
+
)
|
|
291
364
|
|
|
292
365
|
}
|
|
293
366
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package com.pakstr.app.debug
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
|
|
5
|
+
object CrashHandler {
|
|
6
|
+
|
|
7
|
+
fun install(
|
|
8
|
+
context: Context
|
|
9
|
+
) {
|
|
10
|
+
|
|
11
|
+
val defaultHandler =
|
|
12
|
+
Thread.getDefaultUncaughtExceptionHandler()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
AppDebugLogger.error(
|
|
19
|
+
context,
|
|
20
|
+
"CRASH",
|
|
21
|
+
"Unhandled exception in ${thread.name}",
|
|
22
|
+
throwable
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
defaultHandler?.uncaughtException(
|
|
27
|
+
thread,
|
|
28
|
+
throwable
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
package com.pakstr.app.debug
|
|
2
2
|
|
|
3
|
+
import android.content.Context
|
|
4
|
+
|
|
3
5
|
object DebugConfigProvider {
|
|
4
6
|
|
|
5
7
|
private var manifestConfig =
|
|
6
8
|
DebugConfig()
|
|
7
9
|
|
|
10
|
+
|
|
8
11
|
fun initialize(
|
|
9
12
|
config: DebugConfig
|
|
10
13
|
) {
|
|
@@ -13,10 +16,12 @@ object DebugConfigProvider {
|
|
|
13
16
|
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
fun current():
|
|
17
|
-
DebugConfig {
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
fun current(
|
|
21
|
+
context: Context
|
|
22
|
+
): DebugConfig {
|
|
23
|
+
|
|
24
|
+
return DebugRuntimeOverride.get(context)
|
|
20
25
|
?: manifestConfig
|
|
21
26
|
|
|
22
27
|
}
|