pakstr 0.3.4 → 0.5.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/main/AndroidManifest.xml +17 -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/LocalServer.kt +80 -21
- package/android-template/app/src/main/java/com/pakstr/app/MainActivity.kt +61 -11
- package/android-template/app/src/main/java/com/pakstr/app/RuntimeConfig.kt +81 -37
- package/android-template/app/src/main/java/com/pakstr/app/ShellRuntime.kt +100 -9
- package/android-template/app/src/main/java/com/pakstr/app/WebViewController.kt +280 -20
- package/android-template/app/src/main/java/com/pakstr/app/crypto/Bip340Verifier.kt +0 -5
- package/android-template/app/src/main/java/com/pakstr/app/debug/AppDebugLogger.kt +348 -3
- 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/DebugConfig.kt +11 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugConfigLoader.kt +36 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugConfigProvider.kt +29 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugLogStorage.kt +139 -0
- 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 +149 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugReportShare.kt +52 -0
- package/android-template/app/src/main/java/com/pakstr/app/debug/DebugRuntimeOverride.kt +55 -0
- 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/DeveloperToolsManager.kt +63 -0
- 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/AmberSigner.kt +1 -10
- package/android-template/app/src/main/java/com/pakstr/app/signer/NostrBridge.kt +163 -11
- package/android-template/app/src/main/java/com/pakstr/app/signer/SignerManager.kt +71 -0
- package/android-template/app/src/main/res/xml/file_paths.xml +9 -0
- package/android-template/gradle/libs.versions.toml +1 -0
- package/android-template/gradle.properties +2 -1
- package/dist/runners/LocalGradleRunner.js +12 -2
- package/dist/runtime/runtimeConfig.js +6 -1
- package/package.json +1 -1
|
@@ -1,21 +1,366 @@
|
|
|
1
1
|
package com.pakstr.app.debug
|
|
2
2
|
|
|
3
|
+
import android.content.Context
|
|
3
4
|
import android.util.Log
|
|
4
5
|
import com.pakstr.app.BuildConfig
|
|
6
|
+
import com.pakstr.app.RuntimeConfig
|
|
7
|
+
import java.text.SimpleDateFormat
|
|
8
|
+
import java.util.Collections
|
|
9
|
+
import java.util.Date
|
|
10
|
+
import java.util.Locale
|
|
5
11
|
|
|
6
12
|
object AppDebugLogger {
|
|
7
13
|
|
|
14
|
+
private const val TAG = "PakstrDebug"
|
|
15
|
+
|
|
16
|
+
private const val MAX_LOGS = 500
|
|
17
|
+
|
|
18
|
+
private val logs =
|
|
19
|
+
|
|
20
|
+
Collections.synchronizedList(
|
|
21
|
+
|
|
22
|
+
mutableListOf<String>()
|
|
23
|
+
|
|
24
|
+
)
|
|
25
|
+
|
|
8
26
|
fun log(
|
|
27
|
+
context: Context,
|
|
9
28
|
tag: String,
|
|
10
29
|
message: String
|
|
11
30
|
) {
|
|
12
31
|
|
|
13
|
-
if (
|
|
32
|
+
if (!isDebugEnabled(context)) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
14
35
|
|
|
15
|
-
|
|
16
|
-
|
|
36
|
+
save(
|
|
37
|
+
context,
|
|
38
|
+
"DEBUG",
|
|
39
|
+
tag,
|
|
40
|
+
message
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
Log.d(
|
|
44
|
+
TAG,
|
|
45
|
+
"[$tag] $message"
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fun error(
|
|
50
|
+
context: Context,
|
|
51
|
+
tag: String,
|
|
52
|
+
message: String,
|
|
53
|
+
throwable: Throwable? = null
|
|
54
|
+
) {
|
|
55
|
+
if (!isDebugEnabled(context)) {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
val fullMessage =
|
|
59
|
+
if (throwable != null) {
|
|
60
|
+
"$message\n${Log.getStackTraceString(throwable)}"
|
|
61
|
+
} else {
|
|
17
62
|
message
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
save(
|
|
67
|
+
context,
|
|
68
|
+
"ERROR",
|
|
69
|
+
tag,
|
|
70
|
+
fullMessage
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
Log.e(
|
|
75
|
+
TAG,
|
|
76
|
+
"[$tag] $message",
|
|
77
|
+
throwable
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private fun save(
|
|
82
|
+
context: Context,
|
|
83
|
+
level: String,
|
|
84
|
+
tag: String,
|
|
85
|
+
message: String
|
|
86
|
+
) {
|
|
87
|
+
|
|
88
|
+
val sanitized =
|
|
89
|
+
sanitize(message)
|
|
90
|
+
|
|
91
|
+
val entry =
|
|
92
|
+
format(
|
|
93
|
+
level,
|
|
94
|
+
tag,
|
|
95
|
+
sanitized
|
|
18
96
|
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
logs.add(entry)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
DebugLogStorage.append(
|
|
103
|
+
context,
|
|
104
|
+
entry
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
trim()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fun getLogs(): List<String> {
|
|
112
|
+
|
|
113
|
+
return logs.toList()
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fun clear(
|
|
118
|
+
context: Context
|
|
119
|
+
) {
|
|
120
|
+
|
|
121
|
+
logs.clear()
|
|
122
|
+
|
|
123
|
+
DebugLogStorage.clear(context)
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private fun isDebugEnabled(
|
|
128
|
+
|
|
129
|
+
context: Context
|
|
130
|
+
|
|
131
|
+
): Boolean {
|
|
132
|
+
|
|
133
|
+
return BuildConfig.DEBUG ||
|
|
134
|
+
|
|
135
|
+
config(context).enabled
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private fun sanitize(
|
|
140
|
+
message: String
|
|
141
|
+
): String {
|
|
142
|
+
|
|
143
|
+
// Debug build može vidjeti sve
|
|
144
|
+
if (BuildConfig.DEBUG) {
|
|
145
|
+
return message
|
|
19
146
|
}
|
|
147
|
+
|
|
148
|
+
// Release build uvijek sanitizira
|
|
149
|
+
return message
|
|
150
|
+
.replace(
|
|
151
|
+
Regex(
|
|
152
|
+
"\"plaintext\"\\s*:\\s*\".*?\""
|
|
153
|
+
),
|
|
154
|
+
"\"plaintext\":\"***\""
|
|
155
|
+
)
|
|
156
|
+
.replace(
|
|
157
|
+
Regex(
|
|
158
|
+
"\"ciphertext\"\\s*:\\s*\".*?\""
|
|
159
|
+
),
|
|
160
|
+
"\"ciphertext\":\"***\""
|
|
161
|
+
)
|
|
162
|
+
.replace(
|
|
163
|
+
Regex(
|
|
164
|
+
"\"sig\"\\s*:\\s*\".*?\""
|
|
165
|
+
),
|
|
166
|
+
"\"sig\":\"***\""
|
|
167
|
+
)
|
|
168
|
+
.replace(
|
|
169
|
+
Regex(
|
|
170
|
+
"\"event\"\\s*:\\s*\".*?\""
|
|
171
|
+
),
|
|
172
|
+
"\"event\":\"***\""
|
|
173
|
+
)
|
|
174
|
+
.replace(
|
|
175
|
+
Regex(
|
|
176
|
+
"(?i)authorization: .*"
|
|
177
|
+
),
|
|
178
|
+
"authorization: ***"
|
|
179
|
+
)
|
|
180
|
+
.replace(
|
|
181
|
+
Regex(
|
|
182
|
+
"(?i)bearer\\s+[A-Za-z0-9._-]+"
|
|
183
|
+
),
|
|
184
|
+
"Bearer ***"
|
|
185
|
+
)
|
|
186
|
+
.replace(
|
|
187
|
+
Regex(
|
|
188
|
+
"(?i)token=[^\\s&]+"
|
|
189
|
+
),
|
|
190
|
+
"token=***"
|
|
191
|
+
)
|
|
192
|
+
.replace(
|
|
193
|
+
Regex(
|
|
194
|
+
"(?i)password=[^\\s&]+"
|
|
195
|
+
),
|
|
196
|
+
"password=***"
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private fun format(
|
|
201
|
+
level: String,
|
|
202
|
+
tag: String,
|
|
203
|
+
message: String
|
|
204
|
+
): String {
|
|
205
|
+
|
|
206
|
+
val time =
|
|
207
|
+
SimpleDateFormat(
|
|
208
|
+
"yyyy-MM-dd HH:mm:ss",
|
|
209
|
+
Locale.US
|
|
210
|
+
)
|
|
211
|
+
.format(Date())
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
return "$time [$level] $tag: $message"
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private fun trim() {
|
|
219
|
+
|
|
220
|
+
while (logs.size > MAX_LOGS) {
|
|
221
|
+
|
|
222
|
+
logs.removeAt(0)
|
|
223
|
+
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private fun isDevelopmentBuild(): Boolean {
|
|
229
|
+
return BuildConfig.DEBUG
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private fun isProductionDebug(context: Context): Boolean {
|
|
233
|
+
return !BuildConfig.DEBUG &&
|
|
234
|
+
RuntimeConfig.debugEnabled(context)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
fun isNetworkLoggingEnabled(
|
|
238
|
+
|
|
239
|
+
context: Context
|
|
240
|
+
|
|
241
|
+
): Boolean {
|
|
242
|
+
|
|
243
|
+
return BuildConfig.DEBUG ||
|
|
244
|
+
|
|
245
|
+
config(context).networkLogs
|
|
246
|
+
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
fun isWebViewLoggingEnabled(
|
|
250
|
+
|
|
251
|
+
context: Context
|
|
252
|
+
|
|
253
|
+
): Boolean {
|
|
254
|
+
|
|
255
|
+
return BuildConfig.DEBUG ||
|
|
256
|
+
|
|
257
|
+
config(context).webViewLogs
|
|
258
|
+
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
fun network(
|
|
262
|
+
context: Context,
|
|
263
|
+
message: String
|
|
264
|
+
) {
|
|
265
|
+
if (!isNetworkLoggingEnabled(context)) {
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
log(
|
|
270
|
+
context,
|
|
271
|
+
"HTTP",
|
|
272
|
+
message
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
fun webView(
|
|
278
|
+
context: Context,
|
|
279
|
+
message: String
|
|
280
|
+
) {
|
|
281
|
+
if (!isWebViewLoggingEnabled(context)) {
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
log(
|
|
286
|
+
context,
|
|
287
|
+
"WEBVIEW",
|
|
288
|
+
message
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
|
|
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
|
+
}
|
|
322
|
+
|
|
323
|
+
fun exportLogs(
|
|
324
|
+
context: Context
|
|
325
|
+
): String {
|
|
326
|
+
|
|
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
|
+
}
|
|
347
|
+
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
fun load(
|
|
352
|
+
|
|
353
|
+
context: Context
|
|
354
|
+
|
|
355
|
+
) {
|
|
356
|
+
|
|
357
|
+
logs.clear()
|
|
358
|
+
|
|
359
|
+
logs.addAll(
|
|
360
|
+
|
|
361
|
+
DebugLogStorage.read(context)
|
|
362
|
+
|
|
363
|
+
)
|
|
364
|
+
|
|
20
365
|
}
|
|
21
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
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package com.pakstr.app.debug
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject
|
|
4
|
+
|
|
5
|
+
object DebugConfigLoader {
|
|
6
|
+
|
|
7
|
+
fun load(
|
|
8
|
+
manifest: JSONObject
|
|
9
|
+
): DebugConfig {
|
|
10
|
+
|
|
11
|
+
val debug =
|
|
12
|
+
manifest.optJSONObject("debug")
|
|
13
|
+
?: return DebugConfig()
|
|
14
|
+
|
|
15
|
+
return DebugConfig(
|
|
16
|
+
|
|
17
|
+
enabled =
|
|
18
|
+
debug.optBoolean(
|
|
19
|
+
"enabled",
|
|
20
|
+
false
|
|
21
|
+
),
|
|
22
|
+
|
|
23
|
+
networkLogs =
|
|
24
|
+
debug.optBoolean(
|
|
25
|
+
"networkLogs",
|
|
26
|
+
false
|
|
27
|
+
),
|
|
28
|
+
|
|
29
|
+
webViewLogs =
|
|
30
|
+
debug.optBoolean(
|
|
31
|
+
"webViewLogs",
|
|
32
|
+
false
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package com.pakstr.app.debug
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
|
|
5
|
+
object DebugConfigProvider {
|
|
6
|
+
|
|
7
|
+
private var manifestConfig =
|
|
8
|
+
DebugConfig()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
fun initialize(
|
|
12
|
+
config: DebugConfig
|
|
13
|
+
) {
|
|
14
|
+
|
|
15
|
+
manifestConfig = config
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
fun current(
|
|
21
|
+
context: Context
|
|
22
|
+
): DebugConfig {
|
|
23
|
+
|
|
24
|
+
return DebugRuntimeOverride.get(context)
|
|
25
|
+
?: manifestConfig
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
package com.pakstr.app.debug
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import java.io.File
|
|
5
|
+
|
|
6
|
+
object DebugLogStorage {
|
|
7
|
+
|
|
8
|
+
private const val FILE_NAME =
|
|
9
|
+
"pakstr-debug.log"
|
|
10
|
+
|
|
11
|
+
private const val MAX_FILE_SIZE =
|
|
12
|
+
1024 * 1024 // 1 MB
|
|
13
|
+
|
|
14
|
+
private const val MAX_LINES = 5000
|
|
15
|
+
|
|
16
|
+
fun append(
|
|
17
|
+
context: Context,
|
|
18
|
+
entry: String
|
|
19
|
+
) {
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
|
|
23
|
+
val file =
|
|
24
|
+
getFile(context)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
rotateIfNeeded(file)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
file.appendText(
|
|
31
|
+
|
|
32
|
+
entry + "\n"
|
|
33
|
+
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
trimFile(file)
|
|
37
|
+
|
|
38
|
+
} catch (_: Exception) {
|
|
39
|
+
|
|
40
|
+
// Logging must never crash the app
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fun read(
|
|
46
|
+
context: Context
|
|
47
|
+
): List<String> {
|
|
48
|
+
|
|
49
|
+
return try {
|
|
50
|
+
|
|
51
|
+
val file = getFile(context)
|
|
52
|
+
|
|
53
|
+
if (file.exists()) {
|
|
54
|
+
file.readLines()
|
|
55
|
+
} else {
|
|
56
|
+
emptyList()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
} catch (_: Exception) {
|
|
60
|
+
|
|
61
|
+
emptyList()
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
fun clear(
|
|
67
|
+
context: Context
|
|
68
|
+
) {
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
|
|
72
|
+
getFile(context)
|
|
73
|
+
.delete()
|
|
74
|
+
|
|
75
|
+
} catch (_: Exception) {
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private fun rotateIfNeeded(
|
|
81
|
+
file: File
|
|
82
|
+
) {
|
|
83
|
+
|
|
84
|
+
if (!file.exists()) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if (file.length() >= MAX_FILE_SIZE) {
|
|
90
|
+
|
|
91
|
+
file.writeText("")
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private fun getFile(
|
|
98
|
+
context: Context
|
|
99
|
+
): File {
|
|
100
|
+
|
|
101
|
+
return File(
|
|
102
|
+
context.cacheDir,
|
|
103
|
+
FILE_NAME
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private fun trimFile(
|
|
109
|
+
|
|
110
|
+
file: File
|
|
111
|
+
|
|
112
|
+
) {
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
|
|
116
|
+
val lines =
|
|
117
|
+
|
|
118
|
+
file.readLines()
|
|
119
|
+
|
|
120
|
+
if (lines.size > MAX_LINES) {
|
|
121
|
+
|
|
122
|
+
file.writeText(
|
|
123
|
+
|
|
124
|
+
lines
|
|
125
|
+
|
|
126
|
+
.takeLast(MAX_LINES)
|
|
127
|
+
|
|
128
|
+
.joinToString("\n") + "\n"
|
|
129
|
+
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
} catch (_: Exception) {
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
package com.pakstr.app.debug
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
|
|
5
|
+
object DebugPreferences {
|
|
6
|
+
|
|
7
|
+
private const val PREFS_NAME = "pakstr_debug"
|
|
8
|
+
|
|
9
|
+
private const val KEY_ENABLED = "enabled"
|
|
10
|
+
private const val KEY_NETWORK = "networkLogs"
|
|
11
|
+
private const val KEY_WEBVIEW = "webViewLogs"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
private fun prefs(context: Context) =
|
|
15
|
+
context.getSharedPreferences(
|
|
16
|
+
PREFS_NAME,
|
|
17
|
+
Context.MODE_PRIVATE
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
fun save(
|
|
22
|
+
context: Context,
|
|
23
|
+
config: DebugConfig
|
|
24
|
+
) {
|
|
25
|
+
|
|
26
|
+
prefs(context)
|
|
27
|
+
.edit()
|
|
28
|
+
.putBoolean(
|
|
29
|
+
KEY_ENABLED,
|
|
30
|
+
config.enabled
|
|
31
|
+
)
|
|
32
|
+
.putBoolean(
|
|
33
|
+
KEY_NETWORK,
|
|
34
|
+
config.networkLogs
|
|
35
|
+
)
|
|
36
|
+
.putBoolean(
|
|
37
|
+
KEY_WEBVIEW,
|
|
38
|
+
config.webViewLogs
|
|
39
|
+
)
|
|
40
|
+
.apply()
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
fun load(
|
|
46
|
+
context: Context
|
|
47
|
+
): DebugConfig {
|
|
48
|
+
|
|
49
|
+
val prefs = prefs(context)
|
|
50
|
+
|
|
51
|
+
return DebugConfig(
|
|
52
|
+
|
|
53
|
+
enabled =
|
|
54
|
+
prefs.getBoolean(
|
|
55
|
+
KEY_ENABLED,
|
|
56
|
+
false
|
|
57
|
+
),
|
|
58
|
+
|
|
59
|
+
networkLogs =
|
|
60
|
+
prefs.getBoolean(
|
|
61
|
+
KEY_NETWORK,
|
|
62
|
+
false
|
|
63
|
+
),
|
|
64
|
+
|
|
65
|
+
webViewLogs =
|
|
66
|
+
prefs.getBoolean(
|
|
67
|
+
KEY_WEBVIEW,
|
|
68
|
+
false
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
fun clear(
|
|
76
|
+
context: Context
|
|
77
|
+
) {
|
|
78
|
+
|
|
79
|
+
prefs(context)
|
|
80
|
+
.edit()
|
|
81
|
+
.clear()
|
|
82
|
+
.apply()
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
}
|