Version Catalog & Spotless (#92)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
alias libs.plugins.android.application
|
||||
alias libs.plugins.kotlin.android
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -41,15 +41,20 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.4.0'
|
||||
implementation 'androidx.core:core-ktx:1.8.0'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation project(path: ':navi-alfred')
|
||||
implementation "com.github.anrwatchdog:anrwatchdog:1.4.0"
|
||||
implementation project(':navi-alfred')
|
||||
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.4"
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
||||
implementation libs.android.material
|
||||
|
||||
implementation libs.androidx.appcompat
|
||||
implementation libs.androidx.core.ktx
|
||||
implementation libs.androidx.lifecycle.viewmodel.ktx
|
||||
|
||||
implementation libs.anrwatchdog
|
||||
|
||||
implementation libs.gson
|
||||
|
||||
androidTestImplementation libs.androidx.test.espresso.core
|
||||
androidTestImplementation libs.androidx.test.junit
|
||||
|
||||
testImplementation libs.junit
|
||||
}
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alfred.demo
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -10,7 +17,6 @@ import com.navi.alfred.utils.AlfredConstants.BROADCAST_ACTION_TYPE
|
||||
import com.navi.alfred.utils.AlfredConstants.BROADCAST_ERROR_MESSAGE
|
||||
import com.navi.alfred.utils.AlfredConstants.BROADCAST_EXCEPTION
|
||||
import com.navi.alfred.utils.AlfredConstants.BROADCAST_REQUEST
|
||||
import android.widget.Toast
|
||||
import com.navi.alfred.utils.log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alfred.demo
|
||||
|
||||
import android.app.Activity
|
||||
@@ -5,18 +12,18 @@ import android.app.Application
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.alfred.demo.activity.SWWActivity
|
||||
import com.alfred.demo.activity.MainActivity
|
||||
import com.alfred.demo.activity.SWWActivity
|
||||
import com.github.anrwatchdog.ANRWatchDog
|
||||
import com.navi.alfred.AlfredConfig
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.AlfredManager.isAlfredRecordingEnabled
|
||||
import com.navi.alfred.utils.AlfredConstants
|
||||
import com.navi.alfred.utils.AlfredConstants.BROADCAST_ACTION_TYPE
|
||||
import com.navi.alfred.utils.log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import com.github.anrwatchdog.ANRWatchDog
|
||||
import com.navi.alfred.AlfredManager.isAlfredRecordingEnabled
|
||||
import com.navi.alfred.utils.AlfredConstants.BROADCAST_ACTION_TYPE
|
||||
|
||||
class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
private var appForegroundCounter: Int = 0
|
||||
@@ -25,32 +32,37 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
super.onCreate()
|
||||
registerActivityLifecycleCallbacks(this)
|
||||
|
||||
val alfredConfig = AlfredConfig(
|
||||
"Alfred Demo App",
|
||||
"1000",
|
||||
"1.0.0",
|
||||
"qa",
|
||||
"oMv77fgpBg9NFGom0Psizbf7lbrdBVJz"
|
||||
)
|
||||
val alfredConfig =
|
||||
AlfredConfig(
|
||||
"Alfred Demo App",
|
||||
"1000",
|
||||
"1.0.0",
|
||||
"qa",
|
||||
"oMv77fgpBg9NFGom0Psizbf7lbrdBVJz"
|
||||
)
|
||||
AlfredManager.init(alfredConfig, this)
|
||||
getAlfredCruiseInfo()
|
||||
|
||||
|
||||
// Dumping anr data to click stream
|
||||
ANRWatchDog().setIgnoreDebugger(true).setReportMainThreadOnly().setANRListener {
|
||||
if (it.cause?.stackTrace.isNullOrEmpty()) {
|
||||
return@setANRListener
|
||||
ANRWatchDog()
|
||||
.setIgnoreDebugger(true)
|
||||
.setReportMainThreadOnly()
|
||||
.setANRListener {
|
||||
if (it.cause?.stackTrace.isNullOrEmpty()) {
|
||||
return@setANRListener
|
||||
}
|
||||
val className = it.cause?.stackTrace?.get(0)?.className.orEmpty()
|
||||
val anrEventProperties =
|
||||
mutableMapOf(
|
||||
"SCREEN_NAME" to ("Alfred Demo App"),
|
||||
"METHOD_NAME" to it.cause?.stackTrace?.get(0)?.methodName.orEmpty(),
|
||||
"LINE_NUMBER" to it.cause?.stackTrace?.get(0)?.lineNumber.toString(),
|
||||
"APP_IN_FOREGROUND" to isAppInForeground().toString()
|
||||
)
|
||||
anrEventProperties["STACK_TRACE"] = it.cause?.stackTrace?.get(0).toString()
|
||||
AlfredManager.handleAnrEvent(anrEventProperties)
|
||||
}
|
||||
val className = it.cause?.stackTrace?.get(0)?.className.orEmpty()
|
||||
val anrEventProperties = mutableMapOf(
|
||||
"SCREEN_NAME" to ("Alfred Demo App"),
|
||||
"METHOD_NAME" to it.cause?.stackTrace?.get(0)?.methodName.orEmpty(),
|
||||
"LINE_NUMBER" to it.cause?.stackTrace?.get(0)?.lineNumber.toString(),
|
||||
"APP_IN_FOREGROUND" to isAppInForeground().toString()
|
||||
)
|
||||
anrEventProperties["STACK_TRACE"] = it.cause?.stackTrace?.get(0).toString()
|
||||
AlfredManager.handleAnrEvent(anrEventProperties)
|
||||
}.start()
|
||||
.start()
|
||||
|
||||
// Crash Reporting to backend
|
||||
val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
|
||||
@@ -60,12 +72,13 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
return@setDefaultUncaughtExceptionHandler
|
||||
}
|
||||
try {
|
||||
val crashEventProperties = mutableMapOf(
|
||||
"SCREEN_NAME" to ("Alfred Demo App"),
|
||||
"METHOD_NAME" to exception.stackTrace[0]?.methodName.orEmpty(),
|
||||
"LINE_NUMBER" to exception.stackTrace[0]?.lineNumber.toString(),
|
||||
"APP_IN_FOREGROUND" to isAppInForeground().toString()
|
||||
)
|
||||
val crashEventProperties =
|
||||
mutableMapOf(
|
||||
"SCREEN_NAME" to ("Alfred Demo App"),
|
||||
"METHOD_NAME" to exception.stackTrace[0]?.methodName.orEmpty(),
|
||||
"LINE_NUMBER" to exception.stackTrace[0]?.lineNumber.toString(),
|
||||
"APP_IN_FOREGROUND" to isAppInForeground().toString()
|
||||
)
|
||||
exception.stackTrace[0]?.let { stackTraceElement ->
|
||||
crashEventProperties["STACK_TRACE"] = stackTraceElement.toString()
|
||||
}
|
||||
@@ -76,8 +89,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
}
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
appForegroundCounter++
|
||||
@@ -89,8 +101,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
}
|
||||
override fun onActivityPaused(activity: Activity) {}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
appForegroundCounter--
|
||||
@@ -99,11 +110,9 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
|
||||
}
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
}
|
||||
override fun onActivityDestroyed(activity: Activity) {}
|
||||
|
||||
private fun startAlfredRecording(activity: Activity) {
|
||||
if (isAlfredRecordingEnabled()) {
|
||||
@@ -114,12 +123,10 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
screenName = "MainActivity"
|
||||
moduleName = "Demo App"
|
||||
}
|
||||
|
||||
is SWWActivity -> {
|
||||
screenName = "SWWActivity"
|
||||
moduleName = "Demo App"
|
||||
}
|
||||
|
||||
else -> {
|
||||
screenName = AlfredConstants.THIRD_PARTY_SCREEN
|
||||
moduleName = AlfredConstants.THIRD_PARTY_MODULE
|
||||
@@ -156,16 +163,18 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
|
||||
"Alfred",
|
||||
"Alfred - getAlfredCruiseInfo started inside try thread = ${Thread.currentThread().name}"
|
||||
)
|
||||
AlfredManager.getAlfredCruiseInfo(cruiseApiSuccessful = { response ->
|
||||
Log.d(
|
||||
"Alfred",
|
||||
"Alfred - getAlfredCruiseInfo cruiseApiSuccessful h response = $response"
|
||||
)
|
||||
})
|
||||
AlfredManager.getAlfredCruiseInfo(
|
||||
cruiseApiSuccessful = { response ->
|
||||
Log.d(
|
||||
"Alfred",
|
||||
"Alfred - getAlfredCruiseInfo cruiseApiSuccessful h response = $response"
|
||||
)
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.d("Alfred", "Alfred - getAlfredCruiseInfo catch e = $e")
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alfred.demo.activity
|
||||
|
||||
import android.content.Intent
|
||||
@@ -29,4 +36,4 @@ class MainActivity : AppCompatActivity() {
|
||||
)
|
||||
return super.dispatchTouchEvent(ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alfred.demo.activity
|
||||
|
||||
import android.os.Bundle
|
||||
@@ -14,15 +21,7 @@ class SWWActivity : AppCompatActivity() {
|
||||
|
||||
val button = findViewById<Button>(R.id.sww_button)
|
||||
button.setOnClickListener {
|
||||
onSSWError(
|
||||
"SWW Button Clicked",
|
||||
"400",
|
||||
"SWW Activity",
|
||||
"Alfred Demo App",
|
||||
400,
|
||||
"WIFI"
|
||||
|
||||
)
|
||||
onSSWError("SWW Button Clicked", "400", "SWW Activity", "Alfred Demo App", 400, "WIFI")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,4 +53,4 @@ class SWWActivity : AppCompatActivity() {
|
||||
)
|
||||
AlfredManager.handleSWWEvent(swwEventProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="app_name">Alfred Android</string>
|
||||
<string name="crash">Crash Occurred</string>
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ * Copyright © 2024 by Navi Technologies Limited
|
||||
~ * All rights reserved. Strictly confidential
|
||||
~
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Theme.AlfredAndroid" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
|
||||
15
build.gradle
15
build.gradle
@@ -1,5 +1,12 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '8.2.0' apply false
|
||||
id 'com.android.library' version '8.2.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
|
||||
}
|
||||
alias libs.plugins.android.application apply false
|
||||
alias libs.plugins.android.library apply false
|
||||
alias libs.plugins.firebase.crashlytics apply false
|
||||
alias libs.plugins.kotlin.android apply false
|
||||
alias libs.plugins.kotlin.parcelize apply false
|
||||
alias libs.plugins.ksp apply false
|
||||
alias libs.plugins.spotless
|
||||
}
|
||||
|
||||
apply from: 'spotless.gradle'
|
||||
apply from: 'projectDependencyGraph.gradle'
|
||||
|
||||
70
gradle/libs.versions.toml
Normal file
70
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,70 @@
|
||||
[versions]
|
||||
android-material = "1.9.0"
|
||||
androidGradlePlugin = "8.2.0"
|
||||
androidx-appcompat = "1.6.1"
|
||||
androidx-core-ktx = "1.8.0"
|
||||
androidx-lifecycle = "2.6.1"
|
||||
androidx-test-espresso = "3.5.0"
|
||||
androidx-test-junit = "1.1.5"
|
||||
androidx-workRuntimeKtx = "2.8.1"
|
||||
anrwatchdog = "1.4.0"
|
||||
chucker = "4.0.0"
|
||||
firebase-bom = "32.7.0"
|
||||
firebase-crashlytics = "2.9.9"
|
||||
gson = "2.10.1"
|
||||
jakewharton-timber = "5.0.1"
|
||||
junit = "4.13.2"
|
||||
kotlin = "1.9.20"
|
||||
ksp = "1.9.20-1.0.14"
|
||||
loggingInterceptor = "4.12.0"
|
||||
retrofit = "2.9.0"
|
||||
room = "2.5.2"
|
||||
spotless = "6.23.3"
|
||||
|
||||
[libraries]
|
||||
android-material = { module = "com.google.android.material:material", version.ref = "android-material" }
|
||||
|
||||
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
|
||||
|
||||
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" }
|
||||
|
||||
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
|
||||
|
||||
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
||||
androidx-room-testing = { module = "androidx.room:room-testing", version.ref = "room" }
|
||||
|
||||
androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-test-espresso" }
|
||||
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" }
|
||||
|
||||
androidx-workRuntime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-workRuntimeKtx" }
|
||||
|
||||
anrwatchdog = { module = "com.github.anrwatchdog:anrwatchdog", version.ref = "anrwatchdog" }
|
||||
|
||||
chucker-library = { module = "com.github.chuckerteam.chucker:library", version.ref = "chucker" }
|
||||
chucker-libraryNoOp = { module = "com.github.chuckerteam.chucker:library-no-op", version.ref = "chucker" }
|
||||
|
||||
firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
|
||||
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase-bom" }
|
||||
firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics" }
|
||||
|
||||
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
|
||||
|
||||
jakewharton-timber = { module = "com.jakewharton.timber:timber", version.ref = "jakewharton-timber" }
|
||||
|
||||
junit = { module = "junit:junit", version.ref = "junit" }
|
||||
|
||||
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptor" }
|
||||
|
||||
retrofit-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
||||
retrofit-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
|
||||
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
|
||||
firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebase-crashlytics" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
|
||||
@@ -1,9 +1,9 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'kotlin-kapt'
|
||||
alias libs.plugins.android.library
|
||||
alias libs.plugins.kotlin.android
|
||||
alias libs.plugins.kotlin.parcelize
|
||||
alias libs.plugins.ksp
|
||||
id 'maven-publish'
|
||||
id 'kotlin-parcelize'
|
||||
}
|
||||
|
||||
def VERSION = "1.0.20"
|
||||
@@ -83,35 +83,36 @@ publishing {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation 'androidx.core:core-ktx:1.6.0'
|
||||
implementation "androidx.appcompat:appcompat:1.5.1"
|
||||
implementation "com.google.android.material:material:1.7.0"
|
||||
// Timber for logging
|
||||
implementation 'com.jakewharton.timber:timber:5.0.1'
|
||||
// Gson
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
// Firebase SDK for Push Notification
|
||||
api 'com.google.firebase:firebase-analytics-ktx'
|
||||
// Firebase SDK for Google Analytics (Kotlin)
|
||||
api 'com.google.firebase:firebase-crashlytics:18.3.6'
|
||||
// Import the BoM for the Firebase platform
|
||||
api platform('com.google.firebase:firebase-bom:30.1.0')
|
||||
implementation "androidx.room:room-runtime:2.4.3"
|
||||
// Kotlin + coroutines
|
||||
implementation "androidx.work:work-runtime-ktx:2.7.1"
|
||||
api platform(libs.firebase.bom)
|
||||
|
||||
// To use Kotlin annotation processing tool (kapt)
|
||||
kapt "androidx.room:room-compiler:2.4.3"
|
||||
// optional - Kotlin Extensions and Coroutines support for Room
|
||||
implementation "androidx.room:room-ktx:2.4.3"
|
||||
api "com.squareup.retrofit2:retrofit:2.9.0"
|
||||
api 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
api 'com.squareup.okhttp3:logging-interceptor:4.12.0'
|
||||
debugImplementation 'com.github.chuckerteam.chucker:library:3.5.2'
|
||||
releaseImplementation 'com.github.chuckerteam.chucker:library-no-op:3.5.2'
|
||||
testImplementation "androidx.room:room-testing:2.4.3"
|
||||
}
|
||||
implementation libs.android.material
|
||||
|
||||
implementation libs.androidx.appcompat
|
||||
implementation libs.androidx.core.ktx
|
||||
implementation libs.androidx.room.ktx
|
||||
implementation libs.androidx.room.runtime
|
||||
implementation libs.androidx.workRuntime.ktx
|
||||
|
||||
implementation libs.gson
|
||||
|
||||
implementation libs.jakewharton.timber
|
||||
|
||||
debugImplementation libs.chucker.library
|
||||
releaseImplementation libs.chucker.libraryNoOp
|
||||
|
||||
api libs.firebase.analytics
|
||||
api libs.firebase.crashlytics
|
||||
|
||||
api libs.logging.interceptor
|
||||
|
||||
api libs.retrofit.converter.gson
|
||||
api libs.retrofit.retrofit
|
||||
|
||||
ksp libs.androidx.room.compiler
|
||||
|
||||
androidTestImplementation libs.androidx.test.espresso.core
|
||||
androidTestImplementation libs.androidx.test.junit
|
||||
|
||||
testImplementation libs.androidx.room.testing
|
||||
testImplementation libs.junit
|
||||
}
|
||||
|
||||
@@ -65,7 +65,13 @@ data class AlfredConfig(
|
||||
internal var batteryPercentageBeforeEventStart: Float? = null,
|
||||
internal var cruiseAttributes: CruiseAttributes = CruiseAttributes()
|
||||
) {
|
||||
constructor(appName: String, appVersionCode: String, appVersionName: String, flavor: String, apiKey: String) : this(
|
||||
constructor(
|
||||
appName: String,
|
||||
appVersionCode: String,
|
||||
appVersionName: String,
|
||||
flavor: String,
|
||||
apiKey: String
|
||||
) : this(
|
||||
appVersionCode = appVersionCode,
|
||||
appVersionName = appVersionName,
|
||||
appName = appName,
|
||||
@@ -103,7 +109,9 @@ data class AlfredConfig(
|
||||
fun getAlfredEventId(): String = this.alfredEventId
|
||||
|
||||
fun setAlfredEventId() {
|
||||
this.alfredEventId = getAlfredSessionId().plus(UNDERSCORE) + UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
this.alfredEventId =
|
||||
getAlfredSessionId().plus(UNDERSCORE) +
|
||||
UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
}
|
||||
|
||||
fun setAlfredSessionId() {
|
||||
@@ -157,7 +165,8 @@ data class AlfredConfig(
|
||||
|
||||
fun getNetworkType(): String = getNetworkType(AlfredManager.applicationContext)
|
||||
|
||||
fun getNetworkStrength(): Float = com.navi.alfred.utils.getNetworkStrength(AlfredManager.applicationContext)
|
||||
fun getNetworkStrength(): Float =
|
||||
com.navi.alfred.utils.getNetworkStrength(AlfredManager.applicationContext)
|
||||
|
||||
fun getBatteryPercentage(): Float =
|
||||
com.navi.alfred.utils.getBatteryPercentage(AlfredManager.applicationContext)
|
||||
@@ -207,9 +216,7 @@ data class AlfredConfig(
|
||||
|
||||
fun getStorageUsage(): Float {
|
||||
val (totalSize, freeSize) =
|
||||
com.navi.alfred.utils.getStorageUsage(
|
||||
context = AlfredManager.applicationContext
|
||||
)
|
||||
com.navi.alfred.utils.getStorageUsage(context = AlfredManager.applicationContext)
|
||||
return (totalSize - freeSize).toFloat()
|
||||
}
|
||||
|
||||
@@ -277,7 +284,7 @@ data class AlfredConfig(
|
||||
|
||||
fun getCurrentTimeZone(): String? {
|
||||
timeZone = TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT)
|
||||
return this.timeZone;
|
||||
return this.timeZone
|
||||
}
|
||||
|
||||
fun setZipFileName(zipFileName: String) {
|
||||
@@ -319,15 +326,17 @@ data class AlfredConfig(
|
||||
fun getCruiseAttributes(): CruiseAttributes = this.cruiseAttributes
|
||||
|
||||
fun setCruiseAttributes() {
|
||||
this.cruiseAttributes = CruiseAttributes(
|
||||
networkType = getNetworkType(applicationContext),
|
||||
networkStrength = getNetworkStrength(),
|
||||
deviceAttributes = DeviceAttributes(
|
||||
battery = getBatteryPercentage(),
|
||||
storage = getStorageUsage(),
|
||||
memory = getMemoryUsagePercentage()
|
||||
this.cruiseAttributes =
|
||||
CruiseAttributes(
|
||||
networkType = getNetworkType(applicationContext),
|
||||
networkStrength = getNetworkStrength(),
|
||||
deviceAttributes =
|
||||
DeviceAttributes(
|
||||
battery = getBatteryPercentage(),
|
||||
storage = getStorageUsage(),
|
||||
memory = getMemoryUsagePercentage()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun getAppName(): String = this.appName
|
||||
|
||||
@@ -62,14 +62,14 @@ import com.navi.alfred.utils.startSyncEvents
|
||||
import com.navi.alfred.worker.AddEventTask
|
||||
import com.navi.alfred.worker.AddMetricTask
|
||||
import com.navi.alfred.worker.AddNegativeCase
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import java.util.concurrent.Executors
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
object AlfredManager {
|
||||
|
||||
@@ -142,11 +142,12 @@ object AlfredManager {
|
||||
config.setSessionStartRecordingTime()
|
||||
config.setEventStartRecordingTime()
|
||||
handleDeviceAttributes()
|
||||
val startRecordingEvent = buildEvent(
|
||||
AlfredConstants.START_RECORDING_EVENT,
|
||||
screenName = screenName,
|
||||
moduleName = moduleName
|
||||
)
|
||||
val startRecordingEvent =
|
||||
buildEvent(
|
||||
AlfredConstants.START_RECORDING_EVENT,
|
||||
screenName = screenName,
|
||||
moduleName = moduleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddEventTask(startRecordingEvent, context))
|
||||
}
|
||||
currentActivity = WeakReference(activity)
|
||||
@@ -172,9 +173,13 @@ object AlfredManager {
|
||||
LayoutInflater.from(applicationContext)
|
||||
.inflate(R.layout.third_party_screen, null)
|
||||
measureInflatedView(thirdPartyScreenView)
|
||||
thirdPartyScreenView.findViewById<AppCompatTextView>(R.id.tv_third_party_name).text = currentScreen.name
|
||||
thirdPartyScreenView
|
||||
.findViewById<AppCompatTextView>(R.id.tv_third_party_name)
|
||||
.text = currentScreen.name
|
||||
bmpForThirdPartySdkScreen =
|
||||
thirdPartyScreenView?.let { captureScreenshotOfCustomView(it) }
|
||||
thirdPartyScreenView?.let {
|
||||
captureScreenshotOfCustomView(it)
|
||||
}
|
||||
}
|
||||
insertScreenShotPathInDb(
|
||||
this,
|
||||
@@ -206,8 +211,9 @@ object AlfredManager {
|
||||
bmpForCanvas = createBitmapForView(view)
|
||||
}
|
||||
try {
|
||||
val bottomSheetView = reactBottomSheetView?.get()
|
||||
?: dialog?.window?.decorView?.rootView
|
||||
val bottomSheetView =
|
||||
reactBottomSheetView?.get()
|
||||
?: dialog?.window?.decorView?.rootView
|
||||
if (bottomSheetView != null) {
|
||||
captureBottomSheet(
|
||||
view,
|
||||
@@ -250,11 +256,12 @@ object AlfredManager {
|
||||
LayoutInflater.from(applicationContext)
|
||||
.inflate(R.layout.app_background_screen, null)
|
||||
measureInflatedView(appBackgroundView)
|
||||
val stopRecordingEvent = buildEvent(
|
||||
AlfredConstants.STOP_RECORDING_EVENT,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
val stopRecordingEvent =
|
||||
buildEvent(
|
||||
AlfredConstants.STOP_RECORDING_EVENT,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddEventTask(stopRecordingEvent, applicationContext))
|
||||
if (ScreenShotStorageHelper.images.size > 0) {
|
||||
startAnrCrashZipUpload(appBackgroundView)
|
||||
@@ -265,18 +272,21 @@ object AlfredManager {
|
||||
fun getAlfredCruiseInfo(cruiseApiSuccessful: (response: CruiseResponse) -> Unit) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
getCruiseConfig(cruiseApiSuccessful = { response ->
|
||||
cruiseApiSuccessful(response)
|
||||
alfredDataBase = AlfredDatabaseHelper.getAnalyticsDatabase(applicationContext)
|
||||
analyticsDao = alfredDataBase.analyticsDao()
|
||||
screenShotDao = alfredDataBase.screenShotDao()
|
||||
zipDetailsDao = alfredDataBase.zipDetailsDao()
|
||||
apiMetricDao = alfredDataBase.apiMetricDao()
|
||||
negativeCaseDao = alfredDataBase.negativeCaseDao()
|
||||
failureEventDao = alfredDataBase.failureEventDao()
|
||||
sensitiveComposeRepository = ComposeMaskingRepoImpl()
|
||||
startSyncEvents()
|
||||
})
|
||||
getCruiseConfig(
|
||||
cruiseApiSuccessful = { response ->
|
||||
cruiseApiSuccessful(response)
|
||||
alfredDataBase =
|
||||
AlfredDatabaseHelper.getAnalyticsDatabase(applicationContext)
|
||||
analyticsDao = alfredDataBase.analyticsDao()
|
||||
screenShotDao = alfredDataBase.screenShotDao()
|
||||
zipDetailsDao = alfredDataBase.zipDetailsDao()
|
||||
apiMetricDao = alfredDataBase.apiMetricDao()
|
||||
negativeCaseDao = alfredDataBase.negativeCaseDao()
|
||||
failureEventDao = alfredDataBase.failureEventDao()
|
||||
sensitiveComposeRepository = ComposeMaskingRepoImpl()
|
||||
startSyncEvents()
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
@@ -299,8 +309,10 @@ object AlfredManager {
|
||||
startTime: Long,
|
||||
endTime: Long
|
||||
) {
|
||||
if (config.getAlfredStatus() && config.getMetricsApiEnableStatus() && config.getAlfredSessionId()
|
||||
.isNotEmpty()
|
||||
if (
|
||||
config.getAlfredStatus() &&
|
||||
config.getMetricsApiEnableStatus() &&
|
||||
config.getAlfredSessionId().isNotEmpty()
|
||||
) {
|
||||
coroutineDispatcher.executor.execute {
|
||||
val duration: Long = endTime - startTime
|
||||
@@ -349,8 +361,10 @@ object AlfredManager {
|
||||
if (currentTouchEvent?.action == ACTION_DOWN) {
|
||||
val actionPointer = currentTouchEvent.actionIndex
|
||||
previousTouchEvent.action = currentTouchEvent.action
|
||||
previousTouchEvent.pointerPositionX = currentTouchEvent.getX(actionPointer)
|
||||
previousTouchEvent.pointerPositionY = currentTouchEvent.getY(actionPointer)
|
||||
previousTouchEvent.pointerPositionX =
|
||||
currentTouchEvent.getX(actionPointer)
|
||||
previousTouchEvent.pointerPositionY =
|
||||
currentTouchEvent.getY(actionPointer)
|
||||
previousTouchEvent.rawX = currentTouchEvent.getRawX()
|
||||
previousTouchEvent.rawY = currentTouchEvent.getRawY()
|
||||
}
|
||||
@@ -374,10 +388,7 @@ object AlfredManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun handleScreenTransitionEvent(
|
||||
screenName: String?,
|
||||
moduleName: String? = null
|
||||
) {
|
||||
fun handleScreenTransitionEvent(screenName: String?, moduleName: String? = null) {
|
||||
if (isAlfredRecordingEnabled()) {
|
||||
if (config.getAlfredSessionId().isNotEmpty()) {
|
||||
coroutineDispatcher.executor.execute {
|
||||
@@ -399,8 +410,7 @@ object AlfredManager {
|
||||
|
||||
fun handleAnrEvent(anrEventProperties: Map<String, String>) {
|
||||
if (config.getAlfredStatus() && config.getAnrEnableStatus()) {
|
||||
val anrView =
|
||||
LayoutInflater.from(applicationContext).inflate(R.layout.anr_screen, null)
|
||||
val anrView = LayoutInflater.from(applicationContext).inflate(R.layout.anr_screen, null)
|
||||
measureInflatedView(anrView)
|
||||
startAnrCrashZipUpload(anrView)
|
||||
if (config.getAlfredSessionId().isNotEmpty()) {
|
||||
@@ -412,12 +422,7 @@ object AlfredManager {
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddNegativeCase(
|
||||
event,
|
||||
this.applicationContext
|
||||
)
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddNegativeCase(event, this.applicationContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,15 +474,15 @@ object AlfredManager {
|
||||
}
|
||||
|
||||
fun setUserId(userId: String?) {
|
||||
config.setUserId(userId)
|
||||
config.setUserId(userId)
|
||||
}
|
||||
|
||||
fun setUserLocation(latitude: Double, longitude: Double) {
|
||||
config.setLocation(latitude, longitude)
|
||||
config.setLocation(latitude, longitude)
|
||||
}
|
||||
|
||||
fun setDisableDialogScreenShot(status: Boolean) {
|
||||
config.setDisableDialogScreenShot(status)
|
||||
config.setDisableDialogScreenShot(status)
|
||||
}
|
||||
|
||||
fun setPhoneNumber(phoneNumber: String?) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
package com.navi.alfred.db
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.navi.alfred.db.dao.AnalyticsDAO
|
||||
@@ -46,5 +47,4 @@ abstract class AlfredDatabase : RoomDatabase() {
|
||||
abstract fun negativeCaseDao(): NegativeCaseDao
|
||||
|
||||
abstract fun failureEventDao(): FailureEventDao
|
||||
|
||||
}
|
||||
|
||||
@@ -102,4 +102,4 @@ interface FailureEventDao {
|
||||
fun deleteFailureEvents(idList: List<Int>)
|
||||
|
||||
@Query("SELECT count(*) FROM FailureEvent") fun getFailureEventCount(): Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.navi.alfred.model.FailureRequest
|
||||
import timber.log.Timber
|
||||
import java.lang.reflect.Type
|
||||
import timber.log.Timber
|
||||
|
||||
class FailureDataDeserializer : JsonDeserializer<FailureRequest> {
|
||||
override fun deserialize(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2021-2023 by Navi Technologies Limited
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.model
|
||||
|
||||
data class CurrentScreen(
|
||||
var name: String? = "",
|
||||
var isComposeScreen: Boolean? = false
|
||||
) {
|
||||
data class CurrentScreen(var name: String? = "", var isComposeScreen: Boolean? = false) {
|
||||
override fun toString(): String {
|
||||
return "CurrentScreen(name='$name', isComposeScreen=$isComposeScreen)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,14 +9,11 @@ package com.navi.alfred.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.navi.alfred.db.model.ScreenShotPathHelper
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.util.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class ErrorMessage(
|
||||
var statusCode: Int? = null,
|
||||
var message: String? = null
|
||||
) : Parcelable
|
||||
data class ErrorMessage(var statusCode: Int? = null, var message: String? = null) : Parcelable
|
||||
|
||||
data class WorkManagerFailureInputData(
|
||||
var alfredSessionId: String? = "",
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
@@ -18,17 +25,22 @@ data class Failure(
|
||||
@SerializedName("error_name") val errorName: String? = "",
|
||||
@SerializedName("error_status_code") val errorStatusCode: Long? = 0,
|
||||
@SerializedName("error_message") val errorMessage: String? = "",
|
||||
@SerializedName("session_id") val sessionId: String? = AlfredManager.config.getAlfredSessionId(),
|
||||
@SerializedName("network_strength") val networkStrength: Float? = AlfredManager.config.getNetworkStrength(),
|
||||
@SerializedName("session_id")
|
||||
val sessionId: String? = AlfredManager.config.getAlfredSessionId(),
|
||||
@SerializedName("network_strength")
|
||||
val networkStrength: Float? = AlfredManager.config.getNetworkStrength(),
|
||||
@SerializedName("event_id_list") val eventIdList: List<String>? = null
|
||||
)
|
||||
|
||||
data class FailureAttributes(
|
||||
@SerializedName("client_name") val clientName: String? = AlfredManager.config.getAppName(),
|
||||
@SerializedName("device_id") val deviceId: String? = AlfredManager.config.getDeviceId(),
|
||||
@SerializedName("phone_number") val phoneNumber: String? = AlfredManager.config.getPhoneNumber(),
|
||||
@SerializedName("phone_number")
|
||||
val phoneNumber: String? = AlfredManager.config.getPhoneNumber(),
|
||||
@SerializedName("customer_id") val customerId: String? = AlfredManager.config.getUserId(),
|
||||
@SerializedName("app_version_code") val appVersionCode: String? = AlfredManager.config.getAppVersionCode(),
|
||||
@SerializedName("app_version_name") val appVersionName: String? = AlfredManager.config.getAppVersionName(),
|
||||
@SerializedName("app_version_code")
|
||||
val appVersionCode: String? = AlfredManager.config.getAppVersionCode(),
|
||||
@SerializedName("app_version_name")
|
||||
val appVersionName: String? = AlfredManager.config.getAppVersionName(),
|
||||
@SerializedName("session_id") val sessionId: String? = AlfredManager.config.getAlfredSessionId()
|
||||
)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.model
|
||||
|
||||
data class MaskingBounds(
|
||||
val left: Float,
|
||||
val top: Float,
|
||||
val right: Float,
|
||||
val bottom: Float
|
||||
) {
|
||||
data class MaskingBounds(val left: Float, val top: Float, val right: Float, val bottom: Float) {
|
||||
val width: Float
|
||||
get() {
|
||||
return right - left
|
||||
@@ -19,4 +21,4 @@ data class MaskingBounds(
|
||||
override fun toString(): String {
|
||||
return "MaskingBounds(left=$left, top=$top, right=$right, bottom=$bottom)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ data class EventAttribute(
|
||||
@SerializedName("module_name") val moduleName: String? = null,
|
||||
@SerializedName("fragment_list") val fragmentList: List<String>? = null,
|
||||
@SerializedName("zip_name") val zipName: String? = null,
|
||||
@SerializedName("session_time_stamp") val sessionTimeStamp: Long? = AlfredManager.config.getSessionStartRecordingTime(),
|
||||
@SerializedName("session_time_stamp")
|
||||
val sessionTimeStamp: Long? = AlfredManager.config.getSessionStartRecordingTime(),
|
||||
@SerializedName("screenshot_timestamp") val screenShotTimeStamp: Long? = null
|
||||
)
|
||||
|
||||
@@ -62,18 +63,15 @@ data class BaseAttribute(
|
||||
@SerializedName("parent_session_id") val parentSessionId: String? = null,
|
||||
@SerializedName("event_timestamp")
|
||||
val eventTimeStamp: Long? = AlfredManager.config.getEventTimeStamp(),
|
||||
@SerializedName("session_id")
|
||||
val sessionId: String? = null,
|
||||
@SerializedName("session_time_stamp")
|
||||
val sessionTimeStamp: Long? = null,
|
||||
@SerializedName("event_end_time_stamp")
|
||||
val latestScreenshotTimestamp: Long? = null,
|
||||
@SerializedName("timezone")
|
||||
val timezone: String? = AlfredManager.config.getCurrentTimeZone(),
|
||||
@SerializedName("session_id") val sessionId: String? = null,
|
||||
@SerializedName("session_time_stamp") val sessionTimeStamp: Long? = null,
|
||||
@SerializedName("event_end_time_stamp") val latestScreenshotTimestamp: Long? = null,
|
||||
@SerializedName("timezone") val timezone: String? = AlfredManager.config.getCurrentTimeZone(),
|
||||
@SerializedName("metadata") val metaData: MetaData = MetaData(),
|
||||
@SerializedName("snapshot_per_second") val snapshotPerSecond: Int? = AlfredManager.config.getSnapshotPerSecond(),
|
||||
@SerializedName("snapshot_per_second")
|
||||
val snapshotPerSecond: Int? = AlfredManager.config.getSnapshotPerSecond(),
|
||||
@SerializedName("phone_number") val phoneNumber: String? = AlfredManager.config.getPhoneNumber()
|
||||
)
|
||||
)
|
||||
|
||||
data class SessionEventAttribute(
|
||||
@SerializedName("event_id") val eventId: String? = null,
|
||||
@@ -90,9 +88,12 @@ data class DeviceAttributes(
|
||||
)
|
||||
|
||||
data class MetaData(
|
||||
@SerializedName("phone_number") val phoneNumber: String? = AlfredManager.config.getPhoneNumber(),
|
||||
@SerializedName("agent_email_id") val agentEmailId: String? = AlfredManager.config.getAgentEmailId(),
|
||||
@SerializedName("code_push_version") val codePushVersion: String? = AlfredManager.config.getCodePushVersion()
|
||||
@SerializedName("phone_number")
|
||||
val phoneNumber: String? = AlfredManager.config.getPhoneNumber(),
|
||||
@SerializedName("agent_email_id")
|
||||
val agentEmailId: String? = AlfredManager.config.getAgentEmailId(),
|
||||
@SerializedName("code_push_version")
|
||||
val codePushVersion: String? = AlfredManager.config.getCodePushVersion()
|
||||
)
|
||||
|
||||
data class CruiseAttributes(
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
package com.navi.alfred.network
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
@@ -21,12 +22,12 @@ import com.navi.alfred.network.model.RequestInfo
|
||||
import com.navi.alfred.utils.AlfredConstants
|
||||
import com.navi.alfred.utils.handleException
|
||||
import com.navi.alfred.utils.orZero
|
||||
import java.util.concurrent.TimeUnit
|
||||
import okhttp3.*
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object AlfredFailureRetrofitProvider {
|
||||
private const val FAILURE_BASE_URL_QA = "https://qa-sa.navi.com/"
|
||||
@@ -99,14 +100,19 @@ object AlfredFailureRetrofitProvider {
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun setNetworkFailureBroadcast(e: Exception, errorMessage: ErrorMessage, request: Request) {
|
||||
private fun setNetworkFailureBroadcast(
|
||||
e: Exception,
|
||||
errorMessage: ErrorMessage,
|
||||
request: Request
|
||||
) {
|
||||
Log.d("Alfred", "AlfredRetrofitProvider setNetworkFailureBroadcast - sending Broadcast")
|
||||
val intent = Intent(AlfredConstants.BROADCAST_ACTION_TYPE)
|
||||
val requestInfo = RequestInfo(
|
||||
request.url.toString(),
|
||||
request.headers[AlfredConstants.HEADER_X_TARGET],
|
||||
request.headers[AlfredConstants.HEADER_APP_REQUEST_ID]
|
||||
)
|
||||
val requestInfo =
|
||||
RequestInfo(
|
||||
request.url.toString(),
|
||||
request.headers[AlfredConstants.HEADER_X_TARGET],
|
||||
request.headers[AlfredConstants.HEADER_APP_REQUEST_ID]
|
||||
)
|
||||
intent.putExtra(AlfredConstants.BROADCAST_EXCEPTION, e)
|
||||
intent.putExtra(AlfredConstants.BROADCAST_ERROR_MESSAGE, errorMessage)
|
||||
intent.putExtra(AlfredConstants.BROADCAST_REQUEST, requestInfo)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
package com.navi.alfred.network
|
||||
|
||||
|
||||
import com.navi.alfred.model.FailureRequest
|
||||
import com.navi.alfred.utils.AlfredConstants.CONTENT_TYPE
|
||||
import com.navi.alfred.utils.AlfredConstants.X_API_KEY
|
||||
|
||||
@@ -42,7 +42,11 @@ class AlfredNetworkRepository {
|
||||
return AlfredRetrofitProvider.getApiService().getPreSignedUrl(sessionId, ALFRED, apiKey)
|
||||
}
|
||||
|
||||
suspend fun sendSession(url: String, apiKey: String, sessionRequest: SessionRequest): Response<Unit> {
|
||||
suspend fun sendSession(
|
||||
url: String,
|
||||
apiKey: String,
|
||||
sessionRequest: SessionRequest
|
||||
): Response<Unit> {
|
||||
return AlfredRetrofitProvider.getApiService()
|
||||
.sendSession(url, "application/json", apiKey, ALFRED, sessionRequest)
|
||||
}
|
||||
@@ -60,7 +64,11 @@ class AlfredNetworkRepository {
|
||||
return AlfredRetrofitProvider.getApiService().uploadToS3(preSignedUrl, request, ALFRED)
|
||||
}
|
||||
|
||||
suspend fun eventMetric(url: String, apiKey: String, metricRequestBody: EventMetricRequest): Response<Unit> {
|
||||
suspend fun eventMetric(
|
||||
url: String,
|
||||
apiKey: String,
|
||||
metricRequestBody: EventMetricRequest
|
||||
): Response<Unit> {
|
||||
return AlfredRetrofitProvider.getApiService()
|
||||
.sendMetric(url, ALFRED, apiKey, "application/json", metricRequestBody)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
package com.navi.alfred.network
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
@@ -29,12 +30,12 @@ import com.navi.alfred.utils.AlfredConstants.HEADER_APP_REQUEST_ID
|
||||
import com.navi.alfred.utils.AlfredConstants.HEADER_X_TARGET
|
||||
import com.navi.alfred.utils.handleException
|
||||
import com.navi.alfred.utils.orZero
|
||||
import java.util.concurrent.TimeUnit
|
||||
import okhttp3.*
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object AlfredRetrofitProvider {
|
||||
private const val BASE_URL_DEBUG = "https://dev-sa.navi.com/"
|
||||
@@ -117,14 +118,19 @@ object AlfredRetrofitProvider {
|
||||
return apiService
|
||||
}
|
||||
|
||||
private fun setNetworkFailureBroadcast(e: Exception, errorMessage: ErrorMessage, request: Request) {
|
||||
private fun setNetworkFailureBroadcast(
|
||||
e: Exception,
|
||||
errorMessage: ErrorMessage,
|
||||
request: Request
|
||||
) {
|
||||
Log.d("Alfred", "AlfredRetrofitProvider setNetworkFailureBroadcast - sending Broadcast")
|
||||
val intent = Intent(BROADCAST_ACTION_TYPE)
|
||||
val requestInfo = RequestInfo(
|
||||
request.url.toString(),
|
||||
request.headers[HEADER_X_TARGET],
|
||||
request.headers[HEADER_APP_REQUEST_ID]
|
||||
)
|
||||
val requestInfo =
|
||||
RequestInfo(
|
||||
request.url.toString(),
|
||||
request.headers[HEADER_X_TARGET],
|
||||
request.headers[HEADER_APP_REQUEST_ID]
|
||||
)
|
||||
intent.putExtra(BROADCAST_EXCEPTION, e)
|
||||
intent.putExtra(BROADCAST_ERROR_MESSAGE, errorMessage)
|
||||
intent.putExtra(BROADCAST_REQUEST, requestInfo)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.network.model
|
||||
|
||||
import android.os.Parcelable
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.repository
|
||||
|
||||
import android.view.View
|
||||
@@ -6,9 +13,16 @@ import com.navi.alfred.model.MaskingBounds
|
||||
interface ComposeMaskingRepo {
|
||||
fun maskSensitiveComposable(id: String, coordinates: MaskingBounds?, rootView: View?)
|
||||
|
||||
fun maskSensitiveUiTronComposable(id: String, left: Float?, top: Float?, right: Float?, bottom: Float?, rootView: View?)
|
||||
fun maskSensitiveUiTronComposable(
|
||||
id: String,
|
||||
left: Float?,
|
||||
top: Float?,
|
||||
right: Float?,
|
||||
bottom: Float?,
|
||||
rootView: View?
|
||||
)
|
||||
|
||||
fun removeSensitiveComposable(id: String)
|
||||
|
||||
fun blurSensitiveScreen(isVisible: Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.repository
|
||||
|
||||
import android.view.View
|
||||
@@ -9,11 +16,8 @@ class ComposeMaskingRepoImpl : ComposeMaskingRepo {
|
||||
private val sensitiveCoordinates = mutableMapOf<String, MaskingBounds>()
|
||||
private var rootView = WeakReference<View>(null)
|
||||
private var blurSensitiveScreen = false
|
||||
override fun maskSensitiveComposable(
|
||||
id: String,
|
||||
coordinates: MaskingBounds?,
|
||||
rootView: View?
|
||||
) {
|
||||
|
||||
override fun maskSensitiveComposable(id: String, coordinates: MaskingBounds?, rootView: View?) {
|
||||
if (AlfredManager.isAlfredRecordingEnabled()) {
|
||||
if (rootView != this.rootView.get()) {
|
||||
removeAllSensitiveComposables()
|
||||
@@ -69,4 +73,4 @@ class ComposeMaskingRepoImpl : ComposeMaskingRepo {
|
||||
internal fun getBlurSensitiveScreenStatus(): Boolean {
|
||||
return blurSensitiveScreen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,4 +110,4 @@ object AlfredConstants {
|
||||
const val SCREEN_TRANSITION_EVENT = "SCREEN_TRANSITION_EVENT"
|
||||
const val LATEST_SCREENSHOT_TIMESTAMP = "LATEST_SCREENSHOT_TIMESTAMP"
|
||||
const val SNAPSHOT_PER_SECOND = "SNAPSHOT_PER_SECOND"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.navi.alfred.AlfredManager
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
private fun Any.tag(): String {
|
||||
return try {
|
||||
this::class.java.simpleName.ifEmpty { "Empty" }
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.model.Failure
|
||||
import com.navi.alfred.model.FailureAttributes
|
||||
import com.navi.alfred.model.FailureRequest
|
||||
import com.navi.alfred.network.AlfredNetworkRepository
|
||||
import com.navi.alfred.network.model.CruiseResponse
|
||||
import com.navi.alfred.utils.AlfredConstants.DEFAULT_CRUISE_CONFIG_URL
|
||||
|
||||
@@ -29,23 +35,25 @@ internal suspend fun getCruiseConfig(cruiseApiSuccessful: (response: CruiseRespo
|
||||
e.log()
|
||||
}
|
||||
} else {
|
||||
val cruiseFailure = Failure(
|
||||
errorType = AlfredConstants.API_ERROR,
|
||||
requestUrl = DEFAULT_CRUISE_CONFIG_URL,
|
||||
requestMethod = AlfredConstants.GET_METHOD,
|
||||
errorTimestamp = System.currentTimeMillis(),
|
||||
errorName = AlfredConstants.GET_CRUISE_CONFIG_FAILURE,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message()
|
||||
)
|
||||
val cruiseFailure =
|
||||
Failure(
|
||||
errorType = AlfredConstants.API_ERROR,
|
||||
requestUrl = DEFAULT_CRUISE_CONFIG_URL,
|
||||
requestMethod = AlfredConstants.GET_METHOD,
|
||||
errorTimestamp = System.currentTimeMillis(),
|
||||
errorName = AlfredConstants.GET_CRUISE_CONFIG_FAILURE,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message()
|
||||
)
|
||||
try {
|
||||
AlfredManager.networkRepository.sendFailure(
|
||||
AlfredConstants.DEFAULT_SEND_FAILURE_POST_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
failureRequest = FailureRequest(
|
||||
failureAttributes = FailureAttributes(),
|
||||
events = listOf(cruiseFailure)
|
||||
)
|
||||
failureRequest =
|
||||
FailureRequest(
|
||||
failureAttributes = FailureAttributes(),
|
||||
events = listOf(cruiseFailure)
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
@@ -60,9 +68,7 @@ private fun setCruiseConfig(cruiseResponse: CruiseResponse) {
|
||||
|
||||
cruiseConfig.source.let { source ->
|
||||
source.enable?.let { sourceConfig ->
|
||||
AlfredManager.config.setAlfredStatus(
|
||||
sourceConfig
|
||||
)
|
||||
AlfredManager.config.setAlfredStatus(sourceConfig)
|
||||
}
|
||||
source.recordingsConfig?.let { recordingConfig ->
|
||||
recordingConfig.enable?.let { enable ->
|
||||
|
||||
@@ -15,10 +15,10 @@ import android.os.Build
|
||||
import android.os.StatFs
|
||||
import android.telephony.TelephonyManager
|
||||
import com.navi.alfred.AlfredManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal fun handleDeviceAttributes() {
|
||||
AlfredManager.coroutineScope.launch(Dispatchers.IO) {
|
||||
@@ -53,7 +53,6 @@ internal fun getNetworkType(context: Context): String {
|
||||
TelephonyManager.NETWORK_TYPE_CDMA,
|
||||
TelephonyManager.NETWORK_TYPE_1xRTT,
|
||||
TelephonyManager.NETWORK_TYPE_IDEN -> "2G"
|
||||
|
||||
TelephonyManager.NETWORK_TYPE_UMTS,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_0,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_A,
|
||||
@@ -63,7 +62,6 @@ internal fun getNetworkType(context: Context): String {
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_B,
|
||||
TelephonyManager.NETWORK_TYPE_EHRPD,
|
||||
TelephonyManager.NETWORK_TYPE_HSPAP -> "3G"
|
||||
|
||||
TelephonyManager.NETWORK_TYPE_LTE -> "4G"
|
||||
TelephonyManager.NETWORK_TYPE_NR -> "5G"
|
||||
else -> "Unknown" + AlfredConstants.UNDERSCORE + mTelephonyManager.networkType
|
||||
@@ -79,13 +77,13 @@ fun getNetworkStrength(context: Context): Float {
|
||||
try {
|
||||
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val netInfo = cm.activeNetworkInfo ?: return 0f
|
||||
val nc = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
cm.getNetworkCapabilities(cm.activeNetwork)
|
||||
} else {
|
||||
return 0f
|
||||
}
|
||||
val nc =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
cm.getNetworkCapabilities(cm.activeNetwork)
|
||||
} else {
|
||||
return 0f
|
||||
}
|
||||
return nc?.linkUpstreamBandwidthKbps?.toFloat() ?: 0f
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import androidx.annotation.WorkerThread
|
||||
@@ -35,26 +42,28 @@ import com.navi.alfred.worker.AddEventTask
|
||||
import com.navi.alfred.worker.AddFailureTask
|
||||
import com.navi.alfred.worker.AddMetricTask
|
||||
import com.navi.alfred.worker.AddNegativeCase
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.lang.reflect.Type
|
||||
import java.util.UUID
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
internal suspend fun sendEventsToServer(
|
||||
clientTs: Long? = null,
|
||||
snapshotPerSecond: Int? = null,
|
||||
workManagerFlow: Boolean? = false
|
||||
): Boolean {
|
||||
if (workManagerFlow == true || (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus())) {
|
||||
if (
|
||||
workManagerFlow == true ||
|
||||
(AlfredManager.config.getAlfredStatus() &&
|
||||
AlfredManager.config.getEnableRecordingStatus())
|
||||
) {
|
||||
try {
|
||||
var baseAttributes = BaseAttribute()
|
||||
if (workManagerFlow == true) {
|
||||
baseAttributes = BaseAttribute(
|
||||
clientTs = clientTs,
|
||||
snapshotPerSecond = snapshotPerSecond
|
||||
)
|
||||
baseAttributes =
|
||||
BaseAttribute(clientTs = clientTs, snapshotPerSecond = snapshotPerSecond)
|
||||
AlfredManager.analyticsDao = AlfredManager.alfredDataBase.analyticsDao()
|
||||
}
|
||||
AlfredManager.mutex.withLock {
|
||||
@@ -68,18 +77,21 @@ internal suspend fun sendEventsToServer(
|
||||
val events: ArrayList<EventAttribute> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
if (events.size > 0) {
|
||||
val request = AnalyticsRequest(
|
||||
baseAttribute = baseAttributes,
|
||||
events = events
|
||||
)
|
||||
val response = AlfredManager.networkRepository.sendEvents(
|
||||
AlfredManager.config.getPostUrl(),
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
val request =
|
||||
AnalyticsRequest(baseAttribute = baseAttributes, events = events)
|
||||
val response =
|
||||
AlfredManager.networkRepository.sendEvents(
|
||||
AlfredManager.config.getPostUrl(),
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
return if (
|
||||
response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) {
|
||||
AlfredManager.analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
response.isSuccessful &&
|
||||
response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
) {
|
||||
AlfredManager.analyticsDao.deleteEvents(
|
||||
analyticsEvents.map { it.eventId }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
val zipNamesList: MutableList<String> = mutableListOf()
|
||||
@@ -90,17 +102,18 @@ internal suspend fun sendEventsToServer(
|
||||
}
|
||||
eventIdList.add(event.eventId ?: "")
|
||||
}
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_EVENT_POST_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = zipNamesList,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_EVENT_FAILURE,
|
||||
clientTs = request.baseAttribute?.clientTs,
|
||||
eventIdList = eventIdList
|
||||
)
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_EVENT_POST_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = zipNamesList,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_EVENT_FAILURE,
|
||||
clientTs = request.baseAttribute?.clientTs,
|
||||
eventIdList = eventIdList
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
@@ -108,7 +121,9 @@ internal suspend fun sendEventsToServer(
|
||||
)
|
||||
)
|
||||
if (response.code() == AlfredConstants.CODE_API_BAD_REQUEST) {
|
||||
AlfredManager.analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
AlfredManager.analyticsDao.deleteEvents(
|
||||
analyticsEvents.map { it.eventId }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -138,19 +153,23 @@ internal suspend fun sendNegativeCaseToServer(
|
||||
snapshotPerSecond: Int? = null,
|
||||
workManagerFlow: Boolean? = false
|
||||
): Boolean {
|
||||
if (workManagerFlow == true || (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus())) {
|
||||
if (
|
||||
workManagerFlow == true ||
|
||||
(AlfredManager.config.getAlfredStatus() &&
|
||||
AlfredManager.config.getEnableRecordingStatus())
|
||||
) {
|
||||
try {
|
||||
var baseAttributes = BaseAttribute()
|
||||
if (workManagerFlow == true) {
|
||||
baseAttributes = BaseAttribute(
|
||||
clientTs = clientTs,
|
||||
snapshotPerSecond = snapshotPerSecond
|
||||
)
|
||||
baseAttributes =
|
||||
BaseAttribute(clientTs = clientTs, snapshotPerSecond = snapshotPerSecond)
|
||||
AlfredManager.negativeCaseDao = AlfredManager.alfredDataBase.negativeCaseDao()
|
||||
}
|
||||
AlfredManager.mutex.withLock {
|
||||
val negativeEvents =
|
||||
AlfredManager.negativeCaseDao.fetchNegativeCase(AlfredManager.config.getEventBatchSize())
|
||||
AlfredManager.negativeCaseDao.fetchNegativeCase(
|
||||
AlfredManager.config.getEventBatchSize()
|
||||
)
|
||||
if (negativeEvents.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = negativeEvents.map { it.details }
|
||||
@@ -160,29 +179,31 @@ internal suspend fun sendNegativeCaseToServer(
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
if (events.size > 0) {
|
||||
val request =
|
||||
AnalyticsRequest(
|
||||
baseAttribute = baseAttributes,
|
||||
events = events
|
||||
AnalyticsRequest(baseAttribute = baseAttributes, events = events)
|
||||
val response =
|
||||
AlfredManager.networkRepository.sendNegativeCase(
|
||||
DEFAULT_SEND_CRASH_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
val response = AlfredManager.networkRepository.sendNegativeCase(
|
||||
DEFAULT_SEND_CRASH_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
return if (
|
||||
response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
response.isSuccessful &&
|
||||
response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
) {
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(
|
||||
negativeEvents.map { it.negativeCaseId }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_CRASH_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_CRASH_FAILURE
|
||||
)
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_CRASH_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_CRASH_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
@@ -190,7 +211,9 @@ internal suspend fun sendNegativeCaseToServer(
|
||||
)
|
||||
)
|
||||
if (response.code() == AlfredConstants.CODE_API_BAD_REQUEST) {
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(
|
||||
negativeEvents.map { it.negativeCaseId }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -215,42 +238,50 @@ internal suspend fun sendNegativeCaseToServer(
|
||||
return false
|
||||
}
|
||||
|
||||
internal suspend fun sendFailureEventsToServer(
|
||||
workManagerFlow: Boolean? = false
|
||||
): Boolean {
|
||||
if (workManagerFlow == true || (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus())) {
|
||||
internal suspend fun sendFailureEventsToServer(workManagerFlow: Boolean? = false): Boolean {
|
||||
if (
|
||||
workManagerFlow == true ||
|
||||
(AlfredManager.config.getAlfredStatus() &&
|
||||
AlfredManager.config.getEnableRecordingStatus())
|
||||
) {
|
||||
try {
|
||||
if (workManagerFlow == true) {
|
||||
AlfredManager.failureEventDao = AlfredManager.alfredDataBase.failureEventDao()
|
||||
}
|
||||
AlfredManager.mutex.withLock {
|
||||
val failureEvents =
|
||||
AlfredManager.failureEventDao.fetchFailureEvents(AlfredManager.config.getFailureEventBatchSize())
|
||||
AlfredManager.failureEventDao.fetchFailureEvents(
|
||||
AlfredManager.config.getFailureEventBatchSize()
|
||||
)
|
||||
if (failureEvents.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = failureEvents.map { it.details }
|
||||
val listType: Type =
|
||||
object : TypeToken<ArrayList<Failure?>?>() {}.type
|
||||
val listType: Type = object : TypeToken<ArrayList<Failure?>?>() {}.type
|
||||
val events: ArrayList<Failure> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
|
||||
if (events.size > 0) {
|
||||
val failureAttributes = FailureAttributes(sessionId = events[0].sessionId)
|
||||
val failureAttributes =
|
||||
FailureAttributes(sessionId = events[0].sessionId)
|
||||
val request =
|
||||
FailureRequest(
|
||||
failureAttributes = failureAttributes,
|
||||
events = events
|
||||
)
|
||||
val response = AlfredManager.networkRepository.sendFailure(
|
||||
DEFAULT_SEND_FAILURE_POST_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
val response =
|
||||
AlfredManager.networkRepository.sendFailure(
|
||||
DEFAULT_SEND_FAILURE_POST_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
return if (
|
||||
(response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) or
|
||||
(response.code() == AlfredConstants.CODE_API_BAD_REQUEST)
|
||||
(response.isSuccessful &&
|
||||
response.code() == AlfredConstants.CODE_API_SUCCESS) or
|
||||
(response.code() == AlfredConstants.CODE_API_BAD_REQUEST)
|
||||
) {
|
||||
AlfredManager.failureEventDao.deleteFailureEvents(failureEvents.map { it.eventId })
|
||||
AlfredManager.failureEventDao.deleteFailureEvents(
|
||||
failureEvents.map { it.eventId }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -299,83 +330,86 @@ internal fun sendAlfredSessionEvent(
|
||||
request =
|
||||
SessionRequest(
|
||||
base_attribute =
|
||||
BaseAttribute(
|
||||
sessionId = sessionId,
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = clientTs,
|
||||
sessionTimeStamp = sessionTimeStamp,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
),
|
||||
BaseAttribute(
|
||||
sessionId = sessionId,
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = clientTs,
|
||||
sessionTimeStamp = sessionTimeStamp,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
),
|
||||
session_upload_event_attributes =
|
||||
SessionEventAttribute(
|
||||
eventId = currentZipName,
|
||||
beginningDeviceAttributes = DeviceAttributes(),
|
||||
endDeviceAttributes = DeviceAttributes()
|
||||
)
|
||||
SessionEventAttribute(
|
||||
eventId = currentZipName,
|
||||
beginningDeviceAttributes = DeviceAttributes(),
|
||||
endDeviceAttributes = DeviceAttributes()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
request =
|
||||
SessionRequest(
|
||||
base_attribute =
|
||||
BaseAttribute(
|
||||
sessionId = AlfredManager.config.getAlfredSessionId(),
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = AlfredManager.config.getEventStartRecordingTime(),
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp,
|
||||
sessionTimeStamp = AlfredManager.config.getSessionStartRecordingTime()
|
||||
),
|
||||
session_upload_event_attributes =
|
||||
SessionEventAttribute(
|
||||
eventId = currentZipName,
|
||||
beginningDeviceAttributes =
|
||||
DeviceAttributes(
|
||||
battery = AlfredManager.config.batteryPercentageBeforeEventStart,
|
||||
cpu = AlfredManager.config.cpuUsageBeforeEventStart,
|
||||
memory = AlfredManager.config.memoryUsageBeforeEventStart,
|
||||
storage = AlfredManager.config.storageUsageBeforeEventStart
|
||||
BaseAttribute(
|
||||
sessionId = AlfredManager.config.getAlfredSessionId(),
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = AlfredManager.config.getEventStartRecordingTime(),
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp,
|
||||
sessionTimeStamp = AlfredManager.config.getSessionStartRecordingTime()
|
||||
),
|
||||
endDeviceAttributes =
|
||||
DeviceAttributes(
|
||||
battery = AlfredManager.config.getBatteryPercentage(),
|
||||
cpu = AlfredManager.config.getCpuUsage(),
|
||||
memory = AlfredManager.config.getMemoryUsagePercentage(),
|
||||
storage = AlfredManager.config.getStorageUsage()
|
||||
session_upload_event_attributes =
|
||||
SessionEventAttribute(
|
||||
eventId = currentZipName,
|
||||
beginningDeviceAttributes =
|
||||
DeviceAttributes(
|
||||
battery = AlfredManager.config.batteryPercentageBeforeEventStart,
|
||||
cpu = AlfredManager.config.cpuUsageBeforeEventStart,
|
||||
memory = AlfredManager.config.memoryUsageBeforeEventStart,
|
||||
storage = AlfredManager.config.storageUsageBeforeEventStart
|
||||
),
|
||||
endDeviceAttributes =
|
||||
DeviceAttributes(
|
||||
battery = AlfredManager.config.getBatteryPercentage(),
|
||||
cpu = AlfredManager.config.getCpuUsage(),
|
||||
memory = AlfredManager.config.getMemoryUsagePercentage(),
|
||||
storage = AlfredManager.config.getStorageUsage()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
AlfredManager.coroutineScope.launch {
|
||||
val response = AlfredManager.networkRepository.sendSession(
|
||||
DEFAULT_SEND_SESSION_POST_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
val response =
|
||||
AlfredManager.networkRepository.sendSession(
|
||||
DEFAULT_SEND_SESSION_POST_URL,
|
||||
AlfredManager.config.getApiKey(),
|
||||
request
|
||||
)
|
||||
if (response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) {
|
||||
if (!dumpFlow) {
|
||||
AlfredManager.config.setEventStartRecordingTime(true)
|
||||
handleDeviceAttributes()
|
||||
} else {
|
||||
index?.let { index -> AlfredManager.zipDetailsDao.deleteZipFileDetail(AlfredManager.zipFileDetails[index].id) }
|
||||
index?.let { index ->
|
||||
AlfredManager.zipDetailsDao.deleteZipFileDetail(
|
||||
AlfredManager.zipFileDetails[index].id
|
||||
)
|
||||
}
|
||||
if (AlfredManager.workFailureData.size > 0) {
|
||||
AlfredManager.workFailureData.removeAt(0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_SESSION_POST_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = request.session_upload_event_attributes.eventId?.let { listOf(it) },
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_SESSION_FAILURE,
|
||||
clientTs = request.base_attribute.clientTs
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
context = AlfredManager.applicationContext
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_SEND_SESSION_POST_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = request.session_upload_event_attributes.eventId?.let { listOf(it) },
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_SESSION_FAILURE,
|
||||
clientTs = request.base_attribute.clientTs
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(failureEvent, context = AlfredManager.applicationContext)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -387,19 +421,23 @@ internal suspend fun sendIngestMetric(
|
||||
snapshotPerSecond: Int? = null,
|
||||
workManagerFlow: Boolean? = false
|
||||
): Boolean {
|
||||
if ((workManagerFlow == true) || (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus())) {
|
||||
if (
|
||||
(workManagerFlow == true) ||
|
||||
(AlfredManager.config.getAlfredStatus() &&
|
||||
AlfredManager.config.getEnableRecordingStatus())
|
||||
) {
|
||||
try {
|
||||
var baseAttributes = BaseAttribute()
|
||||
if (workManagerFlow == true) {
|
||||
baseAttributes = BaseAttribute(
|
||||
clientTs = clientTs,
|
||||
snapshotPerSecond = snapshotPerSecond
|
||||
)
|
||||
baseAttributes =
|
||||
BaseAttribute(clientTs = clientTs, snapshotPerSecond = snapshotPerSecond)
|
||||
AlfredManager.apiMetricDao = AlfredManager.alfredDataBase.apiMetricDao()
|
||||
}
|
||||
AlfredManager.mutex.withLock {
|
||||
val metricEventList =
|
||||
AlfredManager.apiMetricDao.fetchApiMetric(AlfredManager.config.getEventBatchSize())
|
||||
AlfredManager.apiMetricDao.fetchApiMetric(
|
||||
AlfredManager.config.getEventBatchSize()
|
||||
)
|
||||
if (metricEventList.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = metricEventList.map { it.metric }
|
||||
@@ -420,19 +458,23 @@ internal suspend fun sendIngestMetric(
|
||||
metricRequestBody = request
|
||||
)
|
||||
return if (
|
||||
response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
response.isSuccessful &&
|
||||
response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
) {
|
||||
AlfredManager.apiMetricDao.deleteApiMetric(metricEventList.map { it.id })
|
||||
AlfredManager.apiMetricDao.deleteApiMetric(
|
||||
metricEventList.map { it.id }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_INGEST_METRIC_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_METRIC_FAILURE
|
||||
)
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_INGEST_METRIC_URL,
|
||||
requestMethod = POST_METHOD,
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = INGEST_METRIC_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
@@ -440,7 +482,9 @@ internal suspend fun sendIngestMetric(
|
||||
)
|
||||
)
|
||||
if (response.code() == AlfredConstants.CODE_API_BAD_REQUEST) {
|
||||
AlfredManager.apiMetricDao.deleteApiMetric(metricEventList.map { it.id })
|
||||
AlfredManager.apiMetricDao.deleteApiMetric(
|
||||
metricEventList.map { it.id }
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2021-2023 by Navi Technologies Limited
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
|
||||
fun Boolean?.orFalse() = this ?: false
|
||||
|
||||
fun Int?.orZero() = this ?: 0
|
||||
|
||||
@@ -10,7 +10,11 @@ package com.navi.alfred.utils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
internal fun findViewWithTagRecursive(view: View, tag: String, maskedViews: MutableList<View>): List<View> {
|
||||
internal fun findViewWithTagRecursive(
|
||||
view: View,
|
||||
tag: String,
|
||||
maskedViews: MutableList<View>
|
||||
): List<View> {
|
||||
if (view.tag == tag) {
|
||||
maskedViews.add(view)
|
||||
}
|
||||
@@ -22,4 +26,4 @@ internal fun findViewWithTagRecursive(view: View, tag: String, maskedViews: Muta
|
||||
}
|
||||
}
|
||||
return maskedViews
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,4 +42,4 @@ internal fun isNetworkAvailable(context: Context): Boolean {
|
||||
val connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
||||
return connectivityManager?.activeNetworkInfo?.isConnected.orFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package com.navi.alfred.utils
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
@@ -8,13 +14,13 @@ import com.navi.alfred.AlfredManager
|
||||
internal fun isScreenDisabled(screenName: String? = null, moduleName: String? = null): Boolean {
|
||||
if (
|
||||
moduleName != null &&
|
||||
AlfredManager.config.getDisableModuleList()?.contains(moduleName) == true
|
||||
AlfredManager.config.getDisableModuleList()?.contains(moduleName) == true
|
||||
) {
|
||||
return true
|
||||
} else {
|
||||
if (
|
||||
screenName != null &&
|
||||
AlfredManager.config.getDisableScreenList()?.contains(screenName) == true
|
||||
AlfredManager.config.getDisableScreenList()?.contains(screenName) == true
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import android.content.Context
|
||||
@@ -12,18 +19,18 @@ import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.db.AlfredDatabaseHelper
|
||||
import com.navi.alfred.db.model.ScreenShotPathHelper
|
||||
import com.navi.alfred.model.MaskingBounds
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
internal suspend fun handleScreenShot() {
|
||||
if (
|
||||
ScreenShotStorageHelper.images.size == AlfredManager.imageThreshHoldValue ||
|
||||
ScreenShotStorageHelper.images.size == AlfredManager.imageSecondThreshHoldValue
|
||||
ScreenShotStorageHelper.images.size == AlfredManager.imageSecondThreshHoldValue
|
||||
) {
|
||||
toZip(AlfredManager.screenShotDao.fetchScreenShotsPath(AlfredManager.imageThreshHoldValue))
|
||||
} else {
|
||||
@@ -43,8 +50,8 @@ internal fun combineScreenshots(
|
||||
): Bitmap? {
|
||||
if (
|
||||
backgroundScreenshot == null ||
|
||||
bottomSheetScreenshot == null ||
|
||||
isScreenDisabled(screenName, moduleName)
|
||||
bottomSheetScreenshot == null ||
|
||||
isScreenDisabled(screenName, moduleName)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
@@ -79,8 +86,7 @@ internal fun insertScreenShotPathInDb(
|
||||
val fileDir = context.filesDir
|
||||
val currentTime = System.currentTimeMillis()
|
||||
AlfredManager.config.setLatestScreenshotTimestamp(currentTime)
|
||||
val fileName =
|
||||
currentTime.toString() + AlfredConstants.IMAGE_FILE_EXTENSION
|
||||
val fileName = currentTime.toString() + AlfredConstants.IMAGE_FILE_EXTENSION
|
||||
val path = fileDir.path.plus("/").plus(fileName)
|
||||
val imageUrl = File(path)
|
||||
val fos = FileOutputStream(imageUrl)
|
||||
@@ -89,15 +95,12 @@ internal fun insertScreenShotPathInDb(
|
||||
VideoQuality.HIGH.name -> {
|
||||
10
|
||||
}
|
||||
|
||||
VideoQuality.LOW.name -> {
|
||||
6
|
||||
}
|
||||
|
||||
VideoQuality.MEDIUM.name -> {
|
||||
8
|
||||
}
|
||||
|
||||
else -> {
|
||||
10
|
||||
}
|
||||
@@ -139,7 +142,10 @@ internal fun captureScreenshotOfCustomView(view: View): Bitmap? {
|
||||
internal fun deleteScreenShot() {
|
||||
try {
|
||||
val screenShotPathList: List<ScreenShotPathHelper> =
|
||||
if (AlfredManager.screenShotDao.getScreenShotCount() >= AlfredManager.imageThreshHoldValue) {
|
||||
if (
|
||||
AlfredManager.screenShotDao.getScreenShotCount() >=
|
||||
AlfredManager.imageThreshHoldValue
|
||||
) {
|
||||
AlfredManager.screenShotDao.fetchScreenShotsPath(AlfredManager.imageThreshHoldValue)
|
||||
} else {
|
||||
AlfredManager.screenShotDao.fetchAllScreenShotsPath()
|
||||
@@ -179,7 +185,6 @@ enum class VideoQuality {
|
||||
MEDIUM
|
||||
}
|
||||
|
||||
|
||||
internal suspend fun captureScreen(
|
||||
v: View,
|
||||
context: Context,
|
||||
@@ -195,31 +200,38 @@ internal suspend fun captureScreen(
|
||||
}
|
||||
if (canvas != null && bmp != null) {
|
||||
val currentScreen = AlfredManager.currentScreen
|
||||
val sensitiveCoordinates = AlfredManager.sensitiveComposeRepository.getAllSensitiveComposableCoordinates()
|
||||
val sensitiveCoordinates =
|
||||
AlfredManager.sensitiveComposeRepository.getAllSensitiveComposableCoordinates()
|
||||
val rootView = AlfredManager.sensitiveComposeRepository.getRootViewOfComposeScreen()
|
||||
if (isMaskingEnabled(screenName) || (v.tag == AlfredConstants.SENSITIVE_VIEW_TAG) || (v.tag == AlfredConstants.SENSITIVE_COMPOSE_VIEW_TAG)) {
|
||||
if (
|
||||
isMaskingEnabled(screenName) ||
|
||||
(v.tag == AlfredConstants.SENSITIVE_VIEW_TAG) ||
|
||||
(v.tag == AlfredConstants.SENSITIVE_COMPOSE_VIEW_TAG)
|
||||
) {
|
||||
try {
|
||||
if (currentScreen.isComposeScreen == true) {
|
||||
if (AlfredManager.sensitiveComposeRepository.getBlurSensitiveScreenStatus()) {
|
||||
withContext(Dispatchers.Main) {
|
||||
blurScreen(canvas, v)
|
||||
}
|
||||
withContext(Dispatchers.Main) { blurScreen(canvas, v) }
|
||||
} else {
|
||||
if (rootView != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
captureComposeViewWithMasking(canvas, sensitiveCoordinates, rootView)
|
||||
captureComposeViewWithMasking(
|
||||
canvas,
|
||||
sensitiveCoordinates,
|
||||
rootView
|
||||
)
|
||||
}
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
v.draw(canvas)
|
||||
}
|
||||
withContext(Dispatchers.Main) { v.draw(canvas) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val maskedViewsList = findViewWithTagRecursive(
|
||||
v,
|
||||
AlfredConstants.SENSITIVE_VIEW_TAG, mutableListOf()
|
||||
)
|
||||
val maskedViewsList =
|
||||
findViewWithTagRecursive(
|
||||
v,
|
||||
AlfredConstants.SENSITIVE_VIEW_TAG,
|
||||
mutableListOf()
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
try {
|
||||
if (maskedViewsList.isEmpty()) {
|
||||
@@ -322,17 +334,19 @@ internal fun captureComposeViewWithMasking(
|
||||
paint.color = Color.BLACK
|
||||
|
||||
sensitiveCoordinates.forEach { bounds ->
|
||||
if (bounds.bottom > 0 && bounds.top < rootView.height && bounds.height > 0 && bounds.width > 0) {
|
||||
if (
|
||||
bounds.bottom > 0 &&
|
||||
bounds.top < rootView.height &&
|
||||
bounds.height > 0 &&
|
||||
bounds.width > 0
|
||||
) {
|
||||
canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, paint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun blurScreen(
|
||||
canvas: Canvas,
|
||||
rootView: View
|
||||
) {
|
||||
internal fun blurScreen(canvas: Canvas, rootView: View) {
|
||||
rootView.draw(canvas)
|
||||
val paint = Paint()
|
||||
paint.color = Color.GRAY
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import androidx.work.Constraints
|
||||
@@ -19,11 +26,10 @@ import com.navi.alfred.utils.AlfredConstants.ZIP_ERROR
|
||||
import com.navi.alfred.worker.AddFailureTask
|
||||
import com.navi.alfred.worker.UploadEventsWorker
|
||||
import com.navi.alfred.worker.UploadFileWorker
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
|
||||
internal suspend fun getPreSignedUrl(
|
||||
zipFileName: String,
|
||||
@@ -37,7 +43,9 @@ internal suspend fun getPreSignedUrl(
|
||||
val latestScreenshotName: Long
|
||||
|
||||
if (dumpFlow) {
|
||||
currentZipName = alfredEventIdForDumpFlow ?: UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
currentZipName =
|
||||
alfredEventIdForDumpFlow
|
||||
?: UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
latestScreenshotName = latestScreenshotTimestamp ?: 0L
|
||||
} else {
|
||||
currentZipName = AlfredManager.config.getAlfredEventId()
|
||||
@@ -63,20 +71,18 @@ internal suspend fun getPreSignedUrl(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_GET_PRE_SIGNED_URL_URL.plus(bucketKey),
|
||||
requestMethod = GET_METHOD,
|
||||
zipName = listOf(currentZipName),
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = GET_PRE_SIGNED_URL_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
context = AlfredManager.applicationContext
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = API_ERROR,
|
||||
requestUrl = DEFAULT_GET_PRE_SIGNED_URL_URL.plus(bucketKey),
|
||||
requestMethod = GET_METHOD,
|
||||
zipName = listOf(currentZipName),
|
||||
errorStatusCode = response.code().toLong(),
|
||||
errorMessage = response.message(),
|
||||
errorName = GET_PRE_SIGNED_URL_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(failureEvent, context = AlfredManager.applicationContext)
|
||||
)
|
||||
|
||||
if (!dumpFlow) {
|
||||
@@ -209,20 +215,18 @@ internal suspend fun uploadFile(
|
||||
uploadFile.delete()
|
||||
sendAlfredSessionEvent(dumpFlow, index, currentZipName, latestScreenshotTimestamp)
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = ZIP_ERROR,
|
||||
requestUrl = url,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = listOf(currentZipName ?: ""),
|
||||
errorStatusCode = uploadResponse.code().toLong(),
|
||||
errorMessage = uploadResponse.message(),
|
||||
errorName = UPLOAD_TO_S3_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(
|
||||
failureEvent,
|
||||
context = AlfredManager.applicationContext
|
||||
val failureEvent =
|
||||
buildFailureEvent(
|
||||
errorType = ZIP_ERROR,
|
||||
requestUrl = url,
|
||||
requestMethod = POST_METHOD,
|
||||
zipName = listOf(currentZipName ?: ""),
|
||||
errorStatusCode = uploadResponse.code().toLong(),
|
||||
errorMessage = uploadResponse.message(),
|
||||
errorName = UPLOAD_TO_S3_FAILURE
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
AddFailureTask(failureEvent, context = AlfredManager.applicationContext)
|
||||
)
|
||||
|
||||
if (!dumpFlow) {
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.view.MotionEvent
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.model.NaviMotionEvent
|
||||
import java.lang.Float.min
|
||||
import java.lang.Math.subtractExact
|
||||
@@ -27,19 +25,35 @@ internal fun getTouchEvent(
|
||||
val screenHeight = Resources.getSystem().displayMetrics.heightPixels
|
||||
val eventName =
|
||||
if (
|
||||
(difference(currentTouchEvent?.getX(pointerIndex), previousTouchEvent?.pointerPositionX) &&
|
||||
difference(currentTouchEvent?.getY(pointerIndex), previousTouchEvent?.pointerPositionY)) ||
|
||||
(difference(currentTouchEvent?.rawX, previousTouchEvent?.rawX) &&
|
||||
difference(currentTouchEvent?.rawY, previousTouchEvent?.rawY))
|
||||
(difference(
|
||||
currentTouchEvent?.getX(pointerIndex),
|
||||
previousTouchEvent?.pointerPositionX
|
||||
) &&
|
||||
difference(
|
||||
currentTouchEvent?.getY(pointerIndex),
|
||||
previousTouchEvent?.pointerPositionY
|
||||
)) ||
|
||||
(difference(currentTouchEvent?.rawX, previousTouchEvent?.rawX) &&
|
||||
difference(currentTouchEvent?.rawY, previousTouchEvent?.rawY))
|
||||
) {
|
||||
properties[AlfredConstants.START_X] = min(previousTouchEvent?.rawX ?: 0f, screenWidth.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_Y] = min(previousTouchEvent?.rawY ?: 0f, screenHeight.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_X] =
|
||||
min(previousTouchEvent?.rawX ?: 0f, screenWidth.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_Y] =
|
||||
min(previousTouchEvent?.rawY ?: 0f, screenHeight.toFloat()).times(0.5f).toString()
|
||||
AlfredConstants.TOUCH_EVENT
|
||||
} else {
|
||||
properties[AlfredConstants.START_X] = min(previousTouchEvent?.rawX ?: 0f, screenWidth.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_Y] = min(previousTouchEvent?.rawY ?: 0f, screenHeight.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.END_X] = min(currentTouchEvent?.getRawX() ?: 0f, screenWidth.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.END_Y] = min(currentTouchEvent?.getRawY() ?: 0f, screenHeight.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_X] =
|
||||
min(previousTouchEvent?.rawX ?: 0f, screenWidth.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.START_Y] =
|
||||
min(previousTouchEvent?.rawY ?: 0f, screenHeight.toFloat()).times(0.5f).toString()
|
||||
properties[AlfredConstants.END_X] =
|
||||
min(currentTouchEvent?.getRawX() ?: 0f, screenWidth.toFloat())
|
||||
.times(0.5f)
|
||||
.toString()
|
||||
properties[AlfredConstants.END_Y] =
|
||||
min(currentTouchEvent?.getRawY() ?: 0f, screenHeight.toFloat())
|
||||
.times(0.5f)
|
||||
.toString()
|
||||
AlfredConstants.SCROLL_EVENT
|
||||
}
|
||||
return Pair(eventName, properties)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import android.content.Context
|
||||
@@ -9,9 +16,6 @@ import com.google.gson.Gson
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.db.model.ScreenShotPathHelper
|
||||
import com.navi.alfred.db.model.ZipDetailsHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
@@ -20,6 +24,9 @@ import java.io.FileOutputStream
|
||||
import java.util.UUID
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal fun toZip(imagePathList: List<ScreenShotPathHelper>) {
|
||||
val zipFileName = AlfredManager.config.getAlfredSessionId() + UUID.randomUUID().toString()
|
||||
@@ -56,7 +63,7 @@ internal fun zip(_files: java.util.ArrayList<String>, zipFilePath: String?): Boo
|
||||
try {
|
||||
val imageFile = File(_files[i])
|
||||
val imageFileName = imageFile.name
|
||||
if(checkFileExists(imageFileName, AlfredManager.applicationContext) != null) {
|
||||
if (checkFileExists(imageFileName, AlfredManager.applicationContext) != null) {
|
||||
val fi = FileInputStream(_files[i])
|
||||
origin = BufferedInputStream(fi, buffer)
|
||||
val entry = ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1))
|
||||
@@ -166,14 +173,14 @@ internal fun insertZipDetailsToDbForDumpingLater(
|
||||
) {
|
||||
AlfredManager.zipDetailsDao.insert(
|
||||
data =
|
||||
ZipDetailsHelper(
|
||||
alfredSessionId = alfredSessionId,
|
||||
sessionStartRecordingTime = sessionStartRecordingTime,
|
||||
eventStartRecordingTime = eventStartRecordingTime,
|
||||
zipFileName = zipFileName,
|
||||
alfredEventId = alfredEventId,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
)
|
||||
ZipDetailsHelper(
|
||||
alfredSessionId = alfredSessionId,
|
||||
sessionStartRecordingTime = sessionStartRecordingTime,
|
||||
eventStartRecordingTime = eventStartRecordingTime,
|
||||
zipFileName = zipFileName,
|
||||
alfredEventId = alfredEventId,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -192,7 +199,10 @@ internal fun startAnrCrashZipUpload(view: View) {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun uploadWorkManagerFailedZip(alfredEventId: String? = null, latestScreenshotTimestamp: Long? = null) {
|
||||
internal fun uploadWorkManagerFailedZip(
|
||||
alfredEventId: String? = null,
|
||||
latestScreenshotTimestamp: Long? = null
|
||||
) {
|
||||
if (AlfredManager.workFailureData.size > 0) {
|
||||
val inputData = AlfredManager.workFailureData[0]
|
||||
if (AlfredManager.zipUploadRetryCount < 3) {
|
||||
@@ -240,4 +250,3 @@ internal fun checkFileExists(fileName: String, context: Context): File? {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2021-2023 by Navi Technologies Limited
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2021-2023 by Navi Technologies Limited
|
||||
* * Copyright © 2023 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -15,9 +15,7 @@ import kotlinx.coroutines.runBlocking
|
||||
class SyncFailureTask() : AnalyticsTask {
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
return runBlocking {
|
||||
sendFailureEventsToServer()
|
||||
}
|
||||
return runBlocking { sendFailureEventsToServer() }
|
||||
}
|
||||
|
||||
override fun getTaskName(): String {
|
||||
|
||||
@@ -15,9 +15,7 @@ import kotlinx.coroutines.runBlocking
|
||||
class SyncNegativeCaseTask() : AnalyticsTask {
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
return runBlocking {
|
||||
sendNegativeCaseToServer()
|
||||
}
|
||||
return runBlocking { sendNegativeCaseToServer() }
|
||||
}
|
||||
|
||||
override fun getTaskName(): String {
|
||||
|
||||
@@ -32,7 +32,8 @@ class UploadEventsWorker(context: Context, workerParams: WorkerParameters) :
|
||||
if (clientTs == 0L) {
|
||||
Result.failure()
|
||||
} else {
|
||||
AlfredManager.alfredDataBase = AlfredDatabaseHelper.getAnalyticsDatabase(AlfredManager.applicationContext)
|
||||
AlfredManager.alfredDataBase =
|
||||
AlfredDatabaseHelper.getAnalyticsDatabase(AlfredManager.applicationContext)
|
||||
sendEventsToServer(
|
||||
clientTs = clientTs,
|
||||
snapshotPerSecond = snapshotPerSecond,
|
||||
@@ -48,9 +49,7 @@ class UploadEventsWorker(context: Context, workerParams: WorkerParameters) :
|
||||
snapshotPerSecond = snapshotPerSecond,
|
||||
workManagerFlow = true
|
||||
)
|
||||
sendFailureEventsToServer(
|
||||
workManagerFlow = true
|
||||
)
|
||||
sendFailureEventsToServer(workManagerFlow = true)
|
||||
Result.success()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -17,10 +17,10 @@ import com.navi.alfred.db.model.ScreenShotPathHelper
|
||||
import com.navi.alfred.model.WorkManagerFailureInputData
|
||||
import com.navi.alfred.utils.AlfredConstants
|
||||
import com.navi.alfred.utils.toZipForWorkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.lang.reflect.Type
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
|
||||
CoroutineWorker(context, workerParams) {
|
||||
@@ -38,11 +38,11 @@ class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
|
||||
Gson().fromJson(screenShotList.toString(), listType)
|
||||
val zipFileName =
|
||||
alfredSessionId +
|
||||
sessionStartRecordingTime +
|
||||
AlfredConstants.WORKER_ZIP_FILENAME_ENDPOINT
|
||||
sessionStartRecordingTime +
|
||||
AlfredConstants.WORKER_ZIP_FILENAME_ENDPOINT
|
||||
val alfredEventId =
|
||||
inputData.getString(AlfredConstants.ALFRED_EVENT_ID) ?: UUID.randomUUID().toString()
|
||||
.plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
inputData.getString(AlfredConstants.ALFRED_EVENT_ID)
|
||||
?: UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
val latestScreenshotTimestamp =
|
||||
inputData.getLong(AlfredConstants.LATEST_SCREENSHOT_TIMESTAMP, 0L)
|
||||
workFailureData.add(
|
||||
@@ -60,8 +60,8 @@ class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
|
||||
try {
|
||||
if (
|
||||
alfredSessionId == null ||
|
||||
sessionStartRecordingTime == 0L ||
|
||||
eventStartRecordingTime == 0L
|
||||
sessionStartRecordingTime == 0L ||
|
||||
eventStartRecordingTime == 0L
|
||||
) {
|
||||
Result.failure()
|
||||
} else {
|
||||
|
||||
124
projectDependencyGraph.gradle
Normal file
124
projectDependencyGraph.gradle
Normal file
@@ -0,0 +1,124 @@
|
||||
tasks.register('projectDependencyGraph') {
|
||||
doLast {
|
||||
def dot = new File(rootProject.buildDir, 'reports/dependency-graph/project.dot')
|
||||
dot.parentFile.mkdirs()
|
||||
dot.delete()
|
||||
|
||||
dot << 'digraph {\n'
|
||||
dot << " graph [label=\"${rootProject.name}\\n \",labelloc=t,fontsize=30,ranksep=1.4];\n"
|
||||
dot << ' node [style=filled, fillcolor="#bbbbbb"];\n'
|
||||
dot << ' rankdir=TB;\n'
|
||||
|
||||
def rootProjects = []
|
||||
def queue = [rootProject]
|
||||
while (!queue.isEmpty()) {
|
||||
def project = queue.remove(0)
|
||||
rootProjects.add(project)
|
||||
queue.addAll(project.childProjects.values())
|
||||
}
|
||||
|
||||
def projects = new LinkedHashSet<Project>()
|
||||
def dependencies = new LinkedHashMap<Tuple2<Project, Project>, List<String>>()
|
||||
def multiplatformProjects = []
|
||||
def jsProjects = []
|
||||
def androidProjects = []
|
||||
def dynamicProjects = []
|
||||
def javaProjects = []
|
||||
|
||||
queue = [rootProject]
|
||||
while (!queue.isEmpty()) {
|
||||
def project = queue.remove(0)
|
||||
queue.addAll(project.childProjects.values())
|
||||
|
||||
if (project.plugins.hasPlugin('org.jetbrains.kotlin.multiplatform')) {
|
||||
multiplatformProjects.add(project)
|
||||
}
|
||||
if (project.plugins.hasPlugin('org.jetbrains.kotlin.js')) {
|
||||
jsProjects.add(project)
|
||||
}
|
||||
if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
|
||||
androidProjects.add(project)
|
||||
}
|
||||
if (project.plugins.hasPlugin('com.android.dynamic-feature')) {
|
||||
dynamicProjects.add(project)
|
||||
}
|
||||
if (project.plugins.hasPlugin('java-library') || project.plugins.hasPlugin('java')) {
|
||||
javaProjects.add(project)
|
||||
}
|
||||
|
||||
project.configurations.configureEach { config ->
|
||||
config.dependencies
|
||||
.withType(ProjectDependency)
|
||||
.collect { it.dependencyProject }
|
||||
.each { dependency ->
|
||||
projects.add(project)
|
||||
projects.add(dependency)
|
||||
rootProjects.remove(dependency)
|
||||
|
||||
def graphKey = new Tuple2<Project, Project>(project, dependency)
|
||||
def traits = dependencies.computeIfAbsent(graphKey) { new ArrayList<String>() }
|
||||
|
||||
if (config.name.toLowerCase().endsWith('implementation') && !traits.contains('style=dotted')) {
|
||||
traits.add('style=dotted')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projects = projects.sort { it.path }
|
||||
|
||||
dot << '\n # Projects\n\n'
|
||||
for (project in projects) {
|
||||
def traits = []
|
||||
|
||||
if (rootProjects.contains(project)) {
|
||||
traits.add('shape=box')
|
||||
}
|
||||
|
||||
if (multiplatformProjects.contains(project)) {
|
||||
traits.add('fillcolor="#ffd2b3"')
|
||||
} else if (jsProjects.contains(project)) {
|
||||
traits.add('fillcolor="#ffffba"')
|
||||
} else if (androidProjects.contains(project)) {
|
||||
traits.add('fillcolor="#baffc9"')
|
||||
} else if (dynamicProjects.contains(project)) {
|
||||
traits.add('fillcolor="#bad4ff"')
|
||||
} else if (javaProjects.contains(project)) {
|
||||
traits.add('fillcolor="#ffb3ba"')
|
||||
} else {
|
||||
traits.add('fillcolor="#eeeeee"')
|
||||
}
|
||||
|
||||
dot << " \"${project.path}\" [${traits.join(", ")}];\n"
|
||||
}
|
||||
|
||||
dot << '\n {rank = same;'
|
||||
for (project in projects) {
|
||||
if (rootProjects.contains(project)) {
|
||||
dot << " \"${project.path}\";"
|
||||
}
|
||||
}
|
||||
dot << '}\n'
|
||||
|
||||
dot << '\n # Dependencies\n\n'
|
||||
dependencies.forEach { key, traits ->
|
||||
if (key.v1.path != key.v2.path) {
|
||||
dot << " \"${key.v1.path}\" -> \"${key.v2.path}\""
|
||||
if (!traits.isEmpty()) {
|
||||
dot << " [${traits.join(", ")}]"
|
||||
}
|
||||
dot << '\n'
|
||||
}
|
||||
}
|
||||
|
||||
dot << '}\n'
|
||||
|
||||
def p = 'dot -Tpng -O project.dot'.execute([], dot.parentFile)
|
||||
p.waitFor()
|
||||
if (p.exitValue() != 0) {
|
||||
throw new RuntimeException(p.errorStream.text)
|
||||
}
|
||||
|
||||
println("Project module dependency graph created at ${dot.absolutePath}.png")
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@ pluginManagement {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "alfred"
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
@@ -12,6 +15,6 @@ dependencyResolutionManagement {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = "Alfred Android"
|
||||
|
||||
include ':app'
|
||||
include ':navi-alfred'
|
||||
|
||||
32
spotless.gradle
Normal file
32
spotless.gradle
Normal file
@@ -0,0 +1,32 @@
|
||||
spotless {
|
||||
ratchetFrom 'origin/master'
|
||||
|
||||
format 'misc', {
|
||||
target '**/*.gradle', '**/*.md', '**/.gitignore'
|
||||
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces()
|
||||
endWithNewline()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
target '**/*.kt'
|
||||
|
||||
licenseHeaderFile rootProject.file('spotless.license')
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces()
|
||||
endWithNewline()
|
||||
ktfmt().kotlinlangStyle()
|
||||
}
|
||||
|
||||
java {
|
||||
target '**/*.java'
|
||||
|
||||
licenseHeaderFile rootProject.file('spotless.license')
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces()
|
||||
endWithNewline()
|
||||
removeUnusedImports()
|
||||
googleJavaFormat().aosp()
|
||||
}
|
||||
}
|
||||
7
spotless.license
Normal file
7
spotless.license
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © $YEAR by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user