From 86b540db29b2e4e5b5869b198c044f1ad76e0241 Mon Sep 17 00:00:00 2001 From: Sayed Owais Ali Date: Tue, 27 May 2025 16:26:32 +0530 Subject: [PATCH] NTP-60143 | Alfred events fixes (#335) Co-authored-by: amansingh --- .../com/navi/alfred/core/AlfredManager.kt | 8 ++--- .../handler/AlfredLifecycleHandlerImpl.kt | 5 +-- .../navi/alfred/sevenzutils/GenerateZip.kt | 15 +++++++-- .../com/navi/alfred/usecase/UploadUseCase.kt | 9 +++++ .../navi/alfred/utils/AnalyticsConstants.kt | 2 ++ .../java/com/navi/alfred/utils/CommonUtils.kt | 4 ++- .../java/com/navi/alfred/utils/EventUtils.kt | 5 +++ .../java/com/navi/alfred/utils/FileUtils.kt | 11 ++++++- .../java/com/navi/alfred/utils/ZipUtils.kt | 33 +++++++++++++++---- 9 files changed, 72 insertions(+), 20 deletions(-) diff --git a/navi-alfred/src/main/java/com/navi/alfred/core/AlfredManager.kt b/navi-alfred/src/main/java/com/navi/alfred/core/AlfredManager.kt index c0c4d8b..0d59de5 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/core/AlfredManager.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/core/AlfredManager.kt @@ -192,13 +192,9 @@ object AlfredManager { } } - internal fun updateRecordingState(isBackground: Boolean) { + internal fun resetWhenAppGoesInBackground() { sessionConfig.isCriticalUserJourneyActive.set(false) - isAppInForeground.set(isBackground.not()) - - if (isBackground) { - PixelCopyHandler.cleanup() - } + PixelCopyHandler.cleanup() } fun setUserId(userId: String?) { diff --git a/navi-alfred/src/main/java/com/navi/alfred/core/handler/AlfredLifecycleHandlerImpl.kt b/navi-alfred/src/main/java/com/navi/alfred/core/handler/AlfredLifecycleHandlerImpl.kt index afb2745..e04b633 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/core/handler/AlfredLifecycleHandlerImpl.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/core/handler/AlfredLifecycleHandlerImpl.kt @@ -15,8 +15,8 @@ import com.navi.alfred.core.AlfredManager.initializeAlfredResources import com.navi.alfred.core.AlfredManager.ioCoroutineScope import com.navi.alfred.core.AlfredManager.isAlfredRecordingEnabled import com.navi.alfred.core.AlfredManager.isAppInForeground +import com.navi.alfred.core.AlfredManager.resetWhenAppGoesInBackground import com.navi.alfred.core.AlfredManager.screenRecordingScope -import com.navi.alfred.core.AlfredManager.updateRecordingState import com.navi.alfred.core.handler.AlfredRecordingHandlerImpl.captureScreen import com.navi.alfred.core.handler.interfaces.AlfredLifecycleHandler import com.navi.alfred.model.EventType @@ -100,13 +100,14 @@ object AlfredLifecycleHandlerImpl : AlfredLifecycleHandler { } override fun onApplicationInBackground() { + isAppInForeground.set(false) if (!isAlfredRecordingEnabled()) { return } ioCoroutineScope.launch { prepareUploadWhenAppGoesInBackground(AlfredManager.sessionConfig.alfredZipName) } - updateRecordingState(isBackground = true) + resetWhenAppGoesInBackground() sendAnalyticsEvent(eventName = ALFRED_STOP_RECORDING) dispatchEvent( EventType.StopRecording, diff --git a/navi-alfred/src/main/java/com/navi/alfred/sevenzutils/GenerateZip.kt b/navi-alfred/src/main/java/com/navi/alfred/sevenzutils/GenerateZip.kt index fd25482..e4633cb 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/sevenzutils/GenerateZip.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/sevenzutils/GenerateZip.kt @@ -7,7 +7,6 @@ package com.navi.alfred.sevenzutils -import android.util.Log import com.navi.alfred.sevenzutils.xz.LZMA2Options import com.navi.alfred.sevenzutils.xz.XZOutputStream import com.navi.alfred.utils.AnalyticsConstants.ALFRED_X_ZIP_COMPRESSED_FAILURE @@ -22,20 +21,30 @@ internal fun compressTo7z(zipFileName: String): Boolean { if (!File(inputPath).exists()) return false try { val lzma2Options = LZMA2Options() + lzma2Options.dictSize = 1 shl 20 + val outputStream = XZOutputStream(FileOutputStream(zipFileName), lzma2Options) val inputStream = FileInputStream(inputPath) - val buf = ByteArray(8192) + val buf = ByteArray(4096) var size: Int while ((inputStream.read(buf).also { size = it }) != -1) outputStream.write(buf, 0, size) outputStream.finish() sendAnalyticsEvent(ALFRED_X_ZIP_COMPRESSED_SUCCESS, mapOf("zipFileName" to zipFileName)) return true + } catch (e: OutOfMemoryError) { + sendAnalyticsEvent( + ALFRED_X_ZIP_COMPRESSED_FAILURE, + mapOf( + "exception" to "OutOfMemoryError", + "message" to (e.message ?: "Unknown OOM error"), + ), + ) + return false } catch (e: Exception) { sendAnalyticsEvent( ALFRED_X_ZIP_COMPRESSED_FAILURE, mapOf("exception" to e.message.toString()), ) - Log.e("GenerateZip", "Error compressing to 7z", e) return false } } diff --git a/navi-alfred/src/main/java/com/navi/alfred/usecase/UploadUseCase.kt b/navi-alfred/src/main/java/com/navi/alfred/usecase/UploadUseCase.kt index 7e0cf40..f7b8e99 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/usecase/UploadUseCase.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/usecase/UploadUseCase.kt @@ -13,6 +13,7 @@ import com.navi.alfred.db.dao.ZipDetailsDao import com.navi.alfred.db.model.ZipDetailsHelper import com.navi.alfred.network.AlfredNetworkRepository import com.navi.alfred.utils.AlfredConstants +import com.navi.alfred.utils.AlfredConstants.ALFRED_SESSION_ID import com.navi.alfred.utils.AlfredConstants.FILE_TYPE_XZ import com.navi.alfred.utils.AlfredConstants.FILE_TYPE_ZIP import com.navi.alfred.utils.AnalyticsConstants.ALFRED_GET_PRE_SIGNED_URL_CALLED @@ -45,6 +46,8 @@ class UploadZipUseCase( mapOf( "zipFileName" to zipFileDetail.zipFolderName, "fileTypeExtension" to zipFileDetail.fileTypeExtension, + "source" to zipFileDetail.source, + ALFRED_SESSION_ID to zipFileDetail.alfredSessionId, ), ) @@ -64,6 +67,8 @@ class UploadZipUseCase( "fileTypeExtension" to zipFileDetail.fileTypeExtension, "response_code" to preSignedUrl.code().toString(), "response_message" to preSignedUrl.message(), + "source" to zipFileDetail.source, + ALFRED_SESSION_ID to zipFileDetail.alfredSessionId, ), ) @@ -89,6 +94,8 @@ class UploadZipUseCase( mapOf( "zipFileName" to detail.zipFolderName, "fileTypeExtension" to detail.fileTypeExtension, + "source" to detail.source, + ALFRED_SESSION_ID to detail.alfredSessionId, ), ) @@ -101,6 +108,8 @@ class UploadZipUseCase( "fileTypeExtension" to detail.fileTypeExtension, "response_code" to resp.code().toString(), "response_message" to resp.message(), + "source" to detail.source, + ALFRED_SESSION_ID to detail.alfredSessionId, ), ) if (!resp.isSuccessful) return diff --git a/navi-alfred/src/main/java/com/navi/alfred/utils/AnalyticsConstants.kt b/navi-alfred/src/main/java/com/navi/alfred/utils/AnalyticsConstants.kt index e2d4554..2999c4c 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/utils/AnalyticsConstants.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/utils/AnalyticsConstants.kt @@ -12,6 +12,8 @@ object AnalyticsConstants { const val ALFRED_INIT = "ALFRED_INIT" const val ALFRED_START_RECORDING = "START_RECORDING" const val ALFRED_STOP_RECORDING = "STOP_RECORDING" + const val ALFRED_DELETE_FOLDER_CALLED = "ALFRED_DELETE_FOLDER_CALLED" + const val ALFRED_CLEAR_CORRUPT_FOLDER = "ALFRED_CLEAR_CORRUPT_FOLDER" const val ALFRED_CRUISE_CALLED = "CRUISE_CALLED" const val ALFRED_INIT_RECORDING_SETUP_COMPLETE = "INIT_RECORDING_SETUP_COMPLETE" const val ALFRED_UPLOAD_FILE_WORKER_SCREENSHOT_SIZE = "UPLOAD_FILE_WORKER_SCREENSHOT_SIZE" diff --git a/navi-alfred/src/main/java/com/navi/alfred/utils/CommonUtils.kt b/navi-alfred/src/main/java/com/navi/alfred/utils/CommonUtils.kt index 3d74850..5bd039b 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/utils/CommonUtils.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/utils/CommonUtils.kt @@ -34,7 +34,9 @@ fun recordException(e: Throwable) { internal fun sendAnalyticsEvent(eventName: String, eventAttributes: Map? = null) { val attribute = eventAttributes?.toMutableMap() ?: mutableMapOf() - attribute[ALFRED_SESSION_ID] = AlfredManager.sessionConfig.alfredSessionId + if (attribute[ALFRED_SESSION_ID].isNullOrEmpty()) { + attribute[ALFRED_SESSION_ID] = AlfredManager.sessionConfig.alfredSessionId + } AlfredAnalyticsManager.getAlfredAnalyticsProvider() ?.sendEvent(eventName = "ALFRED_$eventName", eventAttributes = attribute) } diff --git a/navi-alfred/src/main/java/com/navi/alfred/utils/EventUtils.kt b/navi-alfred/src/main/java/com/navi/alfred/utils/EventUtils.kt index 6748a61..2edff87 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/utils/EventUtils.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/utils/EventUtils.kt @@ -19,6 +19,7 @@ import com.navi.alfred.model.EventAttribute import com.navi.alfred.model.SessionEventAttribute import com.navi.alfred.model.SessionRequest import com.navi.alfred.model.UploadSource +import com.navi.alfred.utils.AlfredConstants.ALFRED_SESSION_ID import com.navi.alfred.utils.AlfredConstants.DEFAULT_SEND_SESSION_POST_URL import com.navi.alfred.utils.AlfredConstants.EMPTY import com.navi.alfred.utils.AnalyticsConstants.ALFRED_INGEST_SESSION_CALLED @@ -133,6 +134,8 @@ internal fun sendAlfredSessionEvent(zipFileDetails: ZipDetailsHelper) { mapOf( "zipFileName" to zipFileDetails.zipFolderName, "fileTypeExtension" to zipFileDetails.fileTypeExtension, + "source" to zipFileDetails.source, + ALFRED_SESSION_ID to zipFileDetails.alfredSessionId, ), ) @@ -151,6 +154,8 @@ internal fun sendAlfredSessionEvent(zipFileDetails: ZipDetailsHelper) { "fileTypeExtension" to zipFileDetails.fileTypeExtension, "response_code" to response.code().toString(), "response_message" to response.message(), + "source" to zipFileDetails.source, + ALFRED_SESSION_ID to zipFileDetails.alfredSessionId, ), ) if (response.isSuccessful && response.code() == AlfredConstants.CODE_API_SUCCESS) { diff --git a/navi-alfred/src/main/java/com/navi/alfred/utils/FileUtils.kt b/navi-alfred/src/main/java/com/navi/alfred/utils/FileUtils.kt index 92add62..ccb7638 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/utils/FileUtils.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/utils/FileUtils.kt @@ -12,6 +12,8 @@ import androidx.core.content.edit import com.navi.alfred.core.AlfredManager import com.navi.alfred.utils.AlfredConstants.PREFS_NAME import com.navi.alfred.utils.AlfredConstants.PREF_KEY_CLEANUP_DONE +import com.navi.alfred.utils.AnalyticsConstants.ALFRED_CLEAR_CORRUPT_FOLDER +import com.navi.alfred.utils.AnalyticsConstants.ALFRED_DELETE_FOLDER_CALLED import java.io.File internal fun deleteFolderIfEmpty(folderName: String) { @@ -19,6 +21,10 @@ internal fun deleteFolderIfEmpty(folderName: String) { if (folder.exists() && folder.isDirectory && folder.list()?.isEmpty() == true) { folder.delete() } + sendAnalyticsEvent( + eventName = ALFRED_DELETE_FOLDER_CALLED, + eventAttributes = mapOf("folderName" to folderName), + ) } internal fun cleanUpCorruptFilesIfNeeded() { @@ -47,7 +53,10 @@ internal fun cleanUpCorruptAlfredSessions() { file.name.endsWith(AlfredConstants.ALFRED_ZIP_IDENTIFIER) || file.name.endsWith(AlfredConstants.TEMP_ZIP_FILE_SUFFIX)) } - + sendAnalyticsEvent( + ALFRED_CLEAR_CORRUPT_FOLDER, + mapOf("fileSize" to (files?.size ?: 0).toString()), + ) files?.forEach { file -> if (file.exists()) { file.delete() diff --git a/navi-alfred/src/main/java/com/navi/alfred/utils/ZipUtils.kt b/navi-alfred/src/main/java/com/navi/alfred/utils/ZipUtils.kt index 0bf80cd..9977f3f 100644 --- a/navi-alfred/src/main/java/com/navi/alfred/utils/ZipUtils.kt +++ b/navi-alfred/src/main/java/com/navi/alfred/utils/ZipUtils.kt @@ -11,6 +11,7 @@ import com.navi.alfred.core.AlfredManager import com.navi.alfred.db.model.ZipDetailsHelper import com.navi.alfred.model.UploadSource import com.navi.alfred.sevenzutils.compressTo7z +import com.navi.alfred.utils.AlfredConstants.ALFRED_SESSION_ID import com.navi.alfred.utils.AnalyticsConstants.ALFRED_ZIP_CREATION_FAILED import com.navi.alfred.utils.AnalyticsConstants.ALFRED_ZIP_CREATION_SUCCESS import com.navi.alfred.utils.AnalyticsConstants.ALFRED_ZIP_INITIATED @@ -48,7 +49,6 @@ internal fun toZip( ) if (zip(fileList, zipFilePath, AlfredManager.config.zipFileTypeExtension) == true) { - sendAnalyticsEvent( eventName = ALFRED_ZIP_CREATION_SUCCESS, eventAttributes = @@ -66,8 +66,8 @@ internal fun toZip( zipFolderName = zipFolderName, fileTypeExtension = AlfredManager.config.zipFileTypeExtension, ) - deleteScreenshotsInZipFolder(sessionFolderName, zipFolderName) } + deleteScreenshotsInZipFolder(sessionFolderName, zipFolderName) } } @@ -92,6 +92,7 @@ internal fun toZipForWorkManager( "zipFilePath" to zipFilePath, "fileTypeExtension" to zipFileTypeExtension, "fileCount" to fileList.size.toString(), + ALFRED_SESSION_ID to sessionFolderName, ), ) if (zip(fileList, zipFilePath, zipFileTypeExtension) == true) { @@ -101,6 +102,7 @@ internal fun toZipForWorkManager( mapOf( "zipFilePath" to zipFilePath, "fileTypeExtension" to AlfredManager.config.zipFileTypeExtension, + ALFRED_SESSION_ID to sessionFolderName, ), ) insertZipDetailsToDbForUpload( @@ -112,8 +114,8 @@ internal fun toZipForWorkManager( fileTypeExtension = zipFileTypeExtension, source = UploadSource.WORKER, ) - deleteScreenshotsInZipFolder(sessionFolderName, zipFolderName) } + deleteScreenshotsInZipFolder(sessionFolderName, zipFolderName) } } @@ -121,7 +123,7 @@ internal fun zip(files: List, zipFilePath: String?, fileTypeExtension: S if (zipFilePath == null) { return false } - val buffer = 8192 + val buffer = 4096 val tempZipFilePath = if (fileTypeExtension == AlfredConstants.XZ_FILE_EXTENSION) { zipFilePath + "_zip" @@ -169,9 +171,26 @@ internal fun zip(files: List, zipFilePath: String?, fileTypeExtension: S } if (fileTypeExtension == AlfredConstants.XZ_FILE_EXTENSION) { - if (compressTo7z(zipFilePath)) { - File(tempZipFilePath).delete() - return true + try { + if (compressTo7z(zipFilePath)) { + File(tempZipFilePath).delete() + return true + } else { + File(tempZipFilePath).delete() + sendAnalyticsEvent( + ALFRED_ZIP_CREATION_FAILED, + mapOf( + "zipFilePath" to zipFilePath, + "fileTypeExtension" to fileTypeExtension, + ), + ) + return false + } + } catch (e: Exception) { + sendAnalyticsEvent( + "ALFRED_FALLBACK_TO_ZIP_EXCEPTION", + mapOf("error" to e.message.toString(), "zipFilePath" to zipFilePath), + ) } } else { return true