Release 1.0.9 (#57)
Co-authored-by: Sayed Owais Ali <sayed.owais@navi.com>
This commit is contained in:
@@ -6,7 +6,7 @@ plugins {
|
||||
id 'kotlin-parcelize'
|
||||
}
|
||||
|
||||
def VERSION_NAME = "1.0.8"
|
||||
def VERSION_NAME = "1.0.9"
|
||||
|
||||
android {
|
||||
namespace 'com.navi.alfred'
|
||||
|
||||
@@ -57,6 +57,7 @@ data class AlfredConfig(
|
||||
private var codePushVersion: String? = null,
|
||||
private var apiKey: String = "",
|
||||
private var userId: String? = null,
|
||||
private var latestScreenshotTimestamp: Long = 0L,
|
||||
internal var cpuUsageBeforeEventStart: Float? = null,
|
||||
internal var memoryUsageBeforeEventStart: Float? = null,
|
||||
internal var storageUsageBeforeEventStart: Float? = null,
|
||||
@@ -329,4 +330,10 @@ data class AlfredConfig(
|
||||
}
|
||||
|
||||
fun getAppName(): String = this.appName
|
||||
|
||||
fun getLatestScreenshotTimestamp(): Long = this.latestScreenshotTimestamp
|
||||
|
||||
fun setLatestScreenshotTimestamp(timestamp: Long) {
|
||||
this.latestScreenshotTimestamp = timestamp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent.ACTION_DOWN
|
||||
import android.view.KeyEvent.ACTION_UP
|
||||
import android.view.LayoutInflater
|
||||
@@ -21,17 +20,22 @@ import android.view.View
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import com.navi.alfred.db.AlfredDatabase
|
||||
import com.navi.alfred.db.AlfredDatabaseHelper
|
||||
import com.navi.alfred.db.dao.AnalyticsDAO
|
||||
import com.navi.alfred.db.dao.ApiMetricDao
|
||||
import com.navi.alfred.db.dao.FailureEventDao
|
||||
import com.navi.alfred.db.dao.NegativeCaseDao
|
||||
import com.navi.alfred.db.dao.ScreenShotDao
|
||||
import com.navi.alfred.db.dao.ZipDetailsDao
|
||||
import com.navi.alfred.db.model.ZipDetailsHelper
|
||||
import com.navi.alfred.dispatcher.AlfredDispatcher
|
||||
import com.navi.alfred.model.CurrentScreen
|
||||
import com.navi.alfred.model.NaviMotionEvent
|
||||
import com.navi.alfred.model.WorkManagerFailureInputData
|
||||
import com.navi.alfred.network.AlfredFailureRetrofitProvider
|
||||
import com.navi.alfred.network.AlfredNetworkRepository
|
||||
import com.navi.alfred.network.AlfredRetrofitProvider
|
||||
import com.navi.alfred.network.model.CruiseResponse
|
||||
import com.navi.alfred.repository.ComposeMaskingRepoImpl
|
||||
import com.navi.alfred.utils.AlfredConstants
|
||||
import com.navi.alfred.utils.AlfredConstants.API_METRICS
|
||||
import com.navi.alfred.utils.AlfredConstants.CODE_API_SUCCESS
|
||||
@@ -50,6 +54,7 @@ import com.navi.alfred.utils.getTouchEvent
|
||||
import com.navi.alfred.utils.handleDeviceAttributes
|
||||
import com.navi.alfred.utils.handleScreenShot
|
||||
import com.navi.alfred.utils.insertScreenShotPathInDb
|
||||
import com.navi.alfred.utils.isScreenDisabled
|
||||
import com.navi.alfred.utils.log
|
||||
import com.navi.alfred.utils.measureInflatedView
|
||||
import com.navi.alfred.utils.startAnrCrashZipUpload
|
||||
@@ -84,7 +89,7 @@ object AlfredManager {
|
||||
internal var hasUploadFlowStarted: Boolean = false
|
||||
internal var isAppInBackground: Boolean = false
|
||||
internal var hasRecordingStarted: Boolean = false
|
||||
internal var currentScreenName: String? = null
|
||||
internal var currentScreen: CurrentScreen = CurrentScreen()
|
||||
internal var currentModuleName: String? = null
|
||||
internal var sessionIdForCrash: String? = null
|
||||
internal var sessionStartRecordingTimeForCrash: Long? = null
|
||||
@@ -96,11 +101,15 @@ object AlfredManager {
|
||||
internal lateinit var screenShotDao: ScreenShotDao
|
||||
internal lateinit var zipDetailsDao: ZipDetailsDao
|
||||
internal lateinit var apiMetricDao: ApiMetricDao
|
||||
internal lateinit var analyticsDao: AnalyticsDAO
|
||||
internal lateinit var negativeCaseDao: NegativeCaseDao
|
||||
internal lateinit var failureEventDao: FailureEventDao
|
||||
internal lateinit var zipFileDetails: List<ZipDetailsHelper>
|
||||
internal lateinit var applicationContext: Context
|
||||
internal const val imageThreshHoldValue: Int = 60
|
||||
internal const val imageSecondThreshHoldValue: Int = 100
|
||||
var dialog: Dialog? = null
|
||||
lateinit var sensitiveComposeRepository: ComposeMaskingRepoImpl
|
||||
|
||||
fun init(config: AlfredConfig, context: Context) {
|
||||
this.config = config
|
||||
@@ -153,21 +162,41 @@ object AlfredManager {
|
||||
override fun run() {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
if (moduleName == THIRD_PARTY_MODULE) {
|
||||
currentScreenName = AlfredConstants.THIRD_PARTY_SCREEN
|
||||
if (bmpForThirdPartySdkScreen == null) {
|
||||
val thirdPartyScreenView = LayoutInflater.from(applicationContext)
|
||||
.inflate(R.layout.third_party_screen, null)
|
||||
measureInflatedView(thirdPartyScreenView)
|
||||
thirdPartyScreenView.findViewById<AppCompatTextView>(R.id.tv_third_party_name).text =
|
||||
activity?.localClassName.toString()
|
||||
bmpForThirdPartySdkScreen =
|
||||
thirdPartyScreenView?.let { captureScreenshotOfCustomView(it) }
|
||||
currentScreen.name = activity?.localClassName.toString()
|
||||
if (isScreenDisabled(currentScreen.name, moduleName)) {
|
||||
if (bmpForThirdPartySdkScreen == null) {
|
||||
val thirdPartyScreenView =
|
||||
LayoutInflater.from(applicationContext)
|
||||
.inflate(R.layout.third_party_screen, null)
|
||||
measureInflatedView(thirdPartyScreenView)
|
||||
thirdPartyScreenView.findViewById<AppCompatTextView>(R.id.tv_third_party_name).text = currentScreen.name
|
||||
bmpForThirdPartySdkScreen =
|
||||
thirdPartyScreenView?.let { captureScreenshotOfCustomView(it) }
|
||||
}
|
||||
insertScreenShotPathInDb(
|
||||
this,
|
||||
applicationContext,
|
||||
bmpForThirdPartySdkScreen
|
||||
)
|
||||
} else {
|
||||
if (bmpForCanvas == null) {
|
||||
delay(viewLayoutDelay)
|
||||
bmpForCanvas = createBitmapForView(view)
|
||||
}
|
||||
try {
|
||||
captureScreen(
|
||||
view,
|
||||
context,
|
||||
screenName = currentScreen.name,
|
||||
scope = coroutineScope,
|
||||
canvas = bmpForCanvas?.first,
|
||||
bmp = bmpForCanvas?.second,
|
||||
moduleName = moduleName
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
insertScreenShotPathInDb(
|
||||
this,
|
||||
applicationContext,
|
||||
bmpForThirdPartySdkScreen
|
||||
)
|
||||
} else {
|
||||
if (bmpForCanvas == null) {
|
||||
delay(viewLayoutDelay)
|
||||
@@ -181,7 +210,7 @@ object AlfredManager {
|
||||
view,
|
||||
bottomSheetView,
|
||||
context,
|
||||
currentScreenName,
|
||||
currentScreen.name,
|
||||
bmpForCanvas?.first,
|
||||
rootBmp = bmpForCanvas?.second,
|
||||
moduleName = moduleName
|
||||
@@ -190,7 +219,7 @@ object AlfredManager {
|
||||
captureScreen(
|
||||
view,
|
||||
context,
|
||||
screenName = currentScreenName,
|
||||
screenName = currentScreen.name,
|
||||
scope = coroutineScope,
|
||||
canvas = bmpForCanvas?.first,
|
||||
bmp = bmpForCanvas?.second,
|
||||
@@ -220,7 +249,7 @@ object AlfredManager {
|
||||
measureInflatedView(appBackgroundView)
|
||||
val stopRecordingEvent = buildEvent(
|
||||
AlfredConstants.STOP_RECORDING_EVENT,
|
||||
screenName = currentScreenName,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddEventTask(stopRecordingEvent, applicationContext))
|
||||
@@ -234,13 +263,16 @@ object AlfredManager {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
getCruiseConfig(cruiseApiSuccessful = { response ->
|
||||
Log.d("Alfred", "getAlfredCruiseInfo cruiseApiSuccessfulresponse = $response")
|
||||
cruiseApiSuccessful(response)
|
||||
startSyncEvents(applicationContext)
|
||||
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()
|
||||
@@ -336,6 +368,29 @@ object AlfredManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun handleScreenTransitionEvent(
|
||||
screenName: String?,
|
||||
moduleName: String? = null
|
||||
) {
|
||||
if (isAlfredRecordingEnabled()) {
|
||||
if (config.getAlfredSessionId().isNotEmpty()) {
|
||||
coroutineDispatcher.executor.execute {
|
||||
try {
|
||||
val event =
|
||||
buildEvent(
|
||||
AlfredConstants.SCREEN_TRANSITION_EVENT,
|
||||
screenName = screenName,
|
||||
moduleName = moduleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddEventTask(event, applicationContext))
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun handleAnrEvent(anrEventProperties: Map<String, String>) {
|
||||
if (config.getAlfredStatus() && config.getAnrEnableStatus()) {
|
||||
val anrView =
|
||||
@@ -348,7 +403,7 @@ object AlfredManager {
|
||||
buildNegativeCaseEvent(
|
||||
AlfredConstants.ANR_EVENT,
|
||||
anrEventProperties as HashMap<String, String>,
|
||||
screenName = currentScreenName,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(
|
||||
@@ -374,7 +429,7 @@ object AlfredManager {
|
||||
buildNegativeCaseEvent(
|
||||
AlfredConstants.CRASH_ANALYTICS_EVENT,
|
||||
crashEventProperties as HashMap<String, String>,
|
||||
screenName = currentScreenName,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddNegativeCase(event, applicationContext))
|
||||
@@ -391,7 +446,7 @@ object AlfredManager {
|
||||
buildNegativeCaseEvent(
|
||||
AlfredConstants.ERROR_LOG,
|
||||
swwEventProperties as HashMap<String, String>,
|
||||
screenName = currentScreenName,
|
||||
screenName = currentScreen.name,
|
||||
moduleName = currentModuleName
|
||||
)
|
||||
AlfredDispatcher.addTaskToQueue(AddNegativeCase(event, applicationContext))
|
||||
@@ -400,9 +455,10 @@ object AlfredManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentScreenName(screenName: String?) {
|
||||
fun setCurrentScreenName(screenName: String?, isComposeScreen: Boolean? = false) {
|
||||
if (isAlfredRecordingEnabled()) {
|
||||
currentScreenName = screenName
|
||||
currentScreen.name = screenName ?: ""
|
||||
currentScreen.isComposeScreen = isComposeScreen ?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.navi.alfred.db.model.ZipDetailsHelper
|
||||
NegativeCase::class,
|
||||
FailureEvent::class
|
||||
],
|
||||
version = 4,
|
||||
version = 5,
|
||||
exportSchema = true
|
||||
)
|
||||
abstract class AlfredDatabase : RoomDatabase() {
|
||||
|
||||
@@ -33,7 +33,9 @@ data class ZipDetailsHelper(
|
||||
@ColumnInfo(name = "alfredSessionId") val alfredSessionId: String,
|
||||
@ColumnInfo(name = "sessionStartRecordingTime") val sessionStartRecordingTime: Long,
|
||||
@ColumnInfo(name = "eventStartRecordingTime") val eventStartRecordingTime: Long,
|
||||
@ColumnInfo(name = "zipFileName") val zipFileName: String
|
||||
@ColumnInfo(name = "zipFileName") val zipFileName: String,
|
||||
@ColumnInfo(name = "alfredEventId") val alfredEventId: String,
|
||||
@ColumnInfo(name = "latestScreenshotTimestamp") val latestScreenshotTimestamp: Long
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true) var id: Int = 0
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.navi.alfred.model
|
||||
|
||||
data class CurrentScreen(
|
||||
var name: String? = "",
|
||||
var isComposeScreen: Boolean? = false
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "CurrentScreen(name='$name', isComposeScreen=$isComposeScreen)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,5 +24,7 @@ data class WorkManagerFailureInputData(
|
||||
var eventStartRecordingTime: Long = 0L,
|
||||
var screenShots: List<ScreenShotPathHelper> = emptyList(),
|
||||
val id: UUID,
|
||||
val zipFileName: String
|
||||
val zipFileName: String,
|
||||
val alfredEventId: String,
|
||||
val latestScreenshotTimestamp: Long = 0L
|
||||
)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.navi.alfred.model
|
||||
|
||||
data class MaskingBounds(
|
||||
val left: Float,
|
||||
val top: Float,
|
||||
val right: Float,
|
||||
val bottom: Float
|
||||
) {
|
||||
val width: Float
|
||||
get() {
|
||||
return right - left
|
||||
}
|
||||
|
||||
val height: Float
|
||||
get() {
|
||||
return bottom - top
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "MaskingBounds(left=$left, top=$top, right=$right, bottom=$bottom)"
|
||||
}
|
||||
}
|
||||
@@ -29,6 +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("screenshot_timestamp") val screenShotTimeStamp: Long? = null
|
||||
)
|
||||
|
||||
data class SessionRequest(
|
||||
@@ -61,11 +63,11 @@ data class BaseAttribute(
|
||||
@SerializedName("event_timestamp")
|
||||
val eventTimeStamp: Long? = AlfredManager.config.getEventTimeStamp(),
|
||||
@SerializedName("session_id")
|
||||
val sessionId: String? = AlfredManager.config.getAlfredSessionId(),
|
||||
val sessionId: String? = null,
|
||||
@SerializedName("session_time_stamp")
|
||||
val sessionTimeStamp: Long? = AlfredManager.config.getSessionStartRecordingTime(),
|
||||
val sessionTimeStamp: Long? = null,
|
||||
@SerializedName("event_end_time_stamp")
|
||||
val eventEndTimeStamp: Long? = AlfredManager.config.getEventTimeStamp(),
|
||||
val latestScreenshotTimestamp: Long? = null,
|
||||
@SerializedName("timezone")
|
||||
val timezone: String? = AlfredManager.config.getCurrentTimeZone(),
|
||||
@SerializedName("metadata") val metaData: MetaData = MetaData(),
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.navi.alfred.repository
|
||||
|
||||
import android.view.View
|
||||
import com.navi.alfred.model.MaskingBounds
|
||||
|
||||
interface ComposeMaskingRepo {
|
||||
fun maskSensitiveComposable(id: String, coordinates: MaskingBounds?, currentView: View?)
|
||||
fun removeSensitiveComposable(id: String)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.navi.alfred.repository
|
||||
|
||||
import android.view.View
|
||||
import com.navi.alfred.model.MaskingBounds
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class ComposeMaskingRepoImpl : ComposeMaskingRepo {
|
||||
private val sensitiveCoordinates = mutableMapOf<String, MaskingBounds>()
|
||||
private var rootView = WeakReference<View>(null)
|
||||
override fun maskSensitiveComposable(
|
||||
id: String,
|
||||
coordinates: MaskingBounds?,
|
||||
rootView: View?
|
||||
) {
|
||||
if (rootView != this.rootView.get()) {
|
||||
removeAllSensitiveComposables()
|
||||
}
|
||||
if (coordinates != null) {
|
||||
this.rootView = WeakReference(rootView)
|
||||
sensitiveCoordinates[id] = coordinates
|
||||
}
|
||||
}
|
||||
|
||||
override fun removeSensitiveComposable(id: String) {
|
||||
if (sensitiveCoordinates.containsKey(id)) {
|
||||
sensitiveCoordinates.remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun removeAllSensitiveComposables() {
|
||||
sensitiveCoordinates.clear()
|
||||
}
|
||||
|
||||
internal fun getAllSensitiveComposableCoordinates(): List<MaskingBounds> {
|
||||
return sensitiveCoordinates.values.toList()
|
||||
}
|
||||
|
||||
internal fun getRootViewOfComposeScreen(): View? {
|
||||
return rootView.get()
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,7 @@ object AlfredConstants {
|
||||
const val DISABLE_ALFRED_LOGS = "DISABLE_ALFRED_LOGS"
|
||||
const val DISABLE_CDN_LOGS = "DISABLE_CDN_LOGS"
|
||||
const val SENSITIVE_VIEW_TAG = "sensitive_view"
|
||||
const val SENSITIVE_COMPOSE_VIEW_TAG = "sensitive_compose_view"
|
||||
const val EVENT_DB_NAME = "navi-analytics"
|
||||
const val ZIP_FILE_EXTENSION = ".zip"
|
||||
const val IMAGE_FILE_EXTENSION = ".jpeg"
|
||||
@@ -106,4 +107,6 @@ object AlfredConstants {
|
||||
const val GET_PRE_SIGNED_URL_FAILURE = "GET_PRE_SIGNED_URL_FAILURE"
|
||||
const val API_ERROR = "API_ERROR"
|
||||
const val ZIP_ERROR = "ZIP_ERROR"
|
||||
const val SCREEN_TRANSITION_EVENT = "SCREEN_TRANSITION_EVENT"
|
||||
const val LATEST_SCREENSHOT_TIMESTAMP = "LATEST_SCREENSHOT_TIMESTAMP"
|
||||
}
|
||||
@@ -104,8 +104,8 @@ internal fun getBatteryPercentage(context: Context): Float {
|
||||
internal fun getMemoryUsagePercentage(): Float {
|
||||
val runtime = Runtime.getRuntime()
|
||||
val usedMemory = runtime.totalMemory() - runtime.freeMemory()
|
||||
val maxMemory = runtime.maxMemory()
|
||||
return usedMemory.toFloat() / maxMemory.toFloat() * 100
|
||||
val totalMemory = runtime.totalMemory()
|
||||
return usedMemory.toFloat() / totalMemory.toFloat() * 100
|
||||
}
|
||||
|
||||
internal fun getCpuUsage(): Float {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.navi.alfred.utils
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.db.AlfredDatabaseHelper
|
||||
import com.navi.alfred.db.model.AnalyticsEvent
|
||||
import com.navi.alfred.db.model.ApiMetricHelper
|
||||
import com.navi.alfred.db.model.FailureEvent
|
||||
@@ -43,14 +41,12 @@ import kotlinx.coroutines.sync.withLock
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
internal suspend fun sendEventsToServer(applicationContext: Context): Boolean {
|
||||
internal suspend fun sendEventsToServer(): Boolean {
|
||||
if (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
|
||||
try {
|
||||
AlfredManager.mutex.withLock {
|
||||
val db = AlfredDatabaseHelper.getAnalyticsDatabase(applicationContext)
|
||||
val analyticsDao = db.analyticsDao()
|
||||
val analyticsEvents = analyticsDao.fetchEvents(AlfredManager.config.getEventBatchSize())
|
||||
|
||||
val analyticsEvents =
|
||||
AlfredManager.analyticsDao.fetchEvents(AlfredManager.config.getEventBatchSize())
|
||||
if (analyticsEvents.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = analyticsEvents.map { it.details }
|
||||
@@ -59,10 +55,9 @@ internal suspend fun sendEventsToServer(applicationContext: Context): Boolean {
|
||||
val events: ArrayList<EventAttribute> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
if (events.size > 0) {
|
||||
val sessionId = events.first().sessionId
|
||||
val request =
|
||||
AnalyticsRequest(
|
||||
baseAttribute = BaseAttribute(sessionId = sessionId),
|
||||
baseAttribute = BaseAttribute(),
|
||||
events = events
|
||||
)
|
||||
val response = AlfredManager.networkRepository.sendEvents(
|
||||
@@ -72,7 +67,7 @@ internal suspend fun sendEventsToServer(applicationContext: Context): Boolean {
|
||||
)
|
||||
return if (
|
||||
response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) {
|
||||
analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
AlfredManager.analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
true
|
||||
} else {
|
||||
val zipNamesList: MutableList<String> = mutableListOf()
|
||||
@@ -98,7 +93,7 @@ internal suspend fun sendEventsToServer(applicationContext: Context): Boolean {
|
||||
)
|
||||
)
|
||||
if (response.code() == AlfredConstants.CODE_API_BAD_REQUEST) {
|
||||
analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
AlfredManager.analyticsDao.deleteEvents(analyticsEvents.map { it.eventId })
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -123,15 +118,12 @@ internal suspend fun sendEventsToServer(applicationContext: Context): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
internal suspend fun sendNegativeCaseToServer(applicationContext: Context): Boolean {
|
||||
internal suspend fun sendNegativeCaseToServer(): Boolean {
|
||||
if (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
|
||||
try {
|
||||
AlfredManager.mutex.withLock {
|
||||
val db = AlfredDatabaseHelper.getAnalyticsDatabase(applicationContext)
|
||||
val negativeCaseDao = db.negativeCaseDao()
|
||||
val negativeEvents =
|
||||
negativeCaseDao.fetchNegativeCase(AlfredManager.config.getEventBatchSize())
|
||||
|
||||
AlfredManager.negativeCaseDao.fetchNegativeCase(AlfredManager.config.getEventBatchSize())
|
||||
if (negativeEvents.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = negativeEvents.map { it.details }
|
||||
@@ -140,10 +132,9 @@ internal suspend fun sendNegativeCaseToServer(applicationContext: Context): Bool
|
||||
val events: ArrayList<EventAttribute> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
if (events.size > 0) {
|
||||
val sessionId = events.first().sessionId
|
||||
val request =
|
||||
AnalyticsRequest(
|
||||
baseAttribute = BaseAttribute(sessionId = sessionId),
|
||||
baseAttribute = BaseAttribute(),
|
||||
events = events
|
||||
)
|
||||
val response = AlfredManager.networkRepository.sendNegativeCase(
|
||||
@@ -154,7 +145,7 @@ internal suspend fun sendNegativeCaseToServer(applicationContext: Context): Bool
|
||||
return if (
|
||||
response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS
|
||||
) {
|
||||
negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
true
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
@@ -172,7 +163,7 @@ internal suspend fun sendNegativeCaseToServer(applicationContext: Context): Bool
|
||||
)
|
||||
)
|
||||
if (response.code() == AlfredConstants.CODE_API_BAD_REQUEST) {
|
||||
negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
AlfredManager.negativeCaseDao.deleteNegativeCase(negativeEvents.map { it.negativeCaseId })
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -197,15 +188,12 @@ internal suspend fun sendNegativeCaseToServer(applicationContext: Context): Bool
|
||||
return false
|
||||
}
|
||||
|
||||
internal suspend fun sendFailureEventsToServer(applicationContext: Context): Boolean {
|
||||
internal suspend fun sendFailureEventsToServer(): Boolean {
|
||||
if (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
|
||||
try {
|
||||
AlfredManager.mutex.withLock {
|
||||
val db = AlfredDatabaseHelper.getAnalyticsDatabase(applicationContext)
|
||||
val failureEventDao = db.failureEventDao()
|
||||
val failureEvents =
|
||||
failureEventDao.fetchFailureEvents(AlfredManager.config.getFailureEventBatchSize())
|
||||
|
||||
AlfredManager.failureEventDao.fetchFailureEvents(AlfredManager.config.getFailureEventBatchSize())
|
||||
if (failureEvents.isNotEmpty()) {
|
||||
try {
|
||||
val detailsList = failureEvents.map { it.details }
|
||||
@@ -228,7 +216,7 @@ internal suspend fun sendFailureEventsToServer(applicationContext: Context): Boo
|
||||
(response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) or
|
||||
(response.code() == AlfredConstants.CODE_API_BAD_REQUEST)
|
||||
) {
|
||||
failureEventDao.deleteFailureEvents(failureEvents.map { it.eventId })
|
||||
AlfredManager.failureEventDao.deleteFailureEvents(failureEvents.map { it.eventId })
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -255,14 +243,14 @@ internal suspend fun sendFailureEventsToServer(applicationContext: Context): Boo
|
||||
internal fun sendAlfredSessionEvent(
|
||||
dumpFlow: Boolean = false,
|
||||
index: Int? = null,
|
||||
currentZipName: String? = null
|
||||
currentZipName: String? = null,
|
||||
latestScreenshotTimestamp: Long? = null
|
||||
) {
|
||||
var request: SessionRequest? = null
|
||||
if (dumpFlow) {
|
||||
var clientTs: Long? = null
|
||||
var sessionTimeStamp: Long? = null
|
||||
var sessionId: String? = null
|
||||
var eventEndTimeStamp: Long? = null
|
||||
if (index != null) {
|
||||
val zipFileDetail = AlfredManager.zipFileDetails[index]
|
||||
clientTs = zipFileDetail.eventStartRecordingTime
|
||||
@@ -274,14 +262,6 @@ internal fun sendAlfredSessionEvent(
|
||||
sessionId = AlfredManager.sessionIdForCrash
|
||||
}
|
||||
|
||||
clientTs?.let {
|
||||
eventEndTimeStamp =
|
||||
java.lang.Long.min(
|
||||
it.plus(AlfredConstants.INCREMENT_OF_ONE_MINUTE),
|
||||
AlfredManager.config.getEventTimeStamp()
|
||||
)
|
||||
}
|
||||
|
||||
request =
|
||||
SessionRequest(
|
||||
base_attribute =
|
||||
@@ -290,7 +270,7 @@ internal fun sendAlfredSessionEvent(
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = clientTs,
|
||||
sessionTimeStamp = sessionTimeStamp,
|
||||
eventEndTimeStamp = eventEndTimeStamp
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
),
|
||||
session_upload_event_attributes =
|
||||
SessionEventAttribute(
|
||||
@@ -300,13 +280,6 @@ internal fun sendAlfredSessionEvent(
|
||||
)
|
||||
)
|
||||
} else {
|
||||
val eventEndTimeStamp = AlfredManager.config.getEventStartRecordingTime()
|
||||
?.let {
|
||||
java.lang.Long.min(
|
||||
it.plus(AlfredConstants.INCREMENT_OF_ONE_MINUTE),
|
||||
AlfredManager.config.getEventTimeStamp()
|
||||
)
|
||||
}
|
||||
request =
|
||||
SessionRequest(
|
||||
base_attribute =
|
||||
@@ -314,7 +287,7 @@ internal fun sendAlfredSessionEvent(
|
||||
sessionId = AlfredManager.config.getAlfredSessionId(),
|
||||
eventTimeStamp = AlfredManager.config.getEventTimeStamp(),
|
||||
clientTs = AlfredManager.config.getEventStartRecordingTime(),
|
||||
eventEndTimeStamp = eventEndTimeStamp
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
),
|
||||
session_upload_event_attributes =
|
||||
SessionEventAttribute(
|
||||
@@ -391,7 +364,7 @@ internal suspend fun sendIngestMetric(): Boolean {
|
||||
val sessionId = events.first().sessionId
|
||||
val request =
|
||||
EventMetricRequest(
|
||||
baseAttribute = BaseAttribute(sessionId = sessionId),
|
||||
baseAttribute = BaseAttribute(),
|
||||
metricsAttribute = events
|
||||
)
|
||||
val response =
|
||||
@@ -444,7 +417,7 @@ internal suspend fun sendIngestMetric(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
internal fun startSyncEvents(applicationContext: Context) {
|
||||
internal fun startSyncEvents() {
|
||||
AlfredManager.timer =
|
||||
fixedRateTimer(
|
||||
AlfredConstants.TIMER_THREAD_NAME,
|
||||
@@ -456,11 +429,11 @@ internal fun startSyncEvents(applicationContext: Context) {
|
||||
AddMetricTask.resetEventCount()
|
||||
sendIngestMetric()
|
||||
AddEventTask.resetEventCount()
|
||||
sendEventsToServer(applicationContext)
|
||||
sendEventsToServer()
|
||||
AddNegativeCase.resetEventCount()
|
||||
sendNegativeCaseToServer(applicationContext)
|
||||
sendNegativeCaseToServer()
|
||||
AddFailureTask.resetEventCount()
|
||||
sendFailureEventsToServer(applicationContext)
|
||||
sendFailureEventsToServer()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -483,7 +456,8 @@ internal fun buildEvent(
|
||||
screenName = screenName,
|
||||
moduleName = moduleName,
|
||||
fragmentList = getFragmentList(),
|
||||
zipName = AlfredManager.config.getAlfredEventId()
|
||||
zipName = AlfredManager.config.getAlfredEventId(),
|
||||
screenShotTimeStamp = AlfredManager.config.getLatestScreenshotTimestamp()
|
||||
)
|
||||
return AnalyticsEvent(timeStamp, Gson().toJson(eventData))
|
||||
}
|
||||
@@ -551,7 +525,7 @@ internal fun buildAppPerformanceEvent(
|
||||
eventType = eventType,
|
||||
sessionId = AlfredManager.config.getAlfredSessionId(),
|
||||
attributes = attribute,
|
||||
screenName = AlfredManager.currentScreenName,
|
||||
screenName = AlfredManager.currentScreen.name,
|
||||
moduleName = AlfredManager.currentModuleName,
|
||||
fragmentList = getFragmentList()
|
||||
)
|
||||
|
||||
@@ -4,11 +4,15 @@ import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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 kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -74,8 +78,10 @@ internal fun insertScreenShotPathInDb(
|
||||
scope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val fileDir = context.filesDir
|
||||
val currentTime = System.currentTimeMillis()
|
||||
AlfredManager.config.setLatestScreenshotTimestamp(currentTime)
|
||||
val fileName =
|
||||
System.currentTimeMillis().toString() + AlfredConstants.IMAGE_FILE_EXTENSION
|
||||
currentTime.toString() + AlfredConstants.IMAGE_FILE_EXTENSION
|
||||
val path = fileDir.path.plus("/").plus(fileName)
|
||||
val imageUrl = File(path)
|
||||
val fos = FileOutputStream(imageUrl)
|
||||
@@ -189,34 +195,53 @@ internal suspend fun captureScreen(
|
||||
return null
|
||||
}
|
||||
if (canvas != null && bmp != null) {
|
||||
if (isMaskingEnabled(screenName) || (v.tag == AlfredConstants.SENSITIVE_VIEW_TAG)) {
|
||||
val maskedViewsList = findViewWithTagRecursive(
|
||||
v,
|
||||
AlfredConstants.SENSITIVE_VIEW_TAG, mutableListOf()
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
try {
|
||||
if (maskedViewsList.isEmpty()) {
|
||||
v.draw(canvas)
|
||||
val currentScreen = AlfredManager.currentScreen
|
||||
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)) {
|
||||
try {
|
||||
if (currentScreen.isComposeScreen == true) {
|
||||
if (sensitiveCoordinates.isNotEmpty() && rootView != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
captureComposeViewWithMasking(canvas, sensitiveCoordinates, rootView)
|
||||
}
|
||||
} else {
|
||||
val alphaList = mutableListOf<Pair<View, Float>>()
|
||||
|
||||
for (maskedView in maskedViewsList) {
|
||||
alphaList.add(Pair(maskedView, maskedView.alpha))
|
||||
maskedView.alpha = 0.0f
|
||||
withContext(Dispatchers.Main) {
|
||||
blurScreen(canvas, v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val maskedViewsList = findViewWithTagRecursive(
|
||||
v,
|
||||
AlfredConstants.SENSITIVE_VIEW_TAG, mutableListOf()
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
try {
|
||||
if (maskedViewsList.isEmpty()) {
|
||||
v.draw(canvas)
|
||||
} else {
|
||||
val alphaList = mutableListOf<Pair<View, Float>>()
|
||||
|
||||
for (maskedView in maskedViewsList) {
|
||||
alphaList.add(Pair(maskedView, maskedView.alpha))
|
||||
maskedView.alpha = 0.0f
|
||||
}
|
||||
|
||||
v.draw(canvas)
|
||||
|
||||
for (alphaView in alphaList) {
|
||||
val view = alphaView.first
|
||||
view.alpha = alphaView.second
|
||||
}
|
||||
alphaList.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
|
||||
v.draw(canvas)
|
||||
|
||||
for (alphaView in alphaList) {
|
||||
val view = alphaView.first
|
||||
view.alpha = alphaView.second
|
||||
}
|
||||
alphaList.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
@@ -281,6 +306,39 @@ internal suspend fun captureBottomSheet(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun captureComposeViewWithMasking(
|
||||
canvas: Canvas,
|
||||
sensitiveCoordinates: List<MaskingBounds>,
|
||||
rootView: View
|
||||
) {
|
||||
rootView.draw(canvas)
|
||||
val paint = Paint()
|
||||
paint.color = Color.BLACK
|
||||
|
||||
sensitiveCoordinates.forEach { bounds ->
|
||||
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
|
||||
) {
|
||||
rootView.draw(canvas)
|
||||
val paint = Paint()
|
||||
paint.color = Color.GRAY
|
||||
paint.alpha = 90
|
||||
canvas.drawRect(
|
||||
rootView.left.toFloat(),
|
||||
rootView.top.toFloat(),
|
||||
rootView.right.toFloat(),
|
||||
rootView.bottom.toFloat(),
|
||||
paint
|
||||
)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
internal fun measureInflatedView(view: View, width: Int = 1080, height: Int = 1920) {
|
||||
view.layoutParams = ViewGroup.LayoutParams(width, height)
|
||||
|
||||
@@ -28,13 +28,19 @@ internal suspend fun getPreSignedUrl(
|
||||
zipFileName: String,
|
||||
dumpFlow: Boolean = false,
|
||||
index: Int? = null,
|
||||
workManagerFlow: Boolean? = false
|
||||
workManagerFlow: Boolean? = false,
|
||||
alfredEventIdForDumpFlow: String? = null,
|
||||
latestScreenshotTimestamp: Long? = null
|
||||
) {
|
||||
val currentZipName: String
|
||||
if (dumpFlow && workManagerFlow == false) {
|
||||
currentZipName = UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
val latestScreenshotName: Long
|
||||
|
||||
if (dumpFlow) {
|
||||
currentZipName = alfredEventIdForDumpFlow ?: UUID.randomUUID().toString().plus(AlfredConstants.ALFRED_EVENT_ID)
|
||||
latestScreenshotName = latestScreenshotTimestamp ?: 0L
|
||||
} else {
|
||||
currentZipName = AlfredManager.config.getAlfredEventId()
|
||||
latestScreenshotName = AlfredManager.config.getLatestScreenshotTimestamp()
|
||||
AlfredManager.config.setAlfredEventId()
|
||||
}
|
||||
val bucketKey = currentZipName.plus(AlfredConstants.ZIP_FILE_EXTENSION)
|
||||
@@ -50,7 +56,8 @@ internal suspend fun getPreSignedUrl(
|
||||
index,
|
||||
zipFileName,
|
||||
workManagerFlow = workManagerFlow,
|
||||
currentZipName = currentZipName
|
||||
currentZipName = currentZipName,
|
||||
latestScreenshotTimestamp = latestScreenshotName
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -78,13 +85,15 @@ internal suspend fun getPreSignedUrl(
|
||||
AlfredManager.config.getAlfredSessionId(),
|
||||
AlfredManager.config.getSessionStartRecordingTime(),
|
||||
eventStartRecordingTime,
|
||||
zipFileName
|
||||
zipFileName,
|
||||
currentZipName,
|
||||
latestScreenshotName
|
||||
)
|
||||
}
|
||||
AlfredManager.config.setEventStartRecordingTime(true)
|
||||
}
|
||||
if (workManagerFlow == true) {
|
||||
uploadWorkManagerFailedZip()
|
||||
uploadWorkManagerFailedZip(currentZipName, latestScreenshotName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,6 +117,11 @@ internal fun checkAndInitiateFileUploadWorkManager() {
|
||||
AlfredManager.config.getEventStartRecordingTime() ?: 0L
|
||||
)
|
||||
.putString(AlfredConstants.SCREENSHOT_LIST, Gson().toJson(screenShotList))
|
||||
.putString(AlfredConstants.ALFRED_EVENT_ID, AlfredManager.config.getAlfredEventId())
|
||||
.putLong(
|
||||
AlfredConstants.LATEST_SCREENSHOT_TIMESTAMP,
|
||||
AlfredManager.config.getLatestScreenshotTimestamp()
|
||||
)
|
||||
.build()
|
||||
buildWorkManager(requestData)
|
||||
}
|
||||
@@ -149,13 +163,14 @@ internal suspend fun uploadFile(
|
||||
index: Int? = null,
|
||||
zipFileName: String,
|
||||
workManagerFlow: Boolean? = false,
|
||||
currentZipName: String? = null
|
||||
currentZipName: String? = "",
|
||||
latestScreenshotTimestamp: Long? = 0L
|
||||
) {
|
||||
val requestBody = uploadFile.asRequestBody("application/zip".toMediaTypeOrNull())
|
||||
val uploadResponse = AlfredManager.networkRepository.uploadZipToS3(url, requestBody)
|
||||
if (uploadResponse.isSuccessful && uploadResponse.code() == AlfredConstants.CODE_API_SUCCESS) {
|
||||
uploadFile.delete()
|
||||
sendAlfredSessionEvent(dumpFlow, index, currentZipName)
|
||||
sendAlfredSessionEvent(dumpFlow, index, currentZipName, latestScreenshotTimestamp)
|
||||
} else {
|
||||
val failureEvent = buildFailureEvent(
|
||||
errorType = ZIP_ERROR,
|
||||
@@ -179,13 +194,15 @@ internal suspend fun uploadFile(
|
||||
AlfredManager.config.getAlfredSessionId(),
|
||||
AlfredManager.config.getSessionStartRecordingTime(),
|
||||
eventStartRecordingTime,
|
||||
zipFileName
|
||||
zipFileName,
|
||||
currentZipName ?: "",
|
||||
latestScreenshotTimestamp ?: 0L
|
||||
)
|
||||
}
|
||||
AlfredManager.config.setEventStartRecordingTime(true)
|
||||
}
|
||||
if (workManagerFlow == true) {
|
||||
uploadWorkManagerFailedZip()
|
||||
uploadWorkManagerFailedZip(currentZipName, latestScreenshotTimestamp)
|
||||
}
|
||||
}
|
||||
if (!dumpFlow) {
|
||||
|
||||
@@ -90,7 +90,13 @@ internal fun checkDbBeforeStartRecording() {
|
||||
AlfredManager.applicationContext
|
||||
) != null
|
||||
) {
|
||||
getPreSignedUrl(DumpZipDetailsHelper.zipFileName, true, index)
|
||||
getPreSignedUrl(
|
||||
zipFileName = DumpZipDetailsHelper.zipFileName,
|
||||
dumpFlow = true,
|
||||
index = index,
|
||||
alfredEventIdForDumpFlow = DumpZipDetailsHelper.alfredEventId,
|
||||
latestScreenshotTimestamp = DumpZipDetailsHelper.latestScreenshotTimestamp
|
||||
)
|
||||
} else {
|
||||
AlfredManager.zipDetailsDao.deleteZipFileDetail(DumpZipDetailsHelper.id)
|
||||
}
|
||||
@@ -117,7 +123,9 @@ internal suspend fun toZipForWorkManager(
|
||||
sessionStartRecordingTime: Long? = null,
|
||||
alfredSessionId: String? = null,
|
||||
eventStartRecordingTime: Long? = null,
|
||||
index: Int? = null
|
||||
index: Int? = null,
|
||||
alfredEventId: String,
|
||||
latestScreenshotTimestamp: Long
|
||||
) {
|
||||
AlfredManager.sessionIdForCrash = alfredSessionId
|
||||
AlfredManager.sessionStartRecordingTimeForCrash = sessionStartRecordingTime
|
||||
@@ -137,7 +145,9 @@ internal suspend fun toZipForWorkManager(
|
||||
zipFileName,
|
||||
index = index,
|
||||
workManagerFlow = true,
|
||||
dumpFlow = true
|
||||
dumpFlow = true,
|
||||
alfredEventIdForDumpFlow = alfredEventId,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -146,7 +156,9 @@ internal fun insertZipDetailsToDbForDumpingLater(
|
||||
alfredSessionId: String,
|
||||
sessionStartRecordingTime: Long,
|
||||
eventStartRecordingTime: Long,
|
||||
zipFileName: String
|
||||
zipFileName: String,
|
||||
alfredEventId: String,
|
||||
latestScreenshotTimestamp: Long
|
||||
) {
|
||||
AlfredManager.zipDetailsDao.insert(
|
||||
data =
|
||||
@@ -154,7 +166,9 @@ internal fun insertZipDetailsToDbForDumpingLater(
|
||||
alfredSessionId = alfredSessionId,
|
||||
sessionStartRecordingTime = sessionStartRecordingTime,
|
||||
eventStartRecordingTime = eventStartRecordingTime,
|
||||
zipFileName = zipFileName
|
||||
zipFileName = zipFileName,
|
||||
alfredEventId = alfredEventId,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -174,7 +188,7 @@ internal fun startAnrCrashZipUpload(view: View) {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun uploadWorkManagerFailedZip() {
|
||||
internal fun uploadWorkManagerFailedZip(alfredEventId: String? = null, latestScreenshotTimestamp: Long? = null) {
|
||||
if (AlfredManager.workFailureData.size > 0) {
|
||||
val inputData = AlfredManager.workFailureData[0]
|
||||
if (AlfredManager.zipUploadRetryCount < 3) {
|
||||
@@ -206,7 +220,9 @@ internal fun uploadWorkManagerFailedZip() {
|
||||
alfredSessionId = inputData.alfredSessionId.toString(),
|
||||
eventStartRecordingTime = inputData.eventStartRecordingTime,
|
||||
sessionStartRecordingTime = inputData.sessionStartRecordingTime,
|
||||
zipFileName = inputData.zipFileName
|
||||
zipFileName = inputData.zipFileName,
|
||||
alfredEventId = alfredEventId.toString(),
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp ?: 0L
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class AddEventTask(private val event: AnalyticsEvent, private val context: Conte
|
||||
private fun checkIfSyncIsNeeded() {
|
||||
if (eventCount.get() >= AlfredManager.config.getEventBatchSize()) {
|
||||
resetEventCount()
|
||||
AlfredDispatcher.executeInNewThread(SyncDataTask(context))
|
||||
AlfredDispatcher.executeInNewThread(SyncDataTask())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class AddFailureTask(private val event: FailureEvent, private val context: Conte
|
||||
private fun checkIfSyncIsNeeded() {
|
||||
if (eventCount.get() >= AlfredManager.config.getFailureEventBatchSize()) {
|
||||
resetEventCount()
|
||||
AlfredDispatcher.executeInNewThread(SyncFailureTask(context))
|
||||
AlfredDispatcher.executeInNewThread(SyncFailureTask())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class AddMetricTask(private val event: ApiMetricHelper, private val context: Con
|
||||
private fun checkIfSyncIsNeeded() {
|
||||
if (eventCount.get() >= AlfredManager.config.getEventBatchSize()) {
|
||||
resetEventCount()
|
||||
AlfredDispatcher.executeInNewThread(SyncDataTask(context))
|
||||
AlfredDispatcher.executeInNewThread(SyncDataTask())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class AddNegativeCase(private val negativeCase: NegativeCase, private val contex
|
||||
private fun checkIfSyncIsNeeded() {
|
||||
if (eventCount.get() >= AlfredManager.config.getNegativeCaseBatchSize()) {
|
||||
resetEventCount()
|
||||
AlfredDispatcher.executeInNewThread(SyncNegativeCaseTask(context))
|
||||
AlfredDispatcher.executeInNewThread(SyncNegativeCaseTask())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,18 @@
|
||||
|
||||
package com.navi.alfred.worker
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.navi.alfred.utils.AlfredConstants.SYNC_EVENT_TASK
|
||||
import com.navi.alfred.utils.sendEventsToServer
|
||||
import com.navi.alfred.utils.sendIngestMetric
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class SyncDataTask(private val context: Context) : AnalyticsTask {
|
||||
class SyncDataTask() : AnalyticsTask {
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
return runBlocking {
|
||||
sendIngestMetric()
|
||||
sendEventsToServer(context)
|
||||
sendEventsToServer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,17 +7,16 @@
|
||||
|
||||
package com.navi.alfred.worker
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.navi.alfred.utils.AlfredConstants.SYNC_FAILURE_TASK
|
||||
import com.navi.alfred.utils.sendFailureEventsToServer
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class SyncFailureTask(private val context: Context) : AnalyticsTask {
|
||||
class SyncFailureTask() : AnalyticsTask {
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
return runBlocking {
|
||||
sendFailureEventsToServer(context)
|
||||
sendFailureEventsToServer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,17 +7,16 @@
|
||||
|
||||
package com.navi.alfred.worker
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.navi.alfred.utils.AlfredConstants.SYNC_NEGATIVE_CASE_TASK
|
||||
import com.navi.alfred.utils.sendNegativeCaseToServer
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class SyncNegativeCaseTask(private val context: Context) : AnalyticsTask {
|
||||
class SyncNegativeCaseTask() : AnalyticsTask {
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
return runBlocking {
|
||||
sendNegativeCaseToServer(context)
|
||||
sendNegativeCaseToServer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navi.alfred.AlfredManager
|
||||
import com.navi.alfred.AlfredManager.workFailureData
|
||||
import com.navi.alfred.db.model.ScreenShotPathHelper
|
||||
import com.navi.alfred.model.WorkManagerFailureInputData
|
||||
@@ -21,6 +20,7 @@ import com.navi.alfred.utils.toZipForWorkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.lang.reflect.Type
|
||||
import java.util.UUID
|
||||
|
||||
class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
|
||||
CoroutineWorker(context, workerParams) {
|
||||
@@ -38,8 +38,13 @@ 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)
|
||||
val latestScreenshotTimestamp =
|
||||
inputData.getLong(AlfredConstants.LATEST_SCREENSHOT_TIMESTAMP, 0L)
|
||||
workFailureData.add(
|
||||
WorkManagerFailureInputData(
|
||||
alfredSessionId = alfredSessionId,
|
||||
@@ -47,23 +52,27 @@ class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
|
||||
eventStartRecordingTime,
|
||||
screenShots,
|
||||
id,
|
||||
zipFileName
|
||||
zipFileName,
|
||||
alfredEventId,
|
||||
latestScreenshotTimestamp
|
||||
)
|
||||
)
|
||||
try {
|
||||
if (
|
||||
alfredSessionId == null ||
|
||||
sessionStartRecordingTime == 0L ||
|
||||
eventStartRecordingTime == 0L
|
||||
sessionStartRecordingTime == 0L ||
|
||||
eventStartRecordingTime == 0L
|
||||
) {
|
||||
Result.failure()
|
||||
} else {
|
||||
toZipForWorkManager(
|
||||
screenShots,
|
||||
zipFileName,
|
||||
sessionStartRecordingTime,
|
||||
alfredSessionId,
|
||||
eventStartRecordingTime
|
||||
imagePathList = screenShots,
|
||||
zipFileName = zipFileName,
|
||||
sessionStartRecordingTime = sessionStartRecordingTime,
|
||||
alfredSessionId = alfredSessionId,
|
||||
eventStartRecordingTime = eventStartRecordingTime,
|
||||
alfredEventId = alfredEventId,
|
||||
latestScreenshotTimestamp = latestScreenshotTimestamp
|
||||
)
|
||||
Result.success()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user