diff --git a/embrace-android-sdk/api/embrace-android-sdk.api b/embrace-android-sdk/api/embrace-android-sdk.api index 149c3f2fc8..bf3684e079 100644 --- a/embrace-android-sdk/api/embrace-android-sdk.api +++ b/embrace-android-sdk/api/embrace-android-sdk.api @@ -116,7 +116,6 @@ public final class io/embrace/android/embracesdk/EmbraceSamples { public static final fun throwJvmException ()V public static final fun triggerAnr ()V public static final fun triggerLongAnr ()V - public static final fun verifyIntegration ()V } public abstract interface class io/embrace/android/embracesdk/FlutterInternalInterface : io/embrace/android/embracesdk/internal/EmbraceInternalInterface { diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt deleted file mode 100644 index 6f57b0b65e..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt +++ /dev/null @@ -1,346 +0,0 @@ -package io.embrace.android.embracesdk - -import android.app.Activity -import android.app.AlertDialog -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Handler -import android.os.Looper -import android.widget.Toast -import io.embrace.android.embracesdk.samples.AutomaticVerificationChecker -import io.embrace.android.embracesdk.samples.VerificationActions -import io.embrace.android.embracesdk.samples.VerifyIntegrationException -import io.embrace.android.embracesdk.session.lifecycle.ActivityTracker -import io.embrace.android.embracesdk.session.lifecycle.ProcessStateListener -import io.embrace.android.embracesdk.session.lifecycle.ProcessStateService -import java.io.IOException -import java.util.concurrent.Executors -import java.util.concurrent.RejectedExecutionException -import java.util.concurrent.ScheduledExecutorService -import java.util.concurrent.TimeUnit -import kotlin.system.exitProcess - -/** - * Class that includes the logic to run the automatic Verification executing EmbraceSamples.verifyIntegration() method. - * - * Under the hood this function will create a marker File. If a marker file doesn't already exist, then it execute the following steps: - * 1. Runs {@link io.embrace.android.embracesdk.samples.VerificationActions#runActions()} - * 2. Relaunch the application after the action crash - * 3. Ends session manually and display result - * - */ -internal class EmbraceAutomaticVerification( - private val scheduledExecutorService: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() -) : ProcessStateListener { - private val handler = Handler(Looper.getMainLooper()) - - private var foregroundEventTriggered = false - - internal lateinit var activityLifecycleTracker: ActivityTracker - - internal lateinit var processStateService: ProcessStateService - - var automaticVerificationChecker = AutomaticVerificationChecker() - - var verificationActions = VerificationActions(Embrace.getInstance(), automaticVerificationChecker) - - /** - * This flag track if the verification result popup was displayed or not, - * in case the session continues after running the verification - */ - private var isResultDisplayed = false - - companion object { - internal const val TAG = "[EmbraceVerification]" - private const val ON_FOREGROUND_DELAY = 5000L - private const val EMBRACE_CONTACT_EMAIL = "support@embrace.io" - private const val VERIFY_INTEGRATION_DELAY = 200L - private const val ON_FOREGROUND_TIMEOUT = 5000L - internal val instance = EmbraceAutomaticVerification() - } - - fun verifyIntegration() { - instance.setActivityListener() - instance.runVerifyIntegration() - } - - fun setActivityListener() { - if (!::activityLifecycleTracker.isInitialized) { - activityLifecycleTracker = checkNotNull(Embrace.getImpl().activityLifecycleTracker) - } - if (!::processStateService.isInitialized) { - processStateService = checkNotNull(Embrace.getImpl().activityService) - } - processStateService.addListener(this) - } - - /** - * Started point to run the verification. - * We use a [ScheduledExecutorService] to give enough time to the onForeground callback - * to be executed in order to have a valid context/activity - */ - private fun runVerifyIntegration() { - try { - scheduledExecutorService.schedule( - { startVerification() }, - VERIFY_INTEGRATION_DELAY, - TimeUnit.MILLISECONDS - ) - } catch (e: RejectedExecutionException) { - logInternalError(e, "Start verification rejected") - } - } - - fun startVerification() { - val activity = activityLifecycleTracker.foregroundActivity - if (activity != null) { - try { - if (automaticVerificationChecker.createFile(activity)) { - // should run the verification actions - showToast(activity, activity.getString(R.string.automatic_verification_started)) - verificationActions.runActions() - } else { - // the verification was already started - logInfo("Verification almost ready...") - handler.postDelayed({ - verifyLifecycle() - }, ON_FOREGROUND_TIMEOUT) - } - } catch (e: IOException) { - logInternalError(e, "Embrace SDK cannot run the verification in this moment") - showToast(activity, activity.getString(R.string.automatic_verification_not_started)) - } - } else { - logError("Embrace SDK cannot run the verification in this moment, Activity is not present") - } - } - - private fun verifyLifecycle() { - if (!foregroundEventTriggered) { - logError("OnForeground event was not triggered") - val exceptionsService = checkNotNull(Embrace.getImpl().internalErrorService) - if (verifyIfInitializerIsDisabled()) { - exceptionsService.handleInternalError( - VerifyIntegrationException("ProcessLifecycleInitializer disabled") - ) - showDialogWithError(R.string.automatic_verification_no_initializer_message) - } else { - exceptionsService.handleInternalError( - VerifyIntegrationException("onForeground not invoked") - ) - showDialogWithError(R.string.automatic_verification_lifecycle_error_message) - } - } - } - - fun runEndSession() { - Embrace.getInstance().endSession() - logInfo("End session manually") - } - - /** - * Tries to detect the condition where the ProcessLifecycleInitializer is removed in the build file - * - * @return true if it detects that ProcessLifecycleInitializer is disabled, false otherwise - */ - private fun verifyIfInitializerIsDisabled(): Boolean { - logInfo("Trying to verify lifecycle annotations") - try { - val appInitializerClass: Class<*>? - try { - appInitializerClass = Class.forName("androidx.startup.AppInitializer") - } catch (cnfe: ClassNotFoundException) { - return false - } - - Embrace.getImpl().application?.also { app -> - val getInstance = appInitializerClass.getMethod("getInstance", Context::class.java) - val isEagerlyInitialized = - appInitializerClass.getMethod("isEagerlyInitialized", Class::class.java) - val lifecycleInitializerClass = - Class.forName("androidx.lifecycle.ProcessLifecycleInitializer") - val appInitializer = getInstance.invoke(null, app) - - val result = isEagerlyInitialized.invoke(appInitializer, lifecycleInitializerClass) as Boolean - return result.not() - } ?: run { - return false - } - } catch (e: Exception) { - logWarning("Could not verify if lifecycle annotations are working: $e") - } - return false - } - - /** - * Restarts the app after a forced VerifyIntegrationException - * was captured as part of the automatic verification - */ - fun restartAppFromPendingIntent() { - val exitStatus = 2 - val activity = activityLifecycleTracker.foregroundActivity - if (activity != null) { - val intent = activity.intent - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - intent.putExtra("from_verification", true) - - with(activity) { - finish() - startActivity(intent) - } - exitProcess(exitStatus) - } else { - logError("Cannot restart app, activity is not present") - } - } - - override fun onForeground(coldStart: Boolean, timestamp: Long) { - foregroundEventTriggered = true - val activity = activityLifecycleTracker.foregroundActivity - - if (activity != null) { - val fromVerification = activity.intent.getBooleanExtra("from_verification", false) - - if (!fromVerification) { - return - } - - if (isResultDisplayed) { - logInfo("onForeground called but the result was already displayed") - return - } - - handler.postDelayed({ - runEndSession() - displayResult() - clearUserData() - automaticVerificationChecker.deleteFile() - }, ON_FOREGROUND_DELAY) - } else { - logError("Cannot restart app, activity is not present") - } - } - - private fun clearUserData() { - Embrace.getInstance().clearUserEmail() - Embrace.getInstance().clearUsername() - Embrace.getInstance().clearAllUserPersonas() - Embrace.getInstance().clearUserIdentifier() - Embrace.getInstance().clearUserAsPayer() - } - - private fun displayResult() { - isResultDisplayed = true - - automaticVerificationChecker.isVerificationCorrect()?.also { isCorrect -> - if (isCorrect) { - logInfo("Successful - Embrace is ready to go! πŸŽ‰") - showSuccessDialog() - } else { - logError("Error - Something is wrong with the Embrace Configuration ⚠️") - showDialogWithError() - } - } ?: logError("Cannot display end message") - } - - private fun showToast(activity: Activity, message: String) { - activity.runOnUiThread { - Toast.makeText( - activity, - message, - Toast.LENGTH_LONG - ).show() - } - } - - private fun showSuccessDialog() { - val activity = activityLifecycleTracker.foregroundActivity - if (activity != null) { - val dialogBuilder = AlertDialog.Builder(activity) - dialogBuilder - .setTitle(activity.getString(R.string.automatic_verification_success_title)) - .setMessage(activity.getString(R.string.automatic_verification_success_message)) - .setCancelable(true) - .setPositiveButton(activity.getString(R.string.got_it)) { dialog, _ -> - dialog.dismiss() - } - dialogBuilder.create().show() - } else { - logInfo("Verification success!") - } - } - - private fun showDialogWithError(errorMessage: Int? = null) { - val activity = activityLifecycleTracker.foregroundActivity - if (activity != null) { - val exceptions = automaticVerificationChecker.getExceptions().map { it.message }.toMutableList() - - if (errorMessage != null) { - exceptions.add(activity.getString(errorMessage)) - } - - val errorString = if (exceptions.isNotEmpty()) { - activity.getString(R.string.embrace_verification_errors) - .replace("[X]", exceptions.joinToString("\nπŸ‘‰ ", "πŸ‘‰ ")) - } else { - activity.getString(R.string.automatic_verification_default_error_message) - } - - val dialogBuilder = AlertDialog.Builder(activity) - dialogBuilder - .setTitle(activity.getString(R.string.automatic_verification_error_title)) - .setMessage(errorString) - .setCancelable(true) - .setNegativeButton(activity.getString(R.string.send_error_log)) { dialog, _ -> - sendErrorLog(activity, errorString) - dialog.dismiss() - } - .setPositiveButton(activity.getString(R.string.close)) { dialog, _ -> - dialog.dismiss() - } - dialogBuilder.create().show() - } else { - logError("Verification error - Cannot display popup") - } - } - - private fun sendErrorLog(activity: Activity, errorMessage: String) { - val errorLog = generateErrorLog(errorMessage) - val selectorIntent = Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mailto:$EMBRACE_CONTACT_EMAIL")) - - val emailIntent = Intent(Intent.ACTION_SEND).apply { - putExtra(Intent.EXTRA_EMAIL, arrayOf(EMBRACE_CONTACT_EMAIL)) - putExtra(Intent.EXTRA_SUBJECT, "Android Verification Log") - putExtra(Intent.EXTRA_TEXT, errorLog) - selector = selectorIntent - } - - activity.startActivity(Intent.createChooser(emailIntent, "Send Email")) - } - - private fun generateErrorLog(errorMessage: String): String { - var errorLog = "App ID: ${Embrace.getImpl().metadataService?.getAppId()}\n" + - "App Version: ${Embrace.getImpl().metadataService?.getAppVersionName()}" - errorLog += "\n\n-----------------\n\n" - errorLog += errorMessage - return errorLog - } - - private fun logInfo(message: String) { - Embrace.getInstance().internalInterface.logInfo("$TAG $message", null) - } - - private fun logWarning(message: String) { - Embrace.getInstance().internalInterface.logWarning("$TAG $message", null, null) - } - - private fun logError(message: String) { - Embrace.getInstance().internalInterface.logError("$TAG $message", null, null, false) - } - - private fun logInternalError(t: Throwable, message: String? = null) { - message?.let { logError(message) } - Embrace.getInstance().internalInterface.logInternalError(t) - } -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt index 2098e4cc5d..92014730f2 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt @@ -14,28 +14,6 @@ import io.embrace.android.embracesdk.samples.EmbraceCrashSamples public object EmbraceSamples { private val embraceCrashSamples = EmbraceCrashSamples - private val embraceAutomaticVerification = EmbraceAutomaticVerification() - - /** - * Starts an automatic verification of the following Embrace features: - * - Log a Breadcrumb - * - Set user data - * - Add info, warning and error logs - * - Start and end a moment - * - Executes a GET request - * - Add the trace id to the request (default or the one specified in the local config) - * - Check the current and the latest SDK version - * - Execute a POST request - * - Execute a bad request - * - Trigger an ANR - * - Throw an Exception (yep, the application will be relaunch) - * - * Then, that information can be verified in user sessions dashboard - */ - @JvmStatic - public fun verifyIntegration() { - embraceAutomaticVerification.verifyIntegration() - } /** * Throw a custom JVM crash to be part of current session. diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/CrashModule.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/CrashModule.kt index 7cbd3dc5fb..2417920add 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/CrashModule.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/CrashModule.kt @@ -9,7 +9,6 @@ import io.embrace.android.embracesdk.ndk.NativeCrashDataSourceImpl import io.embrace.android.embracesdk.ndk.NativeCrashService import io.embrace.android.embracesdk.ndk.NativeModule import io.embrace.android.embracesdk.ndk.NoopNativeCrashService -import io.embrace.android.embracesdk.samples.AutomaticVerificationExceptionHandler /** * Contains dependencies that capture crashes @@ -17,7 +16,6 @@ import io.embrace.android.embracesdk.samples.AutomaticVerificationExceptionHandl internal interface CrashModule { val lastRunCrashVerifier: LastRunCrashVerifier val crashService: CrashService - val automaticVerificationExceptionHandler: AutomaticVerificationExceptionHandler val nativeCrashService: NativeCrashService } @@ -59,11 +57,6 @@ internal class CrashModuleImpl( LastRunCrashVerifier(crashMarker, initModule.logger) } - override val automaticVerificationExceptionHandler: AutomaticVerificationExceptionHandler by singleton { - val prevHandler = Thread.getDefaultUncaughtExceptionHandler() - AutomaticVerificationExceptionHandler(prevHandler, initModule.logger) - } - override val nativeCrashService: NativeCrashService by singleton { if (!essentialServiceModule.configService.autoDataCaptureBehavior.isNdkEnabled()) { NoopNativeCrashService() diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt index d387ae8c15..281f7f287b 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt @@ -429,7 +429,6 @@ internal class ModuleInitBootstrapper( } postInit(CrashModule::class) { - Thread.setDefaultUncaughtExceptionHandler(crashModule.automaticVerificationExceptionHandler) serviceRegistry.registerService(crashModule.crashService) } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt deleted file mode 100644 index 201a7e72f6..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt +++ /dev/null @@ -1,82 +0,0 @@ -package io.embrace.android.embracesdk.samples - -import android.app.Activity -import io.embrace.android.embracesdk.Embrace -import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer -import java.io.File -import java.io.FileNotFoundException - -internal class AutomaticVerificationChecker { - private val fileName = "emb_marker_file.txt" - private val verificationResult = VerificationResult() - private lateinit var file: File - private val serializer = EmbraceSerializer() - - /** - * Returns true if the file was created, false if it already existed - */ - fun createFile(activity: Activity): Boolean { - val directory = activity.cacheDir.absolutePath - file = File("$directory/$fileName") - - return generateMarkerFile() - } - - /** - * Verifies if the marker file exists. It is used to determine whether to run the verification or no. - * If marker file does not exist, then we have to run the automatic verification, - * on the other hand, if the marker file exists, - * it means that the verification was executed before and it shouldn't run again - * - * @return true if marker file does not exist, otherwise returns false - */ - private fun generateMarkerFile(): Boolean { - var result = false - if (!file.exists()) { - result = file.createNewFile() - } - - return result - } - - fun deleteFile() { - if (file.exists() && !file.isDirectory) { - file.delete() - } - } - - /** - * The verification is correct if the file doesn't have any exception written. - * This could be called before the file is initialized, in that case it returns null. - */ - fun isVerificationCorrect(): Boolean? { - try { - if (::file.isInitialized) { // we should rethink this flow to avoid having this verification - val fileContent = file.readText() - return if (fileContent.isEmpty()) { - true - } else { - serializer.fromJson(fileContent, VerificationResult::class.java).exceptions.isEmpty() - } - } - } catch (e: FileNotFoundException) { - Embrace.getInstance().internalInterface.logError("Cannot open file", null, null, false) - Embrace.getInstance().internalInterface.logInternalError(e) - } - return null - } - - fun addException(e: Throwable) { - verificationResult.exceptions.add(e) - file.writeText(serializer.toJson(verificationResult)) - } - - fun getExceptions(): List { - val fileContent = file.readText() - return if (fileContent.isBlank()) { - emptyList() - } else { - serializer.fromJson(fileContent, VerificationResult::class.java).exceptions - } - } -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationExceptionHandler.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationExceptionHandler.kt deleted file mode 100644 index 27ddd70505..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationExceptionHandler.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.embrace.android.embracesdk.samples - -import io.embrace.android.embracesdk.EmbraceAutomaticVerification -import io.embrace.android.embracesdk.logging.EmbLogger - -/** - * Exception Handler that verifies if a VerifyIntegrationException was received, - * in order to execute restartAppFromPendingIntent - */ -internal class AutomaticVerificationExceptionHandler( - private val defaultHandler: Thread.UncaughtExceptionHandler?, - private val logger: EmbLogger -) : - - Thread.UncaughtExceptionHandler { - - override fun uncaughtException(thread: Thread, exception: Throwable) { - if (exception.cause?.cause?.javaClass == VerifyIntegrationException::class.java) { - EmbraceAutomaticVerification.instance.restartAppFromPendingIntent() - } - logger.logDebug( - "Finished handling exception. Delegating to default handler.", - exception - ) - defaultHandler?.uncaughtException(thread, exception) - } -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt deleted file mode 100644 index a6d4256e77..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt +++ /dev/null @@ -1,205 +0,0 @@ -package io.embrace.android.embracesdk.samples - -import android.os.Handler -import android.os.Looper -import io.embrace.android.embracesdk.BuildConfig -import io.embrace.android.embracesdk.Embrace -import io.embrace.android.embracesdk.EmbraceAutomaticVerification -import io.embrace.android.embracesdk.Severity -import org.json.JSONObject -import java.io.DataOutputStream -import java.net.HttpURLConnection -import java.net.URL - -/** - * Execute actions to verify the following features: - * - Log a Breadcrumb - * - Set user data - * - Add info, warning and error logs - * - Start and end a moment - * - Executes a GET request - * - Add the trace id to the request (default or the one specified in the local config) - * - Check the current and the latest SDK version - * - Execute a POST request - * - Execute a bad request - * - Trigger an ANR - * - Throw an Exception - */ -internal class VerificationActions( - private val embraceInstance: Embrace, - private val automaticVerificationChecker: AutomaticVerificationChecker, -) { - - companion object { - private const val THROW_EXCEPTION_DELAY_MILLIS = 100L - private const val ANR_DURATION_MILLIS = 2000L - private const val MOMENT_DURATION_MILLIS = 3000L - - private const val networkingGetUrl = - "https://dash-api.embrace.io/external/sdk/android/version" - private const val networkingPostUrl = "https://httpbin.org/post" - private const val networkingWrongUrl = "https://httpbin.org/deaasd/ASdasdkjl" - private const val networkingPostBody = "{\"key_one\":\"value_one\"}" - private const val embraceChangelogLink = "https://embrace.io/docs/android/changelog/" - } - - private val handler = Handler(Looper.getMainLooper()) - - private val actionsToVerify = listOf( - Pair({ setUserData() }, "Set user data"), - Pair({ executeLogsActions() }, "Log messages"), - Pair({ executeMoment() }, "Trigger moment"), - Pair({ executeNetworkHttpGETRequest() }, "Executing network request: GET"), - Pair({ executeNetworkHttpPOSTRequest() }, "Executing network request: POST"), - Pair( - { executeNetworkHttpWrongRequest() }, - "Executing network request: testing a wrong url" - ), - Pair({ triggerAnr() }, "Causing an ANR, the application will be tilt"), - Pair({ throwAnException() }, "Throwing an Exception! πŸ’£") - ) - private var currentStep = 0 - private val totalSteps = actionsToVerify.size - - private val sampleProperties = mapOf( - "String" to "Test String", - "LongString" to "This value will be trimmed Lorem ipsum dolor sit amet, " + - "consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + - "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " + - "consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum. " + - "In culpa qui officia deserunt mollit anim id est laborum.", - "Float" to 1.0f, - "Nested Properties" to mapOf("a" to "b", "c" to "d") - ) - - /** - * Execute actions to verify the following features: - * - Log a Breadcrumb - * - Set user data - * - Add info, warning and error logs - * - Start and end a moment - * - Executes a GET request - * - Check the current and the latest SDK version - * - Execute a POST request - * - Execute a bad request - * - Trigger an ANR - * - Throw an Exception - */ - fun runActions() { - logInfo("${EmbraceAutomaticVerification.TAG} Starting Verification...") - embraceInstance.addBreadcrumb("This is a breadcrumb") - actionsToVerify.forEach { - verifyAction(it.first, it.second) - } - } - - private fun verifyAction(action: () -> Unit, message: String) { - currentStep++ - try { - logInfo(" βœ“ Step $currentStep/$totalSteps: $message") - action.invoke() - } catch (e: Throwable) { - logError("${EmbraceAutomaticVerification.TAG} -- $message ERROR ${e.localizedMessage}") - automaticVerificationChecker.addException(e) - } - } - - private fun setUserData() { - val identifier = "1234567890" - val username = "Mr. Automated User" - val email = "automated@embrace.io" - - embraceInstance.setUserIdentifier(identifier) - embraceInstance.setUsername(username) - embraceInstance.setUserEmail(email) - embraceInstance.setUserAsPayer() - embraceInstance.addUserPersona("userPersona") - } - - private fun executeLogsActions() { - embraceInstance.logMessage("test info", Severity.INFO, sampleProperties) - embraceInstance.logMessage("test warn", Severity.WARNING, sampleProperties) - embraceInstance.logException( - Throwable("Sample throwable"), - Severity.ERROR, - sampleProperties, - "test error" - ) - } - - private fun executeMoment() { - val momentName = "Verify Integration Moment" - val momentIdentifier = "Verify Integration identifier" - embraceInstance.startMoment(momentName, momentIdentifier, sampleProperties) - handler.postDelayed({ - embraceInstance.endMoment(momentName, momentIdentifier) - }, MOMENT_DURATION_MILLIS) - } - - fun executeNetworkHttpGETRequest() { - val connection = URL(networkingGetUrl).openConnection() as HttpURLConnection - connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") - connection.setRequestProperty( - embraceInstance.traceIdHeader, - "traceId : ${embraceInstance.traceIdHeader}" - ) - - val data = connection.inputStream.bufferedReader().readText() - - if (connection.responseCode != HttpURLConnection.HTTP_OK) { - throw VerifyIntegrationException("RESPONSE CODE IS ${connection.responseCode}") - } - - checkEmbraceSDKVersion(JSONObject(data).getString("value")) - } - - private fun checkEmbraceSDKVersion(latestEmbraceVersion: String) { - val currentVersion = BuildConfig.VERSION_NAME - - if (ComparableVersion(currentVersion) < ComparableVersion(latestEmbraceVersion)) { - logInfo( - "${EmbraceAutomaticVerification.TAG} Note that there is a newer version of Embrace available πŸ™Œ! " + - "You can read the changelog for $latestEmbraceVersion here: $embraceChangelogLink" - ) - } - } - - private fun executeNetworkHttpPOSTRequest() { - val connection = URL(networkingPostUrl).openConnection() as HttpURLConnection - connection.doOutput = true - DataOutputStream(connection.outputStream).use { it.writeBytes(networkingPostBody) } - - val result = connection.responseCode - - if (result != HttpURLConnection.HTTP_OK) { - throw VerifyIntegrationException("RESPONSE CODE IS $result") - } - } - - private fun executeNetworkHttpWrongRequest() { - val connection = URL(networkingWrongUrl).openConnection() as HttpURLConnection - val result = connection.responseCode - if (result != HttpURLConnection.HTTP_NOT_FOUND) { - throw VerifyIntegrationException("RESPONSE CODE IS $result") - } - } - - private fun triggerAnr() { - handler.post { Thread.sleep(ANR_DURATION_MILLIS) } - logInfo("${EmbraceAutomaticVerification.TAG} ANR Finished") - } - - private fun throwAnException() { - handler.postDelayed({ - throw VerifyIntegrationException("Forced Exception to verify integration") - }, THROW_EXCEPTION_DELAY_MILLIS) - } - - private fun logInfo(message: String) { - embraceInstance.internalInterface.logInfo("${EmbraceAutomaticVerification.TAG} $message", null) - } - - private fun logError(message: String) { - embraceInstance.internalInterface.logError("${EmbraceAutomaticVerification.TAG} $message", null, null, false) - } -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationResult.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationResult.kt deleted file mode 100644 index 8e6e3eaccb..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationResult.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.embrace.android.embracesdk.samples - -internal class VerificationResult { - val exceptions = mutableListOf() -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerifyIntegrationException.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerifyIntegrationException.kt deleted file mode 100644 index f1a59e0f77..0000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerifyIntegrationException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.embrace.android.embracesdk.samples - -internal class VerifyIntegrationException(message: String) : Exception(message) diff --git a/embrace-android-sdk/src/main/res/values/strings.xml b/embrace-android-sdk/src/main/res/values/strings.xml deleted file mode 100644 index af0e27cc6b..0000000000 --- a/embrace-android-sdk/src/main/res/values/strings.xml +++ /dev/null @@ -1,16 +0,0 @@ - - GOT IT - SEND ERROR LOG - CLOSE - Success! Open your dashboard - Almost done. Please check the Embrace dashboard to confirm that the information was received. - \n\nIf you’re experiencing any issues, reach out to support@embrace.io or your Embrace contact.\n - "Automatic verification has started. The app will relaunch shortly." - Hmm… Something went wrong - Please try again. If you continue to experience issues, - reach out to support@embrace.io or your Embrace contact - The verification cannot be started. Reach out to support@embrace.io or your Embrace contact - The Embrace SDK was not notified of lifecycle events, and will not report sessions. - The Embrace SDK cannot report sessions because ProcessLifecycleInitializer was not called. - Embrace SDK has found the following issues:\n[X].\nPlease reach out to support@embrace.io or your Embrace contact. - diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt deleted file mode 100644 index 295ba3a089..0000000000 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt +++ /dev/null @@ -1,117 +0,0 @@ -package io.embrace.android.embracesdk - -import android.app.Activity -import io.embrace.android.embracesdk.fakes.FakeActivityTracker -import io.embrace.android.embracesdk.fakes.system.mockActivity -import io.embrace.android.embracesdk.internal.EmbraceInternalInterface -import io.mockk.clearAllMocks -import io.mockk.every -import io.mockk.just -import io.mockk.mockk -import io.mockk.mockkStatic -import io.mockk.runs -import io.mockk.unmockkAll -import io.mockk.verify -import org.junit.After -import org.junit.AfterClass -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test -import java.io.IOException -import java.util.concurrent.ExecutorService -import java.util.concurrent.ScheduledExecutorService - -internal class EmbraceAutomaticVerificationTest { - - companion object { - private lateinit var embraceSamples: EmbraceAutomaticVerification - private val activity: Activity = mockActivity() - private val scheduledExecutorService: ScheduledExecutorService = mockk(relaxed = true) - - @BeforeClass - @JvmStatic - fun beforeClass() { - mockkStatic(ScheduledExecutorService::class) - mockkStatic(ExecutorService::class) - mockkStatic(Embrace::class) - mockkStatic(EmbraceImpl::class) - } - - @AfterClass - @JvmStatic - fun afterClass() { - unmockkAll() - } - } - - @Before - fun setup() { - every { Embrace.getInstance().internalInterface } answers { mockk(relaxed = true) } - embraceSamples = EmbraceAutomaticVerification(scheduledExecutorService) - } - - @After - fun after() { - clearAllMocks( - answers = false, - staticMocks = false, - objectMocks = false - ) - } - - @Test - fun `test runEndSession`() { - with(embraceSamples) { - every { Embrace.getInstance().endSession() } just runs - runEndSession() - verify { Embrace.getInstance().endSession() } - } - } - - @Test - fun `test startVerification that captures IOException`() { - with(embraceSamples) { - automaticVerificationChecker = mockk(relaxed = true) - activityLifecycleTracker = FakeActivityTracker(foregroundActivity = activity) - verificationActions = mockk(relaxed = true) - every { automaticVerificationChecker.createFile(activity) } throws IOException("ERROR") - - startVerification() - - verify(exactly = 0) { verificationActions.runActions() } - } - } - - @Test - fun `test startVerification does not run verification steps if marker file exists`() { - with(embraceSamples) { - automaticVerificationChecker = mockk(relaxed = true) - activityLifecycleTracker = FakeActivityTracker(foregroundActivity = activity) - verificationActions = mockk(relaxed = true) - every { automaticVerificationChecker.createFile(activity) } returns false - - startVerification() - - verify(exactly = 0) { - verificationActions.runActions() - } - } - } - - @Test - fun `test startVerification runs verification steps if marker file does not exist`() { - with(embraceSamples) { - automaticVerificationChecker = mockk(relaxed = true) - activityLifecycleTracker = FakeActivityTracker(foregroundActivity = activity) - verificationActions = mockk(relaxed = true) - every { automaticVerificationChecker.createFile(any() as Activity) } returns true - every { verificationActions.runActions() } just runs - - startVerification() - - verify(exactly = 1) { - verificationActions.runActions() - } - } - } -} diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/injection/FakeCrashModule.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/injection/FakeCrashModule.kt index cd99767439..26b3814cb2 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/injection/FakeCrashModule.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/injection/FakeCrashModule.kt @@ -6,7 +6,6 @@ import io.embrace.android.embracesdk.injection.CrashModule import io.embrace.android.embracesdk.internal.crash.CrashFileMarkerImpl import io.embrace.android.embracesdk.internal.crash.LastRunCrashVerifier import io.embrace.android.embracesdk.ndk.NativeCrashService -import io.embrace.android.embracesdk.samples.AutomaticVerificationExceptionHandler import io.mockk.mockk internal class FakeCrashModule : CrashModule { @@ -17,8 +16,5 @@ internal class FakeCrashModule : CrashModule { override val crashService = FakeCrashService() - override val automaticVerificationExceptionHandler = - AutomaticVerificationExceptionHandler(null, mockk(relaxed = true)) - override val nativeCrashService: NativeCrashService = FakeNativeCrashService() } diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/CrashModuleImplTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/CrashModuleImplTest.kt index 07750633f4..f3d455e447 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/CrashModuleImplTest.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/CrashModuleImplTest.kt @@ -37,7 +37,6 @@ internal class CrashModuleImplTest { ) assertNotNull(module.lastRunCrashVerifier) assertNotNull(module.crashService) - assertNotNull(module.automaticVerificationExceptionHandler) assertTrue(module.nativeCrashService is NoopNativeCrashService) } @@ -59,7 +58,6 @@ internal class CrashModuleImplTest { ) assertNotNull(module.lastRunCrashVerifier) assertNotNull(module.crashService) - assertNotNull(module.automaticVerificationExceptionHandler) assertTrue(module.nativeCrashService is NativeCrashDataSource) } }