diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4e7b9e7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.java] +charset = utf-8 +indent_style = space +indent_size = 4 +continuation_indent_size = 8 \ No newline at end of file diff --git a/Sources/.idea/fileTemplates/Kotlin Android Test.kt b/Sources/.idea/fileTemplates/Kotlin Android Test.kt new file mode 100644 index 0000000..84be2a6 --- /dev/null +++ b/Sources/.idea/fileTemplates/Kotlin Android Test.kt @@ -0,0 +1,17 @@ +#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME} + +#end +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import org.junit.Test +import org.junit.runner.RunWith + +#parse("File Header.java") +@RunWith(AndroidJUnit4::class) +@SmallTest +class ${NAME} { + + @Test + fun testFeature() { + } +} \ No newline at end of file diff --git a/Sources/build.gradle b/Sources/build.gradle index 84b65da..db43a76 100644 --- a/Sources/build.gradle +++ b/Sources/build.gradle @@ -9,12 +9,12 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.3' + classpath 'com.android.tools.build:gradle:7.1.2' classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.3' + classpath 'com.google.gms:google-services:4.3.10' } } diff --git a/Sources/gradle/wrapper/gradle-wrapper.properties b/Sources/gradle/wrapper/gradle-wrapper.properties index 05679dc..ffed3a2 100644 --- a/Sources/gradle/wrapper/gradle-wrapper.properties +++ b/Sources/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/Sources/sdk-lint/build.gradle b/Sources/sdk-lint/build.gradle index 52e137c..b80caef 100644 --- a/Sources/sdk-lint/build.gradle +++ b/Sources/sdk-lint/build.gradle @@ -1,13 +1,17 @@ apply plugin: 'java-library' +ext { + lintVersion = '30.1.2' +} + dependencies { - compileOnly 'com.android.tools.lint:lint-api:30.0.3' - compileOnly 'com.android.tools.lint:lint-checks:30.0.3' + compileOnly "com.android.tools.lint:lint-api:$lintVersion" + compileOnly "com.android.tools.lint:lint-checks:$lintVersion" testImplementation "junit:junit:4.12" - testImplementation "com.android.tools.lint:lint:30.0.3" - testImplementation "com.android.tools.lint:lint-tests:30.0.3" - testImplementation "com.android.tools:testutils:30.0.3" + testImplementation "com.android.tools.lint:lint:$lintVersion" + testImplementation "com.android.tools.lint:lint-tests:$lintVersion" + testImplementation "com.android.tools:testutils:$lintVersion" } diff --git a/Sources/sdk/build.gradle b/Sources/sdk/build.gradle index ea2707e..58e0e15 100644 --- a/Sources/sdk/build.gradle +++ b/Sources/sdk/build.gradle @@ -17,19 +17,19 @@ ext { } android { - compileSdkVersion 31 + compileSdkVersion 32 defaultPublishConfig "release" resourcePrefix "com_batchsdk_" defaultConfig { minSdkVersion 15 - targetSdkVersion 31 + targetSdkVersion 32 versionCode 1 - versionName "1.18.2" + versionName "1.19.0" buildConfigField "String", SDK_VERSION, "\"$versionName\"" - buildConfigField "Integer", API_LEVEL, '40' - buildConfigField "Integer", MESSAGING_API_LEVEL, '11' + buildConfigField "Integer", API_LEVEL, '50' + buildConfigField "Integer", MESSAGING_API_LEVEL, '12' buildConfigField "String", WS_DOMAIN, '"ws.batch.com"' consumerProguardFiles 'proguard-consumer-rules.txt' @@ -62,11 +62,6 @@ android { } } - lintOptions { - abortOnError true - baseline file("lint-baseline.xml") - lintConfig file("lint.xml") - } testOptions { execution 'ANDROIDX_TEST_ORCHESTRATOR' @@ -80,6 +75,11 @@ android { } } } + lint { + abortOnError true + baseline file('lint-baseline.xml') + lintConfig file('lint.xml') + } } // Prevent from having accidental kotlin in production code diff --git a/Sources/sdk/maven-publish.gradle b/Sources/sdk/maven-publish.gradle index 925a8f2..d1e02b2 100644 --- a/Sources/sdk/maven-publish.gradle +++ b/Sources/sdk/maven-publish.gradle @@ -71,9 +71,9 @@ publishing { url = "https://batch.com" scm { - url = "https://github.com/BatchLabs/android-sdk" - connection = "scm:git:https://github.com/BatchLabs/android-sdk.git" - developerConnection = "scm:git:https://github.com/BatchLabs/android-sdk.git" + url = "https://github.com/BatchLabs/Batch-Android-SDK" + connection = "scm:git:https://github.com/BatchLabs/Batch-Android-SDK.git" + developerConnection = "scm:git:https://github.com/BatchLabs/Batch-Android-SDK.git" } licenses { diff --git a/Sources/sdk/src/main/AndroidManifest.xml b/Sources/sdk/src/main/AndroidManifest.xml index 505768e..27ef417 100644 --- a/Sources/sdk/src/main/AndroidManifest.xml +++ b/Sources/sdk/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + = android.os.Build.VERSION_CODES.O && shouldRegisterDefaultChannel()) { + void registerBatchChannelIfNeeded(Context c, boolean forceIfOverridden) { + if (!forceIfOverridden && !shouldRegisterDefaultChannel()) { + Logger.internal(PushModule.TAG, "Channel ID overriden, not registering Batch's channel."); + return; + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { Logger.internal(PushModule.TAG, "Registering default Batch notification channel"); //try { NotificationChannel channel = new NotificationChannel( diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchNotificationChannelsManagerPrivateHelper.java b/Sources/sdk/src/main/java/com/batch/android/BatchNotificationChannelsManagerPrivateHelper.java index 215e0db..ef4f8f0 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchNotificationChannelsManagerPrivateHelper.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchNotificationChannelsManagerPrivateHelper.java @@ -13,7 +13,11 @@ public static String getChannelId(BatchNotificationChannelsManager manager) { return manager.getChannelId(null); } - public static void registerBatchChannelIfNeeded(BatchNotificationChannelsManager manager, Context context) { - manager.registerBatchChannelIfNeeded(context); + public static void registerBatchChannelIfNeeded( + BatchNotificationChannelsManager manager, + Context context, + boolean forceIfOverridden + ) { + manager.registerBatchChannelIfNeeded(context, forceIfOverridden); } } diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchPushHelper.java b/Sources/sdk/src/main/java/com/batch/android/BatchPushHelper.java index 40f599e..4c65fb7 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchPushHelper.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchPushHelper.java @@ -3,14 +3,10 @@ import android.content.Context; import android.os.Bundle; import androidx.annotation.Nullable; -import com.batch.android.core.FixedSizeArrayList; import com.batch.android.core.InternalPushData; import com.batch.android.core.Logger; -import com.batch.android.di.providers.ObjectUserPreferencesStorageProvider; import com.batch.android.module.PushModule; import com.google.firebase.messaging.RemoteMessage; -import java.util.ArrayList; -import java.util.Collections; import java.util.Map; /** @@ -21,27 +17,13 @@ */ public class BatchPushHelper { - private static final String ALREADY_SHOWN_IDS_STORAGE_KEY = "push_already_shown"; - private static final int ALREADY_SHOWN_IDS_SIZE = 20; - - // We also keep push id in RAM in case several pushs are received simultaneously - private static final ArrayList beingShownIds = new ArrayList<>(ALREADY_SHOWN_IDS_SIZE); - /** - * Internal method + * This method checks: + * - If this notification is for the current Install ID (if available) + * + * It used to do other stuff as in deduplicate notifications but that's been reworked. */ - public static synchronized boolean isPushValid(Context context, InternalPushData batchData) { - /* - * Check push ID - */ - String pushId = batchData.getPushId(); - if (pushId != null && beingShownIds.contains(pushId)) { - Logger.warning(PushModule.TAG, "Already shown notification[" + pushId + "], aborting"); - return false; - } else if (pushId != null) { - beingShownIds.add(pushId); - } - + public static synchronized boolean canDisplayPush(Context context, InternalPushData batchData) { /* * Check install ID */ @@ -49,7 +31,11 @@ public static synchronized boolean isPushValid(Context context, InternalPushData if (installId != null && !installIDMatchesCurrent(context, installId)) { Logger.warning( PushModule.TAG, - "Received notification[" + pushId + "] for another install id[" + installId + "], aborting" + "Received notification[" + + batchData.getPushId() + + "] for another install id[" + + installId + + "], aborting" ); return false; } @@ -57,26 +43,6 @@ public static synchronized boolean isPushValid(Context context, InternalPushData return true; } - /** - * Internal method - */ - public static synchronized void markPushAsShown(Context context, String pushId) { - if (pushId == null) { - return; - } - - FixedSizeArrayList alreadyShownIds = getShownPushIds(context); - alreadyShownIds.add(pushId); - if ( - !ObjectUserPreferencesStorageProvider.get(context).persist(ALREADY_SHOWN_IDS_STORAGE_KEY, alreadyShownIds) - ) { - Logger.internal(PushModule.TAG, "Error while saving already shown push ids"); - } - - // We remove all occurrences of the id in RAM - BatchPushHelper.beingShownIds.removeAll(Collections.singletonList(pushId)); - } - /** * Convert a Firebase RemoteMessage to a bundle, for compatibility with all the methods that used * to deal with a BroadcastReceiver started by GCM @@ -99,43 +65,6 @@ public static Bundle firebaseMessageToReceiverBundle(@Nullable RemoteMessage mes return retVal; } - /** - * Check if the push has been shown - * - * @param context - * @param pushId - * @return true if the push has already been shown - */ - static boolean isPushAlreadyShown(Context context, String pushId) { - return getShownPushIds(context).contains(pushId); - } - - /** - * Get shown push ids array - * - * @param context - * @return - */ - @SuppressWarnings("unchecked") - private static FixedSizeArrayList getShownPushIds(Context context) { - FixedSizeArrayList alreadyShownIds = null; - try { - Object storedIds = ObjectUserPreferencesStorageProvider.get(context).get(ALREADY_SHOWN_IDS_STORAGE_KEY); - if (storedIds != null) { - alreadyShownIds = (FixedSizeArrayList) storedIds; - } - } catch (Exception e) { - Logger.internal(PushModule.TAG, "Error while reading stored ids", e); - } - - // If nothing found, just create a new array - if (alreadyShownIds == null) { - alreadyShownIds = new FixedSizeArrayList<>(ALREADY_SHOWN_IDS_SIZE); - } - - return alreadyShownIds; - } - /** * Is the given install id mine * diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchPushJobService.java b/Sources/sdk/src/main/java/com/batch/android/BatchPushJobService.java index 729d48c..b7f5c76 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchPushJobService.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchPushJobService.java @@ -43,7 +43,8 @@ public boolean onStartJob(final JobParameters jobParameters) { @Override public boolean onStopJob(JobParameters jobParameters) { - return true; + Logger.internal(TAG, "onStopJob"); + return false; } private static class PresentPushTask extends AsyncTask { diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchPushMessageReceiver.java b/Sources/sdk/src/main/java/com/batch/android/BatchPushMessageReceiver.java index f1faa6c..2616b19 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchPushMessageReceiver.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchPushMessageReceiver.java @@ -1,80 +1,204 @@ package com.batch.android; +import android.Manifest; +import android.annotation.SuppressLint; import android.app.job.JobInfo; import android.app.job.JobScheduler; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.VisibleForTesting; import com.batch.android.annotation.PublicSDK; import com.batch.android.compat.WakefulBroadcastReceiver; -import com.batch.android.core.JobHelper; +import com.batch.android.core.GenericHelper; import com.batch.android.core.Logger; +import java.util.ArrayDeque; /** - * Batch's implementation of GCM's Push BroadcastReceiver - * + * Batch's implementation of FCM's Push BroadcastReceiver */ @PublicSDK public class BatchPushMessageReceiver extends WakefulBroadcastReceiver { private static final String TAG = "BatchPushMessageReceiver"; + @VisibleForTesting + static final int MAX_HANDLED_MESSAGE_IDS_COUNT = 30; + + // Keep a record of the last FCM message IDs we've handled, as it looks like FCM can send + // duplicate pushes. + // This is single threaded, no need to be careful about concurrent accesses + private static final ArrayDeque handledMessageIDs = new ArrayDeque<>(MAX_HANDLED_MESSAGE_IDS_COUNT); + @Override public void onReceive(Context context, Intent intent) { if (intent == null) { - Logger.internal(TAG, "null intent"); + Logger.internal(TAG, "null intent. Ignoring."); return; } - String msgType = intent.getStringExtra("message_type"); - if (msgType == null || "gcm".equalsIgnoreCase(msgType)) { - // Android O forbids us to directly start a service in the background, so use JobScheduler - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - try { - JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - if (scheduler == null) { - Logger.internal(TAG, "Could not get Job Scheduler system service"); - return; - } - - final Bundle intentExtras = intent.getExtras(); - if (intentExtras == null || intentExtras.isEmpty()) { - Logger.internal( - TAG, - "Intent extras were empty, not scheduling push notification presenter job" - ); - return; - } - - final Bundle jobExtras = new Bundle(); - jobExtras.putBundle(BatchPushJobService.JOB_EXTRA_PUSH_DATA_KEY, intentExtras); - - JobInfo job = new JobInfo.Builder( - JobHelper.generateUniqueJobId(scheduler), - new ComponentName(context, BatchPushJobService.class) - ) - .setOverrideDeadline(3600000) // one hour - .setTransientExtras(jobExtras) - .build(); - - if (scheduler.schedule(job) == JobScheduler.RESULT_FAILURE) { - Logger.internal(TAG, "Failed to schedule the push notification presenter job"); - } else { - Logger.internal(TAG, "Successfully scheduled the push notification presenter job"); - } - } catch (JobHelper.GenerationException e) { - Logger.internal(TAG, "Could not find a suitable job ID", e); - } catch (Exception e1) { - Logger.internal(TAG, "Could schedule Batch push presentation job", e1); - } - } else { - // Explicitly specify that BatchPushService will handle the intent and start it. - ComponentName comp = new ComponentName(context.getPackageName(), BatchPushService.class.getName()); - startWakefulService(context, intent.setComponent(comp)); + if (isFCMMessage(intent)) { + final String messageID = getGoogleMessageID(intent); + if (isDuplicateMessage(messageID)) { + Logger.info(TAG, "Got a duplicate message_id from FCM, ignoring."); + return; + } + if (presentNotification(context, intent)) { + markMessageAsHandled(messageID); } } else { Logger.internal(TAG, "Intent was not a push message."); } } + + private boolean isFCMMessage(Intent intent) { + // FCM has multiple push types, which we should not handle + final String type = intent.getStringExtra("message_type"); + return type == null || "gcm".equalsIgnoreCase(type); + } + + @VisibleForTesting + protected boolean presentNotification(@NonNull Context context, @NonNull Intent intent) { + // This method will try to avoid starting a job if possible to avoid potential delays + // in notification display. Up to a certain frequency, high priority FCM messages should go + // into that "fast path". + + // High priority FCM pushes have the RECEIVER_FOREGROUND flag. If it is missing, we can skip + // trying to start a normal service on O and start a Job. + @SuppressLint("InlinedApi") + boolean isHighPriorityPush = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; + + // If we're on Android O and a normal priority push, start a Job, startService is guaranteed + // to fail. + if (!isHighPriorityPush && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Logger.internal(TAG, "Normal priority notification: scheduling a Job"); + return scheduleJob(context, intent); + } else { + // We're either on a high priority push or on an old Android version, start service directly. + // This can happen for multiple reasons: + // - User has forced background restrictions + // - FCM's temporary restriction exclusion has already expired + // - Something else failed + // Fallback on a Job if possible + Logger.internal(TAG, "High priority notification/legacy Android: starting service"); + try { + startPresentationService(context, intent); + return true; + } catch (IllegalStateException e) { + // This exception can happen on Android O, fallback on scheduling a Job. + // On earlier Android versions, it should not happen. + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Logger.internal(TAG, "Failed to start service, scheduling Job"); + return scheduleJob(context, intent); + } else { + Logger.error(TAG, "Could not start notification presentation service:", e); + return false; + } + } + } + } + + @RequiresApi(Build.VERSION_CODES.O) + private boolean scheduleJob(@NonNull Context context, @NonNull Intent intent) { + try { + JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + if (scheduler == null) { + Logger.internal(TAG, "Could not get Job Scheduler system service"); + return false; + } + + final Bundle intentExtras = intent.getExtras(); + if (intentExtras == null || intentExtras.isEmpty()) { + Logger.internal(TAG, "Intent extras were empty, not scheduling push notification presenter job"); + return false; + } + + final Bundle jobExtras = new Bundle(); + jobExtras.putBundle(BatchPushJobService.JOB_EXTRA_PUSH_DATA_KEY, intentExtras); + int jobId = (int) (Math.random() * Integer.MAX_VALUE); + JobInfo job = new JobInfo.Builder(jobId, new ComponentName(context, BatchPushJobService.class)) + .setOverrideDeadline(3600000) // one hour + .setTransientExtras(jobExtras) + .build(); + + if (scheduler.schedule(job) == JobScheduler.RESULT_FAILURE) { + Logger.internal(TAG, "Failed to schedule the push notification presenter job"); + return false; + } + + Logger.internal(TAG, "Successfully scheduled the push notification presenter job"); + return true; + } catch (Exception e1) { + Logger.internal(TAG, "Could schedule Batch push presentation job", e1); + } + return false; + } + + private void startPresentationService(@NonNull Context context, @NonNull Intent intent) { + // Explicitly specify that BatchPushService will handle the intent and start it. + ComponentName comp = new ComponentName(context.getPackageName(), BatchPushService.class.getName()); + if (GenericHelper.isWakeLockPermissionAvailable(context)) { + startWakefulService(context, intent.setComponent(comp)); + } else { + context.startService(intent.setComponent(comp)); + } + } + + private boolean isDuplicateMessage(@Nullable String msgID) { + // Can't deduplicate a message ID if we do not have one + if (msgID == null) { + return false; + } + + return handledMessageIDs.contains(msgID); + } + + private void markMessageAsHandled(@Nullable String msgID) { + if (msgID == null) { + return; + } + + handledMessageIDs.add(msgID); + if (handledMessageIDs.size() > MAX_HANDLED_MESSAGE_IDS_COUNT) { + handledMessageIDs.pollFirst(); + } + } + + // Extract the Firebase Message identifier from the payload + @Nullable + private String getGoogleMessageID(@NonNull Intent intent) { + // GCM apparently can use both keys to store the message ID. + // The google. key can't be controlled via the custom payload, not sure about + // message ID. + // FCM checks for both, so do the same. + final String googleMessageID = intent.getStringExtra("google.message_id"); + if (!TextUtils.isEmpty(googleMessageID)) { + return googleMessageID; + } + + final String messageID = intent.getStringExtra("message_id"); + if (!TextUtils.isEmpty(messageID)) { + return messageID; + } + + return null; + } + + @VisibleForTesting + static int getHandledMessageIDsSize() { + return handledMessageIDs.size(); + } + + @VisibleForTesting + static void resetHandledMessageIDs() { + handledMessageIDs.clear(); + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchPushNotificationPresenter.java b/Sources/sdk/src/main/java/com/batch/android/BatchPushNotificationPresenter.java index a090172..e224048 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchPushNotificationPresenter.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchPushNotificationPresenter.java @@ -172,7 +172,7 @@ public static void presentNotification( ApplicationInfo appInfo = context.getApplicationInfo(); - if (!BatchPushHelper.isPushValid(context, batchData)) { + if (!BatchPushHelper.canDisplayPush(context, batchData)) { return; } @@ -221,7 +221,7 @@ public static void presentNotification( //TODO: Figure out a better place to register the channel (not on every notification display...) // Problem is that we have to do it here in case the app gets updated, and we never get the context when // set up in Application - batchChannelsManager.registerBatchChannelIfNeeded(context); + batchChannelsManager.registerBatchChannelIfNeeded(context, false); /* * Small icon @@ -377,6 +377,7 @@ public static void presentNotification( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { userFlags = userFlags | PendingIntent.FLAG_IMMUTABLE; } + //noinspection WrongConstant launchIntent.addFlags(userFlags); } } @@ -544,9 +545,6 @@ public static void presentNotification( } else { Logger.info("Batch.Push: notification can't be displayed, skipping event dispatcher..."); } - - // The push has been shown, make it as such - BatchPushHelper.markPushAsShown(context, pushId); } /** @@ -599,8 +597,6 @@ private static boolean trySendLandingToForegroundApp(Context context, Bundle ext MessagingModuleProvider .get() .displayMessage(context, new BatchLandingMessage(extras, messageJSON), false); - // A push that's a mobile landing is considered shown - BatchPushHelper.markPushAsShown(context, batchData.getPushId()); return true; } } catch (PayloadParsingException | JSONException e) { diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchPushService.java b/Sources/sdk/src/main/java/com/batch/android/BatchPushService.java index ee0c198..68f0bbd 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchPushService.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchPushService.java @@ -8,7 +8,8 @@ /** * Batch's service for handling the push messages and show a notification *

- * This is a legacy implementation, and should not be used on versions higher than Android O + * This can be used on Android O, if eligibility has been verified beforehand and startService + * exceptions are handled. * */ @PublicSDK diff --git a/Sources/sdk/src/main/java/com/batch/android/BatchWebservice.java b/Sources/sdk/src/main/java/com/batch/android/BatchWebservice.java index 8b9dd30..fe3d982 100644 --- a/Sources/sdk/src/main/java/com/batch/android/BatchWebservice.java +++ b/Sources/sdk/src/main/java/com/batch/android/BatchWebservice.java @@ -7,12 +7,9 @@ import com.batch.android.core.ParameterKeys; import com.batch.android.core.Parameters; import com.batch.android.core.SystemParameterHelper; -import com.batch.android.core.SystemParameterShortName; import com.batch.android.core.Webservice; import com.batch.android.core.WebserviceErrorCause; import com.batch.android.di.providers.ParametersProvider; -import com.batch.android.di.providers.PushModuleProvider; -import com.batch.android.di.providers.TrackerModuleProvider; import com.batch.android.di.providers.WebserviceMetricsProvider; import com.batch.android.json.JSONArray; import com.batch.android.json.JSONObject; @@ -21,7 +18,6 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.List; import java.util.Map; @@ -60,21 +56,6 @@ protected BatchWebservice(Context context, RequestType type, String baseURLForma // --------------------------------------> - /** - * Prepend the API Key into the url parameters - * - * @param parameters - * @return the same parameters with Batch key preprended - */ - private static String[] addBatchApiKey(String[] parameters) { - final String[] retParams = new String[parameters.length + 1]; - retParams[0] = Batch.getAPIKey(); - System.arraycopy(parameters, 0, retParams, 1, parameters.length); - return retParams; - } - - // --------------------------------------> - @Override protected void addDefaultHeaders() { super.addDefaultHeaders(); @@ -114,126 +95,7 @@ protected PostDataProvider getPostDataProvider() { /* * Build ids object */ - JSONObject ids = new JSONObject(); - - /* - * Add modules data - */ - try { - ids.put("m_e", TrackerModuleProvider.get().getState()); - ids.put("m_p", PushModuleProvider.get().getState()); - } catch (Exception e) { - Logger.internal(TAG, "Error while adding module parameters into parameters", e); - } - - /* - * Build all parameters - */ - String baseIdsParameterString = ParametersProvider - .get(applicationContext) - .get(ParameterKeys.WEBSERVICE_IDS_PARAMETERS); - String[] baseParameters; - if (!TextUtils.isEmpty(baseIdsParameterString)) { - baseParameters = baseIdsParameterString.split(","); - } else { - baseParameters = new String[] {}; - } - - String advancedIdsParameterString = ParametersProvider - .get(applicationContext) - .get(ParameterKeys.WEBSERVICE_IDS_ADVANCED_PARAMETERS); - String[] advancedParameters; - if (!TextUtils.isEmpty(advancedIdsParameterString) && Batch.shouldUseAdvancedDeviceInformation()) { - advancedParameters = advancedIdsParameterString.split(","); - } else { - advancedParameters = new String[] {}; - } - - String[] parameters; - - if (advancedParameters.length == 0) { - parameters = baseParameters; - } else if (baseParameters.length == 0) { - parameters = advancedParameters; - } else { - parameters = Arrays.copyOf(baseParameters, baseParameters.length + advancedParameters.length); - System.arraycopy(advancedParameters, 0, parameters, baseParameters.length, advancedParameters.length); - } - - for (String parameter : parameters) { - try { - if (SystemParameterShortName.INSTALL_ID.shortName.equals(parameter)) { - Install install = Batch.getInstall(); - String val = install.getInstallID(); - - if (val != null) { - ids.put(parameter, val); - } - } else if (SystemParameterShortName.DEVICE_INSTALL_DATE.shortName.equals(parameter)) { - Install install = Batch.getInstall(); - Date val = install.getInstallDate(); - - if (val != null) { - ids.put(parameter, Webservice.formatDate(val)); - } - } else if (SystemParameterShortName.SERVER_ID.shortName.equals(parameter)) { - String val = ParametersProvider.get(applicationContext).get(ParameterKeys.SERVER_ID_KEY); - if (val != null) { - ids.put(parameter, val); - } - } else if (SystemParameterShortName.SESSION_ID.shortName.equals(parameter)) { - String val = Batch.getSessionID(); - if (val != null) { - ids.put(parameter, val); - } - } else if (SystemParameterShortName.CUSTOM_USER_ID.shortName.equals(parameter)) { - User user = Batch.getUser(); - if (user != null) { - String customID = user.getCustomID(); - if (customID != null) { - ids.put(parameter, customID); - } - } - } else if (SystemParameterShortName.ADVERTISING_ID.shortName.equals(parameter)) { - if (Batch.shouldUseAdvertisingID()) { - AdvertisingID advertisingID = Batch.getAdvertisingID(); - if (advertisingID != null) { - boolean isIdfaAvailable = advertisingID.isReady() && advertisingID.isNotNull(); - if (isIdfaAvailable) { - ids.put(parameter, advertisingID.get()); - } - } - } - } else if (SystemParameterShortName.ADVERTISING_ID_OPTIN.shortName.equals(parameter)) { - AdvertisingID advertisingID = Batch.getAdvertisingID(); - if (advertisingID != null) { - boolean isIdfaAvailable = advertisingID.isReady(); - if (isIdfaAvailable) { - ids.put(parameter, !advertisingID.isLimited()); - } - } - } else if (SystemParameterShortName.BRIDGE_VERSION.shortName.equals(parameter)) { - String val = SystemParameterHelper.getBridgeVersion(); - - if (val != null && !val.isEmpty()) { - ids.put(parameter, val); - } - } else if (SystemParameterShortName.PLUGIN_VERSION.shortName.equals(parameter)) { - String val = SystemParameterHelper.getPluginVersion(); - - if (val != null && !val.isEmpty()) { - ids.put(parameter, val); - } - } else { - String val = SystemParameterHelper.getValue(parameter, applicationContext); - if (val != null) { - ids.put(parameter, val); - } - } - } catch (Exception e) { - Logger.internal(TAG, "Error while adding " + parameter + " post id", e); - } - } + JSONObject ids = WebserviceParameterUtils.getWebserviceIdsAsJson(applicationContext); /* * Add ids object to post params diff --git a/Sources/sdk/src/main/java/com/batch/android/DisplayReceiptWebservice.java b/Sources/sdk/src/main/java/com/batch/android/DisplayReceiptWebservice.java index ff53e15..19f7c23 100644 --- a/Sources/sdk/src/main/java/com/batch/android/DisplayReceiptWebservice.java +++ b/Sources/sdk/src/main/java/com/batch/android/DisplayReceiptWebservice.java @@ -2,32 +2,25 @@ import android.content.Context; import com.batch.android.core.Logger; +import com.batch.android.core.MessagePackWebservice; import com.batch.android.core.ParameterKeys; import com.batch.android.core.Parameters; import com.batch.android.core.TaskRunnable; -import com.batch.android.core.Webservice; -import com.batch.android.displayreceipt.DisplayReceipt; import com.batch.android.post.DisplayReceiptPostDataProvider; -import com.batch.android.post.PostDataProvider; import com.batch.android.webservice.listener.DisplayReceiptWebserviceListener; import java.net.MalformedURLException; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -class DisplayReceiptWebservice extends Webservice implements TaskRunnable { +class DisplayReceiptWebservice extends MessagePackWebservice implements TaskRunnable { private static final String TAG = "DisplayReceiptWebservice"; - private static final String MSGPACK_SCHEMA_VERSION = "1.0.0"; - private DisplayReceiptWebserviceListener listener; - private DisplayReceiptPostDataProvider dataProvider; - - // --------------------------------------> + private final DisplayReceiptWebserviceListener listener; /** - * @param context - * @param baseURLFormat an url to format with api key (ex : http://sample.com/%s/sample) + * @param context Android context + * @param listener + * @param dataProvider + * @param parameters * @throws MalformedURLException */ protected DisplayReceiptWebservice( @@ -36,58 +29,17 @@ protected DisplayReceiptWebservice( DisplayReceiptPostDataProvider dataProvider, String... parameters ) throws MalformedURLException { - super(context, RequestType.POST, Parameters.DISPLAY_RECEIPT_WS_URL, addSchemaVersion(parameters)); + super(context, dataProvider, Parameters.DISPLAY_RECEIPT_WS_URL, addSchemaVersion(parameters)); if (listener == null) { - throw new NullPointerException("listener==null"); - } - - if (dataProvider == null || dataProvider.isEmpty()) { - throw new NullPointerException("receipt provider is empty"); + throw new NullPointerException("Listener is null"); } - this.listener = listener; - this.dataProvider = dataProvider; - } - - // --------------------------------------> - - /** - * Prepend the schema version into the url parameters - * - * @param parameters - * @return - */ - private static String[] addSchemaVersion(String[] parameters) { - final String[] retParams = new String[parameters.length + 1]; - retParams[0] = MSGPACK_SCHEMA_VERSION; - System.arraycopy(parameters, 0, retParams, 1, parameters.length); - return retParams; - } - - @Override - protected Map getHeaders() { - HashMap header = new HashMap<>(); - header.put("x-batch-protocol-version", MSGPACK_SCHEMA_VERSION); - header.put("x-batch-sdk-version", Parameters.SDK_VERSION); - return header; - } - - @Override - protected PostDataProvider> getPostDataProvider() { - return dataProvider; - } - - // --------------------------------------> - - @Override - public String getTaskIdentifier() { - return "Batch/receiptws"; } @Override public void run() { try { - Logger.internal(TAG, "display receipt webservice started"); + Logger.internal(TAG, "Webservice started"); executeRequest(); listener.onSuccess(); } catch (WebserviceError error) { @@ -95,11 +47,9 @@ public void run() { } } - // -----------------------------------------> - @Override - protected String getURLSorterPatternParameterKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_URLSORTER_PATTERN_KEY; + public String getTaskIdentifier() { + return "Batch/receiptws"; } @Override @@ -107,31 +57,6 @@ protected String getCryptorTypeParameterKey() { return ParameterKeys.DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY; } - @Override - protected String getCryptorModeParameterKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_CRYPTORMODE_KEY; - } - - @Override - protected String getPostCryptorTypeParameterKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_POST_CRYPTORTYPE_KEY; - } - - @Override - protected String getReadCryptorTypeParameterKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_READ_CRYPTORTYPE_KEY; - } - - @Override - protected String getSpecificConnectTimeoutKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_CONNECT_TIMEOUT_KEY; - } - - @Override - protected String getSpecificReadTimeoutKey() { - return ParameterKeys.DISPLAY_RECEIPT_WS_READ_TIMEOUT_KEY; - } - @Override protected String getSpecificRetryCountKey() { return ParameterKeys.DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY; diff --git a/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsJITWebservice.java b/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsJITWebservice.java new file mode 100644 index 0000000..c75a55c --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsJITWebservice.java @@ -0,0 +1,75 @@ +package com.batch.android; + +import android.content.Context; +import com.batch.android.core.Logger; +import com.batch.android.core.MessagePackWebservice; +import com.batch.android.core.ParameterKeys; +import com.batch.android.core.Parameters; +import com.batch.android.core.TaskRunnable; +import com.batch.android.metrics.MetricRegistry; +import com.batch.android.post.LocalCampaignsJITPostDataProvider; +import com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener; +import java.net.MalformedURLException; +import java.util.List; + +class LocalCampaignsJITWebservice extends MessagePackWebservice implements TaskRunnable { + + private static final String TAG = "LocalCampaignsJITWebservice"; + + /** + * Web service callback + */ + private final LocalCampaignsJITWebserviceListener listener; + + protected LocalCampaignsJITWebservice( + Context context, + LocalCampaignsJITWebserviceListener listener, + LocalCampaignsJITPostDataProvider dataProvider, + String... parameters + ) throws MalformedURLException { + super(context, dataProvider, Parameters.LOCAL_CAMPAIGNS_JIT_WS_URL, addBatchApiKey(parameters)); + if (listener == null) { + throw new NullPointerException("Listener is null"); + } + this.listener = listener; + } + + @Override + public String getTaskIdentifier() { + return "Batch/localcampaignsjitws"; + } + + @Override + public void run() { + Logger.internal(TAG, "Webservice started"); + MetricRegistry.localCampaignsJITResponseTime.startTimer(); + try { + byte[] response = executeRequest(); + MetricRegistry.localCampaignsJITResponseTime.observeDuration(); + MetricRegistry.localCampaignsJITCount.labels("OK").inc(); + LocalCampaignsJITPostDataProvider dataProvider = (LocalCampaignsJITPostDataProvider) getPostDataProvider(); + List eligibleCampaigns = dataProvider.unpack(response); + this.listener.onSuccess(eligibleCampaigns); + } catch (WebserviceError error) { + MetricRegistry.localCampaignsJITResponseTime.observeDuration(); + MetricRegistry.localCampaignsJITCount.labels("KO").inc(); + Logger.internal(TAG, error.getReason().toString(), error.getCause()); + this.listener.onFailure(error); + } + } + + @Override + protected String getSpecificConnectTimeoutKey() { + return ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_CONNECT_TIMEOUT_KEY; + } + + @Override + protected String getSpecificReadTimeoutKey() { + return ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_READ_TIMEOUT_KEY; + } + + @Override + protected String getSpecificRetryCountKey() { + return ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_RETRYCOUNT_KEY; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsWebservice.java b/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsWebservice.java index 75daa3d..c9e2535 100644 --- a/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsWebservice.java +++ b/Sources/sdk/src/main/java/com/batch/android/LocalCampaignsWebservice.java @@ -7,6 +7,7 @@ import com.batch.android.core.TaskRunnable; import com.batch.android.di.providers.CampaignManagerProvider; import com.batch.android.json.JSONObject; +import com.batch.android.metrics.MetricRegistry; import com.batch.android.query.LocalCampaignsQuery; import com.batch.android.query.Query; import com.batch.android.query.QueryType; @@ -15,7 +16,6 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; /** * Webservice to ask the server for all type of local campaigns (be in-app or notification) @@ -55,13 +55,14 @@ public void run() { try { Logger.internal(TAG, "local campaigns webservice started"); webserviceMetrics.onWebserviceStarted(this); - + MetricRegistry.localCampaignsSyncResponseTime.startTimer(); /* * Read response */ JSONObject response = null; try { response = getStandardResponseBodyIfValid(); + MetricRegistry.localCampaignsSyncResponseTime.observeDuration(); webserviceMetrics.onWebserviceFinished(this, true); } catch (WebserviceError error) { Logger.internal( @@ -69,6 +70,7 @@ public void run() { "Error while getting local campaigns list : " + error.getReason().toString(), error.getCause() ); + MetricRegistry.localCampaignsSyncResponseTime.observeDuration(); webserviceMetrics.onWebserviceFinished(this, false); switch (error.getReason()) { @@ -85,7 +87,6 @@ public void run() { listener.onError(FailReason.UNEXPECTED_ERROR); break; } - return; } @@ -116,9 +117,7 @@ public void run() { CampaignManagerProvider.get().deleteSavedCampaignsAsync(applicationContext); } else { // else we save them - CampaignManagerProvider - .get() - .saveCampaignsAsync(applicationContext, localCampaignsResponse.getCampaignsToSave()); + CampaignManagerProvider.get().saveCampaignsAsync(applicationContext, localCampaignsResponse); responses.add(localCampaignsResponse); } } else { diff --git a/Sources/sdk/src/main/java/com/batch/android/MetricWebservice.java b/Sources/sdk/src/main/java/com/batch/android/MetricWebservice.java new file mode 100644 index 0000000..7ea9773 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/MetricWebservice.java @@ -0,0 +1,52 @@ +package com.batch.android; + +import android.content.Context; +import com.batch.android.core.Logger; +import com.batch.android.core.MessagePackWebservice; +import com.batch.android.core.ParameterKeys; +import com.batch.android.core.Parameters; +import com.batch.android.core.TaskRunnable; +import com.batch.android.post.MetricPostDataProvider; +import com.batch.android.webservice.listener.MetricWebserviceListener; +import java.net.MalformedURLException; + +class MetricWebservice extends MessagePackWebservice implements TaskRunnable { + + private static final String TAG = "MetricWebservice"; + + private final MetricWebserviceListener listener; + + protected MetricWebservice( + Context context, + MetricWebserviceListener listener, + MetricPostDataProvider dataProvider, + String... parameters + ) throws MalformedURLException { + super(context, dataProvider, Parameters.METRIC_WS_URL, parameters); + if (listener == null) { + throw new NullPointerException("Listener is null"); + } + this.listener = listener; + } + + @Override + public void run() { + Logger.internal(TAG, "Webservice started"); + try { + executeRequest(); + this.listener.onSuccess(); + } catch (WebserviceError error) { + this.listener.onFailure(error); + } + } + + @Override + public String getTaskIdentifier() { + return "Batch/metricsws"; + } + + @Override + protected String getSpecificRetryCountKey() { + return ParameterKeys.METRIC_WS_RETRYCOUNT_KEY; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/WebserviceLauncher.java b/Sources/sdk/src/main/java/com/batch/android/WebserviceLauncher.java index 8304a19..3412af4 100644 --- a/Sources/sdk/src/main/java/com/batch/android/WebserviceLauncher.java +++ b/Sources/sdk/src/main/java/com/batch/android/WebserviceLauncher.java @@ -7,10 +7,15 @@ import com.batch.android.di.providers.LocalCampaignsWebserviceListenerImplProvider; import com.batch.android.di.providers.TaskExecutorProvider; import com.batch.android.event.Event; +import com.batch.android.localcampaigns.model.LocalCampaign; import com.batch.android.post.DisplayReceiptPostDataProvider; +import com.batch.android.post.LocalCampaignsJITPostDataProvider; +import com.batch.android.post.MetricPostDataProvider; import com.batch.android.push.Registration; import com.batch.android.runtime.RuntimeManager; import com.batch.android.webservice.listener.DisplayReceiptWebserviceListener; +import com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener; +import com.batch.android.webservice.listener.MetricWebserviceListener; import com.batch.android.webservice.listener.TrackerWebserviceListener; import com.batch.android.webservice.listener.impl.AttributesCheckWebserviceListenerImpl; import com.batch.android.webservice.listener.impl.AttributesSendWebserviceListenerImpl; @@ -119,6 +124,27 @@ public static TaskRunnable initOptOutTrackerWebservice( } } + /** + * Create an instance of the metrics webservice and return the runnable + * + * @param context android context + * @param dataProvider provider + * @param listener listener + * @return instance of the webservice ready to be run + */ + public static TaskRunnable initMetricWebservice( + Context context, + MetricPostDataProvider dataProvider, + MetricWebserviceListener listener + ) { + try { + return new MetricWebservice(context, listener, dataProvider); + } catch (Exception e) { + Logger.internal(TAG, "Error while initializing metrics webservice", e); + return null; + } + } + /** * Launch the push webservice */ @@ -200,4 +226,21 @@ public static boolean launchLocalCampaignsWebservice(RuntimeManager runtimeManag return false; } } + + public static boolean launchLocalCampaignsJITWebservice( + RuntimeManager runtimeManager, + List campaigns, + LocalCampaignsJITWebserviceListener listener + ) { + LocalCampaignsJITPostDataProvider dataProvider = new LocalCampaignsJITPostDataProvider(campaigns); + try { + TaskExecutorProvider + .get(runtimeManager.getContext()) + .submit(new LocalCampaignsJITWebservice(runtimeManager.getContext(), listener, dataProvider)); + return true; + } catch (Exception e) { + Logger.internal(TAG, "Error while initializing Local Campaigns JIT WS", e); + return false; + } + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/WebserviceParameterUtils.java b/Sources/sdk/src/main/java/com/batch/android/WebserviceParameterUtils.java new file mode 100644 index 0000000..0628a04 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/WebserviceParameterUtils.java @@ -0,0 +1,174 @@ +package com.batch.android; + +import android.content.Context; +import android.text.TextUtils; +import androidx.annotation.NonNull; +import com.batch.android.core.Logger; +import com.batch.android.core.ParameterKeys; +import com.batch.android.core.SystemParameterHelper; +import com.batch.android.core.SystemParameterShortName; +import com.batch.android.core.Webservice; +import com.batch.android.di.providers.ParametersProvider; +import com.batch.android.di.providers.PushModuleProvider; +import com.batch.android.di.providers.TrackerModuleProvider; +import com.batch.android.json.JSONObject; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class to easily get webservice parameters + */ +public class WebserviceParameterUtils { + + private static final String TAG = "WebserviceParameterUtils"; + + /** + * Get webservice ids parameters as map + * @param context context + * @return A Map of parameters to attach in a webservice + */ + public static Map getWebserviceIdsAsMap(Context context) { + return buildIds(context); + } + + /** + * Get webservice ids parameters as json object + * @param context context + * @return A JSONObject of parameters to attach in a webservice + */ + public static JSONObject getWebserviceIdsAsJson(Context context) { + return new JSONObject(buildIds(context)); + } + + /** + * Build ids + * @param context context + * @return map of ids + */ + private static Map buildIds(@NonNull Context context) { + /* + * Build ids object + */ + Map ids = new HashMap<>(); + + /* + * Add modules data + */ + try { + ids.put("m_e", TrackerModuleProvider.get().getState()); + ids.put("m_p", PushModuleProvider.get().getState()); + } catch (Exception e) { + Logger.internal(TAG, "Error while adding module parameters into parameters", e); + } + + /* + * Build all parameters + */ + String baseIdsParameterString = ParametersProvider.get(context).get(ParameterKeys.WEBSERVICE_IDS_PARAMETERS); + String[] baseParameters; + if (!TextUtils.isEmpty(baseIdsParameterString)) { + baseParameters = baseIdsParameterString.split(","); + } else { + baseParameters = new String[] {}; + } + + String advancedIdsParameterString = ParametersProvider + .get(context) + .get(ParameterKeys.WEBSERVICE_IDS_ADVANCED_PARAMETERS); + String[] advancedParameters; + if (!TextUtils.isEmpty(advancedIdsParameterString) && Batch.shouldUseAdvancedDeviceInformation()) { + advancedParameters = advancedIdsParameterString.split(","); + } else { + advancedParameters = new String[] {}; + } + + String[] parameters; + + if (advancedParameters.length == 0) { + parameters = baseParameters; + } else if (baseParameters.length == 0) { + parameters = advancedParameters; + } else { + parameters = Arrays.copyOf(baseParameters, baseParameters.length + advancedParameters.length); + System.arraycopy(advancedParameters, 0, parameters, baseParameters.length, advancedParameters.length); + } + + for (String parameter : parameters) { + try { + if (SystemParameterShortName.INSTALL_ID.shortName.equals(parameter)) { + Install install = Batch.getInstall(); + String val = install.getInstallID(); + + if (val != null) { + ids.put(parameter, val); + } + } else if (SystemParameterShortName.DEVICE_INSTALL_DATE.shortName.equals(parameter)) { + Install install = Batch.getInstall(); + Date val = install.getInstallDate(); + + if (val != null) { + ids.put(parameter, Webservice.formatDate(val)); + } + } else if (SystemParameterShortName.SERVER_ID.shortName.equals(parameter)) { + String val = ParametersProvider.get(context).get(ParameterKeys.SERVER_ID_KEY); + if (val != null) { + ids.put(parameter, val); + } + } else if (SystemParameterShortName.SESSION_ID.shortName.equals(parameter)) { + String val = Batch.getSessionID(); + if (val != null) { + ids.put(parameter, val); + } + } else if (SystemParameterShortName.CUSTOM_USER_ID.shortName.equals(parameter)) { + User user = Batch.getUser(); + if (user != null) { + String customID = user.getCustomID(); + if (customID != null) { + ids.put(parameter, customID); + } + } + } else if (SystemParameterShortName.ADVERTISING_ID.shortName.equals(parameter)) { + if (Batch.shouldUseAdvertisingID()) { + AdvertisingID advertisingID = Batch.getAdvertisingID(); + if (advertisingID != null) { + boolean isIdfaAvailable = advertisingID.isReady() && advertisingID.isNotNull(); + if (isIdfaAvailable) { + ids.put(parameter, advertisingID.get()); + } + } + } + } else if (SystemParameterShortName.ADVERTISING_ID_OPTIN.shortName.equals(parameter)) { + AdvertisingID advertisingID = Batch.getAdvertisingID(); + if (advertisingID != null) { + boolean isIdfaAvailable = advertisingID.isReady(); + if (isIdfaAvailable) { + ids.put(parameter, !advertisingID.isLimited()); + } + } + } else if (SystemParameterShortName.BRIDGE_VERSION.shortName.equals(parameter)) { + String val = SystemParameterHelper.getBridgeVersion(); + + if (val != null && !val.isEmpty()) { + ids.put(parameter, val); + } + } else if (SystemParameterShortName.PLUGIN_VERSION.shortName.equals(parameter)) { + String val = SystemParameterHelper.getPluginVersion(); + + if (val != null && !val.isEmpty()) { + ids.put(parameter, val); + } + } else { + String val = SystemParameterHelper.getValue(parameter, context); + if (val != null) { + ids.put(parameter, val); + } + } + } catch (Exception e) { + Logger.internal(TAG, "Error while adding " + parameter + " post id", e); + } + } + return ids; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/actions/ClipboardActionRunnable.java b/Sources/sdk/src/main/java/com/batch/android/actions/ClipboardActionRunnable.java index 181aa22..6844046 100644 --- a/Sources/sdk/src/main/java/com/batch/android/actions/ClipboardActionRunnable.java +++ b/Sources/sdk/src/main/java/com/batch/android/actions/ClipboardActionRunnable.java @@ -18,6 +18,8 @@ public class ClipboardActionRunnable implements UserActionRunnable { private static final String TAG = "ClipboardBuiltinAction"; + private static final String BASE_ERROR_MSG = "Could not perform clipboard action: "; + public static final String IDENTIFIER = ActionModule.RESERVED_ACTION_IDENTIFIER_PREFIX + "clipboard"; @Override @@ -27,10 +29,15 @@ public void performAction( @NonNull JSONObject args, @Nullable UserActionSource source ) { + if (context == null) { + Logger.internal(TAG, BASE_ERROR_MSG + "no context."); + return; + } + try { String text = args.getString("t"); if (text == null) { - Logger.internal(TAG, "Could not perform clipboard action : text's null"); + Logger.internal(TAG, BASE_ERROR_MSG + "text's null."); return; } String description = args.optString("d", "text"); diff --git a/Sources/sdk/src/main/java/com/batch/android/actions/NotificationPermissionActionRunnable.java b/Sources/sdk/src/main/java/com/batch/android/actions/NotificationPermissionActionRunnable.java new file mode 100644 index 0000000..c347b2e --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/actions/NotificationPermissionActionRunnable.java @@ -0,0 +1,44 @@ +package com.batch.android.actions; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.batch.android.UserActionRunnable; +import com.batch.android.UserActionSource; +import com.batch.android.core.Logger; +import com.batch.android.core.NotificationPermissionHelper; +import com.batch.android.json.JSONObject; +import com.batch.android.module.ActionModule; + +public class NotificationPermissionActionRunnable implements UserActionRunnable { + + private static final String TAG = "NotificationPermissionAction"; + public static final String IDENTIFIER = + ActionModule.RESERVED_ACTION_IDENTIFIER_PREFIX + "android_request_notifications"; + + @Override + public void performAction( + @Nullable Context context, + @NonNull String identifier, + @NonNull JSONObject args, + @Nullable UserActionSource source + ) { + if (context == null) { + Logger.error(TAG, "Tried to perform a notif. permission request action, but no context was available"); + return; + } + + final NotificationPermissionHelper notificationPermissionHelper = new NotificationPermissionHelper(); + notificationPermissionHelper.experimentalUseChannelCreationOnOldTargets = + args.reallyOptBoolean( + "_useChannel", + notificationPermissionHelper.experimentalUseChannelCreationOnOldTargets + ); + notificationPermissionHelper.experimentalForceChannelCreation = + args.reallyOptBoolean( + "_forceChannelCreation", + notificationPermissionHelper.experimentalForceChannelCreation + ); + notificationPermissionHelper.requestPermission(context); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/core/GenericHelper.java b/Sources/sdk/src/main/java/com/batch/android/core/GenericHelper.java index 2141439..57ea515 100644 --- a/Sources/sdk/src/main/java/com/batch/android/core/GenericHelper.java +++ b/Sources/sdk/src/main/java/com/batch/android/core/GenericHelper.java @@ -3,8 +3,10 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.os.Build; import android.util.DisplayMetrics; import android.view.WindowManager; +import androidx.annotation.NonNull; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Locale; @@ -27,6 +29,27 @@ public static boolean checkPermission(String permission, Context context) { return (res == PackageManager.PERMISSION_GRANTED); } + public static boolean isWakeLockPermissionAvailable(@NonNull Context context) { + try { + return GenericHelper.checkPermission("android.permission.WAKE_LOCK", context); + } catch (Exception e) { + Logger.error("Error while checking android.permission.WAKE_LOCK permission", e); + return false; + } + } + + public static boolean targets12LOrOlder(@NonNull Context context) { + // Note: any prerelease Android SDK, even older than 13, will return true here. + // We do not care about that edge case. + try { + int targetSdkVersion = context.getApplicationContext().getApplicationInfo().targetSdkVersion; + return targetSdkVersion <= Build.VERSION_CODES.S_V2; + } catch (Exception e) { + Logger.error("Could not check current target API level", e); + return true; + } + } + /** * Read the MD5 of a content * diff --git a/Sources/sdk/src/main/java/com/batch/android/core/JobHelper.java b/Sources/sdk/src/main/java/com/batch/android/core/JobHelper.java deleted file mode 100644 index 64b9d73..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/core/JobHelper.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.batch.android.core; - -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; -import java.util.List; - -/** - * Simple helper for Android 21+ Jobs - */ - -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) -public class JobHelper { - - private static final int MAX_GENERATION_ATTEMPTS = 20; - - public static synchronized int generateUniqueJobId(@NonNull JobScheduler scheduler) throws GenerationException { - // Consider letting developers override this - int generatedId; - - for (int attempts = 0; attempts <= MAX_GENERATION_ATTEMPTS; attempts++) { - generatedId = (int) (Math.random() * Integer.MAX_VALUE); - - if (!jobListContainsJobId(scheduler.getAllPendingJobs(), generatedId)) { - return generatedId; - } - } - - throw new GenerationException("Could not generate an unique id: attempts exhausted"); - } - - private static boolean jobListContainsJobId(List jobList, int jobId) { - if (jobList == null || jobList.size() == 0) { - return false; - } - - for (JobInfo job : jobList) { - if (job.getId() == jobId) { - return true; - } - } - - return false; - } - - public static class GenerationException extends Exception { - - public GenerationException(String message) { - super(message); - } - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/core/MessagePackWebservice.java b/Sources/sdk/src/main/java/com/batch/android/core/MessagePackWebservice.java new file mode 100644 index 0000000..bae766a --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/core/MessagePackWebservice.java @@ -0,0 +1,94 @@ +package com.batch.android.core; + +import android.content.Context; +import com.batch.android.post.MessagePackPostDataProvider; +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.Map; + +public abstract class MessagePackWebservice extends Webservice implements TaskRunnable { + + private static final String MSGPACK_SCHEMA_VERSION = "1.0.0"; + + private final MessagePackPostDataProvider dataProvider; + + protected MessagePackWebservice( + Context context, + MessagePackPostDataProvider dataProvider, + String urlPattern, + String... parameters + ) throws MalformedURLException { + super(context, RequestType.POST, urlPattern, parameters); + if (dataProvider == null || dataProvider.isEmpty()) { + throw new NullPointerException("Provider is empty"); + } + this.dataProvider = dataProvider; + } + + /** + * Prepend the schema version into the url parameters + * + * Only used for display receipt + * @param parameters parameters + * @return parameters + */ + protected static String[] addSchemaVersion(String[] parameters) { + final String[] retParams = new String[parameters.length + 1]; + retParams[0] = MSGPACK_SCHEMA_VERSION; + System.arraycopy(parameters, 0, retParams, 1, parameters.length); + return retParams; + } + + @Override + protected Map getHeaders() { + HashMap header = new HashMap<>(); + header.put("x-batch-protocol-version", MSGPACK_SCHEMA_VERSION); + header.put("x-batch-sdk-version", Parameters.SDK_VERSION); + return header; + } + + @Override + protected MessagePackPostDataProvider getPostDataProvider() { + return dataProvider; + } + + @Override + protected String getPostCryptorTypeParameterKey() { + return ParameterKeys.MESSAGE_PACK_WS_POST_CRYPTORTYPE_KEY; + } + + @Override + protected String getReadCryptorTypeParameterKey() { + return ParameterKeys.MESSAGE_PACK_WS_READ_CRYPTORTYPE_KEY; + } + + @Override + protected String getURLSorterPatternParameterKey() { + return ParameterKeys.MESSAGE_PACK_WS_URLSORTER_PATTERN_KEY; + } + + @Override + protected String getCryptorTypeParameterKey() { + return ParameterKeys.MESSAGE_PACK_WS_CRYPTORTYPE_KEY; + } + + @Override + protected String getCryptorModeParameterKey() { + return ParameterKeys.MESSAGE_PACK_WS_CRYPTORMODE_KEY; + } + + @Override + protected String getSpecificConnectTimeoutKey() { + return ParameterKeys.MESSAGE_PACK_WS_CONNECT_TIMEOUT_KEY; + } + + @Override + protected String getSpecificReadTimeoutKey() { + return ParameterKeys.MESSAGE_PACK_WS_READ_TIMEOUT_KEY; + } + + @Override + protected String getSpecificRetryCountKey() { + return ParameterKeys.MESSAGE_PACK_WS_RETRYCOUNT_KEY; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/core/NotificationPermissionHelper.java b/Sources/sdk/src/main/java/com/batch/android/core/NotificationPermissionHelper.java new file mode 100644 index 0000000..bc2da73 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/core/NotificationPermissionHelper.java @@ -0,0 +1,99 @@ +package com.batch.android.core; + +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; +import androidx.annotation.NonNull; +import com.batch.android.BatchNotificationChannelsManagerPrivateHelper; +import com.batch.android.di.providers.BatchNotificationChannelsManagerProvider; + +public class NotificationPermissionHelper { + + private static final String TAG = "NotificationPermission"; + private static final String BASE_TARGET_LOG_MESSAGE = "App is targeting Android "; + + public static final String PERMISSION_NOTIFICATION = "android.permission.POST_NOTIFICATIONS"; + + // This will be removed once T hits stable + // We want a bit of flexibility as we don't know what changes Google will make + public boolean experimentalUseChannelCreationOnOldTargets = false; + public boolean experimentalForceChannelCreation = false; + + public void requestPermission(@NonNull Context context) { + // TODO: Test this method. Can't be done until Android T is supported in Robolectric + Logger.internal(TAG, "Requesting notification permission."); + + // TODO: Do nothing on Android < 13. + // As of writing, Android T betas are API level 32 (same as 12L), so allow 12L to pass this check. + // We could implement a codename check but as calling this code on older Android does nothing, + // it's not worth the hassle. + // Note: if we want to implement a proper check, we could look at Build.VERSION.CODENAME == "Tiramisu" + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) { + return; + } + + if ( + context.getSystemService(NotificationManager.class).areNotificationsEnabled() && + GenericHelper.checkPermission(PERMISSION_NOTIFICATION, context) + ) { + Logger.internal(TAG, "Notifications are already enabled, not requesting permission."); + return; + } + + if (GenericHelper.targets12LOrOlder(context)) { + Logger.internal(TAG, BASE_TARGET_LOG_MESSAGE + "12L or lower."); + // Android documentation and Chromium sources + // say that you can't request the permission if you don't target T, but current testing + // shows otherwise: as long as the notification channel isn't created, an app that doesn't + // target android 13 can request the permission. Creating the channels shows the permission + // popup. So, by default + // + // Note: we allow the caller to bypass this and request the way docs say we should, with + // the caveat of it not working if the channel ID is overridden. + if (experimentalUseChannelCreationOnOldTargets) { + Logger.internal(TAG, "Requesting permission by creating channel."); + requestPermissionFromOlderSDK(context); + return; + } + } else { + Logger.internal(TAG, BASE_TARGET_LOG_MESSAGE + "13."); + } + + // Try to get the current activity + // We may already have one: in that case, calling getBaseContext() + // would make us lose it, don't call it blindly. + // On the other hand, androidx's ContextThemeWrapper is not a superclass of Activity + // so we need to call getBaseContext and hope to get it. + // Otherwise, give up, we might be able to find a context by looping but lets not go down + // that road just yet. + if (!(context instanceof Activity)) { + if (context instanceof androidx.appcompat.view.ContextThemeWrapper) { + context = ((androidx.appcompat.view.ContextThemeWrapper) context).getBaseContext(); + } else if (context instanceof android.view.ContextThemeWrapper) { + context = ((android.view.ContextThemeWrapper) context).getBaseContext(); + } + } + + if (context instanceof Activity) { + final Activity activity = (Activity) context; + activity.runOnUiThread(() -> { + activity.requestPermissions(new String[] { PERMISSION_NOTIFICATION }, 0); + }); + } else { + // Should we have a metric here? + Logger.internal(TAG, "Cannot request notification permission: no suitable context."); + } + } + + // Request the permission the google way: by creating the notification channel. + // Note: if the user has a channel id override, this will not work unless forced, which is also + // a controllable experiment. + public void requestPermissionFromOlderSDK(@NonNull Context context) { + BatchNotificationChannelsManagerPrivateHelper.registerBatchChannelIfNeeded( + BatchNotificationChannelsManagerProvider.get(), + context, + experimentalForceChannelCreation + ); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/core/ParameterKeys.java b/Sources/sdk/src/main/java/com/batch/android/core/ParameterKeys.java index 2d6ec79..ecd5410 100644 --- a/Sources/sdk/src/main/java/com/batch/android/core/ParameterKeys.java +++ b/Sources/sdk/src/main/java/com/batch/android/core/ParameterKeys.java @@ -84,17 +84,24 @@ public final class ParameterKeys public final static String INBOX_WS_CONNECT_TIMEOUT_KEY = "ws.inbox.connect.timeout"; public final static String INBOX_WS_READ_TIMEOUT_KEY = "ws.inbox.read.timeout"; - public final static String DISPLAY_RECEIPT_WS_URLSORTER_PATTERN_KEY = "ws.displayreceipt.pattern"; - public final static String DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY = "ws.displayreceipt.getcryptor.type"; - public final static String DISPLAY_RECEIPT_WS_CRYPTORMODE_KEY = "ws.displayreceipt.getcryptor.mode"; - public final static String DISPLAY_RECEIPT_WS_POST_CRYPTORTYPE_KEY = "ws.displayreceipt.postcryptor.type"; - public final static String DISPLAY_RECEIPT_WS_READ_CRYPTORTYPE_KEY = "ws.displayreceipt.readcryptor.type"; - public final static String DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY = "ws.displayreceipt.retry"; - public final static String DISPLAY_RECEIPT_WS_CONNECT_TIMEOUT_KEY = "ws.displayreceipt.connect.timeout"; - public final static String DISPLAY_RECEIPT_WS_READ_TIMEOUT_KEY = "ws.displayreceipt.read.timeout"; + // Default MsgPack webservice parameters + public final static String MESSAGE_PACK_WS_POST_CRYPTORTYPE_KEY = "ws.msgpack.postcryptor.type"; + public final static String MESSAGE_PACK_WS_READ_CRYPTORTYPE_KEY = "ws.msgpack.readcryptor.type"; + public final static String MESSAGE_PACK_WS_URLSORTER_PATTERN_KEY = "ws.msgpack.pattern"; + public final static String MESSAGE_PACK_WS_CRYPTORTYPE_KEY = "ws.msgpack.getcryptor.type"; + public final static String MESSAGE_PACK_WS_CRYPTORMODE_KEY = "ws.msgpack.getcryptor.mode"; + public final static String MESSAGE_PACK_WS_RETRYCOUNT_KEY = "ws.msgpack.retry"; + public final static String MESSAGE_PACK_WS_CONNECT_TIMEOUT_KEY = "ws.msgpack.connect.timeout"; + public final static String MESSAGE_PACK_WS_READ_TIMEOUT_KEY = "ws.msgpack.read.timeout"; - public final static String LOCAL_CAMPAIGNS_WS_INITIAL_DELAY = "lc.wsdelay.initial"; + public final static String DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY = "ws.displayreceipt.getcryptor.type"; + public final static String DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY = "ws.displayreceipt.retry"; + public final static String METRIC_WS_RETRYCOUNT_KEY = "ws.metrics.retry"; + public final static String LOCAL_CAMPAIGNS_JIT_WS_RETRYCOUNT_KEY = "ws.localcampaignsjit.retry"; + public final static String LOCAL_CAMPAIGNS_JIT_WS_READ_TIMEOUT_KEY = "ws.localcampaignsjit.read.timeout"; + public final static String LOCAL_CAMPAIGNS_JIT_WS_CONNECT_TIMEOUT_KEY = "ws.localcampaignsjit.connect.timeout"; + public final static String LOCAL_CAMPAIGNS_WS_INITIAL_DELAY = "lc.wsdelay.initial"; public final static String WS_CIPHERV2_LAST_FAILURE_KEY = "ws.cipherv2.lastfailure"; public final static String DEFAULT_RETRY_NUMBER_KEY = "ws.defaultRetry"; public final static String DEFAULT_CONNECT_TIMEOUT_KEY = "ws.defaultconnectTimeout"; @@ -127,7 +134,6 @@ public final class ParameterKeys public final static String USER_PROFILE_LANGUAGE_KEY = "u_c_l"; public final static String USER_PROFILE_REGION_KEY = "u_c_r"; - public final static String LIB_CURRENTVERSION_KEY = "app.version.current"; public final static String LIB_PREVIOUSVERSION_KEY = "app.version.previous"; } diff --git a/Sources/sdk/src/main/java/com/batch/android/core/Parameters.java b/Sources/sdk/src/main/java/com/batch/android/core/Parameters.java index bdc33ff..89a352f 100644 --- a/Sources/sdk/src/main/java/com/batch/android/core/Parameters.java +++ b/Sources/sdk/src/main/java/com/batch/android/core/Parameters.java @@ -124,6 +124,14 @@ public final class Parameters { * URL of the display receipt WS */ public static final String DISPLAY_RECEIPT_WS_URL = "https://dr" + BuildConfig.WS_DOMAIN + "/a/%s"; + /** + * URL of the metrics WS + */ + public static final String METRIC_WS_URL = "https://wsmetrics.batch.com/api-sdk"; + /** + * URL of the local campaigns JIT (check just in time) WS + */ + public static final String LOCAL_CAMPAIGNS_JIT_WS_URL = BASE_WS_URL + "/lc_jit/%s"; // --------------------------------------------------> @@ -153,10 +161,16 @@ public final class Parameters { appParameters.put(ParameterKeys.INBOX_WS_READ_CRYPTORTYPE_KEY, "5"); appParameters.put(ParameterKeys.INBOX_WS_POST_CRYPTORTYPE_KEY, "5"); appParameters.put(ParameterKeys.INBOX_WS_RETRYCOUNT_KEY, "0"); - appParameters.put(ParameterKeys.DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY, "5"); - appParameters.put(ParameterKeys.DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY, "0"); appParameters.put(ParameterKeys.ATTR_LOCAL_CAMPAIGNS_WS_READ_CRYPTORTYPE_KEY, "5"); appParameters.put(ParameterKeys.ATTR_LOCAL_CAMPAIGNS_WS_POST_CRYPTORTYPE_KEY, "5"); + + appParameters.put(ParameterKeys.DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY, "5"); + appParameters.put(ParameterKeys.DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY, "0"); + appParameters.put(ParameterKeys.METRIC_WS_RETRYCOUNT_KEY, "0"); + appParameters.put(ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_RETRYCOUNT_KEY, "0"); + appParameters.put(ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_READ_TIMEOUT_KEY, "1000"); + appParameters.put(ParameterKeys.LOCAL_CAMPAIGNS_JIT_WS_CONNECT_TIMEOUT_KEY, "1000"); + appParameters.put(ParameterKeys.LOCAL_CAMPAIGNS_WS_INITIAL_DELAY, "5"); appParameters.put(ParameterKeys.EVENT_TRACKER_STATE, "2"); appParameters.put(ParameterKeys.EVENT_TRACKER_INITIAL_DELAY, "10000"); diff --git a/Sources/sdk/src/main/java/com/batch/android/core/Webservice.java b/Sources/sdk/src/main/java/com/batch/android/core/Webservice.java index eebb67e..ebfc9a2 100644 --- a/Sources/sdk/src/main/java/com/batch/android/core/Webservice.java +++ b/Sources/sdk/src/main/java/com/batch/android/core/Webservice.java @@ -4,6 +4,7 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.batch.android.Batch; import com.batch.android.core.URLBuilder.CryptorMode; import com.batch.android.core.Webservice.WebserviceError.Reason; import com.batch.android.di.providers.OptOutModuleProvider; @@ -53,6 +54,12 @@ public abstract class Webservice { */ private static final int WEBSERVICE_ERROR_INVALID_CIPHER = 487; + /** + * Default retry-after delay (in seconds) when server is overloaded + * and no header is provided. + */ + private static final int DEFAULT_RETRY_AFTER = 60; + /** * Debug interceptor. Allows the sample to tweak the SDK behaviour * Can be disabled using {@link Parameters#ENABLE_WS_INTERCEPTOR} @@ -166,6 +173,19 @@ protected void addGetParameter(String key, String value) { builder.addGETParameter(key, value); } + /** + * Prepend the API Key into the url parameters + * + * @param parameters + * @return the same parameters with Batch key prepended + */ + protected static String[] addBatchApiKey(String[] parameters) { + final String[] retParams = new String[parameters.length + 1]; + retParams[0] = Batch.getAPIKey(); + System.arraycopy(parameters, 0, retParams, 1, parameters.length); + return retParams; + } + /** * Return the specific GET parameters you want to add to the request
* You should override this method to provide custom get parameters @@ -400,7 +420,7 @@ public byte[] executeRequest() throws WebserviceError { HttpURLConnection connection = null; WebserviceError error = null; - int errorCode = -1; + int responseCode = -1; /* * Execute request, with retry @@ -417,11 +437,10 @@ public byte[] executeRequest() throws WebserviceError { try { try { connection = buildConnection(); - connection.connect(); } catch (IOException ce) { error = new WebserviceError(WebserviceError.Reason.NETWORK_ERROR, ce); - errorCode = -1; + responseCode = -1; count++; continue; } catch (Exception e) { @@ -432,16 +451,16 @@ public byte[] executeRequest() throws WebserviceError { in = new BufferedInputStream(connection.getInputStream()); } catch (SocketTimeoutException e) { error = new WebserviceError(WebserviceError.Reason.NETWORK_ERROR, e); - errorCode = -1; + responseCode = -1; count++; continue; } catch (IOException ioe) { // Silently continue since error will be handled by isResponseValid(); } - errorCode = connection.getResponseCode(); + responseCode = connection.getResponseCode(); - if (isResponseValid(errorCode)) { + if (isResponseValid(responseCode)) { // Treat GZIP stream. String header = connection.getHeaderField("Content-Encoding"); if (header != null && header.equals("gzip")) { @@ -479,12 +498,11 @@ public byte[] executeRequest() throws WebserviceError { return ba; } else { - int responseCode = connection.getResponseCode(); - error = - new WebserviceError( - getResponseErrorCause(connection.getResponseCode()), - new IOException("Response code : " + responseCode) - ); + Reason reason = getResponseErrorCause(responseCode); + error = new WebserviceError(reason, new IOException("Response code : " + responseCode)); + if (reason == Reason.TOO_MANY_REQUESTS) { + error.setRetryAfter(connection.getHeaderFieldInt("Retry-After", DEFAULT_RETRY_AFTER)); + } if (responseCode == WEBSERVICE_ERROR_INVALID_CIPHER) { enabledDowngradedMode(); } @@ -514,7 +532,7 @@ public byte[] executeRequest() throws WebserviceError { } count++; - } while (count <= getMaxRetryCount() && shouldRetry(errorCode)); + } while (count <= getMaxRetryCount() && shouldRetry(responseCode)); throw error; } @@ -705,6 +723,10 @@ public static WebserviceError.Reason getResponseErrorCause(int statusCode) { return Reason.UNEXPECTED_ERROR; } + if (statusCode == 429) { + return Reason.TOO_MANY_REQUESTS; + } + if (statusCode == 404) { return Reason.NOT_FOUND_ERROR; } @@ -1050,6 +1072,14 @@ public static class WebserviceError extends Throwable { */ private Reason reason; + /** + * Number of seconds we have to wait before sending another request to a webservice who failed. + * + * Server can respond with an HTTP status code 429 ({@link Reason#TOO_MANY_REQUESTS}) + * and specify the time we have to wait with a 'Retry-After' header. + */ + private int retryAfter = 0; + // ------------------------------------------> /** @@ -1105,6 +1135,11 @@ public enum Reason { */ SERVER_ERROR, + /** + * Server overloaded (429) + */ + TOO_MANY_REQUESTS, + /** * Server returns a not found status (404) */ @@ -1135,6 +1170,21 @@ public enum Reason { */ SDK_OPTED_OUT, } + + /** + * Get the time to wait before sending another request + * @return retryAfter (in milliseconds) + */ + public int getRetryAfterInMillis() { + return retryAfter * 1000; + } + + /** + * Set the time (in seconds) to wait before sending another request + */ + public void setRetryAfter(int retryAfter) { + this.retryAfter = retryAfter; + } } // --------------------------------------------------> diff --git a/Sources/sdk/src/main/java/com/batch/android/eventdispatcher/DispatcherSerializer.java b/Sources/sdk/src/main/java/com/batch/android/eventdispatcher/DispatcherSerializer.java new file mode 100644 index 0000000..f3eac1a --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/eventdispatcher/DispatcherSerializer.java @@ -0,0 +1,57 @@ +package com.batch.android.eventdispatcher; + +import androidx.annotation.NonNull; +import com.batch.android.BatchEventDispatcher; +import com.batch.android.json.JSONException; +import com.batch.android.json.JSONObject; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +/** + * Simple class to serialize event dispatchers + */ +public class DispatcherSerializer { + + public static final String FIREBASE_DISPATCHER_NAME = "firebase"; + public static final String AT_INTERNET_DISPATCHER_NAME = "at_internet"; + public static final String MIXPANEL_DISPATCHER_NAME = "mixpanel"; + public static final String GOOGLE_ANALYTICS_DISPATCHER_NAME = "google_analytics"; + public static final String BATCH_PLUGINS_DISPATCHER_NAME = "batch_plugins"; + + private static final String CUSTOM_DISPATCHER_NAME = "other"; + + /** + * List of dispatchers handled by Batch + */ + private static final List knownDispatchers = Arrays.asList( + FIREBASE_DISPATCHER_NAME, + AT_INTERNET_DISPATCHER_NAME, + MIXPANEL_DISPATCHER_NAME, + GOOGLE_ANALYTICS_DISPATCHER_NAME, + BATCH_PLUGINS_DISPATCHER_NAME + ); + + /** + * Serialize a list of dispatchers + * + * @param dispatchers dispatchers to serialize + * @return json object + */ + @NonNull + public static JSONObject serialize(@NonNull Set dispatchers) { + JSONObject json = new JSONObject(); + for (BatchEventDispatcher dispatcher : dispatchers) { + try { + if (dispatcher.getName() == null) { + continue; + } + String name = knownDispatchers.contains(dispatcher.getName()) + ? dispatcher.getName() + : CUSTOM_DISPATCHER_NAME; + json.put(name, dispatcher.getVersion()); + } catch (JSONException ignored) {} + } + return json; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/inbox/InboxDatasource.java b/Sources/sdk/src/main/java/com/batch/android/inbox/InboxDatasource.java index 96d3c2f..5fb3211 100644 --- a/Sources/sdk/src/main/java/com/batch/android/inbox/InboxDatasource.java +++ b/Sources/sdk/src/main/java/com/batch/android/inbox/InboxDatasource.java @@ -377,8 +377,8 @@ protected boolean insert(InboxNotificationContentInternal notification, long fet final ContentValues values = new ContentValues(); values.put(InboxDatabaseHelper.COLUMN_NOTIFICATION_ID, notification.identifiers.identifier); values.put(InboxDatabaseHelper.COLUMN_SEND_ID, notification.identifiers.sendID); - values.put(InboxDatabaseHelper.COLUMN_TITLE, notification.title); - values.put(InboxDatabaseHelper.COLUMN_BODY, notification.body); + values.put(InboxDatabaseHelper.COLUMN_TITLE, notification.title != null ? notification.title : ""); + values.put(InboxDatabaseHelper.COLUMN_BODY, notification.body != null ? notification.body : ""); values.put(InboxDatabaseHelper.COLUMN_UNREAD, notification.isUnread ? 1 : 0); values.put(InboxDatabaseHelper.COLUMN_DATE, notification.date.getTime()); diff --git a/Sources/sdk/src/main/java/com/batch/android/inbox/InboxFetcherInternal.java b/Sources/sdk/src/main/java/com/batch/android/inbox/InboxFetcherInternal.java index 2ce3691..c1f903d 100644 --- a/Sources/sdk/src/main/java/com/batch/android/inbox/InboxFetcherInternal.java +++ b/Sources/sdk/src/main/java/com/batch/android/inbox/InboxFetcherInternal.java @@ -63,6 +63,8 @@ public class InboxFetcherInternal { private InboxDatasource datasource; + private boolean filterSilentNotifications = true; + private InboxFetcherInternal( @NonNull TrackerModule trackerModule, @Nullable InboxDatasource datasource, @@ -161,6 +163,10 @@ public void setFetchLimit(int fetchLimit) { this.fetchLimit = fetchLimit; } + public void setFilterSilentNotifications(boolean filterSilentNotifications) { + this.filterSilentNotifications = filterSilentNotifications; + } + public boolean isEndReached() { return endReached || fetchedNotifications.size() >= fetchLimit; } @@ -243,12 +249,19 @@ public void markAsDeleted(BatchInboxNotificationContent notification) { } @NonNull - private static List convertInternalModelsToPublic( + private List convertInternalModelsToPublic( @NonNull List privateNotifications ) { final List res = new ArrayList<>(); for (InboxNotificationContentInternal privateNotification : privateNotifications) { - res.add(PrivateNotificationContentHelper.getPublicContent(privateNotification)); + final BatchInboxNotificationContent publicContent = PrivateNotificationContentHelper.getPublicContent( + privateNotification + ); + if (filterSilentNotifications && publicContent.isSilent()) { + Logger.verbose(TAG, "Filtering silent notification"); + continue; + } + res.add(publicContent); } return res; } @@ -501,7 +514,7 @@ private List getEventDatas(InboxNotificationContentInternal notifica @NonNull public List getPublicFetchedNotifications() { synchronized (fetchedNotifications) { - return convertInternalModelsToPublic(this.fetchedNotifications); + return convertInternalModelsToPublic(fetchedNotifications); } } diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/CampaignManager.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/CampaignManager.java index 2a0dff3..f9573a5 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/CampaignManager.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/CampaignManager.java @@ -1,27 +1,29 @@ package com.batch.android.localcampaigns; +import static com.batch.android.localcampaigns.model.LocalCampaign.SyncedJITResult; +import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.SECONDS; import android.content.Context; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.batch.android.LoggerLevel; +import com.batch.android.WebserviceLauncher; import com.batch.android.core.DateProvider; import com.batch.android.core.Logger; import com.batch.android.core.Parameters; +import com.batch.android.core.SystemDateProvider; +import com.batch.android.core.Webservice; import com.batch.android.date.BatchDate; import com.batch.android.di.providers.RuntimeManagerProvider; -import com.batch.android.di.providers.SecureDateProviderProvider; import com.batch.android.di.providers.TaskExecutorProvider; -import com.batch.android.json.JSONArray; import com.batch.android.json.JSONException; import com.batch.android.json.JSONObject; import com.batch.android.localcampaigns.model.LocalCampaign; import com.batch.android.localcampaigns.persistence.LocalCampaignsFilePersistence; import com.batch.android.localcampaigns.persistence.LocalCampaignsPersistence; import com.batch.android.localcampaigns.persistence.PersistenceException; -import com.batch.android.localcampaigns.serialization.LocalCampaignDeserializer; -import com.batch.android.localcampaigns.serialization.LocalCampaignSerializer; import com.batch.android.localcampaigns.signal.Signal; import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; import com.batch.android.processor.Module; @@ -30,11 +32,14 @@ import com.batch.android.query.response.LocalCampaignsResponse; import com.batch.android.query.serialization.deserializers.LocalCampaignsResponseDeserializer; import com.batch.android.query.serialization.serializers.LocalCampaignsResponseSerializer; +import com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -51,36 +56,78 @@ public class CampaignManager { private static final String TAG = "CampaignManager"; + private static final String PERSISTENCE_LOCAL_CAMPAIGNS_FILE_NAME = "com.batch.localcampaigns.persist.json"; - private DateProvider dateProvider = SecureDateProviderProvider.get(); + /** + * Delay to wait before calling the jit webservice again after a fail + */ + private static final int DEFAULT_RETRY_AFTER = 60_000; //ms + + /** + * Delay before deleting local campaigns cache if there is no update from server. (15 days) + */ + private static final long CACHE_EXPIRATION_DELAY = DAYS.toMillis(15); + + /** + * Max number of campaigns to send to the server for JIT sync. + */ + private static final int MAX_CAMPAIGNS_JIT_THRESHOLD = 5; + + /** + * Min delay between two JIT sync (in ms) + */ + private static final int MIN_DELAY_BETWEEN_JIT_SYNC = 15_000; + + /** + * Period during cached local campaign requiring a JIT sync is considered as up-to-date. + */ + private static final int JIT_CAMPAIGN_CACHE_PERIOD = 30_000; + + /** + * Date provider + */ + private final DateProvider dateProvider = new SystemDateProvider(); - private LocalCampaignsSQLTracker viewTracker; + private final LocalCampaignsTracker viewTracker; private LocalCampaignsPersistence persistor = new LocalCampaignsFilePersistence(); private final List campaignList = new ArrayList<>(); + private LocalCampaignsResponse.GlobalCappings cappings; + private final Object campaignListLock = new Object(); + /** + * Timestamp to wait before JIT service will be available again + * Is set when JIT succeed or when server respond with HTTP code 429 and specify a retry-after header. + */ + private long nextAvailableJITTimestamp; + /** * Tells if we loaded at least one time the campaigns list (an empty campains list could mean that * we didn't load or that the result is empty) */ - private AtomicBoolean campaignsLoaded = new AtomicBoolean(false); + private final AtomicBoolean campaignsLoaded = new AtomicBoolean(false); /** * Cached list of event names that can potentially triggers the display of a local campaign */ private Set watchedEventNames = new HashSet<>(); - public CampaignManager(@NonNull LocalCampaignsSQLTracker viewTracker) { + /** + * Cached list of synced JIT campaigns + */ + private final Map syncedJITCampaigns = new HashMap<>(); + + public CampaignManager(@NonNull LocalCampaignsTracker viewTracker) { this.viewTracker = viewTracker; } @Provide public static CampaignManager provide() { - return new CampaignManager(new LocalCampaignsSQLTracker()); + return new CampaignManager(new LocalCampaignsTracker()); } /** @@ -136,13 +183,21 @@ public void deleteAllCampaigns(Context context, boolean persist) throws Persiste } } + public interface JITElectionCampaignListener { + void onCampaignElected(@Nullable LocalCampaign electedCampaign); + } + /** - * Get the higher priority campaign between all of those that are satisfied by the latest application event + * Get all campaign between all of those that are satisfied by the latest application event + * and sort them by priority * This is the campaign that you'll want to display */ - public LocalCampaign getCampaignToDisplay(@NonNull Signal signal) { + @NonNull + public List getEligibleCampaignsSortedByPriority(@NonNull Signal signal) { synchronized (this.campaignListLock) { List eligibleCampaigns = new ArrayList<>(); + + // Getting campaign eligible for the given signal for (LocalCampaign campaign : campaignList) { boolean satisfiesTrigger = false; for (LocalCampaign.Trigger trigger : campaign.triggers) { @@ -162,6 +217,8 @@ public LocalCampaign getCampaignToDisplay(@NonNull Signal signal) { eligibleCampaigns.add(campaign); } + + // Sorting eligible campaigns by server priority Collections.sort( eligibleCampaigns, Collections.reverseOrder((o1, o2) -> { @@ -172,17 +229,151 @@ public LocalCampaign getCampaignToDisplay(@NonNull Signal signal) { return (x < y) ? -1 : ((x == y) ? 0 : 1); }) ); + return eligibleCampaigns; + } + } - if (eligibleCampaigns.size() > 0) { - return eligibleCampaigns.get(0); + /** + * Get eligible campaigns requiring a JIT sync + * @param eligibleCampaigns regardless of the JIT sync + * @return all eligible campaigns requiring a JIT sync (max: {@link CampaignManager#MAX_CAMPAIGNS_JIT_THRESHOLD}) + */ + @NonNull + public List getFirstEligibleCampaignsRequiringSync(List eligibleCampaigns) { + List eligibleCampaignsRequiringSync = new ArrayList<>(); + int i = 0; + for (LocalCampaign campaign : eligibleCampaigns) { + if (i >= MAX_CAMPAIGNS_JIT_THRESHOLD) { + break; + } + if (campaign.requiresJustInTimeSync) { + eligibleCampaignsRequiringSync.add(campaign); } else { - Logger.internal(TAG, "No eligible campaign was found"); + break; } + i++; } + return eligibleCampaignsRequiringSync; + } + /** + * Get the first eligible campaign not requiring a JIT sync + * @param eligibleCampaigns regardless of the JIT sync + * @return the first eligible campaign not requiring a JIT sync + */ + @Nullable + public LocalCampaign getFirstCampaignNotRequiringJITSync(@NonNull List eligibleCampaigns) { + for (LocalCampaign campaign : eligibleCampaigns) { + if (!campaign.requiresJustInTimeSync) { + return campaign; + } + } return null; } + /** + * Checking with server if campaigns are still eligible + * @param eligibleCampaignsRequiringSync campaigns to check + * @param listener callback + */ + public void verifyCampaignsEligibilityFromServer( + @NonNull List eligibleCampaignsRequiringSync, + @NonNull JITElectionCampaignListener listener + ) { + // Assert campaign list are not empty + if (eligibleCampaignsRequiringSync.isEmpty()) { + listener.onCampaignElected(null); + return; + } + + if (!isJITServiceAvailable()) { + listener.onCampaignElected(null); + return; + } + + WebserviceLauncher.launchLocalCampaignsJITWebservice( + RuntimeManagerProvider.get(), + eligibleCampaignsRequiringSync, + new LocalCampaignsJITWebserviceListener() { + @Override + public void onSuccess(List eligibleCampaignIds) { + // Saving next jit available timestamp + nextAvailableJITTimestamp = dateProvider.getCurrentDate().getTime() + MIN_DELAY_BETWEEN_JIT_SYNC; + + // Handling jit response + if (eligibleCampaignIds.isEmpty()) { + listener.onCampaignElected(null); + } else { + for (LocalCampaign campaign : eligibleCampaignsRequiringSync) { + SyncedJITResult syncedJITCampaignState = new SyncedJITResult( + dateProvider.getCurrentDate().getTime() + ); + if (!eligibleCampaignIds.contains(campaign.id)) { + eligibleCampaignsRequiringSync.remove(campaign); + syncedJITCampaignState.eligible = false; + } else { + syncedJITCampaignState.eligible = true; + } + syncedJITCampaigns.put(campaign.id, syncedJITCampaignState); + } + if (eligibleCampaignsRequiringSync.isEmpty()) { + // Should not happen + listener.onCampaignElected(null); + } else { + listener.onCampaignElected(eligibleCampaignsRequiringSync.get(0)); + } + } + } + + @Override + public void onFailure(Webservice.WebserviceError error) { + // Saving next jit available timestamp + long retryAfter = error.getRetryAfterInMillis() != 0 + ? error.getRetryAfterInMillis() + : DEFAULT_RETRY_AFTER; + nextAvailableJITTimestamp = dateProvider.getCurrentDate().getTime() + retryAfter; + listener.onCampaignElected(null); + } + } + ); + } + + /** + * Check if JIT sync is available + * + * Meaning MIN_DELAY_BETWEEN_JIT_SYNC or last 'retryAfter' time respond by server is passed. + * @return true if JIT service is available + */ + public synchronized boolean isJITServiceAvailable() { + return dateProvider.getCurrentDate().getTime() >= nextAvailableJITTimestamp; + } + + /** + * Check if the given campaign has been already synced recently + * @param campaign to check + * @return a {@link SyncedJITResult.State} + */ + public SyncedJITResult.State getSyncedJITCampaignState(LocalCampaign campaign) { + if (!campaign.requiresJustInTimeSync) { + //Should not happen but ensure we do not sync for a non-jit campaign + return SyncedJITResult.State.ELIGIBLE; + } + + if (!syncedJITCampaigns.containsKey(campaign.id)) { + return SyncedJITResult.State.REQUIRES_SYNC; + } + + SyncedJITResult syncedJITResult = syncedJITCampaigns.get(campaign.id); + if (syncedJITResult == null) { + return SyncedJITResult.State.REQUIRES_SYNC; + } + + if (dateProvider.getCurrentDate().getTime() >= (syncedJITResult.timestamp + JIT_CAMPAIGN_CACHE_PERIOD)) { + return SyncedJITResult.State.REQUIRES_SYNC; + } + return syncedJITResult.eligible ? SyncedJITResult.State.ELIGIBLE : SyncedJITResult.State.NOT_ELIGIBLE; + } + /** * Checks if an event name will triggers at least one campaign, allowing for a fast pre-filter to check if it is worth * checking other conditions for campaigns with an event triggers @@ -198,6 +389,22 @@ public List getCampaignList() { return new ArrayList<>(campaignList); } + /** + * Get the global in-app cappings + * @return cappings + */ + public LocalCampaignsResponse.GlobalCappings getCappings() { + return cappings; + } + + /** + * Set the global in-app cappings + * @param cappings + */ + public void setCappings(LocalCampaignsResponse.GlobalCappings cappings) { + this.cappings = cappings; + } + /** * Removes campaign that will never be ok, even in the future: * - Expired campaigns @@ -321,6 +528,44 @@ protected boolean isCampaignDisplayable(LocalCampaign campaign) { return true; } + /** + * Check if Global Cappings has been reached + * @return true if cappings are reached + */ + public boolean isOverGlobalCappings() { + if (cappings == null) { + // No cappings + return false; + } + + if (cappings.getSession() != null && viewTracker.getSessionViewsCount() >= cappings.getSession()) { + Logger.internal(TAG, "Session capping has been reached"); + return true; + } + + List timeBasedCappings = cappings.getTimeBasedCappings(); + if (timeBasedCappings != null) { + for (LocalCampaignsResponse.GlobalCappings.TimeBasedCapping timeBasedCapping : timeBasedCappings) { + if (timeBasedCapping.getDuration() != null && timeBasedCapping.getViews() != null) { + long timestamp = dateProvider.getCurrentDate().getTime() - (timeBasedCapping.getDuration() * 1000); + try { + if (viewTracker.getNumberOfViewEventsSince(timestamp) >= timeBasedCapping.getViews()) { + Logger.internal(TAG, "Time-based cappings have been reached"); + return true; + } + } catch (ViewTrackerUnavailableException e) { + Logger.internal( + TAG, + "View tracker is unavailable. Campaigns will be prevented from displaying." + ); + return true; + } + } + } + } + return false; + } + /** * Update the set of watched event names * This method is not thread safe: do not call it without some kind of lock @@ -337,22 +582,24 @@ private void updateWatchedEventNames() { watchedEventNames = newWatchedEvents; } - public void saveCampaigns(@NonNull Context context, @NonNull List campaigns) { + public void saveCampaigns(@NonNull Context context, @NonNull LocalCampaignsResponse response) { try { - LocalCampaignSerializer serializer = new LocalCampaignSerializer(); + LocalCampaignsResponseSerializer serializer = new LocalCampaignsResponseSerializer(); JSONObject jsonData = new JSONObject(); - jsonData.put("campaigns", serializer.serializeList(campaigns)); + jsonData.put("campaigns", serializer.serializeCampaigns(response.getCampaignsToSave())); + jsonData.putOpt("cappings", serializer.serializeCappings(response.getCappings())); + jsonData.putOpt("cache_date", dateProvider.getCurrentDate().getTime()); persistor.persistData(context, jsonData, PERSISTENCE_LOCAL_CAMPAIGNS_FILE_NAME); } catch (PersistenceException e) { - Logger.internal(TAG, "Can't persist local campaigns", e); + Logger.internal(TAG, "Can't persist local campaigns response", e); } catch (JSONException e) { - Logger.internal(TAG, "Can't serialize local campaigns before the save operation", e); + Logger.internal(TAG, "Can't serialize local campaigns response before the save operation", e); e.printStackTrace(); } } - public void saveCampaignsAsync(@NonNull final Context context, @NonNull final List campaigns) { - TaskExecutorProvider.get(context).execute(() -> saveCampaigns(context, campaigns)); + public void saveCampaignsAsync(@NonNull final Context context, @NonNull final LocalCampaignsResponse response) { + TaskExecutorProvider.get(context).execute(() -> saveCampaigns(context, response)); } public void deleteSavedCampaigns(@NonNull final Context context) { @@ -389,10 +636,23 @@ public boolean loadSavedCampaignResponse(@NonNull final Context context) { return false; } - LocalCampaignDeserializer localCampaignDeserializer = new LocalCampaignDeserializer(); + // Ensure cache is not too old. + Long expirationDate = campaignsRawData.reallyOptLong("cache_date", null); + if (expirationDate != null) { + expirationDate += CACHE_EXPIRATION_DELAY; + if (expirationDate <= dateProvider.getCurrentDate().getTime()) { + Logger.internal(TAG, "Local campaign cache is too old, deleting it."); + deleteSavedCampaignsAsync(context); + return false; + } + } + + LocalCampaignsResponseDeserializer localCampaignResponseDeserializer = new LocalCampaignsResponseDeserializer( + campaignsRawData + ); try { - JSONArray jsonCampaigns = campaignsRawData.getJSONArray("campaigns"); - List campaigns = localCampaignDeserializer.deserializeList(jsonCampaigns); + List campaigns = localCampaignResponseDeserializer.deserializeCampaigns(); + cappings = localCampaignResponseDeserializer.deserializeCappings(); updateCampaignList(campaigns); } catch (Exception ex) { Logger.internal(TAG, "Can't convert json to LocalCampaignsResponse : " + ex.toString()); diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignTrackDbHelper.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignTrackDbHelper.java index d5bec75..9aba21a 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignTrackDbHelper.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignTrackDbHelper.java @@ -8,7 +8,7 @@ public final class LocalCampaignTrackDbHelper extends SQLiteOpenHelper { - public static final int DATABASE_VERSION = 1; + public static final int DATABASE_VERSION = 2; public static final String DATABASE_NAME = "LocalCampaignsSQLTracker.db"; public static class LocalCampaignEntry implements BaseColumns { @@ -18,8 +18,18 @@ public static class LocalCampaignEntry implements BaseColumns { public static final String COLUMN_NAME_CAMPAIGN_KIND = "kind"; public static final String COLUMN_NAME_CAMPAIGN_LAST_OCCURRENCE = "last_oc"; public static final String COLUMN_NAME_CAMPAIGN_COUNT = "count"; + + // New table added in version 2 to store every view event tracked + public static final String TABLE_VIEW_EVENTS_NAME = "view_events"; + public static final String COLUMN_NAME_VE_CAMPAIGN_ID = "campaign_id"; + public static final String COLUMN_NAME_VE_TIMESTAMP = "timestamp_ms"; + + public static final String TRIGGER_VIEW_EVENTS_NAME = "trigger_clean_view_events"; } + /** + * SQL request to create the initial view tracker table to count view events per campaign + */ private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + LocalCampaignEntry.TABLE_NAME + @@ -40,8 +50,53 @@ public static class LocalCampaignEntry implements BaseColumns { LocalCampaignEntry.COLUMN_NAME_CAMPAIGN_KIND + ") on conflict replace)"; + /** + * SQL request to delete the view tracker table + */ private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + LocalCampaignEntry.TABLE_NAME; + /** + * SQL request to create the view event table to store every view events + * Must be clean when size is 100 entries + */ + private static final String SQL_CREATE_VIEW_EVENTS_TABLE = + "CREATE TABLE " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " (" + + LocalCampaignEntry._ID + + " INTEGER PRIMARY KEY AUTOINCREMENT," + + LocalCampaignEntry.COLUMN_NAME_VE_CAMPAIGN_ID + + " TEXT," + + LocalCampaignEntry.COLUMN_NAME_VE_TIMESTAMP + + " INTEGER NOT NULL" + + ")"; + + /** + * SQL request to create a trigger when a new view events is inserted. + * When triggered, check if the table has more than 100 rows and delete the oldest. + */ + private static final String SQL_CREATE_TRIGGER_VIEW_EVENT_DELETE_ROWS = + "CREATE TRIGGER " + + LocalCampaignEntry.TRIGGER_VIEW_EVENTS_NAME + + " AFTER INSERT ON " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " BEGIN" + + " DELETE FROM " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " WHERE " + + LocalCampaignEntry.COLUMN_NAME_VE_TIMESTAMP + + "=(" + + " SELECT min(" + + LocalCampaignEntry.COLUMN_NAME_VE_TIMESTAMP + + ") " + + " FROM " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " )" + + " AND (SELECT count(*) from " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " )>100;" + + " END;"; + public LocalCampaignTrackDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -49,11 +104,16 @@ public LocalCampaignTrackDbHelper(Context context) { @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL(SQL_CREATE_ENTRIES); + sqLiteDatabase.execSQL(SQL_CREATE_VIEW_EVENTS_TABLE); + sqLiteDatabase.execSQL(SQL_CREATE_TRIGGER_VIEW_EVENT_DELETE_ROWS); } @Override - public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { - // Empty now + public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { + if (oldVersion < 2) { + sqLiteDatabase.execSQL(SQL_CREATE_VIEW_EVENTS_TABLE); + sqLiteDatabase.execSQL(SQL_CREATE_TRIGGER_VIEW_EVENT_DELETE_ROWS); + } } /** diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsSQLTracker.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsSQLTracker.java index a776a1c..4e3d966 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsSQLTracker.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsSQLTracker.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.Map; -public final class LocalCampaignsSQLTracker implements ViewTracker { +public class LocalCampaignsSQLTracker implements ViewTracker { private static final String TAG = "LocalCampaignsSQLTracker"; private LocalCampaignTrackDbHelper dbHelper; @@ -88,6 +88,16 @@ public ViewTracker.CountedViewEvent trackViewEvent(@NonNull String campaignID) new String[] { campaignID, Integer.toString(ev.count), Long.toString(ev.lastOccurrence) } ); + database.execSQL( + "INSERT INTO " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " (" + + LocalCampaignEntry.COLUMN_NAME_VE_CAMPAIGN_ID + + ", " + + LocalCampaignEntry.COLUMN_NAME_VE_TIMESTAMP + + ") VALUES (?, ?)", + new String[] { campaignID, Long.toString(ev.lastOccurrence) } + ); return ev; } @@ -191,6 +201,31 @@ public long campaignLastOccurrence(@NonNull String campaignID) throws ViewTracke return lastOccurence; } + @Override + public int getNumberOfViewEventsSince(long timestamp) throws ViewTrackerUnavailableException { + ensureWritableDatabase(); + int total = 0; + Cursor countCursor = database.rawQuery( + "SELECT COUNT(*) " + + " FROM " + + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME + + " WHERE " + + LocalCampaignEntry.COLUMN_NAME_VE_TIMESTAMP + + " > ?", + new String[] { Long.toString(timestamp) } + ); + if (countCursor.moveToFirst()) { + total = countCursor.getInt(0); + } + countCursor.close(); + return total; + } + + public void deleteViewEvents() throws ViewTrackerUnavailableException { + ensureWritableDatabase(); + database.execSQL("DELETE FROM " + LocalCampaignEntry.TABLE_VIEW_EVENTS_NAME); + } + private void ensureWritableDatabase() throws ViewTrackerUnavailableException { if (database == null) { if (dbHelper == null) { diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsTracker.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsTracker.java new file mode 100644 index 0000000..ea79c51 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/LocalCampaignsTracker.java @@ -0,0 +1,39 @@ +package com.batch.android.localcampaigns; + +import androidx.annotation.NonNull; + +public final class LocalCampaignsTracker extends LocalCampaignsSQLTracker { + + /** + * Count of the views tracked during the user session. + * This counter is reset when a new session start. + */ + private int sessionViewsCount = 0; + + /** + * Reset the session view count + */ + public void resetSessionViewsCount() { + this.sessionViewsCount = 0; + } + + /** + * Get the count of in-apps viewed during the session + * @return sessionViewsCount + */ + public int getSessionViewsCount() { + return sessionViewsCount; + } + + /** + * Track + * @param campaignID Campaign ID + * @return + * @throws ViewTrackerUnavailableException + */ + @Override + public CountedViewEvent trackViewEvent(@NonNull String campaignID) throws ViewTrackerUnavailableException { + sessionViewsCount++; + return super.trackViewEvent(campaignID); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/ViewTracker.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/ViewTracker.java index d84176c..f961643 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/ViewTracker.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/ViewTracker.java @@ -41,6 +41,14 @@ public interface ViewTracker { */ long campaignLastOccurrence(@NonNull String campaignId) throws ViewTrackerUnavailableException; + /** + * Get the number of view event tracked since a given timestamp + * @param timestamp date (timestamp in ms) + * @return total view events since the given date + * @throws ViewTrackerUnavailableException exception + */ + int getNumberOfViewEventsSince(long timestamp) throws ViewTrackerUnavailableException; + class CountedViewEvent { @NonNull diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/model/LocalCampaign.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/model/LocalCampaign.java index 8bfb331..155ffb2 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/model/LocalCampaign.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/model/LocalCampaign.java @@ -126,6 +126,11 @@ public class LocalCampaign { @Nullable public JSONObject customPayload; + /** + * Flag indicating if this campaign must be verified from the server before being displayed + */ + public boolean requiresJustInTimeSync; + public void generateOccurrenceID() { try { eventData.put("i", Long.toString(System.currentTimeMillis())); @@ -175,4 +180,34 @@ public Output(@NonNull JSONObject payload) { */ protected abstract boolean displayMessage(LocalCampaign campaign); } + + /** + * Class used to cache the result of a LocalCampaign after a JIT sync. + * Keep the timestamp of the sync and whether the campaign was eligible or not. + */ + public static class SyncedJITResult { + + /** + * Possible states for a synced JIT campaign + */ + public enum State { + ELIGIBLE, + NOT_ELIGIBLE, + REQUIRES_SYNC, + } + + /** + * Timestamp of the sync + */ + public long timestamp; + + /** + * Whether the campaign was eligible or not after the sync + */ + public boolean eligible; + + public SyncedJITResult(long timestamp) { + this.timestamp = timestamp; + } + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/output/ActionOutput.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/output/ActionOutput.java new file mode 100644 index 0000000..640ff8d --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/output/ActionOutput.java @@ -0,0 +1,64 @@ +package com.batch.android.localcampaigns.output; + +import android.content.Context; +import android.text.TextUtils; +import androidx.annotation.NonNull; +import com.batch.android.core.Logger; +import com.batch.android.di.providers.ActionModuleProvider; +import com.batch.android.di.providers.RuntimeManagerProvider; +import com.batch.android.json.JSONObject; +import com.batch.android.localcampaigns.model.LocalCampaign; +import com.batch.android.module.LocalCampaignsModule; +import com.batch.android.processor.Module; +import com.batch.android.processor.Provide; +import com.batch.android.runtime.RuntimeManager; + +@Module +public class ActionOutput extends LocalCampaign.Output { + + public ActionOutput(@NonNull JSONObject payload) { + super(payload); + } + + @Provide + public static ActionOutput provide(@NonNull JSONObject payload) { + return new ActionOutput(payload); + } + + @Override + protected boolean displayMessage(LocalCampaign campaign) { + final RuntimeManager runtimeManager = RuntimeManagerProvider.get(); + Context targetContext = runtimeManager.getActivity(); + if (targetContext == null) { + Logger.warning( + LocalCampaignsModule.TAG, + "Could not find an activity to run the action on, falling back on context." + ); + + targetContext = runtimeManager.getContext(); + } + if (targetContext == null) { + Logger.warning( + LocalCampaignsModule.TAG, + "Could not find any context to run the action on: action might fail." + ); + } + + String actionIdentifier = payload.reallyOptString("action", null); + if (TextUtils.isEmpty(actionIdentifier)) { + Logger.error(LocalCampaignsModule.TAG, "Invalid action name, stopping."); + return false; + } + + JSONObject actionArgs = payload.optJSONObject("args"); + + if (actionArgs == null) { + actionArgs = new JSONObject(); + } + + // Maybe add a UserActionSource in the future if this becomes a real product + // InAppMessageUserActionSource isn't right for the job here, as it's tightly coupled + // to the landings. + return ActionModuleProvider.get().performAction(targetContext, actionIdentifier, actionArgs, null); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignDeserializer.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignDeserializer.java index 0d96753..a2aa5fd 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignDeserializer.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignDeserializer.java @@ -4,16 +4,15 @@ import com.batch.android.core.Logger; import com.batch.android.date.TimezoneAwareDate; import com.batch.android.date.UTCDate; +import com.batch.android.di.providers.ActionOutputProvider; import com.batch.android.di.providers.LandingOutputProvider; import com.batch.android.json.JSONArray; import com.batch.android.json.JSONException; import com.batch.android.json.JSONObject; import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; +import com.batch.android.localcampaigns.output.ActionOutput; import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -110,6 +109,8 @@ public LocalCampaign deserialize(JSONObject json) throws JSONException { campaign.customPayload = json.optJSONObject("customPayload"); + campaign.requiresJustInTimeSync = json.reallyOptBoolean("requireJIT", false); + return campaign; } @@ -155,6 +156,8 @@ private LocalCampaign.Output parseOutput(JSONObject json) throws JSONException { JSONObject payload = json.getJSONObject("payload"); if ("LANDING".equals(type)) { output = LandingOutputProvider.get(payload); + } else if ("ACTION".equals(type)) { + output = ActionOutputProvider.get(payload); } else { throw new JSONException("Invalid campaign output type"); } @@ -202,12 +205,8 @@ private LocalCampaign.Trigger parseTrigger(JSONObject json) throws JSONException type = type.toUpperCase(Locale.US); switch (type) { + // Workaround to handle deprecated ASAP trigger as NEXT_SESSION (post-sync) case "NOW": - return new NowTrigger(); - case "CAMPAIGNS_REFRESHED": - return new CampaignsRefreshedTrigger(); - case "CAMPAIGNS_LOADED": - return new CampaignsLoadedTrigger(); case "NEXT_SESSION": return new NextSessionTrigger(); case "EVENT": diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignSerializer.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignSerializer.java index 3314242..ea0a6a6 100644 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignSerializer.java +++ b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/serialization/LocalCampaignSerializer.java @@ -62,6 +62,7 @@ public JSONObject serialize(LocalCampaign campaign) throws JSONException { if (campaign.customPayload != null) { jsonCampaign.put("customPayload", campaign.customPayload); } + jsonCampaign.put("requireJIT", campaign.requiresJustInTimeSync); return jsonCampaign; } diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignal.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignal.java deleted file mode 100644 index ece12c5..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignal.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.batch.android.localcampaigns.signal; - -import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; - -/** - * Event that occurs when the in-app campaign list has been updated from any source - *

- * It actually matches the empty trigger, which shows campaigns when the list is loaded - * (be it at the first SDK start from disk, or when we get an answer from the backend) - */ - -public class CampaignsLoadedSignal implements Signal { - - public boolean satisfiesTrigger(LocalCampaign.Trigger trigger) { - return ( - trigger instanceof NowTrigger || - trigger instanceof CampaignsLoadedTrigger || - trigger instanceof NextSessionTrigger - ); - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignal.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignal.java deleted file mode 100644 index e5aa99a..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignal.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.batch.android.localcampaigns.signal; - -import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; - -/** - * Event that occurs when the in-app campaign list has been updated from any source - *

- * It actually matches the empty trigger, which shows campaigns when the list is loaded - * (be it at the first SDK start from disk, or when we get an answer from the backend) - */ - -public class CampaignsRefreshedSignal implements Signal { - - public boolean satisfiesTrigger(LocalCampaign.Trigger trigger) { - return trigger instanceof NowTrigger || trigger instanceof CampaignsRefreshedTrigger; - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsLoadedTrigger.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsLoadedTrigger.java deleted file mode 100644 index a206e3f..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsLoadedTrigger.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.batch.android.localcampaigns.trigger; - -import com.batch.android.localcampaigns.model.LocalCampaign; - -public class CampaignsLoadedTrigger implements LocalCampaign.Trigger { - - @Override - public String getType() { - return "CAMPAIGNS_LOADED"; - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsRefreshedTrigger.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsRefreshedTrigger.java deleted file mode 100644 index ef0ca55..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/CampaignsRefreshedTrigger.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.batch.android.localcampaigns.trigger; - -import com.batch.android.localcampaigns.model.LocalCampaign; - -public class CampaignsRefreshedTrigger implements LocalCampaign.Trigger { - - @Override - public String getType() { - return "CAMPAIGNS_REFRESHED"; - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/NowTrigger.java b/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/NowTrigger.java deleted file mode 100644 index 08567d5..0000000 --- a/Sources/sdk/src/main/java/com/batch/android/localcampaigns/trigger/NowTrigger.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.batch.android.localcampaigns.trigger; - -import com.batch.android.localcampaigns.model.LocalCampaign; - -/** - * Trigger displaying campaigns as soon as possible - */ - -public class NowTrigger implements LocalCampaign.Trigger { - - @Override - public String getType() { - return "NOW"; - } -} diff --git a/Sources/sdk/src/main/java/com/batch/android/metrics/MetricManager.java b/Sources/sdk/src/main/java/com/batch/android/metrics/MetricManager.java new file mode 100644 index 0000000..d212c0a --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/metrics/MetricManager.java @@ -0,0 +1,180 @@ +package com.batch.android.metrics; + +import android.content.Context; +import com.batch.android.WebserviceLauncher; +import com.batch.android.core.DateProvider; +import com.batch.android.core.Logger; +import com.batch.android.core.SystemDateProvider; +import com.batch.android.core.TaskRunnable; +import com.batch.android.core.Webservice; +import com.batch.android.di.providers.RuntimeManagerProvider; +import com.batch.android.metrics.model.Counter; +import com.batch.android.metrics.model.Metric; +import com.batch.android.metrics.model.Observation; +import com.batch.android.post.MetricPostDataProvider; +import com.batch.android.processor.Module; +import com.batch.android.processor.Provide; +import com.batch.android.processor.Singleton; +import com.batch.android.webservice.listener.MetricWebserviceListener; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +@Module +@Singleton +public class MetricManager { + + private static final String TAG = "MetricManager"; + + /** + * Delay to wait before calling the metric webservice again after a fail + */ + private static final int DEFAULT_RETRY_AFTER = 60_000; //ms + + /** + * Delay to wait if other metrics are to send + */ + private static final int DELAY_BEFORE_SENDING = 1000; //ms + + /** + * List of metrics registered + */ + private final List> metrics = new ArrayList<>(); + + /** + * Flag indicating whether we has started sending metrics + */ + private final AtomicBoolean isSending = new AtomicBoolean(); + + /** + * Single thread scheduled executor + */ + private final ScheduledExecutorService sendExecutor = Executors.newSingleThreadScheduledExecutor(); + + /** + * Timestamp to wait before metrics webservice will be available again + */ + private long nextMetricServiceAvailableTimestamp; + + /** + * System date provider + */ + private final DateProvider dateProvider = new SystemDateProvider(); + + @Provide + public static MetricManager provide() { + return new MetricManager(); + } + + public void addMetric(Metric metric) { + synchronized (metrics) { + this.metrics.add(metric); + } + } + + /** + * Get metrics to send + * + * @return metrics + */ + private List> getMetricsToSend() { + synchronized (metrics) { + List> metricsToSend = new ArrayList<>(); + for (Metric metric : metrics) { + if (metric.hasChildren()) { + for (Object child : metric.getChildren().values()) { + if (child instanceof Counter) { + Counter counter = (Counter) child; + if (counter.hasChanged()) { + metricsToSend.add(new Counter((Counter) child)); + counter.reset(); + } + } else { + Observation observation = ((Observation) child); + if (observation.hasChanged()) { + metricsToSend.add(new Observation((Observation) child)); + observation.reset(); + } + } + } + } else { + if (metric.hasChanged()) { + if (metric instanceof Counter) { + metricsToSend.add(new Counter((Counter) metric)); + } else { + metricsToSend.add(new Observation((Observation) metric)); + } + metric.reset(); + } + } + } + return metricsToSend; + } + } + + /** + * Check if the metric webservice is available. + * + * @return true if service is available or false if we have to wait + */ + private boolean isMetricServiceAvailable() { + return dateProvider.getCurrentDate().getTime() >= nextMetricServiceAvailableTimestamp; + } + + /** + * Send the metrics + */ + public void sendMetrics() { + if (isSending.get()) { + // We are already sending metrics + return; + } + + if (!isMetricServiceAvailable()) { + // Server looks like overloaded, we wait + return; + } + + isSending.set(true); + Context context = RuntimeManagerProvider.get().getContext(); + + sendExecutor.schedule( + () -> { + List> metricsToSend = getMetricsToSend(); + if (metricsToSend.isEmpty()) { + return; + } + MetricPostDataProvider dataProvider = new MetricPostDataProvider(metricsToSend); + TaskRunnable runnable = WebserviceLauncher.initMetricWebservice( + context, + dataProvider, + new MetricWebserviceListener() { + @Override + public void onSuccess() { + Logger.info(TAG, "Metrics sent with success."); + isSending.set(false); + } + + @Override + public void onFailure(Webservice.WebserviceError error) { + Logger.info(TAG, "Fail sending metrics."); + long retryAfter = error.getRetryAfterInMillis() != 0 + ? error.getRetryAfterInMillis() + : DEFAULT_RETRY_AFTER; + nextMetricServiceAvailableTimestamp = dateProvider.getCurrentDate().getTime() + retryAfter; + isSending.set(false); + } + } + ); + if (runnable != null) { + runnable.run(); + } + }, + DELAY_BEFORE_SENDING, + TimeUnit.MILLISECONDS + ); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/metrics/MetricRegistry.java b/Sources/sdk/src/main/java/com/batch/android/metrics/MetricRegistry.java new file mode 100644 index 0000000..95afa7b --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/metrics/MetricRegistry.java @@ -0,0 +1,27 @@ +package com.batch.android.metrics; + +import com.batch.android.metrics.model.Counter; +import com.batch.android.metrics.model.Observation; + +/** + * Simple class to centralize registered metrics + */ +public final class MetricRegistry { + + // Monitor local campaigns JIT response time + public static final Observation localCampaignsJITResponseTime = new Observation( + "sdk_local_campaigns_jit_ws_duration" + ) + .register(); + + // Monitor local campaign ws call by status ("OK", "KO") + public static final Counter localCampaignsJITCount = new Counter("sdk_local_campaigns_jit_ws_count") + .labelNames("status") + .register(); + + // Monitor local campaigns sync response time + public static final Observation localCampaignsSyncResponseTime = new Observation( + "sdk_local_campaigns_sync_ws_duration" + ) + .register(); +} diff --git a/Sources/sdk/src/main/java/com/batch/android/metrics/model/Counter.java b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Counter.java new file mode 100644 index 0000000..c292b3d --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Counter.java @@ -0,0 +1,47 @@ +package com.batch.android.metrics.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class Counter extends Metric { + + private float value; + + public Counter(Counter counter) { + super(counter.name); + this.type = counter.type; + this.value = counter.value; + this.values = new ArrayList<>(counter.values); + this.children = new ConcurrentHashMap<>(counter.children); + this.labelNames = counter.labelNames; + this.labelValues = counter.labelValues; + } + + public Counter(String name) { + super(name); + type = Type.COUNTER; + values = new ArrayList<>(); + } + + @Override + protected Counter newChild(List labels) { + Counter counter = new Counter(name).labelNames(labelNames.toArray(new String[0])); + counter.labelValues = labels; + return counter; + } + + @Override + public void reset() { + value = 0f; + values.clear(); + children.clear(); + } + + public void inc() { + value++; + values.clear(); + values.add(value); + update(); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/metrics/model/Metric.java b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Metric.java new file mode 100644 index 0000000..94dae71 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Metric.java @@ -0,0 +1,110 @@ +package com.batch.android.metrics.model; + +import com.batch.android.di.providers.MetricManagerProvider; +import com.batch.android.msgpack.MessagePackHelper; +import com.batch.android.msgpack.core.MessageBufferPacker; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public abstract class Metric { + + protected interface Type { + String COUNTER = "counter"; + String OBSERVATION = "observation"; + } + + protected final String name; + + protected String type; + + protected List values; + + protected List labelNames; + + protected List labelValues; + + protected ConcurrentMap, Child> children = new ConcurrentHashMap<>(); + + public Metric(String name) { + this.name = name; + } + + public Child register() { + MetricManagerProvider.get().addMetric(this); + return (Child) this; + } + + public Child labelNames(String... labels) { + this.labelNames = Arrays.asList(labels); + return (Child) this; + } + + public Child labels(String... labels) { + Child child = this.children.get(Arrays.asList(labels)); + if (child == null) { + List labelsValues = Arrays.asList(labels); + child = newChild(labelsValues); + this.children.put(labelsValues, child); + } + return child; + } + + public abstract void reset(); + + protected abstract Child newChild(List labels); + + public void pack(MessageBufferPacker packer) throws Exception { + Map objectMap = new HashMap<>(); + objectMap.put("name", name); + objectMap.put("type", type); + objectMap.put("values", values); + if (labelNames != null && labelValues != null && labelNames.size() == labelValues.size()) { + Map labels = new HashMap<>(); + for (int i = 0; i < labelNames.size(); i++) { + labels.put(labelNames.get(i), labelValues.get(i)); + } + objectMap.put("labels", labels); + } + MessagePackHelper.packObject(packer, objectMap); + } + + protected void update() { + MetricManagerProvider.get().sendMetrics(); + } + + public boolean hasChanged() { + return values.size() > 0; + } + + public boolean hasChildren() { + return children.size() > 0; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public List getValues() { + return values; + } + + public List getLabelNames() { + return labelNames; + } + + public List getLabelValues() { + return labelValues; + } + + public ConcurrentMap, Child> getChildren() { + return children; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/metrics/model/Observation.java b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Observation.java new file mode 100644 index 0000000..31032e7 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/metrics/model/Observation.java @@ -0,0 +1,62 @@ +package com.batch.android.metrics.model; + +import static java.lang.System.currentTimeMillis; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +public class Observation extends Metric { + + private long startTime; + + private AtomicBoolean observing = new AtomicBoolean(); + + public Observation(String name) { + super(name); + type = Type.OBSERVATION; + values = new ArrayList<>(); + } + + public Observation(Observation observation) { + super(observation.name); + this.type = observation.type; + this.values = observation.values; + this.values = new ArrayList<>(observation.values); + this.children = new ConcurrentHashMap<>(observation.children); + this.labelNames = observation.labelNames; + this.labelValues = observation.labelValues; + this.observing = observation.observing; + this.startTime = observation.startTime; + } + + @Override + protected Observation newChild(List labels) { + Observation observation = new Observation(name).labelNames(labelNames.toArray(new String[0])); + observation.labelValues = labels; + return observation; + } + + @Override + public void reset() { + values.clear(); + children.clear(); + } + + public void startTimer() { + startTime = currentTimeMillis(); + observing.set(true); + } + + public void observeDuration() { + observing.set(false); + float duration = (currentTimeMillis() - startTime) / 1000f; + values.add(duration); + update(); + } + + public boolean isObserving() { + return observing.get(); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/module/ActionModule.java b/Sources/sdk/src/main/java/com/batch/android/module/ActionModule.java index 1c4a366..6bb96ad 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/ActionModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/ActionModule.java @@ -13,6 +13,7 @@ import com.batch.android.actions.DeeplinkActionRunnable; import com.batch.android.actions.GroupActionRunnable; import com.batch.android.actions.LocalCampaignsRefreshActionRunnable; +import com.batch.android.actions.NotificationPermissionActionRunnable; import com.batch.android.actions.RatingActionRunnable; import com.batch.android.actions.UserDataBuiltinActionRunnable; import com.batch.android.actions.UserEventBuiltinActionRunnable; @@ -250,6 +251,11 @@ private void registerBuiltinActions() { RatingActionRunnable.IDENTIFIER, new UserAction(RatingActionRunnable.IDENTIFIER, new RatingActionRunnable()) ); + + registeredActions.put( + NotificationPermissionActionRunnable.IDENTIFIER, + new UserAction(NotificationPermissionActionRunnable.IDENTIFIER, new NotificationPermissionActionRunnable()) + ); } public int getDrawableIdForNameOrAlias(@NonNull Context context, @Nullable String drawableName) { diff --git a/Sources/sdk/src/main/java/com/batch/android/module/BatchModule.java b/Sources/sdk/src/main/java/com/batch/android/module/BatchModule.java index 1a0a2fd..f22100d 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/BatchModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/BatchModule.java @@ -1,5 +1,7 @@ package com.batch.android.module; +import android.content.Context; +import androidx.annotation.NonNull; import com.batch.android.runtime.State; /** @@ -24,6 +26,15 @@ public abstract class BatchModule { // -----------------------------------> + /** + * Called by Batch as soon as a context is available in the runtimeManager + * For convenience, the application context is available as a parameter. + * LocalBroadcastManager is also up. + */ + public void batchContextBecameAvailable(@NonNull Context applicationContext) { + // Override this method + } + /** * Called by Batch before batch start
* NB : Context & activity are already available from the runtimeManager diff --git a/Sources/sdk/src/main/java/com/batch/android/module/BatchModuleMaster.java b/Sources/sdk/src/main/java/com/batch/android/module/BatchModuleMaster.java index 1fbadb5..bcd3464 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/BatchModuleMaster.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/BatchModuleMaster.java @@ -1,5 +1,7 @@ package com.batch.android.module; +import android.content.Context; +import androidx.annotation.NonNull; import com.batch.android.di.providers.ActionModuleProvider; import com.batch.android.di.providers.DisplayReceiptModuleProvider; import com.batch.android.di.providers.EventDispatcherModuleProvider; @@ -58,6 +60,13 @@ public int getState() { return 1; } + @Override + public void batchContextBecameAvailable(@NonNull Context applicationContext) { + for (BatchModule module : modules) { + module.batchContextBecameAvailable(applicationContext); + } + } + @Override public void batchWillStart() { for (BatchModule module : modules) { diff --git a/Sources/sdk/src/main/java/com/batch/android/module/DisplayReceiptModule.java b/Sources/sdk/src/main/java/com/batch/android/module/DisplayReceiptModule.java index 7972cd7..996c14d 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/DisplayReceiptModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/DisplayReceiptModule.java @@ -9,7 +9,6 @@ import com.batch.android.BatchDisplayReceiptJobService; import com.batch.android.WebserviceLauncher; import com.batch.android.core.InternalPushData; -import com.batch.android.core.JobHelper; import com.batch.android.core.Logger; import com.batch.android.core.TaskRunnable; import com.batch.android.core.Webservice; @@ -119,9 +118,9 @@ public void scheduleDisplayReceipt(Context context, @NonNull InternalPushData pu Logger.internal(TAG, "Could not get Job Scheduler system service"); return; } - + int jobId = (int) (Math.random() * Integer.MAX_VALUE); JobInfo.Builder builder = new JobInfo.Builder( - JobHelper.generateUniqueJobId(scheduler), + jobId, new ComponentName(context, BatchDisplayReceiptJobService.class) ) .setOverrideDeadline(dma * 1000L) @@ -140,10 +139,8 @@ public void scheduleDisplayReceipt(Context context, @NonNull InternalPushData pu } else { Logger.internal(TAG, "Successfully scheduled the display receipt job"); } - } catch (JobHelper.GenerationException e) { - Logger.internal(TAG, "Could not find a suitable job ID", e); } catch (Exception e1) { - Logger.internal(TAG, "Could schedule Batch display receipt job", e1); + Logger.internal(TAG, "Could not schedule Batch display receipt job", e1); } } else { sendReceipt(context, false); diff --git a/Sources/sdk/src/main/java/com/batch/android/module/EventDispatcherModule.java b/Sources/sdk/src/main/java/com/batch/android/module/EventDispatcherModule.java index 9d7b296..88e9b9e 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/EventDispatcherModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/EventDispatcherModule.java @@ -2,6 +2,7 @@ import android.content.Context; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.batch.android.Batch; import com.batch.android.BatchEventDispatcher; import com.batch.android.core.DiscoveryServiceHelper; @@ -9,6 +10,8 @@ import com.batch.android.di.providers.OptOutModuleProvider; import com.batch.android.eventdispatcher.DispatcherDiscoveryService; import com.batch.android.eventdispatcher.DispatcherRegistrar; +import com.batch.android.eventdispatcher.DispatcherSerializer; +import com.batch.android.json.JSONObject; import com.batch.android.processor.Module; import com.batch.android.processor.Provide; import com.batch.android.processor.Singleton; @@ -114,11 +117,34 @@ public void loadDispatcherFromContext(Context context) { BatchEventDispatcher dispatcher = registrar.getDispatcher(context); if (dispatcher != null) { addEventDispatcher(dispatcher); - printLoadedDispatcher(dispatcher.getClass().getName()); + String dispatcherName = dispatcher.getClass().getName(); + if (dispatcher.getName() != null) { + dispatcherName = dispatcher.getName(); + } else { + Logger.warning( + TAG, + "The version of your event dispatcher: " + + dispatcherName + + " is outdated, please update it." + ); + } + printLoadedDispatcher(dispatcherName); } } catch (Throwable e) { Logger.error(String.format("Could not instantiate %s", name), e); } } } + + /** + * Get dispatchers as json object used for the analytics + * @return A JSONObject of dispatcher Name:Version + */ + @Nullable + public JSONObject getDispatchersAnalyticRepresentation() { + synchronized (eventDispatchers) { + JSONObject json = DispatcherSerializer.serialize(eventDispatchers); + return json.length() > 0 ? json : null; + } + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/module/LocalCampaignsModule.java b/Sources/sdk/src/main/java/com/batch/android/module/LocalCampaignsModule.java index 59eb32a..9509596 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/LocalCampaignsModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/LocalCampaignsModule.java @@ -1,5 +1,7 @@ package com.batch.android.module; +import static com.batch.android.localcampaigns.model.LocalCampaign.SyncedJITResult; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -9,16 +11,13 @@ import com.batch.android.compat.LocalBroadcastManager; import com.batch.android.core.Logger; import com.batch.android.core.NamedThreadFactory; -import com.batch.android.core.ParameterKeys; import com.batch.android.di.providers.CampaignManagerProvider; import com.batch.android.di.providers.LocalBroadcastManagerProvider; -import com.batch.android.di.providers.ParametersProvider; import com.batch.android.di.providers.RuntimeManagerProvider; import com.batch.android.di.providers.TaskExecutorProvider; import com.batch.android.localcampaigns.CampaignManager; import com.batch.android.localcampaigns.model.LocalCampaign; import com.batch.android.localcampaigns.persistence.PersistenceException; -import com.batch.android.localcampaigns.signal.CampaignsLoadedSignal; import com.batch.android.localcampaigns.signal.EventTrackedSignal; import com.batch.android.localcampaigns.signal.NewSessionSignal; import com.batch.android.localcampaigns.signal.PublicEventTrackedSignal; @@ -27,10 +26,11 @@ import com.batch.android.processor.Provide; import com.batch.android.processor.Singleton; import com.batch.android.runtime.SessionManager; -import java.util.Timer; -import java.util.TimerTask; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; /** * Batch's Local Campaigns Messaging Module. @@ -42,22 +42,45 @@ public class LocalCampaignsModule extends BatchModule { public static final String TAG = "LocalCampaigns"; - private CampaignManager campaignManager; + /** + * Campaign manager instance + */ + private final CampaignManager campaignManager; + + /** + * Flag indicating whether we already tried to load the campaigns in cache + */ private boolean triedToReadSavedCampaign = false; /** - * Executor responsible for handling the campaign event based trigger + * Signals in queue */ - private ExecutorService triggerExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory()); + private final LinkedList signalQueue = new LinkedList<>(); - private BroadcastReceiver localBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - onLocalBroadcast(intent); - } - }; + /** + * Flag indicating whether we are ready to process a signal. + * + * Meaning local campaigns have been synchronized from server, else signals are enqueue. + * This flag shouldn't be true when campaigns are loaded from cache, only after + * a synchronisation with the server. + */ + private final AtomicBoolean isReady = new AtomicBoolean(false); - private boolean broadcastReceiverRegistered = false; + /** + * Flag indicating whether we are waiting for the end of JIT synchronization. + * All signal processed during this time will be enqueue until the end. + */ + private final AtomicBoolean isWaitingJITSync = new AtomicBoolean(false); + + /** + * Executor responsible for handling the campaign event based trigger + */ + private final ExecutorService triggerExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory()); + + /** + * Flag indicating whether the new session broadcast receiver is registered + */ + private boolean isNewSessionBroadcastReceiverRegistered = false; private LocalCampaignsModule(CampaignManager campaignManager) { this.campaignManager = campaignManager; @@ -82,7 +105,43 @@ public int getState() { //endregion + /** + * Start sending a signal + * If another one is already processing, signal is added to queue. + * @param signal signal to send + */ public void sendSignal(@NonNull Signal signal) { + if (isReady.get()) { + processSignal(signal); + } else { + enqueueSignal(signal); + } + } + + /** + * Add a signal to the queue + * @param signal signal to enqueue + */ + private void enqueueSignal(@NonNull Signal signal) { + synchronized (signalQueue) { + // Ensure we are still processing the signal or synchronizing campaigns + if (isReady.get() && !isWaitingJITSync.get()) { + sendSignal(signal); + } else { + Logger.internal( + TAG, + "Local Campaign module isn't ready, enqueueing signal: " + signal.getClass().getSimpleName() + ); + signalQueue.add(signal); + } + } + } + + /** + * Process a signal + * @param signal signal to process + */ + private void processSignal(@NonNull Signal signal) { if (signal instanceof EventTrackedSignal) { // Skip processing the signal if the event is not watched to avoid useless work // Otherwise, transform the signal in a more specialized one for public events, @@ -101,94 +160,216 @@ public void sendSignal(@NonNull Signal signal) { } } - displayMessage(signal); + // Ensure we are not over global in-app cappings + if (campaignManager.isOverGlobalCappings()) { + return; + } + + Signal finalSignal = signal; + triggerExecutor.submit(() -> { + if (isWaitingJITSync.get()) { + Logger.internal(TAG, "JIT sync in progress, enqueue signal."); + enqueueSignal(finalSignal); + } else { + electCampaignForSignal(finalSignal); + } + }); } - public void wipeData(@NonNull Context context) { - try { - campaignManager.deleteAllCampaigns(context, true); - } catch (PersistenceException e) { - Logger.internal(TAG, "Could not delete persisted campaigns", e); + /** + * Elect the right campaign for a given signal and display it. + * + * Election process is the following : + * - Get all eligible campaigns sorted by priority for a signal: + * - If no eligible campaigns found: + * Do nothing + * - Else: Look if the first one is requiring a JIT sync : + * - Yes: Check if we need to make a new JIT sync (meaning last call for this campaign is older than {@link CampaignManager#JIT_CAMPAIGN_CACHE_PERIOD}) + * - Yes: Check if JIT service is available : + * - Yes: Sync all campaigns requiring a JIT sync limited by {@link CampaignManager#MAX_CAMPAIGNS_JIT_THRESHOLD}) and stopping at the first campaign that not requiring JIT: + * - If server respond with no eligible campaigns : + * - Display the first campaign not requiring a JIT sync (if there's one else do noting) + * - else : + * - Display the first campaign verified by the server + * - No: Display the first campaign not requiring a JIT sync (if there's one else do noting) + * -No: Display it + * - No: Display it + */ + private void electCampaignForSignal(final @NonNull Signal signal) { + // Get all eligible campaigns (sorted by priority) regardless of the JIT sync + List eligibleCampaigns = campaignManager.getEligibleCampaignsSortedByPriority(signal); + + if (!eligibleCampaigns.isEmpty()) { + // Get the first elected campaign + LocalCampaign firstElectedCampaign = eligibleCampaigns.get(0); + if (firstElectedCampaign.requiresJustInTimeSync && signal instanceof EventTrackedSignal) { + SyncedJITResult.State syncedCampaignState = campaignManager.getSyncedJITCampaignState( + firstElectedCampaign + ); + if (syncedCampaignState == SyncedJITResult.State.ELIGIBLE) { + // Last succeed JIT sync for this campaign is NOT older than 30 sec, considering eligibility up to date. + Logger.internal(TAG, "Skipping JIT sync since this campaign has been already synced recently."); + displayMessage(firstElectedCampaign); + } else if ( + syncedCampaignState == SyncedJITResult.State.REQUIRES_SYNC && + campaignManager.isJITServiceAvailable() + ) { + // JIT available, getting all campaigns to sync + List eligibleCampaignsRequiringSync = campaignManager.getFirstEligibleCampaignsRequiringSync( + eligibleCampaigns + ); + LocalCampaign fallbackCampaign = campaignManager.getFirstCampaignNotRequiringJITSync( + eligibleCampaigns + ); + isWaitingJITSync.set(true); + campaignManager.verifyCampaignsEligibilityFromServer( + eligibleCampaignsRequiringSync, + electedCampaign -> { + if (electedCampaign != null) { + Logger.internal(TAG, "Elected campaign has been synchronized with JIT."); + displayMessage(electedCampaign); + } else if (fallbackCampaign != null) { + Logger.internal( + TAG, + "JIT respond with no eligible campaigns or with error. Fallback on offline campaign." + ); + displayMessage(fallbackCampaign); + } else { + Logger.info(TAG, "Ne eligible campaigns found after the JIT sync."); + } + isWaitingJITSync.set(false); + dequeueSignals(); + } + ); + } else { + // JIT not available or campaign is cached and not eligible, fallback on the first eligible campaign not requiring a JIT sync + LocalCampaign firstEligibleCampaignNotRequiringJITSync = campaignManager.getFirstCampaignNotRequiringJITSync( + eligibleCampaigns + ); + if (firstEligibleCampaignNotRequiringJITSync != null) { + Logger.internal( + TAG, + "JIT not available or campaign is cached and not eligible, fallback on offline campaign." + ); + displayMessage(firstEligibleCampaignNotRequiringJITSync); + } + } + } else { + // First elected campaign is not requiring a JIT sync, display it ! + Logger.internal(TAG, "Elected campaign not requiring a sync, display it."); + displayMessage(firstElectedCampaign); + } + } else { + Logger.internal(TAG, "No eligible campaigns found."); } } /** - * Displays the campaign for the specified signal and track view using the ViewTracker + * Display the local campaign message + * @param campaign to display */ - private void displayMessage(final @NonNull Signal signal) { - triggerExecutor.submit(() -> { - LocalCampaign campaign = campaignManager.getCampaignToDisplay(signal); - if (campaign != null) { - campaign.generateOccurrenceID(); - campaign.displayMessage(); - } - }); + private void displayMessage(@NonNull LocalCampaign campaign) { + campaign.generateOccurrenceID(); + campaign.displayMessage(); } - private void onLocalBroadcast(Intent intent) { - if (SessionManager.INTENT_NEW_SESSION.equals(intent.getAction())) { - sendSignal(new NewSessionSignal()); + /** + * Make this module ready to process signals enqueued. + */ + private void makeReady() { + isReady.set(true); + dequeueSignals(); + } - WebserviceLauncher.launchLocalCampaignsWebservice(RuntimeManagerProvider.get()); + /** + * Dequeue all signals + */ + private void dequeueSignals() { + synchronized (signalQueue) { + LinkedList enqueuedSignals = new LinkedList<>(signalQueue); + signalQueue.clear(); + + if (!enqueuedSignals.isEmpty()) { + Logger.info(TAG, "Replaying " + enqueuedSignals.size() + " local campaign signals"); + } + + for (Signal signal : enqueuedSignals) { + processSignal(signal); + } } } - @Override - public void batchDidStart() { - campaignManager.openViewTracker(); + /** + * Release the signal queue when the local campaigns webservice is finished + */ + public void onLocalCampaignsWebserviceFinished() { + makeReady(); + } + + /** + * Delete all campaigns from the manager + * @param context context + */ + public void wipeData(@NonNull Context context) { + try { + campaignManager.deleteAllCampaigns(context, true); + } catch (PersistenceException e) { + Logger.internal(TAG, "Could not delete persisted campaigns", e); + } + } - if (!broadcastReceiverRegistered) { - LocalBroadcastManager lbm = LocalBroadcastManagerProvider.getSingleton(); - if (lbm != null) { - broadcastReceiverRegistered = true; - IntentFilter filter = new IntentFilter(); - filter.addAction(SessionManager.INTENT_NEW_SESSION); - lbm.registerReceiver(localBroadcastReceiver, filter); + /** + * Broadcast receiver listening on new_session intent. + */ + private final BroadcastReceiver newSessionBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (SessionManager.INTENT_NEW_SESSION.equals(intent.getAction())) { + isReady.set(false); + sendSignal(new NewSessionSignal()); + WebserviceLauncher.launchLocalCampaignsWebservice(RuntimeManagerProvider.get()); } } + }; - // Load saved campaigns and call webservice - final Context context = RuntimeManagerProvider.get().getContext(); - SessionManager sessionManager = RuntimeManagerProvider.get().getSessionManager(); + /** + * Register the broadcast receiver for "new_session" intent if needed. + * @param context used to instantiate the LocalBroadcastManager singleton if its not. + */ + public void registerBroadcastReceiverIfNeeded(@NonNull Context context) { + if (!isNewSessionBroadcastReceiverRegistered) { + LocalBroadcastManager lbm = LocalBroadcastManagerProvider.get(context); + isNewSessionBroadcastReceiverRegistered = true; + IntentFilter filter = new IntentFilter(); + filter.addAction(SessionManager.INTENT_NEW_SESSION); + lbm.registerReceiver(newSessionBroadcastReceiver, filter); + } + } - if ( - context != null && sessionManager != null && sessionManager.isSessionActive() && !triedToReadSavedCampaign - ) { + /** + * Load the saved campaigns from cache + * @param context used to instantiate the TaskExecutor singleton if its not. + */ + private void loadSavedCampaigns(@NonNull Context context) { + campaignManager.openViewTracker(); + if (!triedToReadSavedCampaign) { TaskExecutorProvider .get(context) .submit(() -> { - // Try loading via local file if (campaignManager.hasSavedCampaigns(context)) { - if (campaignManager.loadSavedCampaignResponse(context)) { - sendSignal(new CampaignsLoadedSignal()); - } - triedToReadSavedCampaign = true; + campaignManager.loadSavedCampaignResponse(context); } - - int delay = 0; - - try { - delay = - Integer.valueOf( - ParametersProvider.get(context).get(ParameterKeys.LOCAL_CAMPAIGNS_WS_INITIAL_DELAY) - ); - } catch (NumberFormatException ignored) {} - - // Try loading via webservice - new Timer() - .schedule( - new TimerTask() { - @Override - public void run() { - WebserviceLauncher.launchLocalCampaignsWebservice(RuntimeManagerProvider.get()); - } - }, - delay * 1000 - ); }); + triedToReadSavedCampaign = true; } } + @Override + public void batchContextBecameAvailable(@NonNull Context applicationContext) { + registerBroadcastReceiverIfNeeded(applicationContext); + loadSavedCampaigns(applicationContext); + } + @Override public void batchDidStop() { campaignManager.closeViewTracker(); diff --git a/Sources/sdk/src/main/java/com/batch/android/module/PushModule.java b/Sources/sdk/src/main/java/com/batch/android/module/PushModule.java index 933c6d0..acdee20 100644 --- a/Sources/sdk/src/main/java/com/batch/android/module/PushModule.java +++ b/Sources/sdk/src/main/java/com/batch/android/module/PushModule.java @@ -705,7 +705,6 @@ public void onNotificationDisplayed(Context context, Intent intent) { try { if (shouldDisplayPush(context, intent)) { InternalPushData pushData = InternalPushData.getPushDataForReceiverIntent(intent); - BatchPushHelper.markPushAsShown(context, pushData.getPushId()); if (pushData.getReceiptMode() == InternalPushData.ReceiptMode.DISPLAY) { displayReceiptModule.scheduleDisplayReceipt(context, pushData); @@ -723,7 +722,6 @@ public void onNotificationDisplayed(Context context, RemoteMessage message) { try { if (shouldDisplayPush(context, message)) { InternalPushData pushData = InternalPushData.getPushDataForFirebaseMessage(message); - BatchPushHelper.markPushAsShown(context, pushData.getPushId()); if (pushData.getReceiptMode() == InternalPushData.ReceiptMode.DISPLAY) { displayReceiptModule.scheduleDisplayReceipt(context, pushData); diff --git a/Sources/sdk/src/main/java/com/batch/android/msgpack/MessagePackHelper.java b/Sources/sdk/src/main/java/com/batch/android/msgpack/MessagePackHelper.java index 34b8c19..bb33918 100644 --- a/Sources/sdk/src/main/java/com/batch/android/msgpack/MessagePackHelper.java +++ b/Sources/sdk/src/main/java/com/batch/android/msgpack/MessagePackHelper.java @@ -3,6 +3,7 @@ import com.batch.android.msgpack.core.MessageBufferPacker; import com.batch.android.msgpack.value.Value; import java.math.BigInteger; +import java.net.URI; import java.util.List; import java.util.Map; @@ -30,6 +31,8 @@ public static void packObject(MessageBufferPacker packer, Object object) throws packer.packBoolean((Boolean) object); } else if (object instanceof String) { packer.packString((String) object); + } else if (object instanceof URI) { + packer.packString(object.toString()); } else if (object instanceof Value) { ((Value) object).writeTo(packer); } else if (object instanceof Map) { diff --git a/Sources/sdk/src/main/java/com/batch/android/post/DisplayReceiptPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/DisplayReceiptPostDataProvider.java index bf95570..e1b4fae 100644 --- a/Sources/sdk/src/main/java/com/batch/android/post/DisplayReceiptPostDataProvider.java +++ b/Sources/sdk/src/main/java/com/batch/android/post/DisplayReceiptPostDataProvider.java @@ -1,15 +1,15 @@ package com.batch.android.post; -import com.batch.android.core.Logger; import com.batch.android.displayreceipt.DisplayReceipt; import com.batch.android.msgpack.core.MessageBufferPacker; import com.batch.android.msgpack.core.MessagePack; import java.util.Collection; -public class DisplayReceiptPostDataProvider implements PostDataProvider> { +public class DisplayReceiptPostDataProvider extends MessagePackPostDataProvider> { private static final String TAG = "DisplayReceiptPostDataProvider"; - private Collection receipts; + + private final Collection receipts; public DisplayReceiptPostDataProvider(Collection receipts) { this.receipts = receipts; @@ -20,7 +20,8 @@ public Collection getRawData() { return receipts; } - private byte[] pack() throws Exception { + @Override + byte[] pack() throws Exception { MessageBufferPacker packer = MessagePack.newDefaultBufferPacker(); packer.packArrayHeader(receipts.size()); @@ -32,25 +33,7 @@ private byte[] pack() throws Exception { } @Override - public byte[] getData() { - if (receipts == null || receipts.size() == 0) { - return new byte[0]; - } - - try { - return pack(); - } catch (Exception e) { - Logger.internal(TAG, "Could not pack receipt list", e); - return new byte[0]; - } - } - public boolean isEmpty() { return this.receipts.isEmpty(); } - - @Override - public String getContentType() { - return "application/msgpack"; - } } diff --git a/Sources/sdk/src/main/java/com/batch/android/post/JSONPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/JSONPostDataProvider.java index 70d4719..fdab6c7 100644 --- a/Sources/sdk/src/main/java/com/batch/android/post/JSONPostDataProvider.java +++ b/Sources/sdk/src/main/java/com/batch/android/post/JSONPostDataProvider.java @@ -48,6 +48,11 @@ public String getContentType() { return "application/json"; } + @Override + public boolean isEmpty() { + return data == null || data.length() == 0; + } + @Override public JSONObject getRawData() { return data; diff --git a/Sources/sdk/src/main/java/com/batch/android/post/LocalCampaignsJITPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/LocalCampaignsJITPostDataProvider.java new file mode 100644 index 0000000..72ec78b --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/post/LocalCampaignsJITPostDataProvider.java @@ -0,0 +1,119 @@ +package com.batch.android.post; + +import android.content.Context; +import androidx.annotation.NonNull; +import com.batch.android.WebserviceParameterUtils; +import com.batch.android.core.Logger; +import com.batch.android.di.providers.CampaignManagerProvider; +import com.batch.android.di.providers.RuntimeManagerProvider; +import com.batch.android.di.providers.SQLUserDatasourceProvider; +import com.batch.android.localcampaigns.ViewTracker; +import com.batch.android.localcampaigns.model.LocalCampaign; +import com.batch.android.msgpack.MessagePackHelper; +import com.batch.android.msgpack.core.MessageBufferPacker; +import com.batch.android.msgpack.core.MessagePack; +import com.batch.android.msgpack.core.MessageUnpacker; +import com.batch.android.user.SQLUserDatasource; +import com.batch.android.user.UserAttribute; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LocalCampaignsJITPostDataProvider extends MessagePackPostDataProvider> { + + private static final String TAG = "LocalCampaignsJITPostDataProvider"; + + private static final String IDS_KEY = "ids"; + private static final String CAMPAIGNS_KEY = "campaigns"; + private static final String ATTRIBUTES_KEY = "attributes"; + private static final String VIEWS_KEY = "views"; + private static final String COUNT_KEY = "count"; + private static final String ELIGIBLE_CAMPAIGNS_KEY = "eligibleCampaigns"; + + private final Collection campaigns; + + public LocalCampaignsJITPostDataProvider(Collection campaigns) { + this.campaigns = campaigns; + } + + @Override + public Collection getRawData() { + return campaigns; + } + + @Override + byte[] pack() throws Exception { + ViewTracker viewTracker = CampaignManagerProvider.get().getViewTracker(); + MessageBufferPacker packer = MessagePack.newDefaultBufferPacker(); + + Map postData = new HashMap<>(); + + // Adding system ids + Map ids = new HashMap<>(); + Context context = RuntimeManagerProvider.get().getContext(); + if (context != null) { + ids = WebserviceParameterUtils.getWebserviceIdsAsMap(context); + } + + // Adding campaigns ids to check + List campaignIds = new ArrayList<>(); + for (LocalCampaign campaign : campaigns) { + campaignIds.add(campaign.id); + } + + // Adding views count for each campaign + Map counts = viewTracker.getViewCounts(campaignIds); + Map views = new HashMap<>(); + for (Map.Entry entry : counts.entrySet()) { + Map countMap = new HashMap<>(); + countMap.put(COUNT_KEY, entry.getValue()); + views.put(entry.getKey(), countMap); + } + + // Adding attributes + final SQLUserDatasource datasource = SQLUserDatasourceProvider.get(context); + Map attributes = UserAttribute.getServerMapRepresentation(datasource.getAttributes()); + + postData.put(IDS_KEY, ids); + postData.put(CAMPAIGNS_KEY, campaignIds); + postData.put(ATTRIBUTES_KEY, attributes); + postData.put(VIEWS_KEY, views); + + MessagePackHelper.packObject(packer, postData); + packer.close(); + return packer.toByteArray(); + } + + @NonNull + public List unpack(byte[] data) { + List eligibleCampaigns = new ArrayList<>(); + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(data); + try { + // Unpack root map header + unpacker.unpackMapHeader(); + + // Unpack "eligibleCampaigns" key + String key = unpacker.unpackString(); + + if (ELIGIBLE_CAMPAIGNS_KEY.equals(key)) { + // Unpack list of campaign id + int eligibleCampaignsSize = unpacker.unpackArrayHeader(); + for (int i = 0; i < eligibleCampaignsSize; i++) { + String campaignId = unpacker.unpackString(); + eligibleCampaigns.add(campaignId); + } + } + } catch (IOException e) { + Logger.internal(TAG, "Could not unpack campaign jit response."); + } + return eligibleCampaigns; + } + + @Override + public boolean isEmpty() { + return campaigns.isEmpty(); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/post/MessagePackPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/MessagePackPostDataProvider.java new file mode 100644 index 0000000..b947d02 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/post/MessagePackPostDataProvider.java @@ -0,0 +1,25 @@ +package com.batch.android.post; + +import com.batch.android.core.Logger; + +public abstract class MessagePackPostDataProvider implements PostDataProvider { + + private static final String TAG = "MessagePackPostDataProvider"; + + abstract byte[] pack() throws Exception; + + @Override + public byte[] getData() { + try { + return pack(); + } catch (Exception e) { + Logger.internal(TAG, "Could not pack data", e); + return new byte[0]; + } + } + + @Override + public String getContentType() { + return "application/msgpack"; + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/post/MetricPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/MetricPostDataProvider.java new file mode 100644 index 0000000..b697ce7 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/post/MetricPostDataProvider.java @@ -0,0 +1,38 @@ +package com.batch.android.post; + +import com.batch.android.metrics.model.Metric; +import com.batch.android.msgpack.core.MessageBufferPacker; +import com.batch.android.msgpack.core.MessagePack; +import java.util.Collection; + +public class MetricPostDataProvider extends MessagePackPostDataProvider>> { + + private static final String TAG = "DisplayReceiptPostDataProvider"; + + private final Collection> metrics; + + public MetricPostDataProvider(Collection> metrics) { + this.metrics = metrics; + } + + @Override + public Collection> getRawData() { + return metrics; + } + + @Override + byte[] pack() throws Exception { + MessageBufferPacker packer = MessagePack.newDefaultBufferPacker(); + packer.packArrayHeader(metrics.size()); + for (Metric data : metrics) { + data.pack(packer); + } + packer.close(); + return packer.toByteArray(); + } + + @Override + public boolean isEmpty() { + return this.metrics.isEmpty(); + } +} diff --git a/Sources/sdk/src/main/java/com/batch/android/post/ParametersPostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/ParametersPostDataProvider.java index 655cf82..0225f06 100644 --- a/Sources/sdk/src/main/java/com/batch/android/post/ParametersPostDataProvider.java +++ b/Sources/sdk/src/main/java/com/batch/android/post/ParametersPostDataProvider.java @@ -75,4 +75,9 @@ public byte[] getData() { public String getContentType() { return "application/x-www-form-urlencoded"; } + + @Override + public boolean isEmpty() { + return params.isEmpty(); + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/post/PostDataProvider.java b/Sources/sdk/src/main/java/com/batch/android/post/PostDataProvider.java index 3b89812..5d4f625 100644 --- a/Sources/sdk/src/main/java/com/batch/android/post/PostDataProvider.java +++ b/Sources/sdk/src/main/java/com/batch/android/post/PostDataProvider.java @@ -27,4 +27,10 @@ public interface PostDataProvider { * @return */ String getContentType(); + + /** + * Checks whether this provider is empty or not. + * @return true if empty + */ + boolean isEmpty(); } diff --git a/Sources/sdk/src/main/java/com/batch/android/push/GCMAbstractRegistrationProvider.java b/Sources/sdk/src/main/java/com/batch/android/push/GCMAbstractRegistrationProvider.java index b9e08f1..868986c 100644 --- a/Sources/sdk/src/main/java/com/batch/android/push/GCMAbstractRegistrationProvider.java +++ b/Sources/sdk/src/main/java/com/batch/android/push/GCMAbstractRegistrationProvider.java @@ -71,7 +71,7 @@ public void checkLibraryAvailability() throws PushRegistrationProviderAvailabili throw new PushRegistrationProviderAvailabilityException("Batch.Push : Permission C2D_MESSAGE is missing."); } - if (!isWakeLockPermissionAvailable()) { + if (!GenericHelper.isWakeLockPermissionAvailable(context)) { throw new PushRegistrationProviderAvailabilityException("Batch.Push : Permission WAKE_LOCK is missing."); } } @@ -100,13 +100,4 @@ private boolean isC2DMessagePermissionAvailable() { return false; } } - - private boolean isWakeLockPermissionAvailable() { - try { - return GenericHelper.checkPermission("android.permission.WAKE_LOCK", context); - } catch (Exception e) { - Logger.error(TAG, "Error while checking android.permission.WAKE_LOCK permission", e); - return false; - } - } } diff --git a/Sources/sdk/src/main/java/com/batch/android/query/response/LocalCampaignsResponse.java b/Sources/sdk/src/main/java/com/batch/android/query/response/LocalCampaignsResponse.java index d5937e6..68cd550 100644 --- a/Sources/sdk/src/main/java/com/batch/android/query/response/LocalCampaignsResponse.java +++ b/Sources/sdk/src/main/java/com/batch/android/query/response/LocalCampaignsResponse.java @@ -32,6 +32,11 @@ public class LocalCampaignsResponse extends Response { */ private Long minDisplayInterval; + /** + * Global in-app cappings + */ + private GlobalCappings cappings; + public LocalCampaignsResponse(String queryID) { super(QueryType.LOCAL_CAMPAIGNS, queryID); } @@ -84,6 +89,82 @@ public boolean hasError() { return error != null; } + @Nullable + public GlobalCappings getCappings() { + return cappings; + } + + public void setCappings(GlobalCappings cappings) { + this.cappings = cappings; + } + + public boolean hasCappings() { + return cappings != null; + } + + /** + * Global In-App Cappings + */ + public static class GlobalCappings { + + /** + * Time-Based Capping + * Eg: Display no more than 3 in-apps every 1 hours + */ + public static class TimeBasedCapping { + + /** + * Number of views allowed + */ + private final Integer views; + + /** + * Capping duration (in seconds) + */ + private final Integer duration; + + public TimeBasedCapping(Integer views, Integer duration) { + this.views = views; + this.duration = duration; + } + + @Nullable + public Integer getViews() { + return views; + } + + @Nullable + public Integer getDuration() { + return duration; + } + } + + /** + * Number of in-apps displayable during a user session + */ + private final Integer session; + + /** + * List of time-based cappings + */ + private final List timeBasedCappings; + + public GlobalCappings(Integer session, List timeBasedCappings) { + this.session = session; + this.timeBasedCappings = timeBasedCappings; + } + + @Nullable + public Integer getSession() { + return session; + } + + @Nullable + public List getTimeBasedCappings() { + return timeBasedCappings; + } + } + public static class Error { /** diff --git a/Sources/sdk/src/main/java/com/batch/android/query/serialization/deserializers/LocalCampaignsResponseDeserializer.java b/Sources/sdk/src/main/java/com/batch/android/query/serialization/deserializers/LocalCampaignsResponseDeserializer.java index 7e0e7a0..9f7c988 100644 --- a/Sources/sdk/src/main/java/com/batch/android/query/serialization/deserializers/LocalCampaignsResponseDeserializer.java +++ b/Sources/sdk/src/main/java/com/batch/android/query/serialization/deserializers/LocalCampaignsResponseDeserializer.java @@ -1,5 +1,7 @@ package com.batch.android.query.serialization.deserializers; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.batch.android.core.Logger; import com.batch.android.json.JSONArray; import com.batch.android.json.JSONException; @@ -53,16 +55,84 @@ public LocalCampaignsResponse deserialize() throws JSONException { JSONArray jsonCampaigns = json.optJSONArray("campaigns"); List campaigns = localCampaignDeserializer.deserializeList(jsonCampaigns); response.setCampaigns(campaigns); + response.setMinDisplayInterval(minDisplayInterval); + + LocalCampaignsResponse.GlobalCappings cappings = deserializeCappings(); + response.setCappings(cappings); + return response; } + /** + * Only deserialize the local campaigns from the json response + * @return A list of LocalCampaign + */ + @NonNull + public List deserializeCampaigns() { + JSONArray jsonCampaigns = json.optJSONArray("campaigns"); + return localCampaignDeserializer.deserializeList(jsonCampaigns); + } + + /** + * Only deserialize the global in-app cappings from the json response + * + * @return the LocalCampaignsResponse.GlobalCappings + * @throws JSONException parsing exception + */ + @Nullable + public LocalCampaignsResponse.GlobalCappings deserializeCappings() throws JSONException { + LocalCampaignsResponse.GlobalCappings cappings = null; + if (json != null && json.hasNonNull("cappings")) { + JSONObject jsonCappings = json.getJSONObject("cappings"); + + Integer session = jsonCappings.reallyOptInteger("session", null); + + List timeBasedCappings = null; + + if (jsonCappings.hasNonNull("time")) { + timeBasedCappings = parseTimeBasedCappings(jsonCappings.getJSONArray("time")); + } + cappings = new LocalCampaignsResponse.GlobalCappings(session, timeBasedCappings); + } + return cappings; + } + + /** + * Parse a json array into a list of Time-Based Cappings + * + * @param json time based capping array + * @return the LocalCampaignsResponse.GlobalCappings.TimeBasedCapping list + */ + @Nullable + private List parseTimeBasedCappings(JSONArray json) { + List timeBasedCappings = new ArrayList<>(); + for (int i = 0; i < json.length(); i++) { + try { + JSONObject jsonTimeBasedCapping = json.getJSONObject(i); + Integer views = jsonTimeBasedCapping.reallyOptInteger("views", null); + Integer duration = jsonTimeBasedCapping.reallyOptInteger("duration", null); + if (views != null && views != 0 && duration != null && duration != 0) { + LocalCampaignsResponse.GlobalCappings.TimeBasedCapping timeBasedCapping = new LocalCampaignsResponse.GlobalCappings.TimeBasedCapping( + views, + duration + ); + timeBasedCappings.add(timeBasedCapping); + } + } catch (Exception e) { + Logger.internal(TAG, "An error occurred while parsing an In-App TimeBasedCapping. Skipping.", e); + } + } + return timeBasedCappings.isEmpty() ? null : timeBasedCappings; + } + /** * Parse error response if there's one * * @return LocalCampaignsResponse.Error || null * @throws JSONException parsing exception */ + @Nullable private LocalCampaignsResponse.Error parseError() throws JSONException { LocalCampaignsResponse.Error error = null; if (json != null && json.hasNonNull("error")) { diff --git a/Sources/sdk/src/main/java/com/batch/android/query/serialization/serializers/LocalCampaignsResponseSerializer.java b/Sources/sdk/src/main/java/com/batch/android/query/serialization/serializers/LocalCampaignsResponseSerializer.java index 2aa597a..ca0f393 100644 --- a/Sources/sdk/src/main/java/com/batch/android/query/serialization/serializers/LocalCampaignsResponseSerializer.java +++ b/Sources/sdk/src/main/java/com/batch/android/query/serialization/serializers/LocalCampaignsResponseSerializer.java @@ -1,42 +1,33 @@ package com.batch.android.query.serialization.serializers; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.batch.android.json.JSONArray; import com.batch.android.json.JSONException; import com.batch.android.json.JSONObject; +import com.batch.android.localcampaigns.model.LocalCampaign; import com.batch.android.localcampaigns.serialization.LocalCampaignSerializer; import com.batch.android.query.response.LocalCampaignsResponse; +import java.util.List; /** * Serializer class for {@link LocalCampaignsResponse} */ public class LocalCampaignsResponseSerializer { - /** - * Initial local campaign response object - */ - private final LocalCampaignsResponse response; - /** * Local campaign serializer */ private final LocalCampaignSerializer localCampaignSerializer = new LocalCampaignSerializer(); /** - * Constructor - * - * @param response initial response object - */ - public LocalCampaignsResponseSerializer(LocalCampaignsResponse response) { - this.response = response; - } - - /** + * (Method not used) * Serialize a LocalCampaignsResponse to a JSONObject * * @return local campaigns response serialized * @throws JSONException parsing exception */ - public JSONObject serialize() throws JSONException { + public JSONObject serialize(LocalCampaignsResponse response) throws JSONException { if (response == null) { throw new JSONException("Cannot serialize a null response"); } @@ -48,6 +39,46 @@ public JSONObject serialize() throws JSONException { } JSONArray jsonCampaigns = localCampaignSerializer.serializeList(response.getCampaigns()); jsonLocalCampaignResponse.put("campaigns", jsonCampaigns); + + JSONObject jsonCappings = serializeCappings(response.getCappings()); + jsonLocalCampaignResponse.putOpt("cappings", jsonCappings); return jsonLocalCampaignResponse; } + + /** + * Serialize a list of campaigns into a json array + * @param campaigns to serialize + * @return serialized campaigns + * @throws JSONException parsing exception + */ + @NonNull + public JSONArray serializeCampaigns(List campaigns) throws JSONException { + return localCampaignSerializer.serializeList(campaigns); + } + + /** + * Serialize global in-app cappings into a json object + * @param cappings to serialize + * @return serialized cappings + * @throws JSONException parsing exception + */ + @Nullable + public JSONObject serializeCappings(LocalCampaignsResponse.GlobalCappings cappings) throws JSONException { + if (cappings != null) { + JSONObject jsonGlobalCapping = new JSONObject(); + jsonGlobalCapping.putOpt("session", cappings.getSession()); + if (cappings.getTimeBasedCappings() != null) { + JSONArray jsonTimeBasedCappings = new JSONArray(); + for (LocalCampaignsResponse.GlobalCappings.TimeBasedCapping timeBasedCapping : cappings.getTimeBasedCappings()) { + JSONObject jsonTimeBasedCapping = new JSONObject(); + jsonTimeBasedCapping.put("views", timeBasedCapping.getViews()); + jsonTimeBasedCapping.put("duration", timeBasedCapping.getDuration()); + jsonTimeBasedCappings.put(jsonTimeBasedCapping); + } + jsonGlobalCapping.put("time", jsonTimeBasedCappings); + } + return jsonGlobalCapping; + } + return null; + } } diff --git a/Sources/sdk/src/main/java/com/batch/android/runtime/RuntimeManager.java b/Sources/sdk/src/main/java/com/batch/android/runtime/RuntimeManager.java index 7be5c42..c8b2ce1 100644 --- a/Sources/sdk/src/main/java/com/batch/android/runtime/RuntimeManager.java +++ b/Sources/sdk/src/main/java/com/batch/android/runtime/RuntimeManager.java @@ -6,6 +6,7 @@ import android.os.Handler; import android.os.Looper; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.batch.android.core.Logger; import com.batch.android.debug.FindMyInstallationHelper; @@ -365,6 +366,7 @@ public void setContext(Context context) { * * @return context or null */ + @Nullable public Context getContext() { return context; } diff --git a/Sources/sdk/src/main/java/com/batch/android/runtime/SessionManager.java b/Sources/sdk/src/main/java/com/batch/android/runtime/SessionManager.java index 49a8e11..03a7fcc 100644 --- a/Sources/sdk/src/main/java/com/batch/android/runtime/SessionManager.java +++ b/Sources/sdk/src/main/java/com/batch/android/runtime/SessionManager.java @@ -8,11 +8,15 @@ import android.content.res.Configuration; import android.os.Bundle; import android.os.SystemClock; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.batch.android.core.ExcludedActivityHelper; import com.batch.android.core.Logger; import com.batch.android.core.Parameters; +import com.batch.android.di.providers.CampaignManagerProvider; import com.batch.android.di.providers.LocalBroadcastManagerProvider; +import com.batch.android.di.providers.LocalCampaignsModuleProvider; +import com.batch.android.localcampaigns.LocalCampaignsTracker; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -57,11 +61,6 @@ public String getSessionIdentifier() { return sessionIdentifier; } - public synchronized boolean isSessionActive() { - invalidateSessionIfNeeded(); - return sessionActive; - } - private synchronized void invalidateSessionIfNeeded() { if ( sessionActive && @@ -73,11 +72,17 @@ private synchronized void invalidateSessionIfNeeded() { } } - synchronized void startNewSessionIfNeeded(Context c) { + synchronized void startNewSessionIfNeeded(@NonNull Context c) { invalidateSessionIfNeeded(); if (!sessionActive) { sessionActive = true; sessionIdentifier = UUID.randomUUID().toString(); + + // Reset the view tracker session count + LocalCampaignsTracker tracker = (LocalCampaignsTracker) CampaignManagerProvider.get().getViewTracker(); + tracker.resetSessionViewsCount(); + + // Broadcast the new session intent Logger.internal(TAG, "Starting a new session, id: '" + sessionIdentifier + "'"); LocalBroadcastManagerProvider.get(c).sendBroadcast(new Intent(INTENT_NEW_SESSION)); } diff --git a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/DisplayReceiptWebserviceListener.java b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/DisplayReceiptWebserviceListener.java index 82a8828..e71df79 100644 --- a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/DisplayReceiptWebserviceListener.java +++ b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/DisplayReceiptWebserviceListener.java @@ -14,7 +14,7 @@ public interface DisplayReceiptWebserviceListener { /** * Called when a request fail * - * @param error + * @param error webservice request error */ void onFailure(Webservice.WebserviceError error); } diff --git a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/LocalCampaignsJITWebserviceListener.java b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/LocalCampaignsJITWebserviceListener.java new file mode 100644 index 0000000..2af3dfb --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/LocalCampaignsJITWebserviceListener.java @@ -0,0 +1,22 @@ +package com.batch.android.webservice.listener; + +import com.batch.android.core.Webservice; +import java.util.List; + +/** + * Listener for LocalCampaignsJITWebservice + */ + +public interface LocalCampaignsJITWebserviceListener { + /** + * Called on success + */ + void onSuccess(List eligibleCampaigns); + + /** + * Called on error + * + * @param error webservice error + */ + void onFailure(Webservice.WebserviceError error); +} diff --git a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/MetricWebserviceListener.java b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/MetricWebserviceListener.java new file mode 100644 index 0000000..9c17594 --- /dev/null +++ b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/MetricWebserviceListener.java @@ -0,0 +1,20 @@ +package com.batch.android.webservice.listener; + +import com.batch.android.core.Webservice; + +/** + * Listener for the metric webservice + */ +public interface MetricWebserviceListener { + /** + * Called when a request succeed + */ + void onSuccess(); + + /** + * Called when a request fail + * + * @param error error + */ + void onFailure(Webservice.WebserviceError error); +} diff --git a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/impl/LocalCampaignsWebserviceListenerImpl.java b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/impl/LocalCampaignsWebserviceListenerImpl.java index d5a78c5..c591be1 100644 --- a/Sources/sdk/src/main/java/com/batch/android/webservice/listener/impl/LocalCampaignsWebserviceListenerImpl.java +++ b/Sources/sdk/src/main/java/com/batch/android/webservice/listener/impl/LocalCampaignsWebserviceListenerImpl.java @@ -5,7 +5,6 @@ import com.batch.android.di.providers.CampaignManagerProvider; import com.batch.android.di.providers.LocalCampaignsModuleProvider; import com.batch.android.localcampaigns.CampaignManager; -import com.batch.android.localcampaigns.signal.CampaignsRefreshedSignal; import com.batch.android.module.LocalCampaignsModule; import com.batch.android.processor.Module; import com.batch.android.processor.Provide; @@ -20,6 +19,7 @@ public class LocalCampaignsWebserviceListenerImpl implements LocalCampaignsWebserviceListener { private LocalCampaignsModule localCampaignsModule; + private CampaignManager campaignManager; private LocalCampaignsWebserviceListenerImpl( @@ -48,10 +48,12 @@ public void onSuccess(List responses) { @Override public void onError(FailReason reason) { Logger.internal(LocalCampaignsModule.TAG, "Error while refreshing local campaigns: " + reason.toString()); + localCampaignsModule.onLocalCampaignsWebserviceFinished(); } private void handleInAppResponse(LocalCampaignsResponse response) { + campaignManager.setCappings(response.getCappings()); campaignManager.updateCampaignList(response.getCampaigns()); - localCampaignsModule.sendSignal(new CampaignsRefreshedSignal()); + localCampaignsModule.onLocalCampaignsWebserviceFinished(); } } diff --git a/Sources/sdk/src/test/java/com/batch/android/BatchPushMessageReceiverTest.kt b/Sources/sdk/src/test/java/com/batch/android/BatchPushMessageReceiverTest.kt new file mode 100644 index 0000000..a467f32 --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/BatchPushMessageReceiverTest.kt @@ -0,0 +1,98 @@ +package com.batch.android + +import android.content.Context +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import org.junit.After +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import java.util.* + +@RunWith(AndroidJUnit4::class) +@SmallTest +class BatchPushMessageReceiverTest { + + companion object { + const val EXTRA_MSG_TYPE = "message_type" + } + + val context: Context = ApplicationProvider.getApplicationContext() + + @After + fun tearDown() { + BatchPushMessageReceiver.resetHandledMessageIDs() + } + + @Test + fun testMessageDeduplication() { + val receiver = ObservablePushMessageReceiver() + + // Test that unique message IDs are all handled + for (i in 0..BatchPushMessageReceiver.MAX_HANDLED_MESSAGE_IDS_COUNT + 10) { + receiver.reset() + receiver.onReceive(context, makeMessageIntent(null)) + Assert.assertTrue(receiver.presentNotificationCalled) + } + + // We looped more than MAX_HANDLED_MESSAGE_IDS_COUNT, test that the receiver isn't leaking + // memory by storing infinite IDs + Assert.assertEquals(BatchPushMessageReceiver.MAX_HANDLED_MESSAGE_IDS_COUNT, + BatchPushMessageReceiver.getHandledMessageIDsSize()) + + // Test that multiple pushes are deduplicated + val duplicateMessageID = UUID.randomUUID().toString() + receiver.reset() + receiver.onReceive(context, makeMessageIntent(duplicateMessageID)) + Assert.assertTrue(receiver.presentNotificationCalled) + receiver.reset() + receiver.onReceive(context, makeMessageIntent(null)) + Assert.assertTrue(receiver.presentNotificationCalled) + receiver.reset() + receiver.onReceive(context, makeMessageIntent(duplicateMessageID)) + Assert.assertFalse(receiver.presentNotificationCalled) + } + + @Test + fun testIgnoresNonFCMMessages() { + val receiver = ObservablePushMessageReceiver() + val intent = Intent() + + receiver.onReceive(context, intent) + Assert.assertTrue(receiver.presentNotificationCalled) + + receiver.reset() + intent.putExtra(EXTRA_MSG_TYPE, "gcm") + Assert.assertFalse(receiver.presentNotificationCalled) + + receiver.reset() + intent.putExtra(EXTRA_MSG_TYPE, "data") + Assert.assertFalse(receiver.presentNotificationCalled) + } + + private fun makeMessageIntent(forceID: String?): Intent { + val identifier = forceID ?: UUID.randomUUID().toString() + + return Intent().apply { + putExtra("msg", "test message") + putExtra("com.batch", "{}") + putExtra(EXTRA_MSG_TYPE, "gcm") + putExtra("google.message_id", identifier) + } + } +} + +private class ObservablePushMessageReceiver: BatchPushMessageReceiver() { + var presentNotificationCalled = false + + override fun presentNotification(context: Context, intent: Intent): Boolean { + presentNotificationCalled = true + return true + } + + fun reset() { + presentNotificationCalled = false + } +} \ No newline at end of file diff --git a/Sources/sdk/src/test/java/com/batch/android/inbox/InboxNotificationContentParsingTest.kt b/Sources/sdk/src/test/java/com/batch/android/inbox/InboxNotificationContentParsingTest.kt new file mode 100644 index 0000000..ef3c907 --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/inbox/InboxNotificationContentParsingTest.kt @@ -0,0 +1,110 @@ +package com.batch.android.inbox + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.batch.android.Batch +import com.batch.android.BatchInboxNotificationContent +import com.batch.android.BatchNotificationSource +import com.batch.android.PrivateNotificationContentHelper +import com.batch.android.json.JSONObject +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import java.util.* + +@RunWith(AndroidJUnit4::class) +@SmallTest +class InboxNotificationContentParsingTest { + + val now = Date() + val notifID = UUID.randomUUID().toString() + + @Test + fun testPayloadParsing() { + // Test multiple combinations of payloads + + var payload = addMessageToPayload(makeBaseNotificationPayload(), "foo", "bar") + var content: BatchInboxNotificationContent = makePublicNotification(payload) + Assert.assertEquals("foo", content.body) + Assert.assertEquals("bar", content.title) + Assert.assertTrue(content.isUnread) + Assert.assertFalse(content.isDeleted) + Assert.assertFalse(content.isSilent) + Assert.assertEquals("https://batch.com", content.pushPayload.deeplink) + Assert.assertEquals(now, content.date) + Assert.assertEquals(notifID, content.notificationIdentifier) + Assert.assertEquals(BatchNotificationSource.TRANSACTIONAL, content.source) + + payload = addMessageToPayload(makeBaseNotificationPayload(), "foo", null) + payload.put("read", true) + payload.getJSONObject("payload").getJSONObject("com.batch").put("t", "c") + content = makePublicNotification(payload) + Assert.assertEquals("foo", content.body) + Assert.assertNull(content.title) + Assert.assertFalse(content.isUnread) + Assert.assertFalse(content.isDeleted) + Assert.assertFalse(content.isSilent) + Assert.assertEquals(BatchNotificationSource.CAMPAIGN, content.source) + } + + @Test + fun testSilentNotificationDetection() { + // Test that a notification with no title and no body is silent + + var payload = addMessageToPayload(makeBaseNotificationPayload(), null, null) + var content: BatchInboxNotificationContent = makePublicNotification(payload) + Assert.assertTrue(content.isSilent) + + // Test that a notification with a title and no body is silent + payload = addMessageToPayload(makeBaseNotificationPayload(), null, "bar") + content = makePublicNotification(payload) + Assert.assertTrue(content.isSilent) + + // Test that a notification with a title and body BUT with the "s" flag in com.batch is silent + payload = addMessageToPayload(makeBaseNotificationPayload(), null, null) + payload.getJSONObject("payload").getJSONObject("com.batch").put("s", true) + content = makePublicNotification(payload) + Assert.assertTrue(content.isSilent) + + // Test that a notification with a body is not silent + payload = addMessageToPayload(makeBaseNotificationPayload(), "foo", null) + content = makePublicNotification(payload) + Assert.assertFalse(content.isSilent) + } + + private fun makeBaseNotificationPayload(): JSONObject { + return JSONObject().apply { + put("notificationId", notifID) + put("sendId", "abcdeff") + put("notificationTime", now.time) + put("payload", JSONObject().apply { + put("com.batch", JSONObject().apply { + put("t", "t") + put("at", JSONObject().apply { + put("u", "https://batch.com") + }) + put("od", JSONObject().apply { + put("n", "5a3c93c0-7a3b-0000-0000-69f412b0000000") + }) + put("l", "https://batch.com") + put("i", "6y4g8guj-u1586420592376_000000") + }) + }) + } + } + + private fun addMessageToPayload(rootPayload: JSONObject, body: String?, title: String?): JSONObject { + val payload = rootPayload.getJSONObject("payload") + body?.let { + payload.put(Batch.Push.BODY_KEY, body) + } + title?.let { + payload.put(Batch.Push.TITLE_KEY, title) + } + return rootPayload + } + + private fun makePublicNotification(payload: JSONObject): BatchInboxNotificationContent { + return InboxFetchWebserviceClient.parseNotification(payload).let(PrivateNotificationContentHelper::getPublicContent) + } +} \ No newline at end of file diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/CampaignManagerTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/CampaignManagerTest.java index c449a46..9bab711 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/CampaignManagerTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/CampaignManagerTest.java @@ -1,8 +1,10 @@ package com.batch.android.localcampaigns; +import static com.batch.android.localcampaigns.model.LocalCampaign.SyncedJITResult; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -27,12 +29,18 @@ import java.io.InputStreamReader; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.powermock.reflect.Whitebox; @RunWith(AndroidJUnit4.class) @MediumTest @@ -41,14 +49,14 @@ public class CampaignManagerTest { private Context context; private CampaignManager campaignManager; private JSONObject jsonCampaigns; - private LocalCampaignsSQLTracker tracker; + private LocalCampaignsTracker tracker; @Before public void setUp() throws IOException, JSONException { context = ApplicationProvider.getApplicationContext(); RuntimeManagerProvider.get().setContext(context); - tracker = new LocalCampaignsSQLTracker(); + tracker = new LocalCampaignsTracker(); campaignManager = new CampaignManager(tracker); // Read fake campaigns file @@ -73,7 +81,7 @@ public void testSaveCampaigns() throws NoSuchFieldException, IllegalAccessExcept removeExistingSave(); assertFalse(campaignManager.hasSavedCampaigns(context)); LocalCampaignsResponse response = new LocalCampaignsResponseDeserializer(jsonCampaigns).deserialize(); - campaignManager.saveCampaigns(context, response.getCampaigns()); + campaignManager.saveCampaigns(context, response); assertTrue(campaignManager.hasSavedCampaigns(context)); removeExistingSave(); @@ -100,12 +108,14 @@ public void testSaveAndLoadCampaigns() throws NoSuchFieldException, IllegalAcces // Save using the code that will actually save the response in production, rather // than reimplementing it in the tests. LocalCampaignsResponse response = new LocalCampaignsResponseDeserializer(jsonCampaigns).deserialize(); - campaignManager.saveCampaigns(context, response.getCampaigns()); + campaignManager.saveCampaigns(context, response); assertTrue(campaignManager.hasSavedCampaigns(context)); assertEquals(0, campaignManager.getCampaignList().size()); + assertNull(campaignManager.getCappings()); campaignManager.loadSavedCampaignResponse(context); assertEquals(1, campaignManager.getCampaignList().size()); + assertNotNull(campaignManager.getCappings()); removeExistingSave(); assertFalse(campaignManager.hasSavedCampaigns(context)); @@ -115,11 +125,31 @@ public void testSaveAndLoadCampaigns() throws NoSuchFieldException, IllegalAcces public void testLoadCampaigns() throws NoSuchFieldException, IllegalAccessException, JSONException { removeExistingSave(); LocalCampaignsResponse response = new LocalCampaignsResponseDeserializer(jsonCampaigns).deserialize(); - campaignManager.saveCampaigns(context, response.getCampaigns()); + campaignManager.saveCampaigns(context, response); assertTrue(campaignManager.getCampaignList().isEmpty()); + assertNull(campaignManager.getCappings()); campaignManager.loadSavedCampaignResponse(context); assertFalse(campaignManager.getCampaignList().isEmpty()); + assertNotNull(campaignManager.getCappings()); + } + + @Test + public void testLoadExpiredCampaigns() throws JSONException, NoSuchFieldException, IllegalAccessException { + removeExistingSave(); + + final BatchDate fakeCurrentDate = new UTCDate(0); + Field dateProviderField = CampaignManager.class.getDeclaredField("dateProvider"); + dateProviderField.setAccessible(true); + dateProviderField.set(campaignManager, (DateProvider) () -> fakeCurrentDate); + + LocalCampaignsResponse response = new LocalCampaignsResponseDeserializer(jsonCampaigns).deserialize(); + campaignManager.saveCampaigns(context, response); + + fakeCurrentDate.setTime(TimeUnit.DAYS.toMillis(15)); + + campaignManager.loadSavedCampaignResponse(context); + assertTrue(campaignManager.getCampaignList().isEmpty()); } @Test @@ -171,6 +201,45 @@ public void testCapping() assertTrue(campaignManager.isCampaignOverCapping(campaign, true)); } + @Test + public void testGlobalCapping() + throws JSONException, NoSuchFieldException, IllegalAccessException, ViewTrackerUnavailableException { + // Load cappings from the json local campaign response (2/session & 1/h) + reloadCampaigns(); + + // Setting fake date provider + final BatchDate fakeCurrentDate = new UTCDate(0); + Field dateProviderField = CampaignManager.class.getDeclaredField("dateProvider"); + dateProviderField.setAccessible(true); + dateProviderField.set(campaignManager, (DateProvider) () -> fakeCurrentDate); + + DateProvider oldDateProvider = tracker.getDateProvider(); + tracker.setDateProvider(() -> fakeCurrentDate); + + assertFalse(campaignManager.isOverGlobalCappings()); + + campaignManager.getViewTracker().trackViewEvent("campaign_id"); + + // We have reached time-based capping + assertTrue(campaignManager.isOverGlobalCappings()); + + // Adding 1h + fakeCurrentDate.setTime(3600 * 1000); + + // time-based capping released + assertFalse(campaignManager.isOverGlobalCappings()); + + campaignManager.getViewTracker().trackViewEvent("campaign_id"); + + // Adding 1h + fakeCurrentDate.setTime(3600 * 1000); + + // We have reached the session capping + assertTrue(campaignManager.isOverGlobalCappings()); + + tracker.setDateProvider(oldDateProvider); + } + @Test public void testGracePeriod() throws NoSuchFieldException, IllegalAccessException, ViewTrackerUnavailableException, JSONException { @@ -289,9 +358,81 @@ public void testPriority() throws NoSuchFieldException, IllegalAccessException { campaignManager.updateCampaignList(fakeCampaigns); - LocalCampaign campainToDisplay = campaignManager.getCampaignToDisplay(trigger -> true); + List eligibleCampaigns = campaignManager.getEligibleCampaignsSortedByPriority(trigger -> true); + + assertFalse(eligibleCampaigns.isEmpty()); + assertSame(highPriorityCampaign, eligibleCampaigns.get(0)); + } + + @Test + public void testGetEligibleCampaignsRequiringSync() { + List fakeCampaigns = new ArrayList<>(); + fakeCampaigns.add(createFakeCampaignWithPriority(0)); + fakeCampaigns.add(createFakeCampaignWithPriority(10)); + Assert.assertEquals(0, campaignManager.getFirstEligibleCampaignsRequiringSync(fakeCampaigns).size()); + LocalCampaign jitCampaign = createFakeCampaignWithPriority(0); + jitCampaign.requiresJustInTimeSync = true; + fakeCampaigns.add(0, jitCampaign); + Assert.assertEquals(jitCampaign, campaignManager.getFirstEligibleCampaignsRequiringSync(fakeCampaigns).get(0)); + } + + @Test + public void testGetFirstCampaignNotRequiringJITSync() { + List fakeCampaigns = new ArrayList<>(); + LocalCampaign jitCampaign = createFakeCampaignWithPriority(0); + jitCampaign.requiresJustInTimeSync = true; + fakeCampaigns.add(jitCampaign); + LocalCampaign expectedCampaign = createFakeCampaignWithPriority(0); + fakeCampaigns.add(expectedCampaign); + Assert.assertEquals(expectedCampaign, campaignManager.getFirstCampaignNotRequiringJITSync(fakeCampaigns)); + } + + @Test + public void testIsJITServiceAvailable() { + Assert.assertTrue(campaignManager.isJITServiceAvailable()); + Whitebox.setInternalState(campaignManager, "nextAvailableJITTimestamp", new Date().getTime() + 1000L); + Assert.assertFalse(campaignManager.isJITServiceAvailable()); + } + + @Test + public void testGetSyncedJITCampaignState() throws NoSuchFieldException, IllegalAccessException { + // Get synced jit campaign from manager + Field syncedCampaignsField = CampaignManager.class.getDeclaredField("syncedJITCampaigns"); + syncedCampaignsField.setAccessible(true); + Map syncedCampaigns = (HashMap) syncedCampaignsField.get( + campaignManager + ); + + // Replace the SecureDateProvider with a fake DateProvider + final BatchDate fakeCurrentDate = new UTCDate(0); + Field dateProviderField = CampaignManager.class.getDeclaredField("dateProvider"); + dateProviderField.setAccessible(true); + dateProviderField.set(campaignManager, (DateProvider) () -> fakeCurrentDate); + + // Ensure non-jit campaign is return as eligible + LocalCampaign campaign = createFakeCampaignWithPriority(0); + Assert.assertEquals(SyncedJITResult.State.ELIGIBLE, campaignManager.getSyncedJITCampaignState(campaign)); + + // Ensure non-cached jit campaign requires a sync + campaign.requiresJustInTimeSync = true; + assert syncedCampaigns != null; + Assert.assertEquals(SyncedJITResult.State.REQUIRES_SYNC, campaignManager.getSyncedJITCampaignState(campaign)); + + // Adding fake synced jit result in cache + SyncedJITResult result = new SyncedJITResult(fakeCurrentDate.getTime()); + result.eligible = false; + syncedCampaigns.put(campaign.id, result); + + // Ensure cached jit campaign is not eligible + Assert.assertEquals(SyncedJITResult.State.NOT_ELIGIBLE, campaignManager.getSyncedJITCampaignState(campaign)); + + // Ensure cached jit campaign is eligible + result.eligible = true; + Assert.assertEquals(SyncedJITResult.State.ELIGIBLE, campaignManager.getSyncedJITCampaignState(campaign)); - assertSame(highPriorityCampaign, campainToDisplay); + // Ensure cached jit campaign requires a new sync + fakeCurrentDate.setTime(30_000); + Assert.assertEquals(SyncedJITResult.State.REQUIRES_SYNC, campaignManager.getSyncedJITCampaignState(campaign)); } private void removeExistingSave() throws NoSuchFieldException, IllegalAccessException { @@ -315,7 +456,7 @@ private void removeExistingSave() throws NoSuchFieldException, IllegalAccessExce private void reloadCampaigns() throws NoSuchFieldException, IllegalAccessException, JSONException { removeExistingSave(); LocalCampaignsResponse response = new LocalCampaignsResponseDeserializer(jsonCampaigns).deserialize(); - campaignManager.saveCampaigns(context, response.getCampaigns()); + campaignManager.saveCampaigns(context, response); campaignManager.loadSavedCampaignResponse(context); } diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/EventTriggerTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/EventTriggerTest.java index 6fb0e8e..cfec041 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/EventTriggerTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/EventTriggerTest.java @@ -2,6 +2,7 @@ import static org.mockito.ArgumentMatchers.argThat; +import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.rule.ActivityTestRule; @@ -43,7 +44,7 @@ public void setUp() { LocalCampaignsModule module = DITestUtils.mockSingletonDependency(LocalCampaignsModule.class, null); simulateBatchStart(activityRule.getActivity()); - module.batchDidStart(); + module.batchContextBecameAvailable(ApplicationProvider.getApplicationContext()); } @After @@ -90,6 +91,9 @@ public void testCampaignDisplayedAfterEventTracked() CampaignManagerProvider.get().updateCampaignList(Collections.singletonList(campaign)); + // Simulate synchro is finished + LocalCampaignsModuleProvider.get().onLocalCampaignsWebserviceFinished(); + // Track the event which is linked to the Local Campaign Batch.User.trackEvent(EVENT_NAME_TEST); diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsModuleTests.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsModuleTests.java new file mode 100644 index 0000000..a502774 --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsModuleTests.java @@ -0,0 +1,70 @@ +package com.batch.android.localcampaigns; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import com.batch.android.di.DI; +import com.batch.android.di.DITestUtils; +import com.batch.android.di.providers.CampaignManagerProvider; +import com.batch.android.di.providers.LandingOutputProvider; +import com.batch.android.di.providers.LocalCampaignsModuleProvider; +import com.batch.android.json.JSONObject; +import com.batch.android.localcampaigns.model.LocalCampaign; +import com.batch.android.localcampaigns.signal.NewSessionSignal; +import com.batch.android.localcampaigns.signal.Signal; +import com.batch.android.localcampaigns.trigger.NextSessionTrigger; +import com.batch.android.module.LocalCampaignsModule; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.LinkedList; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LocalCampaignsModuleTests { + + @Before + public void setup() { + DI.reset(); + LocalCampaignsModule module = DITestUtils.mockSingletonDependency(LocalCampaignsModule.class, null); + module.batchDidStart(); + } + + @After + public void teardown() { + DI.reset(); + } + + @Test + public void testSignalQueue() throws NoSuchFieldException, IllegalAccessException, InterruptedException { + LocalCampaignsModule module = LocalCampaignsModuleProvider.get(); + + Field signalQueueField = LocalCampaignsModule.class.getDeclaredField("signalQueue"); + signalQueueField.setAccessible(true); + LinkedList signalQueue = (LinkedList) signalQueueField.get(module); + + Field isReadyField = LocalCampaignsModule.class.getDeclaredField("isReady"); + isReadyField.setAccessible(true); + AtomicBoolean isReady = (AtomicBoolean) isReadyField.get(module); + + assert signalQueue != null; + assert isReady != null; + + Assert.assertFalse(isReady.get()); + Assert.assertEquals(0, signalQueue.size()); + + module.sendSignal(new NewSessionSignal()); + Assert.assertEquals(1, signalQueue.size()); + + // Simulate synchro is finished + module.onLocalCampaignsWebserviceFinished(); + + Assert.assertTrue(isReady.get()); + Assert.assertEquals(0, signalQueue.size()); + } +} diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsResponseFactory.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsResponseFactory.java index 988b0ae..16a79c1 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsResponseFactory.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsResponseFactory.java @@ -12,12 +12,27 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.List; public class LocalCampaignsResponseFactory { public LocalCampaignsResponse createLocalCampaignsResponse() throws JSONException { LocalCampaignsResponse response = new LocalCampaignsResponse("dummy_id"); response.setCampaigns(new ArrayList<>()); + + // Global cappings + List timeBasedCappings = new ArrayList<>(); + LocalCampaignsResponse.GlobalCappings.TimeBasedCapping timeBasedCapping = new LocalCampaignsResponse.GlobalCappings.TimeBasedCapping( + 2, + 3600 + ); + timeBasedCappings.add(timeBasedCapping); + LocalCampaignsResponse.GlobalCappings cappings = new LocalCampaignsResponse.GlobalCappings( + 2, + timeBasedCappings + ); + response.setCappings(cappings); + // Local campaigns LocalCampaign campaign = new LocalCampaign(); campaign.id = "25876676"; campaign.capping = 3; @@ -36,6 +51,7 @@ public LocalCampaignsResponse createLocalCampaignsResponse() throws JSONExceptio "{\n \"type\":\"LANDING\",\n \"payload\":{\n \"kind\":\"universal\",\n \"id\":\"webtest\",\n \"did\":\"webtest\",\n \"hero\":\"https://static.batch.com.s3.eu-west-1.amazonaws.com/documentation/logo_batch_full_178.png\",\n \"h1\":\"WOW\",\n \"h2\":\"Ho\",\n \"h3\":\"Subtitle\",\n \"body\":\"This is a NEXT_SESSION triggered campaign.\",\n \"close\":true,\n \"cta\":[\n {\n \"l\":\"Okay!\",\n \"a\":null,\n \"args\":{\n \n }\n },\n {\n \"l\":\"Okay!2\",\n \"a\":null,\n \"args\":{\n \n }\n }\n ],\n \"style\":\"#image-cnt {blur: 200;} #image {border-radius: 10; margin-left: 30; margin-right: 30; margin-top: 40;} #placeholder{background-color:#018BAA;}#content {\\n background-color: #018BFF;\\n height: 100%\\n padding-top: 24;\\n padding-left: 20;\\n padding-right: 20;\\n padding-bottom: 20;\\n}\\n#h1 {\\n color: #018BFF;\\n padding-left: 15;\\n padding-right: 15;\\n padding-top: 4;\\n padding-bottom: 4;\\n border-radius: 12;\\n background-color:white;\\n font-weight: bold;\\n font-size: 12;\\n height: 24;\\n width: auto;\\n}\\n#h2 {\\n margin-top: 24;\\n color: white;\\n font-weight: bold;\\n font-size: 35;\\n}\\n#body {\\n color: #80C5FF;\\n}\\n#cta1 {\\n color: #018BFF;\\n padding-left: 60;\\n padding-right: 60;\\n padding-top: 10;\\n padding-bottom: 10;\\n border-radius: 4;\\n background-color:white;\\n font-weight: bold;\\n font-size: 18;\\n}\\n#close {\\n glyph-width: 1.5;\\n glyph-padding: 11;\\n background-color: #212C3C;\\n margin-top: 30;\\n margin-right: 30;\\n}\"\n }\n}" ) ); + campaign.requiresJustInTimeSync = true; response.getCampaigns().add(campaign); return response; } diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignSQLTrackerTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsTrackerTest.java similarity index 73% rename from Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignSQLTrackerTest.java rename to Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsTrackerTest.java index 1b7ab88..61e114e 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignSQLTrackerTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/LocalCampaignsTrackerTest.java @@ -5,6 +5,8 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.batch.android.core.DateProvider; +import com.batch.android.core.SystemDateProvider; import java.lang.reflect.Field; import org.junit.Assert; import org.junit.Before; @@ -13,7 +15,7 @@ @RunWith(AndroidJUnit4.class) @SmallTest -public class LocalCampaignSQLTrackerTest { +public class LocalCampaignsTrackerTest { private Context appContext; private Field dbHelperField; @@ -124,6 +126,38 @@ public void testCampaignLastOccurence() throws ViewTrackerUnavailableException { tracker.close(); } + @Test + public void testGetNumberOfViewEventsSince() throws ViewTrackerUnavailableException { + // Clear database + appContext.deleteDatabase(LocalCampaignTrackDbHelper.DATABASE_NAME); + + LocalCampaignsSQLTracker tracker = new LocalCampaignsSQLTracker(); + tracker.open(appContext); + + DateProvider dateProvider = new SystemDateProvider(); + + //0 tracked view events + Assert.assertEquals( + 0, + tracker.getNumberOfViewEventsSince(dateProvider.getCurrentDate().getTime() - (60 * 1000)) + ); + + // track view event + tracker.trackViewEvent("campaign_id"); + + long timestamp = dateProvider.getCurrentDate().getTime(); + // 1 tracked view event since 1 sec + Assert.assertEquals(1, tracker.getNumberOfViewEventsSince(timestamp - (1000))); + + // Adding 1 sec + timestamp += 1000; + + // 0 tracked view event since 1 sec + Assert.assertEquals(0, tracker.getNumberOfViewEventsSince(timestamp - (1000))); + + tracker.close(); + } + @Test // Tests that the db being not opened results in a specific exception public void testUnavailabilityException() { @@ -135,4 +169,16 @@ public void testUnavailabilityException() { } Assert.fail("A ViewTrackerUnavailableException should have been thrown"); } + + @Test + public void testSessionViewsCount() throws ViewTrackerUnavailableException { + LocalCampaignsTracker tracker = new LocalCampaignsTracker(); + tracker.open(appContext); + Assert.assertEquals(0, tracker.getSessionViewsCount()); + tracker.trackViewEvent("campaign_id"); + Assert.assertEquals(1, tracker.getSessionViewsCount()); + tracker.close(); + tracker.resetSessionViewsCount(); + Assert.assertEquals(0, tracker.getSessionViewsCount()); + } } diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/output/ActionOutputTest.kt b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/output/ActionOutputTest.kt new file mode 100644 index 0000000..a312125 --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/output/ActionOutputTest.kt @@ -0,0 +1,129 @@ +package com.batch.android.localcampaigns.output + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.batch.android.JSONObjectMockitoMatcher +import com.batch.android.di.DI +import com.batch.android.di.DITest +import com.batch.android.di.DITestUtils +import com.batch.android.json.JSONObject +import com.batch.android.localcampaigns.model.LocalCampaign +import com.batch.android.module.ActionModule +import com.batch.android.runtime.RuntimeManager +import org.junit.After +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mockito +import org.powermock.api.mockito.PowerMockito + +@Suppress("UsePropertyAccessSyntax") +@RunWith(AndroidJUnit4::class) +@SmallTest +class ActionOutputTest { + + @After + fun cleanup() { + DI.reset() + } + + @Test + fun testExecutesAction() { + val context: Context = ApplicationProvider.getApplicationContext() + val runtimeManager = DITestUtils.mockSingletonDependency(RuntimeManager::class.java, null) + PowerMockito + .doReturn(context) + .`when`(runtimeManager) + .getContext() + + val actionModuleSpy = DITestUtils.mockSingletonDependency(ActionModule::class.java, null) + PowerMockito + .doReturn(true) + .`when`(actionModuleSpy) + .performAction(any(), anyString(), any(JSONObject::class.java), any()) + + val fakeCampaign = LocalCampaign() + fakeCampaign.id = "foobar" + + var output = ActionOutput(JSONObject().apply { + put("action", "foo") + }) + Assert.assertTrue(output.displayMessage(fakeCampaign)) + + Mockito.verify(actionModuleSpy).performAction(Mockito.eq(context), + Mockito.eq("foo"), + JSONObjectMockitoMatcher.eq(JSONObject()), + Mockito.isNull()) + + output = ActionOutput(JSONObject().apply { + put("action", "foobar") + // Invalid args type + put("args", 2) + }) + Assert.assertTrue(output.displayMessage(fakeCampaign)) + + Mockito.verify(actionModuleSpy).performAction(Mockito.eq(context), + Mockito.eq("foobar"), + JSONObjectMockitoMatcher.eq(JSONObject()), + Mockito.isNull()) + + output = ActionOutput(JSONObject().apply { + put("action", "foobaz") + put("args", JSONObject().apply { + put("arg1", "val1") + }) + }) + Assert.assertTrue(output.displayMessage(fakeCampaign)) + + Mockito.verify(actionModuleSpy).performAction(Mockito.eq(context), + Mockito.eq("foobaz"), + JSONObjectMockitoMatcher.eq(JSONObject().apply { + put("arg1", "val1") + }), + Mockito.isNull()) + } + + @Test + fun testDoesNotCrashWithInvalidPayload() { + val actionModuleSpy = DITestUtils.mockSingletonDependency(ActionModule::class.java, null) + PowerMockito + .doReturn(false) + .`when`(actionModuleSpy) + .performAction(any(), anyString(), any(JSONObject::class.java), any()) + + val runtimeManager = DITestUtils.mockSingletonDependency(RuntimeManager::class.java, null) + PowerMockito + .doReturn(null) + .`when`(runtimeManager) + .getContext() + + val fakeCampaign = LocalCampaign() + fakeCampaign.id = "foobar" + + var output = ActionOutput(JSONObject()) + Assert.assertFalse(output.displayMessage(fakeCampaign)) + + output = ActionOutput(JSONObject().apply { + put("foo", "bar") + }) + Assert.assertFalse(output.displayMessage(fakeCampaign)) + + Mockito.verifyNoInteractions(actionModuleSpy) + + output = ActionOutput(JSONObject().apply { + put("action", 2) + }) + Assert.assertFalse(output.displayMessage(fakeCampaign)) + + output = ActionOutput(JSONObject().apply { + put("action", JSONObject()) + }) + Assert.assertFalse(output.displayMessage(fakeCampaign)) + + // Don't call "verifyNoInteractions" as "action" is stringified if of the wrong type + } +} \ No newline at end of file diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/serialization/LocalCampaignsResponseSerializationTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/serialization/LocalCampaignsResponseSerializationTest.java index 07e3bd2..60d4118 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/serialization/LocalCampaignsResponseSerializationTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/serialization/LocalCampaignsResponseSerializationTest.java @@ -8,6 +8,7 @@ import com.batch.android.json.JSONObject; import com.batch.android.localcampaigns.LocalCampaignsResponseFactory; import com.batch.android.localcampaigns.model.LocalCampaign; +import com.batch.android.localcampaigns.output.ActionOutput; import com.batch.android.localcampaigns.output.LandingOutput; import com.batch.android.query.response.LocalCampaignsResponse; import com.batch.android.query.serialization.deserializers.LocalCampaignsResponseDeserializer; @@ -32,10 +33,26 @@ public void setUp() { @Test public void testValidSerialization() throws JSONException { LocalCampaignsResponse response = factory.createLocalCampaignsResponse(); - LocalCampaignsResponseSerializer serializer = new LocalCampaignsResponseSerializer(response); - JSONObject serializedResponse = serializer.serialize(); + LocalCampaignsResponseSerializer serializer = new LocalCampaignsResponseSerializer(); + JSONObject serializedResponse = serializer.serialize(response); + Assert.assertEquals(response.getQueryID(), serializedResponse.getString("id")); Assert.assertFalse(serializedResponse.has("minDisplayInterval")); + + // Global cappings + LocalCampaignsResponse.GlobalCappings cappings = response.getCappings(); + JSONObject jsonGlobalCappings = serializer.serializeCappings(cappings); + Assert.assertEquals(cappings.getSession(), Integer.valueOf(jsonGlobalCappings.getInt("session"))); + Assert.assertEquals( + cappings.getTimeBasedCappings().get(0).getViews(), + Integer.valueOf(jsonGlobalCappings.getJSONArray("time").getJSONObject(0).getInt("views")) + ); + Assert.assertEquals( + cappings.getTimeBasedCappings().get(0).getDuration(), + Integer.valueOf(jsonGlobalCappings.getJSONArray("time").getJSONObject(0).getInt("duration")) + ); + + // Local campaigns Assert.assertTrue(serializedResponse.hasNonNull("campaigns")); LocalCampaign campaign = response.getCampaigns().get(0); JSONObject serializedCampaign = serializedResponse.getJSONArray("campaigns").getJSONObject(0); @@ -69,6 +86,7 @@ public void testValidSerialization() throws JSONException { campaign.output.payload, serializedCampaign.getJSONObject("output").getJSONObject("payload") ); + Assert.assertTrue(serializedCampaign.getBoolean("requireJIT")); } @Test @@ -82,7 +100,27 @@ public void testValidDeserialization() throws JSONException, IOException { Assert.assertFalse(response.hasError()); Assert.assertTrue(response.hasCampaigns()); Assert.assertNull(response.getMinDisplayInterval()); - Assert.assertEquals(response.getCampaigns().size(), 1); + Assert.assertEquals(response.getCampaigns().size(), 2); + + // Global cappings + JSONObject jsonCappings = validJsonCampaignsResponse.getJSONObject("cappings"); + JSONObject jsonTimeBasedCappings = jsonCappings.getJSONArray("time").getJSONObject(0); + Assert.assertNotNull(response.getCappings()); + Assert.assertNotNull(response.getCappings().getSession()); + Assert.assertNotNull(response.getCappings().getTimeBasedCappings()); + Assert.assertTrue(response.hasCappings()); + Assert.assertEquals(response.getCappings().getSession().intValue(), jsonCappings.getInt("session")); + Assert.assertEquals(response.getCappings().getTimeBasedCappings().size(), 1); + Assert.assertEquals( + response.getCappings().getTimeBasedCappings().get(0).getViews().intValue(), + jsonTimeBasedCappings.getInt("views") + ); + Assert.assertEquals( + response.getCappings().getTimeBasedCappings().get(0).getDuration().intValue(), + jsonTimeBasedCappings.getInt("duration") + ); + + // Local Campaign JSONObject jsonCampaign = validJsonCampaignsResponse.getJSONArray("campaigns").getJSONObject(0); LocalCampaign campaign = response.getCampaigns().get(0); Assert.assertEquals(jsonCampaign.getString("campaignId"), campaign.id); @@ -112,6 +150,13 @@ public void testValidDeserialization() throws JSONException, IOException { Assert.assertEquals(jsonTriggers.getJSONObject(0).getString("type"), campaign.triggers.get(0).getType()); Assert.assertTrue(campaign.output instanceof LandingOutput); Assert.assertEquals(jsonCampaign.getJSONObject("output").getJSONObject("payload"), campaign.output.payload); + Assert.assertTrue(campaign.requiresJustInTimeSync); + + // Test ACTION deserialization + jsonCampaign = validJsonCampaignsResponse.getJSONArray("campaigns").getJSONObject(1); + campaign = response.getCampaigns().get(1); + Assert.assertTrue(campaign.output instanceof ActionOutput); + Assert.assertEquals(jsonCampaign.getJSONObject("output").getJSONObject("payload"), campaign.output.payload); } @Test @@ -122,6 +167,7 @@ public void testErrorDeserialization() throws JSONException { LocalCampaignsResponse response = deserializer.deserialize(); Assert.assertTrue(response.hasError()); Assert.assertFalse(response.hasCampaigns()); + Assert.assertFalse(response.hasCappings()); } @Test @@ -132,5 +178,6 @@ public void testEmptyDeserialization() throws JSONException { LocalCampaignsResponse response = deserializer.deserialize(); Assert.assertFalse(response.hasError()); Assert.assertFalse(response.hasCampaigns()); + Assert.assertFalse(response.hasCappings()); } } diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignalTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignalTest.java deleted file mode 100644 index 30b8929..0000000 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsLoadedSignalTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.batch.android.localcampaigns.signal; - -import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; -import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; -import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; -import org.junit.Assert; -import org.junit.Test; - -public class CampaignsLoadedSignalTest { - - @Test - public void testSatisfiesTrigger() { - Signal signal = new CampaignsLoadedSignal(); - - Assert.assertTrue(signal.satisfiesTrigger(new NowTrigger())); - Assert.assertTrue(signal.satisfiesTrigger(new CampaignsLoadedTrigger())); - Assert.assertTrue(signal.satisfiesTrigger(new NextSessionTrigger())); - - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsRefreshedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new EventLocalCampaignTrigger("eventname", null))); - Assert.assertFalse( - signal.satisfiesTrigger( - new LocalCampaign.Trigger() { - @Override - public String getType() { - return null; - } - } - ) - ); - } -} diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignalTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignalTest.java deleted file mode 100644 index 93e75c6..0000000 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/CampaignsRefreshedSignalTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.batch.android.localcampaigns.signal; - -import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; -import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; -import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; -import org.junit.Assert; -import org.junit.Test; - -public class CampaignsRefreshedSignalTest { - - @Test - public void testSatisfiesTrigger() { - Signal signal = new CampaignsRefreshedSignal(); - - Assert.assertTrue(signal.satisfiesTrigger(new NowTrigger())); - Assert.assertTrue(signal.satisfiesTrigger(new CampaignsRefreshedTrigger())); - - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsLoadedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new NextSessionTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new EventLocalCampaignTrigger("eventname", null))); - Assert.assertFalse( - signal.satisfiesTrigger( - new LocalCampaign.Trigger() { - @Override - public String getType() { - return null; - } - } - ) - ); - } -} diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/EventTrackedSignalTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/EventTrackedSignalTest.java index 6cd2af1..e56f6a3 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/EventTrackedSignalTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/EventTrackedSignalTest.java @@ -1,11 +1,8 @@ package com.batch.android.localcampaigns.signal; import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; import org.junit.Assert; import org.junit.Test; @@ -18,9 +15,6 @@ public void testSatisfiesTrigger() { Assert.assertTrue(signal.satisfiesTrigger(new EventLocalCampaignTrigger(eventName, null))); - Assert.assertFalse(signal.satisfiesTrigger(new NowTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsRefreshedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsLoadedTrigger())); Assert.assertFalse(signal.satisfiesTrigger(new NextSessionTrigger())); Assert.assertFalse( signal.satisfiesTrigger( diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/NewSessionSignalTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/NewSessionSignalTest.java index 4596987..e7135d9 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/NewSessionSignalTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/NewSessionSignalTest.java @@ -1,11 +1,8 @@ package com.batch.android.localcampaigns.signal; import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; import org.junit.Assert; import org.junit.Test; @@ -17,9 +14,6 @@ public void testSatisfiesTrigger() { Assert.assertTrue(signal.satisfiesTrigger(new NextSessionTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsRefreshedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsLoadedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new NowTrigger())); Assert.assertFalse(signal.satisfiesTrigger(new EventLocalCampaignTrigger("eventname", null))); Assert.assertFalse( signal.satisfiesTrigger( diff --git a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/PublicEventTrackedSignalTest.java b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/PublicEventTrackedSignalTest.java index 4cc1a07..2448ceb 100644 --- a/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/PublicEventTrackedSignalTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/localcampaigns/signal/PublicEventTrackedSignalTest.java @@ -3,11 +3,8 @@ import com.batch.android.json.JSONException; import com.batch.android.json.JSONObject; import com.batch.android.localcampaigns.model.LocalCampaign; -import com.batch.android.localcampaigns.trigger.CampaignsLoadedTrigger; -import com.batch.android.localcampaigns.trigger.CampaignsRefreshedTrigger; import com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger; import com.batch.android.localcampaigns.trigger.NextSessionTrigger; -import com.batch.android.localcampaigns.trigger.NowTrigger; import com.batch.android.module.UserModule; import org.junit.Assert; import org.junit.Test; @@ -39,9 +36,6 @@ public void testSatisfiesTrigger() throws JSONException { signal.satisfiesTrigger(new EventLocalCampaignTrigger(eventName, "toto")) ); - Assert.assertFalse(signal.satisfiesTrigger(new NowTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsRefreshedTrigger())); - Assert.assertFalse(signal.satisfiesTrigger(new CampaignsLoadedTrigger())); Assert.assertFalse(signal.satisfiesTrigger(new NextSessionTrigger())); Assert.assertFalse( signal.satisfiesTrigger( diff --git a/Sources/sdk/src/test/java/com/batch/android/metrics/CounterMatcher.java b/Sources/sdk/src/test/java/com/batch/android/metrics/CounterMatcher.java new file mode 100644 index 0000000..677d170 --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/metrics/CounterMatcher.java @@ -0,0 +1,22 @@ +package com.batch.android.metrics; + +import com.batch.android.metrics.model.Counter; +import org.mockito.ArgumentMatcher; + +public class CounterMatcher implements ArgumentMatcher { + + private final Counter expected; + + public CounterMatcher(Counter counter) { + this.expected = counter; + } + + @Override + public boolean matches(Counter argument) { + return ( + expected.getName().equals(argument.getName()) && + expected.getType().equals(argument.getType()) && + expected.getValues().equals(argument.getValues()) + ); + } +} diff --git a/Sources/sdk/src/test/java/com/batch/android/metrics/MetricManagerTest.java b/Sources/sdk/src/test/java/com/batch/android/metrics/MetricManagerTest.java new file mode 100644 index 0000000..98d5b6b --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/metrics/MetricManagerTest.java @@ -0,0 +1,78 @@ +package com.batch.android.metrics; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.MediumTest; +import com.batch.android.di.DITest; +import com.batch.android.di.DITestUtils; +import com.batch.android.metrics.model.Counter; +import com.batch.android.metrics.model.Metric; +import com.batch.android.metrics.model.Observation; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.reflect.Whitebox; + +@RunWith(AndroidJUnit4.class) +@MediumTest +public class MetricManagerTest extends DITest { + + @Test + public void testAddMetric() { + MetricManager manager = PowerMockito.spy(DITestUtils.mockSingletonDependency(MetricManager.class, null)); + Counter counter = new Counter("counter_test_metric"); + manager.addMetric(counter); + Mockito.verify(manager, Mockito.times(1)).addMetric(Mockito.argThat(new CounterMatcher(counter))); + } + + @Test + public void testGetMetricsToSend() throws Exception { + MetricManager manager = PowerMockito.spy(DITestUtils.mockSingletonDependency(MetricManager.class, null)); + PowerMockito.doNothing().when(manager).sendMetrics(); + Counter counter = new Counter("counter_test_metric").register(); + counter.inc(); + + Observation observation = new Observation("observation_test_metric").labelNames("label1", "label2").register(); + observation.labels("value1", "value2").startTimer(); + observation.labels("value1", "value2").observeDuration(); + observation.labels("value3", "value3").startTimer(); + + //Making copy of metrics because the reset method will be called when getMetricsToSend is done + List> expected = new ArrayList<>(); + expected.add(new Counter(counter)); + expected.add(new Observation(observation.labels("value1", "value2"))); + + List> actual = Whitebox.invokeMethod(manager, "getMetricsToSend"); + + Assert.assertEquals(expected.size(), actual.size()); + + for (int i = 0; i < expected.size(); i++) { + Metric expectedMetric = expected.get(i); + Metric actualMetric = actual.get(i); + Assert.assertEquals(expectedMetric.getName(), actualMetric.getName()); + Assert.assertEquals(expectedMetric.getType(), actualMetric.getType()); + Assert.assertEquals(expectedMetric.getLabelNames(), actualMetric.getLabelNames()); + Assert.assertEquals(expectedMetric.getLabelValues(), actualMetric.getLabelValues()); + Assert.assertEquals(expectedMetric.getValues(), actualMetric.getValues()); + } + } + + @Test + public void testIsWaiting() throws NoSuchFieldException, IllegalAccessException { + MetricManager manager = DITestUtils.mockSingletonDependency(MetricManager.class, null); + + Field isWaitingField = MetricManager.class.getDeclaredField("isSending"); + isWaitingField.setAccessible(true); + AtomicBoolean isSending = (AtomicBoolean) isWaitingField.get(manager); + + Counter counter = new Counter("counter_test_metric").register(); + Assert.assertFalse(isSending.get()); + counter.inc(); + Assert.assertTrue(isSending.get()); + } +} diff --git a/Sources/sdk/src/test/java/com/batch/android/post/DisplayReceiptPostDataProviderTest.java b/Sources/sdk/src/test/java/com/batch/android/post/DisplayReceiptPostDataProviderTest.java index d0aa223..374c743 100644 --- a/Sources/sdk/src/test/java/com/batch/android/post/DisplayReceiptPostDataProviderTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/post/DisplayReceiptPostDataProviderTest.java @@ -2,6 +2,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.batch.android.displayreceipt.DisplayReceipt; import java.util.ArrayList; @@ -58,4 +60,15 @@ public void testData() { assertArrayEquals(receiptList.toArray(), provider.getRawData().toArray()); assertArrayEquals(body, provider.getData()); } + + @Test + public void testIsEmpty() { + List receiptList = new ArrayList<>(); + DisplayReceiptPostDataProvider provider = new DisplayReceiptPostDataProvider(receiptList); + assertTrue(provider.isEmpty()); + + receiptList.add(null); + provider = new DisplayReceiptPostDataProvider(receiptList); + assertFalse(provider.isEmpty()); + } } diff --git a/Sources/sdk/src/test/java/com/batch/android/post/JSONPostDataProviderTest.java b/Sources/sdk/src/test/java/com/batch/android/post/JSONPostDataProviderTest.java index 2cca9c3..b7fc810 100644 --- a/Sources/sdk/src/test/java/com/batch/android/post/JSONPostDataProviderTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/post/JSONPostDataProviderTest.java @@ -1,8 +1,10 @@ package com.batch.android.post; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import com.batch.android.json.JSONException; import com.batch.android.json.JSONObject; import org.junit.Test; @@ -34,6 +36,17 @@ public void testReadData() throws Exception { assertTrue("decoded data is not equals to input", areEquals(input, new JSONObject(new String(data)))); } + @Test + public void testIsEmpty() throws JSONException { + JSONObject input = new JSONObject(); + JSONPostDataProvider provider = new JSONPostDataProvider(input); + assertTrue(provider.isEmpty()); + + input.put("key", "value"); + provider = new JSONPostDataProvider(input); + assertFalse(provider.isEmpty()); + } + /** * Are those 2 json object equals * diff --git a/Sources/sdk/src/test/java/com/batch/android/post/LocalCampaignsJITPostDataProviderTest.java b/Sources/sdk/src/test/java/com/batch/android/post/LocalCampaignsJITPostDataProviderTest.java new file mode 100644 index 0000000..57df34b --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/post/LocalCampaignsJITPostDataProviderTest.java @@ -0,0 +1,89 @@ +package com.batch.android.post; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import com.batch.android.core.ByteArrayHelper; +import com.batch.android.di.providers.CampaignManagerProvider; +import com.batch.android.di.providers.SQLUserDatasourceProvider; +import com.batch.android.localcampaigns.LocalCampaignsTracker; +import com.batch.android.localcampaigns.model.LocalCampaign; +import com.batch.android.metrics.model.Counter; +import com.batch.android.metrics.model.Metric; +import com.batch.android.metrics.model.Observation; +import com.batch.android.user.SQLUserDatasource; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for MetricPostDataProvider + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LocalCampaignsJITPostDataProviderTest { + + @Test + public void testPack() { + Context context = ApplicationProvider.getApplicationContext(); + + LocalCampaignsTracker tracker = (LocalCampaignsTracker) CampaignManagerProvider.get().getViewTracker(); + tracker.open(context); + + SQLUserDatasource datasource = SQLUserDatasourceProvider.get(context); + + List campaigns = new ArrayList<>(); + LocalCampaign campaign1 = new LocalCampaign(); + campaign1.id = "c1"; + LocalCampaign campaign2 = new LocalCampaign(); + campaign2.id = "c2"; + LocalCampaign campaign3 = new LocalCampaign(); + campaign3.id = "c3"; + campaigns.add(campaign1); + campaigns.add(campaign2); + campaigns.add(campaign3); + + byte[] expectedData = ByteArrayHelper.hexToBytes( + "84A963616D706169676E7393A26331A26332A26333A369647380AA6174747269627574657380A5766965777383A2633381A5636F756E7400A2633181A5636F756E7400A2633281A5636F756E7400" + ); + + LocalCampaignsJITPostDataProvider provider = new LocalCampaignsJITPostDataProvider(campaigns); + + assertEquals("application/msgpack", provider.getContentType()); + assertArrayEquals(campaigns.toArray(), provider.getRawData().toArray()); + assertArrayEquals(expectedData, provider.getData()); + + tracker.close(); + datasource.close(); + } + + @Test + public void testUnpack() { + String fakeHexResponse = "81b1656c696769626c6543616d706169676e7392a26332a26333"; + byte[] fakeResponse = ByteArrayHelper.hexToBytes(fakeHexResponse); + LocalCampaignsJITPostDataProvider provider = new LocalCampaignsJITPostDataProvider(new ArrayList<>()); + List eligibleCampaigns = provider.unpack(fakeResponse); + Assert.assertEquals("c2", eligibleCampaigns.get(0)); + Assert.assertEquals("c3", eligibleCampaigns.get(1)); + } + + @Test + public void testIsEmpty() { + List campaigns = new ArrayList<>(); + LocalCampaignsJITPostDataProvider provider = new LocalCampaignsJITPostDataProvider(campaigns); + assertTrue(provider.isEmpty()); + + LocalCampaign campaign = new LocalCampaign(); + campaigns.add(campaign); + provider = new LocalCampaignsJITPostDataProvider(campaigns); + assertFalse(provider.isEmpty()); + } +} diff --git a/Sources/sdk/src/test/java/com/batch/android/post/MetricPostDataProviderTest.java b/Sources/sdk/src/test/java/com/batch/android/post/MetricPostDataProviderTest.java new file mode 100644 index 0000000..7daad3f --- /dev/null +++ b/Sources/sdk/src/test/java/com/batch/android/post/MetricPostDataProviderTest.java @@ -0,0 +1,60 @@ +package com.batch.android.post; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import com.batch.android.metrics.model.Counter; +import com.batch.android.metrics.model.Metric; +import com.batch.android.metrics.model.Observation; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for MetricPostDataProvider + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MetricPostDataProviderTest { + + @Test + public void testData() { + List> metrics = new ArrayList<>(); + Counter counter = new Counter("counter_test_metric"); + Observation observation = new Observation("observation_test_metric"); + counter.inc(); + metrics.add(counter); + metrics.add(observation); + + // prettier-ignore + byte[] body = new byte[]{-110, -125, -90, 118, 97, 108, 117, 101, 115, -111, -54, 63, -128, + 0, 0, -92, 110, 97, 109, 101, -77, 99, 111, 117, 110, 116, 101, 114, 95, 116, 101, + 115, 116, 95, 109, 101, 116, 114, 105, 99, -92, 116, 121, 112, 101, -89, 99, 111, + 117, 110, 116, 101, 114, -125, -90, 118, 97, 108, 117, 101, 115, -112, -92, 110, 97, + 109, 101, -73, 111, 98, 115, 101, 114, 118, 97, 116, 105, 111, 110, 95, 116, 101, + 115, 116, 95, 109, 101, 116, 114, 105, 99, -92, 116, 121, 112, 101, -85, 111, 98, + 115, 101, 114, 118, 97, 116, 105, 111, 110}; + + MetricPostDataProvider provider = new MetricPostDataProvider(metrics); + assertEquals("application/msgpack", provider.getContentType()); + assertArrayEquals(metrics.toArray(), provider.getRawData().toArray()); + assertArrayEquals(body, provider.getData()); + } + + @Test + public void testIsEmpty() { + List> metrics = new ArrayList<>(); + MetricPostDataProvider provider = new MetricPostDataProvider(metrics); + assertTrue(provider.isEmpty()); + + Counter counter = new Counter("test_metric"); + metrics.add(counter); + provider = new MetricPostDataProvider(metrics); + assertFalse(provider.isEmpty()); + } +} diff --git a/Sources/sdk/src/test/java/com/batch/android/post/ParametersPostDataProviderTest.java b/Sources/sdk/src/test/java/com/batch/android/post/ParametersPostDataProviderTest.java index a43b2b7..b21de1d 100644 --- a/Sources/sdk/src/test/java/com/batch/android/post/ParametersPostDataProviderTest.java +++ b/Sources/sdk/src/test/java/com/batch/android/post/ParametersPostDataProviderTest.java @@ -1,6 +1,9 @@ package com.batch.android.post; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; @@ -31,4 +34,15 @@ public void testReadData() throws Exception { byte[] data = provider.getData(); assertEquals("decoded data is not equals to input", key + "=" + value, new String(data)); } + + @Test + public void testIsEmpty() { + Map input = new HashMap<>(); + ParametersPostDataProvider provider = new ParametersPostDataProvider(input); + assertTrue(provider.isEmpty()); + + input.put("key", "value"); + provider = new ParametersPostDataProvider(input); + assertFalse(provider.isEmpty()); + } } diff --git a/Sources/sdk/src/test/resources/fake_geo_campaigns.json b/Sources/sdk/src/test/resources/fake_geo_campaigns.json index defeecd..bc7e322 100644 --- a/Sources/sdk/src/test/resources/fake_geo_campaigns.json +++ b/Sources/sdk/src/test/resources/fake_geo_campaigns.json @@ -2,6 +2,14 @@ "queries": [ { "id": "c2b63fc3-bb8c-4acd-9441-aa8202211884", + "cappings": { + "session": 2, + "time": [ + {"views": 1, "duration": 3600}, + {"views": 0, "duration": 3600}, + {"views": 1, "duration": 0} + ] + }, "campaigns": [ { "campaignId": "next_session_triggered_campaign", @@ -15,6 +23,7 @@ "maximumApiLevel": 30, "priority": 2, "minDisplayInterval": 3, + "requireJIT": true, "startDate": { "ts": 1499960145, "userTZ": false @@ -57,6 +66,27 @@ "style": "#image-cnt {blur: 200;} #image {border-radius: 10; margin-left: 30; margin-right: 30; margin-top: 40;} #placeholder{background-color:#018BAA;}#content {\n background-color: #018BFF;\n height: 100%\n padding-top: 24;\n padding-left: 20;\n padding-right: 20;\n padding-bottom: 20;\n}\n#h1 {\n color: #018BFF;\n padding-left: 15;\n padding-right: 15;\n padding-top: 4;\n padding-bottom: 4;\n border-radius: 12;\n background-color:white;\n font-weight: bold;\n font-size: 12;\n height: 24;\n width: auto;\n}\n#h2 {\n margin-top: 24;\n color: white;\n font-weight: bold;\n font-size: 35;\n}\n#body {\n color: #80C5FF;\n}\n#cta1 {\n color: #018BFF;\n padding-left: 60;\n padding-right: 60;\n padding-top: 10;\n padding-bottom: 10;\n border-radius: 4;\n background-color:white;\n font-weight: bold;\n font-size: 18;\n}\n#close {\n glyph-width: 1.5;\n glyph-padding: 11;\n background-color: #212C3C;\n margin-top: 30;\n margin-right: 30;\n}" } } + }, + { + "campaignId": "action_output_campaign", + "triggers": [ + { + "type": "NEXT_SESSION" + } + ], + "eventData": { + "type": "l", + "foo": "bar" + }, + "output": { + "type": "ACTION", + "payload": { + "action": "batch.deeplink", + "args": { + "l": "https://batch.com" + } + } + } } ] } diff --git a/proguard-mappings/1.19.0/checksum.md5 b/proguard-mappings/1.19.0/checksum.md5 new file mode 100644 index 0000000..fe1110f --- /dev/null +++ b/proguard-mappings/1.19.0/checksum.md5 @@ -0,0 +1 @@ +MD5 (public-sdk/Batch.aar) = 8f5b46273e791d26ce6aa461075cd946 diff --git a/proguard-mappings/1.19.0/checksum.sha b/proguard-mappings/1.19.0/checksum.sha new file mode 100644 index 0000000..acb9bad --- /dev/null +++ b/proguard-mappings/1.19.0/checksum.sha @@ -0,0 +1 @@ +13eb19c2148ff3c3c4a5206cb621318f27a4f0a2 public-sdk/Batch.aar diff --git a/proguard-mappings/1.19.0/mapping.txt b/proguard-mappings/1.19.0/mapping.txt new file mode 100644 index 0000000..34f09ea --- /dev/null +++ b/proguard-mappings/1.19.0/mapping.txt @@ -0,0 +1,9151 @@ +# compiler: R8 +# compiler_version: 3.1.66 +# pg_map_id: f3315f2 +# common_typos_disable +# {"id":"com.android.tools.r8.mapping","version":"1.0"} +com.batch.android.AdsIdentifierProviderAvailabilityException -> com.batch.android.AdsIdentifierProviderAvailabilityException: + 1:1:void (java.lang.String):9:9 -> +com.batch.android.AdvertisingID -> com.batch.android.a: + java.lang.String advertisingID -> a + boolean limited -> b + boolean advertisingIdReady -> c + java.lang.String UNAVAILABLE_AD_ID -> e + java.lang.String TAG -> d + 1:1:void ():48:48 -> + 2:8:void ():44:50 -> + 1:1:java.lang.String access$002(com.batch.android.AdvertisingID,java.lang.String):16:16 -> a + 2:2:boolean access$102(com.batch.android.AdvertisingID,boolean):16:16 -> a + 3:7:java.lang.String get():105:109 -> a + 8:8:java.lang.String get():106:106 -> a + 1:1:boolean access$202(com.batch.android.AdvertisingID,boolean):16:16 -> b + 2:11:void initAdvertisingID():57:66 -> b + 12:12:void initAdvertisingID():62:62 -> b + 1:5:boolean isLimited():119:123 -> c + 6:6:boolean isLimited():120:120 -> c + 1:1:boolean isNotNull():132:132 -> d + 1:1:boolean isReady():94:94 -> e +com.batch.android.AdvertisingID$1 -> com.batch.android.a$a: + com.batch.android.AdvertisingID this$0 -> a + 1:1:void (com.batch.android.AdvertisingID):67:67 -> + 1:2:void onError(java.lang.Exception):78:79 -> onError + 1:4:void onSuccess(java.lang.String,boolean):70:73 -> onSuccess +com.batch.android.AttributesCheckWebservice -> com.batch.android.b: + java.lang.String TAG -> v + com.batch.android.webservice.listener.AttributesCheckWebserviceListener listener -> u + long version -> s + java.lang.String transactionID -> t + 1:16:void (android.content.Context,long,java.lang.String,com.batch.android.webservice.listener.AttributesCheckWebserviceListener):51:66 -> + 17:17:void (android.content.Context,long,java.lang.String,com.batch.android.webservice.listener.AttributesCheckWebserviceListener):61:61 -> + 18:18:void (android.content.Context,long,java.lang.String,com.batch.android.webservice.listener.AttributesCheckWebserviceListener):57:57 -> + 19:19:void (android.content.Context,long,java.lang.String,com.batch.android.webservice.listener.AttributesCheckWebserviceListener):53:53 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():180:180 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():185:185 -> B + 1:1:java.lang.String getSpecificRetryCountKey():190:190 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():155:155 -> F + 1:1:java.lang.String getPropertyParameterKey():150:150 -> H + 1:3:java.util.List getQueries():73:75 -> I + 1:1:java.lang.String getTaskIdentifier():143:143 -> a + 1:1:java.lang.String getCryptorModeParameterKey():165:165 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():160:160 -> p + 1:52:void run():83:134 -> run + 53:53:void run():128:128 -> run + 54:68:void run():94:108 -> run + 69:69:void run():105:105 -> run + 70:70:void run():102:102 -> run + 71:109:void run():99:137 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():170:170 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():175:175 -> y +com.batch.android.AttributesCheckWebservice$1 -> com.batch.android.b$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():97:97 -> +com.batch.android.AttributesSendWebservice -> com.batch.android.c: + java.lang.String TAG -> w + java.util.Map attributes -> t + com.batch.android.webservice.listener.AttributesSendWebserviceListener listener -> v + long version -> s + java.util.Map tags -> u + 1:21:void (android.content.Context,long,java.util.Map,java.util.Map,com.batch.android.webservice.listener.AttributesSendWebserviceListener):58:78 -> + 22:22:void (android.content.Context,long,java.util.Map,java.util.Map,com.batch.android.webservice.listener.AttributesSendWebserviceListener):72:72 -> + 23:23:void (android.content.Context,long,java.util.Map,java.util.Map,com.batch.android.webservice.listener.AttributesSendWebserviceListener):68:68 -> + 24:24:void (android.content.Context,long,java.util.Map,java.util.Map,com.batch.android.webservice.listener.AttributesSendWebserviceListener):64:64 -> + 25:25:void (android.content.Context,long,java.util.Map,java.util.Map,com.batch.android.webservice.listener.AttributesSendWebserviceListener):60:60 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():189:189 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():194:194 -> B + 1:1:java.lang.String getSpecificRetryCountKey():199:199 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():164:164 -> F + 1:1:java.lang.String getPropertyParameterKey():159:159 -> H + 1:3:java.util.List getQueries():85:87 -> I + 1:1:java.lang.String getTaskIdentifier():152:152 -> a + 1:1:java.lang.String getCryptorModeParameterKey():174:174 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():169:169 -> p + 1:49:void run():95:143 -> run + 50:50:void run():137:137 -> run + 51:65:void run():106:120 -> run + 66:66:void run():117:117 -> run + 67:67:void run():114:114 -> run + 68:103:void run():111:146 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():179:179 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():184:184 -> y +com.batch.android.AttributesSendWebservice$1 -> com.batch.android.c$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():109:109 -> +com.batch.android.Batch -> com.batch.android.Batch: + android.content.Intent newIntent -> f + com.batch.android.module.BatchModule moduleMaster -> k + java.lang.String sessionID -> h + boolean didLogOptOutWarning -> i + com.batch.android.AdvertisingID advertisingID -> b + android.content.BroadcastReceiver receiver -> e + com.batch.android.User user -> d + java.lang.Boolean lastNotificationAuthorizationStatus -> j + com.batch.android.Install install -> c + com.batch.android.core.ExcludedActivityHelper excludedActivityHelper -> g + com.batch.android.Config config -> a + 1:71:void ():110:180 -> + 1:1:void ():185:185 -> + void manageUpdate(java.lang.String,java.lang.String) -> a + 1:1:com.batch.android.Install access$000():78:78 -> a + 2:3:void lambda$getAPIKey$0(java.lang.StringBuilder,com.batch.android.runtime.State):198:199 -> a + 4:11:com.batch.android.runtime.State lambda$setConfig$1(com.batch.android.Config,com.batch.android.runtime.State):250:257 -> a + 12:13:void lambda$getLoggerLevel$5(java.util.concurrent.atomic.AtomicReference,com.batch.android.runtime.State):341:342 -> a + 14:22:void _optOut(android.content.Context,boolean,com.batch.android.BatchOptOutResultListener):510:518 -> a + 23:23:void _optOut(android.content.Context,boolean,com.batch.android.BatchOptOutResultListener):506:506 -> a + 24:27:void lambda$_optOut$7(android.content.Context,java.lang.Void):513:516 -> a + 28:28:void lambda$_optOut$8(com.batch.android.BatchOptOutResultListener,java.lang.Exception):520:520 -> a + 29:400:void doBatchStart(android.content.Context,boolean,boolean):2018:2389 -> a + 401:680:com.batch.android.runtime.State lambda$doBatchStart$9(com.batch.android.runtime.RuntimeManager,boolean,android.content.Context,boolean,java.util.concurrent.atomic.AtomicBoolean,java.lang.StringBuilder,com.batch.android.runtime.State):2025:2304 -> a + 681:711:com.batch.android.runtime.State lambda$doBatchStart$9(com.batch.android.runtime.RuntimeManager,boolean,android.content.Context,boolean,java.util.concurrent.atomic.AtomicBoolean,java.lang.StringBuilder,com.batch.android.runtime.State):2302:2332 -> a + 712:729:com.batch.android.runtime.State lambda$doBatchStart$9(com.batch.android.runtime.RuntimeManager,boolean,android.content.Context,boolean,java.util.concurrent.atomic.AtomicBoolean,java.lang.StringBuilder,com.batch.android.runtime.State):2331:2348 -> a + 730:731:void lambda$doBatchStart$10(com.batch.android.runtime.RuntimeManager,java.util.concurrent.atomic.AtomicBoolean,java.lang.StringBuilder,boolean,com.batch.android.runtime.State):2368:2369 -> a + 732:732:void lambda$doBatchStart$10(com.batch.android.runtime.RuntimeManager,java.util.concurrent.atomic.AtomicBoolean,java.lang.StringBuilder,boolean,com.batch.android.runtime.State):2366:2366 -> a + 733:797:com.batch.android.runtime.State lambda$onStop$11(boolean,android.content.Context,boolean,com.batch.android.runtime.State):2408:2472 -> a + 798:798:com.batch.android.runtime.State lambda$onStop$11(boolean,android.content.Context,boolean,com.batch.android.runtime.State):2460:2460 -> a + 799:799:void lambda$onWebserviceExecutorWorkFinished$12(java.util.concurrent.atomic.AtomicBoolean,com.batch.android.runtime.State):2495:2495 -> a + 800:811:com.batch.android.runtime.State lambda$doStop$13(com.batch.android.runtime.State):2517:2528 -> a + 812:812:void checkForNotificationAuthorizationChange(android.content.Context):2622:2622 -> a + 813:828:void checkForNotificationAuthorizationChange(android.content.Context):2620:2635 -> a + 829:847:void checkForNotificationAuthorizationChange(android.content.Context):2634:2652 -> a + 848:855:void lambda$checkForNotificationAuthorizationChange$14(android.content.Context,com.batch.android.runtime.RuntimeManager):2641:2648 -> a + 1:1:void access$100():78:78 -> b + 2:3:void lambda$shouldUseAdvancedDeviceInformation$3(java.util.concurrent.atomic.AtomicBoolean,com.batch.android.runtime.State):291:292 -> b + 4:5:void lambda$getSessionID$6(java.lang.StringBuilder,com.batch.android.runtime.State):360:361 -> b + 6:84:void onStop(android.content.Context,boolean,boolean):2404:2482 -> b + 1:1:void access$200():78:78 -> c + 2:3:void lambda$shouldUseAdvertisingID$2(java.util.concurrent.atomic.AtomicBoolean,com.batch.android.runtime.State):273:274 -> c + 1:1:void copyBatchExtras(android.content.Intent,android.content.Intent):398:398 -> copyBatchExtras + 2:2:void copyBatchExtras(android.os.Bundle,android.os.Bundle):411:411 -> copyBatchExtras + 1:2:void lambda$shouldUseGoogleInstanceID$4(java.util.concurrent.atomic.AtomicBoolean,com.batch.android.runtime.State):311:312 -> d + 3:6:void clearCachedInstallData():2551:2554 -> d + 1:22:void doStop():2513:2534 -> e + 1:1:com.batch.android.AdvertisingID getAdvertisingID():2565:2565 -> f + 1:1:com.batch.android.Install getInstall():2574:2574 -> g + 1:11:java.lang.String getAPIKey():194:204 -> getAPIKey + 1:1:java.lang.String getBroadcastPermissionName(android.content.Context):421:421 -> getBroadcastPermissionName + 1:10:com.batch.android.LoggerLevel getLoggerLevel():337:346 -> getLoggerLevel + 1:12:java.lang.String getSessionID():355:366 -> getSessionID + 1:9:com.batch.android.BatchUserProfile getUserProfile():225:233 -> getUserProfile + 1:1:com.batch.android.User getUser():2583:2583 -> h + 1:10:void onWebserviceExecutorWorkFinished():2492:2501 -> i + 1:1:boolean isOptedOut(android.content.Context):553:553 -> isOptedOut + 2:2:boolean isOptedOut(android.content.Context):551:551 -> isOptedOut + 1:3:boolean isRunningInDevMode():381:383 -> isRunningInDevMode + 1:23:void updateVersionManagement():2593:2615 -> j + 1:3:void onCreate(android.app.Activity):1929:1931 -> onCreate + 1:1:void onDestroy(android.app.Activity):2011:2011 -> onDestroy + 1:2:void onNewIntent(android.app.Activity,android.content.Intent):1990:1991 -> onNewIntent + 1:1:void onServiceCreate(android.content.Context,boolean):1969:1969 -> onServiceCreate + 1:1:void onServiceDestroy(android.content.Context):1980:1980 -> onServiceDestroy + 1:1:void onStart(android.app.Activity):1948:1948 -> onStart + 1:1:void onStop(android.app.Activity):2001:2001 -> onStop + 1:1:void optIn(android.content.Context):540:540 -> optIn + 2:2:void optIn(android.content.Context):538:538 -> optIn + 1:1:void optOut(android.content.Context):447:447 -> optOut + 2:2:void optOut(android.content.Context,com.batch.android.BatchOptOutResultListener):463:463 -> optOut + 1:1:void optOutAndWipeData(android.content.Context):477:477 -> optOutAndWipeData + 2:2:void optOutAndWipeData(android.content.Context,com.batch.android.BatchOptOutResultListener):496:496 -> optOutAndWipeData + 1:2:void setConfig(com.batch.android.Config):248:249 -> setConfig + 1:1:void setFindMyInstallationEnabled(boolean):565:565 -> setFindMyInstallationEnabled + 1:10:boolean shouldUseAdvancedDeviceInformation():287:296 -> shouldUseAdvancedDeviceInformation + 1:10:boolean shouldUseAdvertisingID():269:278 -> shouldUseAdvertisingID + 1:10:boolean shouldUseGoogleInstanceID():307:316 -> shouldUseGoogleInstanceID +com.batch.android.Batch$1 -> com.batch.android.Batch$a: +com.batch.android.Batch$Actions -> com.batch.android.Batch$Actions: + 1:1:void ():1848:1848 -> + 1:1:void addDrawableAlias(java.lang.String,int):1888:1888 -> addDrawableAlias + 1:1:boolean performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject):1905:1905 -> performAction + 1:1:void register(com.batch.android.UserAction):1860:1860 -> register + 1:1:void setDeeplinkInterceptor(com.batch.android.BatchDeeplinkInterceptor):1914:1914 -> setDeeplinkInterceptor + 1:1:void unregister(java.lang.String):1872:1872 -> unregister +com.batch.android.Batch$Debug -> com.batch.android.Batch$Debug: + 1:1:void ():576:576 -> + 1:2:void startDebugActivity(android.content.Context):587:588 -> startDebugActivity +com.batch.android.Batch$EventDispatcher -> com.batch.android.Batch$EventDispatcher: + 1:1:void ():1152:1152 -> + 1:1:void addDispatcher(com.batch.android.BatchEventDispatcher):1161:1161 -> addDispatcher + 1:1:boolean removeDispatcher(com.batch.android.BatchEventDispatcher):1170:1170 -> removeDispatcher +com.batch.android.Batch$EventDispatcher$Type -> com.batch.android.Batch$EventDispatcher$Type: + com.batch.android.Batch$EventDispatcher$Type[] $VALUES -> a + 1:9:void ():1179:1187 -> + 10:10:void ():1177:1177 -> + 1:1:void (java.lang.String,int):1178:1178 -> + 1:1:boolean isMessagingEvent():1194:1194 -> isMessagingEvent + 1:1:boolean isNotificationEvent():1190:1190 -> isNotificationEvent + 1:1:com.batch.android.Batch$EventDispatcher$Type valueOf(java.lang.String):1177:1177 -> valueOf + 1:1:com.batch.android.Batch$EventDispatcher$Type[] values():1177:1177 -> values +com.batch.android.Batch$Inbox -> com.batch.android.Batch$Inbox: + 1:1:void ():600:600 -> + 1:2:com.batch.android.BatchInboxFetcher getFetcher(android.content.Context):614:615 -> getFetcher + 3:3:com.batch.android.BatchInboxFetcher getFetcher(android.content.Context):612:612 -> getFetcher + 4:4:com.batch.android.BatchInboxFetcher getFetcher(android.content.Context,java.lang.String,java.lang.String):636:636 -> getFetcher + 5:5:com.batch.android.BatchInboxFetcher getFetcher(android.content.Context,java.lang.String,java.lang.String):634:634 -> getFetcher + 6:6:com.batch.android.BatchInboxFetcher getFetcher(java.lang.String,java.lang.String):651:651 -> getFetcher +com.batch.android.Batch$InternalBroadcastReceiver -> com.batch.android.Batch$b: + 1:1:void ():2665:2665 -> + 2:2:void (com.batch.android.Batch$1):2665:2665 -> + 1:12:void onReceive(android.content.Context,android.content.Intent):2673:2684 -> onReceive + 13:13:void onReceive(android.content.Context,android.content.Intent):2681:2681 -> onReceive +com.batch.android.Batch$Messaging -> com.batch.android.Batch$Messaging: + 1:1:void ():1522:1522 -> + 1:1:boolean hasPendingMessage():1824:1824 -> hasPendingMessage + 1:1:boolean isDoNotDisturbEnabled():1815:1815 -> isDoNotDisturbEnabled + 1:1:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage):1765:1765 -> loadBanner + 1:1:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage):1746:1746 -> loadFragment + 1:1:com.batch.android.BatchMessage popPendingMessage():1837:1837 -> popPendingMessage + 1:1:void setAutomaticMode(boolean):1700:1700 -> setAutomaticMode + 1:1:void setDoNotDisturbEnabled(boolean):1808:1808 -> setDoNotDisturbEnabled + 1:1:void setLifecycleListener(com.batch.android.Batch$Messaging$LifecycleListener):1722:1722 -> setLifecycleListener + 1:1:void setShowForegroundLandings(boolean):1689:1689 -> setShowForegroundLandings + 1:1:void setTypefaceOverride(android.graphics.Typeface,android.graphics.Typeface):1713:1713 -> setTypefaceOverride + 1:1:void show(android.content.Context,com.batch.android.BatchMessage):1788:1788 -> show + 2:2:void show(android.content.Context,com.batch.android.BatchMessage):1786:1786 -> show + 3:3:void show(android.content.Context,com.batch.android.BatchMessage):1783:1783 -> show +com.batch.android.Batch$Messaging$DisplayHint -> com.batch.android.Batch$Messaging$DisplayHint: + android.view.View view -> b + com.batch.android.Batch$Messaging$DisplayHintStrategy strategy -> a + 1:3:void (android.view.View,com.batch.android.Batch$Messaging$DisplayHintStrategy):1644:1646 -> + 1:1:com.batch.android.Batch$Messaging$DisplayHint embed(android.widget.FrameLayout):1672:1672 -> embed + 2:2:com.batch.android.Batch$Messaging$DisplayHint embed(android.widget.FrameLayout):1669:1669 -> embed + 1:1:com.batch.android.Batch$Messaging$DisplayHint findUsingView(android.view.View):1659:1659 -> findUsingView + 2:2:com.batch.android.Batch$Messaging$DisplayHint findUsingView(android.view.View):1656:1656 -> findUsingView +com.batch.android.Batch$Messaging$DisplayHintStrategy -> com.batch.android.Batch$Messaging$a: + com.batch.android.Batch$Messaging$DisplayHintStrategy[] $VALUES -> c + com.batch.android.Batch$Messaging$DisplayHintStrategy EMBED -> b + com.batch.android.Batch$Messaging$DisplayHintStrategy TRANSVERSE_HIERARCHY -> a + 1:2:void ():1629:1630 -> + 3:3:void ():1628:1628 -> + 1:1:void (java.lang.String,int):1628:1628 -> + 1:1:com.batch.android.Batch$Messaging$DisplayHintStrategy valueOf(java.lang.String):1628:1628 -> valueOf + 1:1:com.batch.android.Batch$Messaging$DisplayHintStrategy[] values():1628:1628 -> values +com.batch.android.Batch$Push -> com.batch.android.Batch$Push: + 1:1:void ():663:663 -> + 1:1:void appendBatchData(android.content.Intent,android.content.Intent):831:831 -> appendBatchData + 2:2:void appendBatchData(android.os.Bundle,android.content.Intent):842:842 -> appendBatchData + 3:3:void appendBatchData(com.google.firebase.messaging.RemoteMessage,android.content.Intent):853:853 -> appendBatchData + 1:1:void dismissNotifications():744:744 -> dismissNotifications + 1:1:void displayNotification(android.content.Context,android.content.Intent):1017:1017 -> displayNotification + 2:2:void displayNotification(android.content.Context,android.content.Intent,boolean):1028:1028 -> displayNotification + 3:3:void displayNotification(android.content.Context,android.content.Intent,com.batch.android.BatchNotificationInterceptor):1043:1043 -> displayNotification + 4:4:void displayNotification(android.content.Context,android.content.Intent,com.batch.android.BatchNotificationInterceptor,boolean):1061:1061 -> displayNotification + 5:5:void displayNotification(android.content.Context,com.google.firebase.messaging.RemoteMessage):1068:1068 -> displayNotification + 6:6:void displayNotification(android.content.Context,com.google.firebase.messaging.RemoteMessage,com.batch.android.BatchNotificationInterceptor):1080:1080 -> displayNotification + 1:1:com.batch.android.BatchNotificationChannelsManager getChannelsManager():731:731 -> getChannelsManager + 1:1:java.lang.String getLastKnownPushToken():1123:1123 -> getLastKnownPushToken + 1:1:java.util.EnumSet getNotificationsType(android.content.Context):754:754 -> getNotificationsType + 1:1:boolean isBatchPush(android.content.Intent):781:781 -> isBatchPush + 2:2:boolean isBatchPush(com.google.firebase.messaging.RemoteMessage):793:793 -> isBatchPush + 1:1:boolean isManualDisplayModeActivated():810:810 -> isManualDisplayModeActivated + 1:1:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,android.os.Bundle):887:887 -> makePendingIntent + 2:2:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,android.os.Bundle):884:884 -> makePendingIntent + 3:3:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,android.os.Bundle):880:880 -> makePendingIntent + 4:4:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,android.os.Bundle):876:876 -> makePendingIntent + 5:5:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,com.google.firebase.messaging.RemoteMessage):921:921 -> makePendingIntent + 6:6:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,com.google.firebase.messaging.RemoteMessage):918:918 -> makePendingIntent + 7:7:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,com.google.firebase.messaging.RemoteMessage):914:914 -> makePendingIntent + 8:8:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,com.google.firebase.messaging.RemoteMessage):910:910 -> makePendingIntent + 1:1:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,android.os.Bundle):953:953 -> makePendingIntentForDeeplink + 2:2:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,android.os.Bundle):950:950 -> makePendingIntentForDeeplink + 3:3:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,android.os.Bundle):946:946 -> makePendingIntentForDeeplink + 4:4:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,android.os.Bundle):942:942 -> makePendingIntentForDeeplink + 5:5:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,com.google.firebase.messaging.RemoteMessage):985:985 -> makePendingIntentForDeeplink + 6:6:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,com.google.firebase.messaging.RemoteMessage):982:982 -> makePendingIntentForDeeplink + 7:7:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,com.google.firebase.messaging.RemoteMessage):978:978 -> makePendingIntentForDeeplink + 8:8:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,com.google.firebase.messaging.RemoteMessage):974:974 -> makePendingIntentForDeeplink + 1:1:void onNotificationDisplayed(android.content.Context,android.content.Intent):1100:1100 -> onNotificationDisplayed + 2:2:void onNotificationDisplayed(android.content.Context,com.google.firebase.messaging.RemoteMessage):1110:1110 -> onNotificationDisplayed + 1:1:void refreshRegistration():1140:1140 -> refreshRegistration + 1:1:void setAdditionalIntentFlags(java.lang.Integer):1090:1090 -> setAdditionalIntentFlags + 1:1:void setGCMSenderId(java.lang.String):692:692 -> setGCMSenderId + 1:1:void setLargeIcon(android.graphics.Bitmap):723:723 -> setLargeIcon + 1:1:void setManualDisplay(boolean):820:820 -> setManualDisplay + 1:1:void setNotificationInterceptor(com.batch.android.BatchNotificationInterceptor):1132:1132 -> setNotificationInterceptor + 1:1:void setNotificationsColor(int):803:803 -> setNotificationsColor + 1:1:void setNotificationsType(java.util.EnumSet):769:769 -> setNotificationsType + 1:1:void setSmallIconResourceId(int):701:701 -> setSmallIconResourceId + 1:1:void setSound(android.net.Uri):714:714 -> setSound + 1:1:boolean shouldDisplayPush(android.content.Context,android.content.Intent):995:995 -> shouldDisplayPush + 2:2:boolean shouldDisplayPush(android.content.Context,com.google.firebase.messaging.RemoteMessage):1007:1007 -> shouldDisplayPush +com.batch.android.Batch$User -> com.batch.android.Batch$User: + 1:1:void ():1278:1278 -> + 1:1:com.batch.android.BatchUserDataEditor editor():1357:1357 -> editor + 1:1:void fetchAttributes(android.content.Context,com.batch.android.BatchAttributesFetchListener):1370:1370 -> fetchAttributes + 1:1:void fetchTagCollections(android.content.Context,com.batch.android.BatchTagCollectionsFetchListener):1383:1383 -> fetchTagCollections + 1:1:com.batch.android.BatchUserDataEditor getEditor():1346:1346 -> getEditor + 1:1:java.lang.String getIdentifier(android.content.Context):1335:1335 -> getIdentifier + 2:2:java.lang.String getIdentifier(android.content.Context):1332:1332 -> getIdentifier + 1:3:java.lang.String getInstallationID():1288:1290 -> getInstallationID + 1:1:java.lang.String getLanguage(android.content.Context):1307:1307 -> getLanguage + 2:2:java.lang.String getLanguage(android.content.Context):1304:1304 -> getLanguage + 1:1:java.lang.String getRegion(android.content.Context):1321:1321 -> getRegion + 2:2:java.lang.String getRegion(android.content.Context):1318:1318 -> getRegion + 1:1:void printDebugInformation():1507:1507 -> printDebugInformation + 1:1:void trackEvent(java.lang.String):1393:1393 -> trackEvent + 2:2:void trackEvent(java.lang.String,java.lang.String):1404:1404 -> trackEvent + 3:10:void trackEvent(java.lang.String,java.lang.String,com.batch.android.json.JSONObject):1420:1427 -> trackEvent + 11:19:void trackEvent(java.lang.String,java.lang.String,com.batch.android.BatchEventData):1442:1450 -> trackEvent + 1:1:void trackLocation(android.location.Location):1464:1464 -> trackLocation + 1:1:void trackTransaction(double):1474:1474 -> trackTransaction + 2:11:void trackTransaction(double,com.batch.android.json.JSONObject):1488:1497 -> trackTransaction +com.batch.android.BatchActionActivity -> com.batch.android.BatchActionActivity: + java.lang.String TAG -> a + 1:1:void ():20:20 -> + 1:1:android.content.Intent addPayloadToIntent(android.content.Intent,android.os.Bundle):28:28 -> a + 2:5:androidx.core.app.TaskStackBuilder addPayloadToTaskStackBuilder(androidx.core.app.TaskStackBuilder,android.os.Bundle):38:41 -> a + 6:40:void launchDeeplink(android.content.Intent,java.lang.String):56:90 -> a + 41:46:void launchDeeplink(android.content.Intent,java.lang.String):81:86 -> a + 47:94:void launchDeeplink(android.content.Intent,java.lang.String):64:111 -> a + 95:100:void launchDeeplink(android.content.Intent,java.lang.String):102:107 -> a + 101:126:void launchDeeplink(android.content.Intent,java.lang.String):94:119 -> a + 1:2:void onDestroy():163:164 -> onDestroy + 1:19:void onStart():124:142 -> onStart + 20:20:void onStart():136:136 -> onStart + 21:39:void onStart():134:152 -> onStart + 1:2:void onStop():157:158 -> onStop +com.batch.android.BatchActionService -> com.batch.android.BatchActionService: + java.lang.String TAG -> a + java.lang.String ACTION_EXTRA_IDENTIFIER -> c + java.lang.String INTENT_ACTION -> b + java.lang.String ACTION_EXTRA_DISMISS_NOTIFICATION_ID -> e + java.lang.String ACTION_EXTRA_ARGS -> d + 1:1:void ():28:28 -> + 1:47:void onHandleIntent(android.content.Intent):33:79 -> onHandleIntent +com.batch.android.BatchActivityLifecycleHelper -> com.batch.android.BatchActivityLifecycleHelper: + 1:1:void ():19:19 -> + 1:1:void onActivityCreated(android.app.Activity,android.os.Bundle):23:23 -> onActivityCreated + 1:1:void onActivityDestroyed(android.app.Activity):47:47 -> onActivityDestroyed + 1:1:void onActivityStarted(android.app.Activity):28:28 -> onActivityStarted + 1:1:void onActivityStopped(android.app.Activity):39:39 -> onActivityStopped +com.batch.android.BatchAlertContent -> com.batch.android.BatchAlertContent: + java.lang.String trackingIdentifier -> a + java.lang.String body -> c + com.batch.android.BatchAlertContent$CTA acceptCTA -> e + java.lang.String title -> b + java.lang.String cancelLabel -> d + 1:8:void (com.batch.android.messaging.model.AlertMessage):26:33 -> + 1:1:com.batch.android.BatchAlertContent$CTA getAcceptCTA():59:59 -> getAcceptCTA + 1:1:java.lang.String getBody():49:49 -> getBody + 1:1:java.lang.String getCancelLabel():54:54 -> getCancelLabel + 1:1:java.lang.String getTitle():44:44 -> getTitle + 1:1:java.lang.String getTrackingIdentifier():39:39 -> getTrackingIdentifier +com.batch.android.BatchAlertContent$CTA -> com.batch.android.BatchAlertContent$CTA: + com.batch.android.json.JSONObject args -> c + java.lang.String label -> a + java.lang.String action -> b + 1:8:void (com.batch.android.messaging.model.CTA):71:78 -> + 1:1:java.lang.String getAction():90:90 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():95:95 -> getArgs + 1:1:java.lang.String getLabel():85:85 -> getLabel +com.batch.android.BatchBannerContent -> com.batch.android.BatchBannerContent: + java.lang.String mediaAccessibilityDescription -> g + java.lang.String mediaURL -> f + java.lang.Long autoCloseTimeMillis -> i + java.util.List ctas -> d + com.batch.android.BatchBannerContent$Action globalTapAction -> e + java.lang.String trackingIdentifier -> a + boolean showCloseButton -> h + java.lang.String body -> c + java.lang.String title -> b + 1:1:void (com.batch.android.messaging.model.BannerMessage):36:36 -> + 2:34:void (com.batch.android.messaging.model.BannerMessage):24:56 -> + 1:1:java.lang.Long getAutoCloseTimeMillis():93:93 -> getAutoCloseTimeMillis + 1:1:java.lang.String getBody():69:69 -> getBody + 1:1:java.util.List getCtas():73:73 -> getCtas + 1:1:com.batch.android.BatchBannerContent$Action getGlobalTapAction():77:77 -> getGlobalTapAction + 1:1:java.lang.String getMediaAccessibilityDescription():85:85 -> getMediaAccessibilityDescription + 1:1:java.lang.String getMediaURL():81:81 -> getMediaURL + 1:1:java.lang.String getTitle():65:65 -> getTitle + 1:1:java.lang.String getTrackingIdentifier():61:61 -> getTrackingIdentifier + 1:1:boolean isShowCloseButton():89:89 -> isShowCloseButton +com.batch.android.BatchBannerContent$Action -> com.batch.android.BatchBannerContent$Action: + com.batch.android.json.JSONObject args -> b + java.lang.String action -> a + 1:7:void (com.batch.android.messaging.model.Action):103:109 -> + 1:1:java.lang.String getAction():116:116 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():121:121 -> getArgs +com.batch.android.BatchBannerContent$CTA -> com.batch.android.BatchBannerContent$CTA: + java.lang.String label -> c + 1:2:void (com.batch.android.messaging.model.CTA):131:132 -> + 1:1:java.lang.String getLabel():137:137 -> getLabel +com.batch.android.BatchBannerView -> com.batch.android.BatchBannerView: + com.batch.android.messaging.model.BannerMessage message -> b + com.batch.android.messaging.view.formats.EmbeddedBannerContainer shownContainer -> c + com.batch.android.MessagingAnalyticsDelegate analyticsDelegate -> e + com.batch.android.BatchMessage rawMessage -> a + boolean shown -> d + 1:1:void (com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate):39:39 -> + 2:13:void (com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate):31:42 -> + 1:8:void lambda$show$0(android.view.View):123:130 -> a + 9:16:void lambda$embed$1(android.widget.FrameLayout):163:170 -> a + 1:2:void dismiss(boolean):186:187 -> dismiss + 1:9:void embed(android.widget.FrameLayout):152:160 -> embed + 10:10:void embed(android.widget.FrameLayout):149:149 -> embed + 1:25:void show(android.app.Activity):64:88 -> show + 26:26:void show(android.app.Activity):58:58 -> show + 27:35:void show(android.view.View):112:120 -> show + 36:36:void show(android.view.View):109:109 -> show +com.batch.android.BatchBannerViewPrivateHelper -> com.batch.android.d: + 1:1:void ():10:10 -> + 1:1:com.batch.android.BatchBannerView newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate):17:17 -> a +com.batch.android.BatchDeeplinkInterceptor -> com.batch.android.BatchDeeplinkInterceptor: + 1:1:android.content.Intent getFallbackIntent(android.content.Context):31:31 -> getFallbackIntent +com.batch.android.BatchDisplayReceiptJobService -> com.batch.android.BatchDisplayReceiptJobService: + java.lang.String TAG -> a + 1:1:void ():18:18 -> + 1:3:boolean onStartJob(android.app.job.JobParameters):24:26 -> onStartJob +com.batch.android.BatchDisplayReceiptJobService$SendReceiptTask -> com.batch.android.BatchDisplayReceiptJobService$a: + java.lang.ref.WeakReference originService -> a + android.app.job.JobParameters originJobParameters -> b + 1:3:void (android.app.job.JobService,android.app.job.JobParameters):40:42 -> + 1:10:java.lang.Void doInBackground(java.lang.Void[]):47:56 -> a + 1:1:java.lang.Object doInBackground(java.lang.Object[]):35:35 -> doInBackground +com.batch.android.BatchEventData -> com.batch.android.BatchEventData: + java.util.Map attributes -> a + int MAXIMUM_STRING_LENGTH -> f + int MAXIMUM_URL_LENGTH -> g + int MAXIMUM_VALUES -> d + java.util.Set tags -> b + int MAXIMUM_TAGS -> e + boolean convertedFromLegacyAPI -> c + 1:1:void ():37:37 -> + 2:5:void ():35:38 -> + 6:6:void (com.batch.android.json.JSONObject):41:41 -> + 7:38:void (com.batch.android.json.JSONObject):35:66 -> + 1:1:int lambda$new$0(java.lang.String,java.lang.String):46:46 -> a + 2:2:java.util.Map getAttributes():78:78 -> a + 3:20:boolean enforceURIValue(java.net.URI):286:303 -> a + 21:21:boolean enforceDateValue(java.util.Date):315:315 -> a + 22:23:boolean enforceAttributeName(java.lang.String):323:324 -> a + 1:10:com.batch.android.BatchEventData addTag(java.lang.String):96:105 -> addTag + 1:1:boolean getConvertedFromLegacyAPI():86:86 -> b + 2:3:boolean enforceAttributesCount(java.lang.String):253:254 -> b + 1:1:java.util.Set getTags():82:82 -> c + 2:11:boolean enforceStringValue(java.lang.String):264:273 -> c + 1:2:void init():73:74 -> d + 3:3:java.lang.String normalizeKey(java.lang.String):337:337 -> d + 1:14:com.batch.android.json.JSONObject toInternalJSON():233:246 -> e + 1:2:com.batch.android.BatchEventData put(java.lang.String,java.lang.String):120:121 -> put + 3:4:com.batch.android.BatchEventData put(java.lang.String,java.net.URI):135:136 -> put + 5:6:com.batch.android.BatchEventData put(java.lang.String,float):150:151 -> put + 7:8:com.batch.android.BatchEventData put(java.lang.String,double):165:166 -> put + 9:10:com.batch.android.BatchEventData put(java.lang.String,int):180:181 -> put + 11:12:com.batch.android.BatchEventData put(java.lang.String,long):195:196 -> put + 13:14:com.batch.android.BatchEventData put(java.lang.String,boolean):210:211 -> put + 15:16:com.batch.android.BatchEventData put(java.lang.String,java.util.Date):225:226 -> put +com.batch.android.BatchEventData$TypedAttribute -> com.batch.android.BatchEventData$a: + com.batch.android.user.AttributeType type -> b + java.lang.Object value -> a + 1:3:void (java.lang.Object,com.batch.android.user.AttributeType):345:347 -> +com.batch.android.BatchEventDataPrivateHelper -> com.batch.android.e: + 1:1:void ():12:12 -> + 1:33:java.util.Map getAttributesFromEventData(com.batch.android.BatchEventData):15:47 -> a + 34:34:java.util.Map getAttributesFromEventData(com.batch.android.BatchEventData):44:44 -> a + 35:39:java.util.Map getAttributesFromEventData(com.batch.android.BatchEventData):36:40 -> a + 40:44:java.util.Map getAttributesFromEventData(com.batch.android.BatchEventData):28:32 -> a + 1:1:boolean getConvertedFromLegacyAPIFromEvent(com.batch.android.BatchEventData):60:60 -> b + 1:1:java.util.Set getTagsFromEventData(com.batch.android.BatchEventData):56:56 -> c +com.batch.android.BatchEventDataPrivateHelper$1 -> com.batch.android.e$a: + int[] $SwitchMap$com$batch$android$user$AttributeType -> a + 1:1:void ():26:26 -> +com.batch.android.BatchImageContent -> com.batch.android.BatchImageContent: + com.batch.android.BatchImageContent$Action globalTapAction -> a + long globalTapDelay -> b + int autoCloseDelay -> g + boolean isFullscreen -> h + com.batch.android.messaging.Size2D imageSize -> f + boolean allowSwipeToDismiss -> c + java.lang.String imageDescription -> e + java.lang.String imageURL -> d + 1:11:void (com.batch.android.messaging.model.ImageMessage):27:37 -> + 1:1:int getAutoCloseDelay():75:75 -> getAutoCloseDelay + 1:1:com.batch.android.BatchImageContent$Action getGlobalTapAction():102:102 -> getGlobalTapAction + 1:1:long getGlobalTapDelay():98:98 -> getGlobalTapDelay + 1:1:java.lang.String getImageDescription():86:86 -> getImageDescription + 1:4:android.graphics.Point getImageSize():79:82 -> getImageSize + 1:1:java.lang.String getImageURL():90:90 -> getImageURL + 1:1:boolean isAllowSwipeToDismiss():94:94 -> isAllowSwipeToDismiss + 1:1:boolean isFullscreen():71:71 -> isFullscreen +com.batch.android.BatchImageContent$Action -> com.batch.android.BatchImageContent$Action: + com.batch.android.json.JSONObject args -> b + java.lang.String action -> a + 1:7:void (com.batch.android.messaging.model.Action):48:54 -> + 1:1:java.lang.String getAction():61:61 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():66:66 -> getArgs +com.batch.android.BatchInAppMessage -> com.batch.android.BatchInAppMessage: + com.batch.android.json.JSONObject customPayload -> d + java.lang.String campaignId -> f + java.lang.String LANDING_PAYLOAD_KEY -> i + com.batch.android.json.JSONObject landingPayload -> c + java.lang.String CAMPAIGN_TOKEN_KEY -> k + java.lang.String CUSTOM_PAYLOAD_KEY -> j + com.batch.android.BatchInAppMessage$Content cachedContent -> h + java.lang.String CAMPAIGN_EVENT_DATA_KEY -> m + java.lang.String CAMPAIGN_ID_KEY -> l + java.lang.String campaignToken -> e + com.batch.android.json.JSONObject eventData -> g + 1:6:void (java.lang.String,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.json.JSONObject,com.batch.android.json.JSONObject):73:78 -> + 1:25:com.batch.android.BatchInAppMessage getInstanceFromBundle(android.os.Bundle):39:63 -> a + 26:26:com.batch.android.BatchInAppMessage getInstanceFromBundle(android.os.Bundle):50:50 -> a + 27:34:android.os.Bundle getBundleRepresentation():103:110 -> a + 1:1:com.batch.android.json.JSONObject getCustomPayloadInternal():91:91 -> b + 1:1:com.batch.android.json.JSONObject getJSON():83:83 -> c + 1:1:java.lang.String getKind():96:96 -> d + 1:1:java.lang.String getCampaignId():115:115 -> e + 1:1:com.batch.android.json.JSONObject getEventData():119:119 -> f + 1:1:java.lang.String getCampaignToken():178:178 -> getCampaignToken + 1:23:com.batch.android.BatchInAppMessage$Content getContent():146:168 -> getContent + 1:8:com.batch.android.json.JSONObject getCustomPayload():125:132 -> getCustomPayload +com.batch.android.BatchInboxFetcher -> com.batch.android.BatchInboxFetcher: + android.os.Handler handler -> b + com.batch.android.inbox.InboxFetcherInternal impl -> a + 1:1:void (com.batch.android.inbox.InboxFetcherInternal):38:38 -> + 2:5:void (com.batch.android.inbox.InboxFetcherInternal):36:39 -> + 1:1:android.os.Handler access$000(com.batch.android.BatchInboxFetcher):32:32 -> a + 1:22:void fetchNewNotifications(com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener):123:144 -> fetchNewNotifications + 1:19:void fetchNextPage(com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener):155:173 -> fetchNextPage + 1:1:java.util.List getFetchedNotifications():111:111 -> getFetchedNotifications + 1:1:boolean hasMore():76:76 -> hasMore + 1:1:void markAllAsRead():92:92 -> markAllAsRead + 1:1:void markAsDeleted(com.batch.android.BatchInboxNotificationContent):101:101 -> markAsDeleted + 1:1:void markAsRead(com.batch.android.BatchInboxNotificationContent):85:85 -> markAsRead + 1:1:void setFetchLimit(int):57:57 -> setFetchLimit + 1:1:void setFilterSilentNotifications(boolean):67:67 -> setFilterSilentNotifications + 1:1:void setHandlerOverride(android.os.Handler):184:184 -> setHandlerOverride + 1:1:void setMaxPageSize(int):47:47 -> setMaxPageSize +com.batch.android.BatchInboxFetcher$1 -> com.batch.android.BatchInboxFetcher$a: + com.batch.android.BatchInboxFetcher this$0 -> b + com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener val$originalListener -> a + 1:1:void (com.batch.android.BatchInboxFetcher,com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener):126:126 -> + 1:1:void lambda$onFetchSuccess$0(com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener,java.util.List,boolean,boolean):134:134 -> a + 2:2:void lambda$onFetchFailure$1(com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener,java.lang.String):140:140 -> a + 1:1:void onFetchFailure(java.lang.String):140:140 -> onFetchFailure + 1:1:void onFetchSuccess(java.util.List,boolean,boolean):133:133 -> onFetchSuccess +com.batch.android.BatchInboxFetcher$2 -> com.batch.android.BatchInboxFetcher$b: + com.batch.android.BatchInboxFetcher this$0 -> b + com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener val$originalListener -> a + 1:1:void (com.batch.android.BatchInboxFetcher,com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener):158:158 -> + 1:1:void lambda$onFetchSuccess$0(com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener,java.util.List,boolean):164:164 -> a + 2:2:void lambda$onFetchFailure$1(com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener,java.lang.String):169:169 -> a + 1:1:void onFetchFailure(java.lang.String):169:169 -> onFetchFailure + 1:1:void onFetchSuccess(java.util.List,boolean):164:164 -> onFetchSuccess +com.batch.android.BatchInboxNotificationContent -> com.batch.android.BatchInboxNotificationContent: + com.batch.android.inbox.InboxNotificationContentInternal internalContent -> a + com.batch.android.BatchPushPayload batchPushPayloadCache -> b + 1:1:void (com.batch.android.inbox.InboxNotificationContentInternal):27:27 -> + 2:10:void (com.batch.android.inbox.InboxNotificationContentInternal):20:28 -> + 1:1:java.lang.String getBody():48:48 -> getBody + 1:1:java.util.Date getDate():73:73 -> getDate + 1:1:java.lang.String getNotificationIdentifier():38:38 -> getNotificationIdentifier + 1:5:com.batch.android.BatchPushPayload getPushPayload():107:111 -> getPushPayload + 1:1:java.util.Map getRawPayload():97:97 -> getRawPayload + 1:1:com.batch.android.BatchNotificationSource getSource():53:53 -> getSource + 1:1:java.lang.String getTitle():43:43 -> getTitle + 1:1:boolean isDeleted():68:68 -> isDeleted + 1:1:boolean isSilent():85:85 -> isSilent + 1:1:boolean isUnread():57:57 -> isUnread +com.batch.android.BatchInterstitialContent -> com.batch.android.BatchInterstitialContent: + java.lang.String mediaAccessibilityDescription -> g + java.lang.String mediaURL -> f + java.util.List ctas -> e + java.lang.String trackingIdentifier -> a + boolean showCloseButton -> h + java.lang.String title -> c + java.lang.String header -> b + java.lang.String body -> d + 1:1:void (com.batch.android.messaging.model.UniversalMessage):35:35 -> + 2:30:void (com.batch.android.messaging.model.UniversalMessage):27:55 -> + 1:1:java.lang.String getBody():72:72 -> getBody + 1:1:java.util.List getCtas():76:76 -> getCtas + 1:1:java.lang.String getHeader():64:64 -> getHeader + 1:1:java.lang.String getMediaAccessibilityDescription():84:84 -> getMediaAccessibilityDescription + 1:1:java.lang.String getMediaURL():80:80 -> getMediaURL + 1:1:java.lang.String getTitle():68:68 -> getTitle + 1:1:java.lang.String getTrackingIdentifier():60:60 -> getTrackingIdentifier + 1:1:boolean shouldShowCloseButton():88:88 -> shouldShowCloseButton +com.batch.android.BatchInterstitialContent$CTA -> com.batch.android.BatchInterstitialContent$CTA: + com.batch.android.json.JSONObject args -> c + java.lang.String label -> a + java.lang.String action -> b + 1:8:void (com.batch.android.messaging.model.CTA):100:107 -> + 1:1:java.lang.String getAction():119:119 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():124:124 -> getArgs + 1:1:java.lang.String getLabel():114:114 -> getLabel +com.batch.android.BatchLandingMessage -> com.batch.android.BatchLandingMessage: + com.batch.android.json.JSONObject landing -> d + android.os.Bundle payload -> c + java.lang.String GOOGLE_PREFIX -> e + 1:3:void (android.os.Bundle,com.batch.android.json.JSONObject):23:25 -> + 1:5:android.os.Bundle cleanBundle(android.os.Bundle):35:39 -> a + 6:7:android.os.Bundle getBundleRepresentation():79:80 -> a + 1:7:com.batch.android.json.JSONObject getCustomPayloadInternal():55:61 -> b + 1:1:com.batch.android.json.JSONObject getJSON():47:47 -> c + 1:1:java.lang.String getKind():72:72 -> d + 1:1:android.os.Bundle getPushBundle():85:85 -> getPushBundle +com.batch.android.BatchMessage -> com.batch.android.BatchMessage: + java.lang.String KIND_KEY -> a + java.lang.String DATA_KEY -> b + 1:1:void ():24:24 -> + android.os.Bundle getBundleRepresentation() -> a + com.batch.android.json.JSONObject getCustomPayloadInternal() -> b + com.batch.android.json.JSONObject getJSON() -> c + java.lang.String getKind() -> d + 1:19:com.batch.android.BatchMessage$Format getFormat():112:130 -> getFormat + 1:22:com.batch.android.BatchMessage getMessageForBundle(android.os.Bundle):74:95 -> getMessageForBundle + 23:23:com.batch.android.BatchMessage getMessageForBundle(android.os.Bundle):76:76 -> getMessageForBundle + 24:24:com.batch.android.BatchMessage getMessageForBundle(android.os.Bundle):71:71 -> getMessageForBundle + 1:5:void writeToBundle(android.os.Bundle):48:52 -> writeToBundle + 6:6:void writeToBundle(android.os.Bundle):45:45 -> writeToBundle + 1:5:void writeToIntent(android.content.Intent):61:65 -> writeToIntent + 6:6:void writeToIntent(android.content.Intent):58:58 -> writeToIntent +com.batch.android.BatchMessage$Format -> com.batch.android.BatchMessage$Format: + com.batch.android.BatchMessage$Format[] $VALUES -> a + 1:25:void ():148:172 -> + 26:26:void ():142:142 -> + 1:1:void (java.lang.String,int):143:143 -> + 1:1:com.batch.android.BatchMessage$Format valueOf(java.lang.String):142:142 -> valueOf + 1:1:com.batch.android.BatchMessage$Format[] values():142:142 -> values +com.batch.android.BatchMessageAction -> com.batch.android.BatchMessageAction: + com.batch.android.json.JSONObject args -> b + java.lang.String action -> a + 1:7:void (com.batch.android.messaging.model.Action):24:30 -> + 1:1:java.lang.String getAction():37:37 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():42:42 -> getArgs + 1:1:boolean isDismissAction():46:46 -> isDismissAction +com.batch.android.BatchMessageCTA -> com.batch.android.BatchMessageCTA: + java.lang.String label -> c + 1:2:void (com.batch.android.messaging.model.CTA):20:21 -> + 1:1:java.lang.String getLabel():26:26 -> getLabel +com.batch.android.BatchMessagingException -> com.batch.android.BatchMessagingException: + 1:1:void ():12:12 -> + 2:2:void (java.lang.String):16:16 -> + 3:3:void (java.lang.String,java.lang.Throwable):20:20 -> + 4:4:void (java.lang.Throwable):24:24 -> +com.batch.android.BatchMessagingWebViewJavascriptBridge -> com.batch.android.BatchMessagingWebViewJavascriptBridge: + android.content.Context applicationContext -> a + com.batch.android.BatchMessage message -> b + com.batch.android.messaging.WebViewActionListener actionListener -> c + java.lang.String TAG -> d + 1:4:void (android.content.Context,com.batch.android.BatchMessage,com.batch.android.messaging.WebViewActionListener):37:40 -> + 1:6:java.lang.String makeSuccessResult(com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider):82:87 -> a + 7:12:java.lang.String makeErrorResult(java.lang.String):93:98 -> a + 13:38:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):104:129 -> a + 39:40:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):126:127 -> a + 41:41:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):116:116 -> a + 42:46:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):106:110 -> a + 47:63:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):108:124 -> a + 64:67:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):118:121 -> a + 68:68:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):114:114 -> a + 69:69:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getMethodResultProvider(java.lang.String,com.batch.android.json.JSONObject):112:112 -> a + 70:80:java.lang.String getAdvertisingID():162:172 -> a + 81:84:void dismiss(com.batch.android.json.JSONObject):213:216 -> a + 1:3:java.lang.String getAdvertisingIDValue():185:187 -> b + 4:15:void openDeeplink(com.batch.android.json.JSONObject):239:250 -> b + 16:16:void openDeeplink(com.batch.android.json.JSONObject):241:241 -> b + 1:1:java.lang.String getCustomLanguage():144:144 -> c + 2:15:void performAction(com.batch.android.json.JSONObject):221:234 -> c + 16:16:void performAction(com.batch.android.json.JSONObject):223:223 -> c + 1:5:java.lang.String getCustomPayload():196:200 -> d + 1:1:java.lang.String getCustomRegion():150:150 -> e + 1:1:java.lang.String getCustomUserID():156:156 -> f + 1:1:com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider getGenericSuccessResultProvider():257:257 -> g + 1:1:java.lang.String getInstallationID():138:138 -> h + 1:5:java.lang.String getTrackingID():205:209 -> i + 1:1:boolean isAdvertisingIDAllowedByConfig():178:178 -> j + 1:1:java.lang.String lambda$getGenericSuccessResultProvider$0():257:257 -> k + 1:30:java.lang.String postMessage(java.lang.String,java.lang.String):46:75 -> postMessage + 31:32:java.lang.String postMessage(java.lang.String,java.lang.String):71:72 -> postMessage + 33:34:java.lang.String postMessage(java.lang.String,java.lang.String):68:69 -> postMessage + 35:36:java.lang.String postMessage(java.lang.String,java.lang.String):64:65 -> postMessage + 37:38:java.lang.String postMessage(java.lang.String,java.lang.String):57:58 -> postMessage + 39:39:java.lang.String postMessage(java.lang.String,java.lang.String):47:47 -> postMessage +com.batch.android.BatchMessagingWebViewJavascriptBridge$1 -> com.batch.android.BatchMessagingWebViewJavascriptBridge$a: +com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProvider -> com.batch.android.BatchMessagingWebViewJavascriptBridge$b: + java.lang.String getResult() -> a +com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProviderException -> com.batch.android.BatchMessagingWebViewJavascriptBridge$c: + 1:1:void (java.lang.String):273:273 -> + 1:1:java.lang.String getMessage():280:280 -> getMessage +com.batch.android.BatchMessagingWebViewJavascriptBridge$BridgeResultProviderRuntimeException -> com.batch.android.BatchMessagingWebViewJavascriptBridge$d: + java.lang.String internalMessage -> b + int code -> a + 1:3:void (int,java.lang.String):295:297 -> + 4:6:void (int,java.lang.String,java.lang.Throwable):305:307 -> + 1:1:int getCode():311:311 -> a + 1:1:java.lang.String getMessage():317:317 -> getMessage +com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause -> com.batch.android.BatchMessagingWebViewJavascriptBridge$e: + com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause SSL -> b + com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause BAD_HTTP_STATUSCODE -> c + com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause TIMEOUT -> d + com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause[] $VALUES -> e + com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause UNKNOWN -> a + 1:4:void ():324:327 -> + 5:5:void ():323:323 -> + 1:1:void (java.lang.String,int):323:323 -> + 1:1:com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause valueOf(java.lang.String):323:323 -> valueOf + 1:1:com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause[] values():323:323 -> values +com.batch.android.BatchMessagingWebViewJavascriptBridge$UnknownMethodException -> com.batch.android.BatchMessagingWebViewJavascriptBridge$f: + 1:1:void ():321:321 -> + 2:2:void (com.batch.android.BatchMessagingWebViewJavascriptBridge$1):321:321 -> +com.batch.android.BatchModalContent -> com.batch.android.BatchModalContent: + java.lang.String mediaAccessibilityDescription -> g + java.lang.String mediaURL -> f + java.lang.Long autoCloseTimeMillis -> i + java.util.List ctas -> d + com.batch.android.BatchModalContent$Action globalTapAction -> e + java.lang.String trackingIdentifier -> a + boolean showCloseButton -> h + java.lang.String body -> c + java.lang.String title -> b + 1:1:void (com.batch.android.messaging.model.ModalMessage):36:36 -> + 2:34:void (com.batch.android.messaging.model.ModalMessage):24:56 -> + 1:1:java.lang.Long getAutoCloseTimeMillis():93:93 -> getAutoCloseTimeMillis + 1:1:java.lang.String getBody():69:69 -> getBody + 1:1:java.util.List getCtas():73:73 -> getCtas + 1:1:com.batch.android.BatchModalContent$Action getGlobalTapAction():77:77 -> getGlobalTapAction + 1:1:java.lang.String getMediaAccessibilityDescription():85:85 -> getMediaAccessibilityDescription + 1:1:java.lang.String getMediaURL():81:81 -> getMediaURL + 1:1:java.lang.String getTitle():65:65 -> getTitle + 1:1:java.lang.String getTrackingIdentifier():61:61 -> getTrackingIdentifier + 1:1:boolean isShowCloseButton():89:89 -> isShowCloseButton +com.batch.android.BatchModalContent$Action -> com.batch.android.BatchModalContent$Action: + com.batch.android.json.JSONObject args -> b + java.lang.String action -> a + 1:7:void (com.batch.android.messaging.model.Action):103:109 -> + 1:1:java.lang.String getAction():116:116 -> getAction + 1:1:com.batch.android.json.JSONObject getArgs():121:121 -> getArgs +com.batch.android.BatchModalContent$CTA -> com.batch.android.BatchModalContent$CTA: + java.lang.String label -> c + 1:2:void (com.batch.android.messaging.model.CTA):131:132 -> + 1:1:java.lang.String getLabel():137:137 -> getLabel +com.batch.android.BatchNotificationAction -> com.batch.android.BatchNotificationAction: + 1:36:void ():21:56 -> + 1:39:java.util.List getSupportActions(android.content.Context,java.util.List,com.batch.android.BatchPushPayload,java.lang.Integer):87:125 -> getSupportActions + 40:50:java.util.List getSupportActions(android.content.Context,java.util.List,com.batch.android.BatchPushPayload,java.lang.Integer):123:133 -> getSupportActions + 51:65:java.util.List getSupportActions(android.content.Context,java.util.List,com.batch.android.BatchPushPayload,java.lang.Integer):131:145 -> getSupportActions + 66:66:java.util.List getSupportActions(android.content.Context,java.util.List,com.batch.android.BatchPushPayload,java.lang.Integer):139:139 -> getSupportActions + 67:67:java.util.List getSupportActions(android.content.Context,java.util.List,com.batch.android.BatchPushPayload,java.lang.Integer):84:84 -> getSupportActions +com.batch.android.BatchNotificationChannelsManager -> com.batch.android.BatchNotificationChannelsManager: + com.batch.android.BatchNotificationChannelsManager$NotificationChannelIdInterceptor channelIdInterceptor -> c + java.lang.String channelOverride -> a + com.batch.android.module.PushModule pushModule -> d + com.batch.android.BatchNotificationChannelsManager$ChannelNameProvider channelNameProvider -> b + 1:16:void (com.batch.android.module.PushModule):36:51 -> + 17:17:void (com.batch.android.module.PushModule):37:37 -> + 1:14:java.lang.String getChannelId(com.batch.android.BatchPushPayload):58:71 -> a + 15:34:void registerBatchChannelIfNeeded(android.content.Context,boolean):89:108 -> a + 35:42:void registerBatchChannelIfNeeded(android.content.Context,boolean):106:113 -> a + 43:56:java.lang.String getBatchChannelName():124:137 -> a + 1:1:boolean shouldRegisterDefaultChannel():85:85 -> b + 1:1:boolean openSystemChannelSettings(android.content.Context):213:213 -> openSystemChannelSettings + 2:7:boolean openSystemChannelSettings(android.content.Context,java.lang.String):234:239 -> openSystemChannelSettings + 8:8:boolean openSystemChannelSettings(android.content.Context,java.lang.String):232:232 -> openSystemChannelSettings + 9:9:boolean openSystemChannelSettings(android.content.Context,java.lang.String):228:228 -> openSystemChannelSettings + 1:1:com.batch.android.BatchNotificationChannelsManager provide():42:42 -> provide + 1:1:void setChannelIdInterceptor(com.batch.android.BatchNotificationChannelsManager$NotificationChannelIdInterceptor):201:201 -> setChannelIdInterceptor + 1:1:void setChannelIdOverride(java.lang.String):160:160 -> setChannelIdOverride + 1:1:void setChannelName(android.content.Context,int):189:189 -> setChannelName + 1:1:void setChannelNameProvider(com.batch.android.BatchNotificationChannelsManager$ChannelNameProvider):177:177 -> setChannelNameProvider +com.batch.android.BatchNotificationChannelsManager$StringResChannelNameProvider -> com.batch.android.BatchNotificationChannelsManager$StringResChannelNameProvider: + android.content.Context context -> a + int resId -> b + 1:3:void (android.content.Context,int):277:279 -> + 1:1:java.lang.String getDefaultChannelName():284:284 -> getDefaultChannelName +com.batch.android.BatchNotificationChannelsManagerPrivateHelper -> com.batch.android.f: + 1:1:void ():9:9 -> + 1:1:java.lang.String getChannelId(com.batch.android.BatchNotificationChannelsManager):13:13 -> a + 2:2:void registerBatchChannelIfNeeded(com.batch.android.BatchNotificationChannelsManager,android.content.Context,boolean):21:21 -> a +com.batch.android.BatchNotificationInterceptor -> com.batch.android.BatchNotificationInterceptor: + 1:1:void ():17:17 -> +com.batch.android.BatchNotificationSource -> com.batch.android.BatchNotificationSource: + com.batch.android.BatchNotificationSource[] $VALUES -> a + 1:4:void ():11:14 -> + 5:5:void ():9:9 -> + 1:1:void (java.lang.String,int):10:10 -> + 1:1:com.batch.android.BatchNotificationSource valueOf(java.lang.String):9:9 -> valueOf + 1:1:com.batch.android.BatchNotificationSource[] values():9:9 -> values +com.batch.android.BatchOptOutResultListener$ErrorPolicy -> com.batch.android.BatchOptOutResultListener$ErrorPolicy: + com.batch.android.BatchOptOutResultListener$ErrorPolicy[] $VALUES -> a + 1:6:void ():19:24 -> + 7:7:void ():14:14 -> + 1:1:void (java.lang.String,int):15:15 -> + 1:1:com.batch.android.BatchOptOutResultListener$ErrorPolicy valueOf(java.lang.String):14:14 -> valueOf + 1:1:com.batch.android.BatchOptOutResultListener$ErrorPolicy[] values():14:14 -> values +com.batch.android.BatchPushData -> com.batch.android.BatchPushData: + android.content.Context context -> b + com.batch.android.core.InternalPushData internalPushData -> a + 1:14:void (android.content.Context,android.content.Intent):36:49 -> + 15:15:void (android.content.Context,android.content.Intent):42:42 -> + 16:16:void (android.content.Context,android.content.Intent):38:38 -> + 1:9:java.lang.String getBigPictureURL():118:126 -> getBigPictureURL + 10:10:java.lang.String getBigPictureURL():123:123 -> getBigPictureURL + 1:6:java.lang.String getCustomLargeIconURL():92:97 -> getCustomLargeIconURL + 1:1:java.lang.String getDeeplink():71:71 -> getDeeplink + 1:1:boolean hasBigPicture():106:106 -> hasBigPicture + 1:1:boolean hasCustomLargeIcon():80:80 -> hasCustomLargeIcon + 1:1:boolean hasDeeplink():61:61 -> hasDeeplink +com.batch.android.BatchPushHelper -> com.batch.android.g: + 1:1:void ():18:18 -> + 1:6:boolean canDisplayPush(android.content.Context,com.batch.android.core.InternalPushData):30:35 -> a + 7:7:boolean canDisplayPush(android.content.Context,com.batch.android.core.InternalPushData):32:32 -> a + 8:15:android.os.Bundle firebaseMessageToReceiverBundle(com.google.firebase.messaging.RemoteMessage):56:63 -> a + 16:17:boolean installIDMatchesCurrent(android.content.Context,java.lang.String):75:76 -> a +com.batch.android.BatchPushInstanceIDService -> com.batch.android.BatchPushInstanceIDService: + 1:1:void ():12:12 -> + 1:3:void onTokenRefresh():16:18 -> onTokenRefresh +com.batch.android.BatchPushJobService -> com.batch.android.BatchPushJobService: + java.lang.String TAG -> a + 1:1:void ():20:20 -> + 1:12:boolean onStartJob(android.app.job.JobParameters):29:40 -> onStartJob + 1:1:boolean onStopJob(android.app.job.JobParameters):46:46 -> onStopJob +com.batch.android.BatchPushJobService$PresentPushTask -> com.batch.android.BatchPushJobService$a: + android.os.Bundle pushData -> a + android.app.job.JobParameters originJobParameters -> c + java.lang.ref.WeakReference originService -> b + 1:4:void (android.os.Bundle,android.app.job.JobService,android.app.job.JobParameters):62:65 -> + 1:29:java.lang.Void doInBackground(java.lang.Void[]):70:98 -> a + 30:32:java.lang.Void doInBackground(java.lang.Void[]):92:94 -> a + 33:43:java.lang.Void doInBackground(java.lang.Void[]):90:100 -> a + 1:1:java.lang.Object doInBackground(java.lang.Object[]):50:50 -> doInBackground +com.batch.android.BatchPushMessageDismissReceiver -> com.batch.android.BatchPushMessageDismissReceiver: + java.lang.String TAG -> d + 1:1:void ():17:17 -> + 1:21:void onReceive(android.content.Context,android.content.Intent):24:44 -> onReceive + 22:22:void onReceive(android.content.Context,android.content.Intent):30:30 -> onReceive +com.batch.android.BatchPushMessageReceiver -> com.batch.android.BatchPushMessageReceiver: + java.util.ArrayDeque handledMessageIDs -> f + int MAX_HANDLED_MESSAGE_IDS_COUNT -> e + java.lang.String TAG -> d + 1:1:void ():39:39 -> + 1:1:void ():29:29 -> + 1:26:boolean presentNotification(android.content.Context,android.content.Intent):77:102 -> a + 27:27:boolean isDuplicateMessage(java.lang.String):161:161 -> a + 28:34:java.lang.String getGoogleMessageID(android.content.Intent):182:188 -> a + 35:35:int getHandledMessageIDsSize():197:197 -> a + 1:2:boolean isFCMMessage(android.content.Intent):64:65 -> b + 3:28:boolean scheduleJob(android.content.Context,android.content.Intent):112:137 -> b + 29:49:boolean scheduleJob(android.content.Context,android.content.Intent):120:140 -> b + 50:52:void markMessageAsHandled(java.lang.String):169:171 -> b + 53:53:void resetHandledMessageIDs():202:202 -> b + 1:5:void startPresentationService(android.content.Context,android.content.Intent):147:151 -> c + 1:15:void onReceive(android.content.Context,android.content.Intent):44:58 -> onReceive +com.batch.android.BatchPushNotificationPresenter -> com.batch.android.h: + java.lang.String TAG -> a + int DEFAULT_NO_NOTIFICATION -> e + java.lang.String CUSTOM_SMALL_ICON_FIREBASE_METADATA_NAME -> c + java.lang.String CUSTOM_SMALL_ICON_METADATA_NAME -> b + java.lang.String CUSTOM_COLOR_METADATA -> d + 1:1:void ():59:59 -> + 1:42:void displayForPush(android.content.Context,android.os.Bundle):82:123 -> a + 43:52:void _handleLocalCampaignsSilentPush(android.content.Context):131:140 -> a + 53:257:void presentNotification(android.content.Context,android.os.Bundle,com.batch.android.BatchPushPayload,com.batch.android.BatchNotificationInterceptor):154:358 -> a + 258:324:void presentNotification(android.content.Context,android.os.Bundle,com.batch.android.BatchPushPayload,com.batch.android.BatchNotificationInterceptor):352:418 -> a + 325:392:void presentNotification(android.content.Context,android.os.Bundle,com.batch.android.BatchPushPayload,com.batch.android.BatchNotificationInterceptor):417:484 -> a + 393:459:void presentNotification(android.content.Context,android.os.Bundle,com.batch.android.BatchPushPayload,com.batch.android.BatchNotificationInterceptor):480:546 -> a + 460:460:void presentNotification(android.content.Context,android.os.Bundle,com.batch.android.BatchPushPayload,com.batch.android.BatchNotificationInterceptor):208:208 -> a + 461:504:boolean trySendLandingToForegroundApp(android.content.Context,android.os.Bundle,com.batch.android.core.InternalPushData):560:603 -> a + 505:509:android.graphics.Bitmap resizeLargeIcon(android.content.Context,android.graphics.Bitmap):613:617 -> a + 510:530:void applyNotificationFormat(android.content.Context,com.batch.android.push.formats.NotificationFormat,androidx.core.app.NotificationCompat$Builder):734:754 -> a + 1:5:int getAppPrimaryColor(android.content.Context):696:700 -> b + 1:26:int getDefaults(android.content.Context):629:654 -> c + 1:10:java.lang.Integer getMetaDataPushColor(android.content.Context):714:723 -> d + 1:15:java.lang.Integer getMetaDataSmallIconResId(android.content.Context):674:688 -> e +com.batch.android.BatchPushPayload -> com.batch.android.BatchPushPayload: + android.os.Bundle rawData -> b + com.batch.android.core.InternalPushData internalPushData -> a + 1:8:void (android.os.Bundle):50:57 -> + 9:9:void (android.os.Bundle):54:54 -> + 10:15:void (com.google.firebase.messaging.RemoteMessage):60:65 -> + 1:1:com.batch.android.core.InternalPushData getInternalData():352:352 -> a + 1:2:java.util.List getActions():293:294 -> getActions + 1:9:java.lang.String getBigPictureURL(android.content.Context):257:265 -> getBigPictureURL + 10:10:java.lang.String getBigPictureURL(android.content.Context):262:262 -> getBigPictureURL + 1:1:java.lang.String getChannel():334:334 -> getChannel + 1:6:java.lang.String getCustomLargeIconURL(android.content.Context):231:236 -> getCustomLargeIconURL + 1:1:java.lang.String getDeeplink():210:210 -> getDeeplink + 1:1:java.lang.String getGroup():315:315 -> getGroup + 1:5:com.batch.android.BatchMessage getLandingMessage():282:286 -> getLandingMessage + 1:1:int getPriority():306:306 -> getPriority + 1:1:android.os.Bundle getPushBundle():346:346 -> getPushBundle + 1:1:boolean hasBigPicture():245:245 -> hasBigPicture + 1:1:boolean hasCustomLargeIcon():219:219 -> hasCustomLargeIcon + 1:1:boolean hasDeeplink():200:200 -> hasDeeplink + 1:1:boolean hasLandingMessage():273:273 -> hasLandingMessage + 1:1:boolean isGroupSummary():324:324 -> isGroupSummary + 1:7:com.batch.android.BatchPushPayload payloadFromBundle(android.os.Bundle):86:92 -> payloadFromBundle + 8:8:com.batch.android.BatchPushPayload payloadFromBundle(android.os.Bundle):89:89 -> payloadFromBundle + 9:9:com.batch.android.BatchPushPayload payloadFromBundle(android.os.Bundle):83:83 -> payloadFromBundle + 1:1:com.batch.android.BatchPushPayload payloadFromFirebaseMessage(com.google.firebase.messaging.RemoteMessage):153:153 -> payloadFromFirebaseMessage + 2:2:com.batch.android.BatchPushPayload payloadFromFirebaseMessage(com.google.firebase.messaging.RemoteMessage):150:150 -> payloadFromFirebaseMessage + 1:1:com.batch.android.BatchPushPayload payloadFromReceiverExtras(android.os.Bundle):134:134 -> payloadFromReceiverExtras + 2:2:com.batch.android.BatchPushPayload payloadFromReceiverExtras(android.os.Bundle):131:131 -> payloadFromReceiverExtras + 1:7:com.batch.android.BatchPushPayload payloadFromReceiverIntent(android.content.Intent):110:116 -> payloadFromReceiverIntent + 8:8:com.batch.android.BatchPushPayload payloadFromReceiverIntent(android.content.Intent):113:113 -> payloadFromReceiverIntent + 9:9:com.batch.android.BatchPushPayload payloadFromReceiverIntent(android.content.Intent):107:107 -> payloadFromReceiverIntent + 1:1:void writeToBundle(android.os.Bundle):172:172 -> writeToBundle + 2:2:void writeToBundle(android.os.Bundle):169:169 -> writeToBundle + 1:1:void writeToIntentExtras(android.content.Intent):187:187 -> writeToIntentExtras + 2:2:void writeToIntentExtras(android.content.Intent):184:184 -> writeToIntentExtras +com.batch.android.BatchPushPayload$ParsingException -> com.batch.android.BatchPushPayload$ParsingException: + 1:1:void ():33:33 -> + 2:2:void (java.lang.String):37:37 -> + 3:3:void (java.lang.String,java.lang.Throwable):42:42 -> +com.batch.android.BatchPushReceiver -> com.batch.android.BatchPushReceiver: + 1:1:void ():17:17 -> + 1:17:void onReceive(android.content.Context,android.content.Intent):21:37 -> onReceive +com.batch.android.BatchPushService -> com.batch.android.BatchPushService: + java.lang.String TAG -> a + 1:1:void ():21:21 -> + 1:11:void onHandleIntent(android.content.Intent):28:38 -> onHandleIntent + 12:19:void onHandleIntent(android.content.Intent):31:38 -> onHandleIntent + 20:20:void onHandleIntent(android.content.Intent):35:35 -> onHandleIntent + 21:27:void onHandleIntent(android.content.Intent):33:39 -> onHandleIntent +com.batch.android.BatchQueryWebservice -> com.batch.android.i: + java.util.List responses -> p + java.util.List queries -> o + com.batch.android.WebserviceMetrics webserviceMetrics -> q + java.lang.String TAG -> r + 1:2:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):56:57 -> + java.util.List getQueries() -> I + 1:5:com.batch.android.query.response.Response getResponseFor(java.lang.Class,com.batch.android.query.QueryType):218:222 -> a + 6:6:com.batch.android.query.response.Response getResponseFor(java.lang.Class,com.batch.android.query.QueryType):219:219 -> a + 7:8:com.batch.android.query.response.Response getResponseForType(com.batch.android.query.QueryType):239:240 -> a + 1:2:com.batch.android.query.Query getQueryForID(java.lang.String):255:256 -> b + 1:55:void parseQueries(com.batch.android.json.JSONObject):145:199 -> c + 56:56:void parseQueries(com.batch.android.json.JSONObject):196:196 -> c + 57:57:void parseQueries(com.batch.android.json.JSONObject):193:193 -> c + 58:58:void parseQueries(com.batch.android.json.JSONObject):190:190 -> c + 59:59:void parseQueries(com.batch.android.json.JSONObject):187:187 -> c + 60:80:void parseQueries(com.batch.android.json.JSONObject):184:204 -> c + 81:81:void parseQueries(com.batch.android.json.JSONObject):175:175 -> c + 82:86:void parseQueries(com.batch.android.json.JSONObject):151:155 -> c + 87:87:void parseQueries(com.batch.android.json.JSONObject):146:146 -> c + 1:11:void parseResponse(com.batch.android.json.JSONObject):124:134 -> d + 1:33:com.batch.android.post.PostDataProvider getPostDataProvider():69:101 -> w +com.batch.android.BatchQueryWebservice$1 -> com.batch.android.i$a: + int[] $SwitchMap$com$batch$android$query$QueryType -> a + 1:1:void ():182:182 -> +com.batch.android.BatchUserAttribute -> com.batch.android.BatchUserAttribute: + 1:3:void (java.lang.Object,com.batch.android.BatchUserAttribute$Type):15:17 -> + 1:2:java.lang.Boolean getBooleanValue():46:47 -> getBooleanValue + 1:2:java.util.Date getDateValue():22:23 -> getDateValue + 1:2:java.lang.Number getNumberValue():38:39 -> getNumberValue + 1:2:java.lang.String getStringValue():30:31 -> getStringValue + 1:2:java.net.URI getUriValue():54:55 -> getUriValue +com.batch.android.BatchUserAttribute$Type -> com.batch.android.BatchUserAttribute$Type: + com.batch.android.BatchUserAttribute$Type[] $VALUES -> a + 1:6:void ():62:67 -> + 7:7:void ():60:60 -> + 1:1:void (java.lang.String,int):61:61 -> + 1:1:com.batch.android.BatchUserAttribute$Type valueOf(java.lang.String):60:60 -> valueOf + 1:1:com.batch.android.BatchUserAttribute$Type[] values():60:60 -> values +com.batch.android.BatchUserDataEditor -> com.batch.android.BatchUserDataEditor: + java.util.List operationQueue -> a + int ATTR_STRING_MAX_LENGTH -> h + java.util.regex.Pattern ATTR_KEY_PATTERN -> d + int ATTR_URL_MAX_LENGTH -> i + int REGION_INDEX -> f + boolean[] updatedFields -> b + int IDENTIFIER_INDEX -> g + int LANGAGUE_INDEX -> e + java.lang.String[] userFields -> c + 1:1:void ():32:32 -> + 1:1:void ():44:44 -> + 2:4:void ():40:42 -> + 1:1:void lambda$setAttribute$0(java.lang.String,long,com.batch.android.user.SQLUserDatasource):118:118 -> a + 2:2:void lambda$setAttribute$1(java.lang.String,double,com.batch.android.user.SQLUserDatasource):140:140 -> a + 3:3:void lambda$setAttribute$2(java.lang.String,boolean,com.batch.android.user.SQLUserDatasource):162:162 -> a + 4:4:void lambda$setAttribute$3(java.lang.String,java.util.Date,com.batch.android.user.SQLUserDatasource):193:193 -> a + 5:5:void lambda$setAttribute$5(java.lang.String,java.net.URI,com.batch.android.user.SQLUserDatasource):272:272 -> a + 6:6:void lambda$addTag$7(java.lang.String,java.lang.String,com.batch.android.user.SQLUserDatasource):351:351 -> a + 7:7:void lambda$clearTagCollection$9(java.lang.String,com.batch.android.user.SQLUserDatasource):427:427 -> a + 8:28:com.batch.android.core.Promise save(boolean):459:479 -> a + 29:33:void lambda$save$10(java.util.List,com.batch.android.core.Promise):466:470 -> a + 34:44:java.lang.String normalizeAttributeKey(java.lang.String):489:499 -> a + 45:51:java.lang.String normalizeAttributeKey(java.lang.String):490:496 -> a + 52:57:com.batch.android.user.UserOperation getUserUpdateOperation():520:525 -> a + 58:87:void lambda$getUserUpdateOperation$11(com.batch.android.user.SQLUserDatasource):526:555 -> a + 88:88:void lambda$getUserUpdateOperation$11(com.batch.android.user.SQLUserDatasource):528:528 -> a + 1:29:com.batch.android.BatchUserDataEditor addTag(java.lang.String,java.lang.String):324:352 -> addTag + 30:33:com.batch.android.BatchUserDataEditor addTag(java.lang.String,java.lang.String):339:339 -> addTag + 34:37:com.batch.android.BatchUserDataEditor addTag(java.lang.String,java.lang.String):326:326 -> addTag + 1:1:void lambda$removeAttribute$6(java.lang.String,com.batch.android.user.SQLUserDatasource):294:294 -> b + 2:2:void lambda$removeTag$8(java.lang.String,java.lang.String,com.batch.android.user.SQLUserDatasource):396:396 -> b + 3:7:java.lang.String normalizeTagCollection(java.lang.String):503:507 -> b + 8:8:java.lang.String normalizeTagCollection(java.lang.String):504:504 -> b + 9:14:java.util.List popOperationQueue():561:566 -> b + 1:1:void lambda$setAttribute$4(java.lang.String,java.lang.String,com.batch.android.user.SQLUserDatasource):228:228 -> c + 2:6:java.lang.String normalizeTagValue(java.lang.String):511:515 -> c + 7:7:java.lang.String normalizeTagValue(java.lang.String):512:512 -> c + 1:3:com.batch.android.BatchUserDataEditor clearAttributes():306:308 -> clearAttributes + 1:13:com.batch.android.BatchUserDataEditor clearTagCollection(java.lang.String):423:435 -> clearTagCollection + 14:17:com.batch.android.BatchUserDataEditor clearTagCollection(java.lang.String):429:429 -> clearTagCollection + 21:23:com.batch.android.BatchUserDataEditor clearTagCollection(java.lang.String):433:435 -> clearTagCollection + 1:3:com.batch.android.BatchUserDataEditor clearTags():408:410 -> clearTags + 1:8:com.batch.android.BatchUserDataEditor removeAttribute(java.lang.String):288:295 -> removeAttribute + 1:29:com.batch.android.BatchUserDataEditor removeTag(java.lang.String,java.lang.String):369:397 -> removeTag + 30:33:com.batch.android.BatchUserDataEditor removeTag(java.lang.String,java.lang.String):384:384 -> removeTag + 34:37:com.batch.android.BatchUserDataEditor removeTag(java.lang.String,java.lang.String):371:371 -> removeTag + 1:7:void save():448:454 -> save + 1:8:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,long):112:119 -> setAttribute + 9:16:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,double):134:141 -> setAttribute + 17:24:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,boolean):156:163 -> setAttribute + 25:41:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.util.Date):178:194 -> setAttribute + 42:62:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.lang.String):209:229 -> setAttribute + 63:63:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.lang.String):216:216 -> setAttribute + 64:93:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.net.URI):244:273 -> setAttribute + 94:94:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.net.URI):262:262 -> setAttribute + 95:95:com.batch.android.BatchUserDataEditor setAttribute(java.lang.String,java.net.URI):251:251 -> setAttribute + 1:7:com.batch.android.BatchUserDataEditor setIdentifier(java.lang.String):92:98 -> setIdentifier + 1:7:com.batch.android.BatchUserDataEditor setLanguage(java.lang.String):56:62 -> setLanguage + 1:7:com.batch.android.BatchUserDataEditor setRegion(java.lang.String):74:80 -> setRegion +com.batch.android.BatchUserDataEditor$AttributeValidationException -> com.batch.android.BatchUserDataEditor$a: + 1:1:void ():575:575 -> +com.batch.android.BatchUserProfile -> com.batch.android.BatchUserProfile: + android.content.Context context -> a + 1:5:void (android.content.Context):26:30 -> + 6:6:void (android.content.Context):28:28 -> + 1:1:long getVersion():143:143 -> a + 1:1:boolean hasCustomLanguage():68:68 -> b + 1:1:boolean hasCustomRegion():106:106 -> c + 1:1:java.lang.String getCustomID():133:133 -> getCustomID + 1:1:java.lang.String getLanguage():59:59 -> getLanguage + 1:1:java.lang.String getRegion():95:95 -> getRegion + 1:1:com.batch.android.BatchUserProfile setCustomID(java.lang.String):121:121 -> setCustomID + 1:1:com.batch.android.BatchUserProfile setLanguage(java.lang.String):45:45 -> setLanguage + 1:1:com.batch.android.BatchUserProfile setRegion(java.lang.String):81:81 -> setRegion +com.batch.android.BatchWebViewContent -> com.batch.android.BatchWebViewContent: + java.lang.String url -> a + 1:2:void (com.batch.android.messaging.model.WebViewMessage):16:17 -> + 1:1:java.lang.String getURL():22:22 -> getURL +com.batch.android.BatchWebservice -> com.batch.android.j: + int retryCount -> l + com.batch.android.core.WebserviceErrorCause lastFailureCause -> m + java.lang.String TAG -> n + 1:1:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):52:52 -> + 2:19:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):37:54 -> + 1:30:void addPropertyParameters():193:222 -> G + 31:39:void addPropertyParameters():218:226 -> G + java.lang.String getPropertyParameterKey() -> H + 1:5:void onRetry(com.batch.android.core.WebserviceErrorCause):179:183 -> a + 6:31:void handleParameters(com.batch.android.json.JSONObject):250:275 -> a + 32:32:void handleParameters(com.batch.android.json.JSONObject):246:246 -> a + 33:37:java.lang.String generateAcceptLanguage(android.content.Context):346:350 -> a + 1:24:void addDefaultHeaders():61:84 -> b + 25:29:void handleServerID(com.batch.android.json.JSONObject):290:294 -> b + 30:30:void handleServerID(com.batch.android.json.JSONObject):286:286 -> b + 31:56:java.lang.String generateUserAgent(android.content.Context):308:333 -> b + 1:82:com.batch.android.post.PostDataProvider getPostDataProvider():93:174 -> w +com.batch.android.BuildConfig -> com.batch.android.a.a: + java.lang.Integer API_LEVEL -> d + java.lang.String WS_DOMAIN -> i + java.lang.String SDK_VERSION -> h + java.lang.Integer MESSAGING_API_LEVEL -> g + boolean ENABLE_DEBUG_LOGGER -> e + boolean ENABLE_WS_INTERCEPTOR -> f + boolean DEBUG -> a + java.lang.String BUILD_TYPE -> c + java.lang.String LIBRARY_PACKAGE_NAME -> b + 1:7:void ():11:17 -> + 1:1:void ():6:6 -> +com.batch.android.Config -> com.batch.android.Config: + com.batch.android.LoggerDelegate loggerDelegate -> e + java.lang.String apikey -> a + com.batch.android.LoggerLevel loggerLevel -> f + boolean shouldUseAdvertisingID -> b + boolean shouldUseAdvancedDeviceInformation -> c + boolean shouldUseGoogleInstanceID -> d + 1:1:void (java.lang.String):43:43 -> + 2:27:void (java.lang.String):19:44 -> + 1:1:com.batch.android.Config setCanUseAdvancedDeviceInformation(boolean):90:90 -> setCanUseAdvancedDeviceInformation + 1:1:com.batch.android.Config setCanUseAdvertisingID(boolean):68:68 -> setCanUseAdvertisingID + 1:1:com.batch.android.Config setCanUseInstanceID(boolean):129:129 -> setCanUseInstanceID + 1:1:com.batch.android.Config setLoggerDelegate(com.batch.android.LoggerDelegate):103:103 -> setLoggerDelegate + 1:1:com.batch.android.Config setLoggerLevel(com.batch.android.LoggerLevel):114:114 -> setLoggerLevel +com.batch.android.DeeplinkInterceptorRuntimeException -> com.batch.android.a.b: + java.lang.RuntimeException wrappedRuntimeException -> a + 1:2:void (java.lang.RuntimeException):17:18 -> + 1:1:java.lang.RuntimeException getWrappedRuntimeException():22:22 -> a +com.batch.android.DisplayReceiptWebservice -> com.batch.android.k: + com.batch.android.webservice.listener.DisplayReceiptWebserviceListener listener -> n + java.lang.String TAG -> o + 1:5:void (android.content.Context,com.batch.android.webservice.listener.DisplayReceiptWebserviceListener,com.batch.android.post.DisplayReceiptPostDataProvider,java.lang.String[]):32:36 -> + 6:6:void (android.content.Context,com.batch.android.webservice.listener.DisplayReceiptWebserviceListener,com.batch.android.post.DisplayReceiptPostDataProvider,java.lang.String[]):34:34 -> + 1:1:java.lang.String getSpecificRetryCountKey():62:62 -> C + 1:1:java.lang.String getTaskIdentifier():52:52 -> a + 1:1:java.lang.String getCryptorTypeParameterKey():57:57 -> p + 1:5:void run():42:46 -> run +com.batch.android.FailReason -> com.batch.android.FailReason: + com.batch.android.FailReason[] $VALUES -> a + 1:17:void ():14:30 -> + 18:18:void ():9:9 -> + 1:1:void (java.lang.String,int):10:10 -> + 1:1:com.batch.android.FailReason valueOf(java.lang.String):9:9 -> valueOf + 1:1:com.batch.android.FailReason[] values():9:9 -> values +com.batch.android.GoogleApiAvailabilityContainer -> com.batch.android.a.c: + java.lang.String TAG -> a + 1:1:void ():15:15 -> + 1:3:int getGooglePlayServicesVersionCode():20:22 -> a + 4:11:boolean deviceNotSupportPlayServiceVersion(android.content.Context):43:50 -> a + 1:8:boolean mustDeviceUpdatePlayServices(android.content.Context):29:36 -> b +com.batch.android.ImageDownloadWebservice -> com.batch.android.l: + java.lang.String TAG -> m + java.lang.String url -> l + 1:2:void (android.content.Context,java.lang.String,java.util.List):25:26 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():148:148 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():153:153 -> B + 1:1:java.lang.String getSpecificRetryCountKey():158:158 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():123:123 -> F + 1:20:android.graphics.Bitmap run():86:105 -> G + 21:28:android.graphics.Bitmap run():102:109 -> G + 1:13:java.lang.String buildImageURL(android.content.Context,java.lang.String,java.util.List):44:56 -> a + 14:20:java.lang.String appendDensityToImageURL(java.lang.String,java.lang.Double):73:79 -> a + 1:1:java.lang.String getCryptorModeParameterKey():133:133 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():128:128 -> p + 1:1:java.lang.String getPostCryptorTypeParameterKey():138:138 -> v + com.batch.android.post.PostDataProvider getPostDataProvider() -> w + 1:1:java.lang.String getReadCryptorTypeParameterKey():143:143 -> y +com.batch.android.Install -> com.batch.android.m: + java.util.Date installDate -> b + java.lang.String installID -> a + 1:7:void (android.content.Context):30:36 -> + 8:8:void (android.content.Context):32:32 -> + 1:1:java.util.Date getInstallDate():56:56 -> a + 2:2:java.lang.String generateInstallID(android.content.Context):84:84 -> a + 1:1:java.lang.String getInstallID():47:47 -> b + 2:11:java.util.Date getInstallDate(android.content.Context):96:105 -> b + 1:4:java.lang.String getInstallID(android.content.Context):68:71 -> c +com.batch.android.IntentParser -> com.batch.android.n: + java.lang.String FROM_PUSH_LEGACY_KEY -> g + java.lang.String FROM_PUSH_KEY -> f + java.lang.String PUSH_ID_LEGACY_KEY -> i + java.lang.String PUSH_ID_KEY -> h + android.content.Intent intent -> a + java.lang.String TAG -> c + com.batch.android.BatchPushPayload payload -> b + java.lang.String ALREADY_TRACKED_OPEN_KEY -> e + java.lang.String ALREADY_SHOWN_LANDING_KEY -> d + 1:1:void (android.app.Activity):72:72 -> + 2:2:void (android.content.Intent):80:80 -> + 3:33:void (android.content.Intent):62:92 -> + 1:5:boolean comesFromPush():106:110 -> a + 6:15:void putPushExtrasToIntent(android.os.Bundle,com.batch.android.core.InternalPushData,android.content.Intent):236:245 -> a + 16:18:void copyExtras(android.content.Intent,android.content.Intent):257:259 -> a + 19:45:void copyExtras(android.os.Bundle,android.os.Bundle):270:296 -> a + 1:5:com.batch.android.BatchMessage getLanding():181:185 -> b + 1:2:android.os.Bundle getPushBundle():226:227 -> c + 1:8:com.batch.android.core.InternalPushData getPushData():213:220 -> d + 1:7:java.lang.String getPushId():195:201 -> e + 1:5:boolean hasLanding():143:147 -> f + 1:1:boolean hasPushPayload():97:97 -> g + 1:5:boolean isLandingAlreadyShown():156:160 -> h + 1:5:boolean isOpenAlreadyTracked():119:123 -> i + 1:5:void markLandingAsAlreadyShown():167:171 -> j + 1:4:void markOpenAsAlreadyTracked():130:133 -> k +com.batch.android.LocalCampaignsJITWebservice -> com.batch.android.o: + com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener listener -> n + java.lang.String TAG -> o + 1:5:void (android.content.Context,com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener,com.batch.android.post.LocalCampaignsJITPostDataProvider,java.lang.String[]):30:34 -> + 6:6:void (android.content.Context,com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener,com.batch.android.post.LocalCampaignsJITPostDataProvider,java.lang.String[]):32:32 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():63:63 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():68:68 -> B + 1:1:java.lang.String getSpecificRetryCountKey():73:73 -> C + 1:1:java.lang.String getTaskIdentifier():39:39 -> a + 1:14:void run():44:57 -> run +com.batch.android.LocalCampaignsWebservice -> com.batch.android.p: + com.batch.android.webservice.listener.LocalCampaignsWebserviceListener listener -> s + java.lang.String TAG -> t + 1:2:void (android.content.Context,com.batch.android.webservice.listener.LocalCampaignsWebserviceListener):38:39 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():173:173 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():178:178 -> B + 1:1:java.lang.String getSpecificRetryCountKey():183:183 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():148:148 -> F + 1:1:java.lang.String getPropertyParameterKey():143:143 -> H + 1:3:java.util.List getQueries():46:48 -> I + 1:1:java.lang.String getTaskIdentifier():136:136 -> a + 1:1:java.lang.String getCryptorModeParameterKey():158:158 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():153:153 -> p + 1:59:void run():56:114 -> run + 60:60:void run():113:113 -> run + 61:77:void run():111:127 -> run + 78:82:void run():68:68 -> run + 87:101:void run():73:87 -> run + 102:102:void run():84:84 -> run + 103:103:void run():81:81 -> run + 104:156:void run():78:130 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():163:163 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():168:168 -> y +com.batch.android.LocalCampaignsWebservice$1 -> com.batch.android.p$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():76:76 -> +com.batch.android.LoggerLevel -> com.batch.android.LoggerLevel: + com.batch.android.LoggerLevel[] $VALUES -> b + int level -> a + 1:5:void ():7:11 -> + 6:6:void ():5:5 -> + 1:2:void (java.lang.String,int,int):15:16 -> + 1:1:boolean canLog(com.batch.android.LoggerLevel):21:21 -> canLog + 1:1:com.batch.android.LoggerLevel valueOf(java.lang.String):5:5 -> valueOf + 1:1:com.batch.android.LoggerLevel[] values():5:5 -> values +com.batch.android.MessagingActivity -> com.batch.android.MessagingActivity: + android.content.BroadcastReceiver dismissReceiver -> a + java.lang.String ROTATED -> c + java.lang.String TAG -> b + java.lang.String DIALOG_FRAGMENT_TAG -> d + 1:7:void ():23:29 -> + 1:12:boolean showMessage(com.batch.android.BatchMessage):110:121 -> a + 1:4:void finish():98:101 -> finish + 1:23:void onCreate(android.os.Bundle):40:62 -> onCreate + 24:48:void onCreate(android.os.Bundle):44:68 -> onCreate + 1:3:void onDestroy():91:93 -> onDestroy + 1:6:void onDialogDismiss(androidx.fragment.app.DialogFragment):129:134 -> onDialogDismiss + 1:2:void onSaveInstanceState(android.os.Bundle):73:74 -> onSaveInstanceState + 1:2:void onStart():79:80 -> onStart + 1:2:void onStop():85:86 -> onStop + 1:6:void startActivityForMessage(android.content.Context,com.batch.android.BatchMessage):143:148 -> startActivityForMessage +com.batch.android.MessagingActivity$1 -> com.batch.android.MessagingActivity$a: + com.batch.android.MessagingActivity this$0 -> a + 1:1:void (com.batch.android.MessagingActivity):29:29 -> + 1:2:void onReceive(android.content.Context,android.content.Intent):32:33 -> onReceive +com.batch.android.MessagingAnalyticsDelegate -> com.batch.android.q: + java.lang.String STATE_KEY_CALLED_METHODS -> g + com.batch.android.module.EventDispatcherModule eventDispatcherModule -> c + com.batch.android.module.MessagingModule messagingModule -> a + com.batch.android.module.TrackerModule trackerModule -> b + java.util.ArrayList calledMethods -> f + com.batch.android.messaging.model.Message message -> d + com.batch.android.BatchMessage sourceMessage -> e + 1:1:void (com.batch.android.module.MessagingModule,com.batch.android.module.TrackerModule,com.batch.android.module.EventDispatcherModule,com.batch.android.messaging.model.Message,com.batch.android.BatchMessage):54:54 -> + 2:15:void (com.batch.android.module.MessagingModule,com.batch.android.module.TrackerModule,com.batch.android.module.EventDispatcherModule,com.batch.android.messaging.model.Message,com.batch.android.BatchMessage):46:59 -> + 1:4:com.batch.android.MessagingAnalyticsDelegate provide(com.batch.android.messaging.model.Message,com.batch.android.BatchMessage):64:67 -> a + 5:12:boolean ensureOnce(java.lang.String):75:82 -> a + 13:27:void onGlobalTap(com.batch.android.messaging.model.Action):88:102 -> a + 28:28:void onGlobalTap(com.batch.android.messaging.model.Action):97:97 -> a + 29:44:void onCTAClicked(int,com.batch.android.messaging.model.CTA):109:124 -> a + 45:45:void onCTAClicked(int,com.batch.android.messaging.model.CTA):119:119 -> a + 46:70:void onWebViewClickTracked(com.batch.android.messaging.model.Action,java.lang.String):133:157 -> a + 71:71:void onWebViewClickTracked(com.batch.android.messaging.model.Action,java.lang.String):152:152 -> a + 72:78:void onClosedError(com.batch.android.messaging.model.MessagingError):177:183 -> a + 79:79:void onClosedError(com.batch.android.messaging.model.MessagingError):181:181 -> a + 80:86:void onAutoClosedAfterDelay():192:198 -> a + 87:87:void onAutoClosedAfterDelay():196:196 -> a + 88:88:void onSaveInstanceState(android.os.Bundle):239:239 -> a + 1:7:void onClosed():166:172 -> b + 8:8:void onClosed():170:170 -> b + 9:11:void restoreState(android.os.Bundle):231:233 -> b + 1:4:void onViewDismissed():219:222 -> c + 1:12:void onViewShown():203:214 -> d + 13:13:void onViewShown():212:212 -> d +com.batch.android.MetricWebservice -> com.batch.android.s: + com.batch.android.webservice.listener.MetricWebserviceListener listener -> n + java.lang.String TAG -> o + 1:5:void (android.content.Context,com.batch.android.webservice.listener.MetricWebserviceListener,com.batch.android.post.MetricPostDataProvider,java.lang.String[]):25:29 -> + 6:6:void (android.content.Context,com.batch.android.webservice.listener.MetricWebserviceListener,com.batch.android.post.MetricPostDataProvider,java.lang.String[]):27:27 -> + 1:1:java.lang.String getSpecificRetryCountKey():50:50 -> C + 1:1:java.lang.String getTaskIdentifier():45:45 -> a + 1:6:void run():34:39 -> run +com.batch.android.NotificationInterceptorRuntimeException -> com.batch.android.t: + java.lang.RuntimeException wrappedRuntimeException -> a + 1:2:void (java.lang.RuntimeException):17:18 -> + 1:1:java.lang.RuntimeException getWrappedRuntimeException():22:22 -> a +com.batch.android.PrivateNotificationContentHelper -> com.batch.android.u: + 1:1:void ():12:12 -> + 1:1:com.batch.android.inbox.InboxNotificationContentInternal getInternalContent(com.batch.android.BatchInboxNotificationContent):15:15 -> a + 2:2:com.batch.android.BatchInboxNotificationContent getPublicContent(com.batch.android.inbox.InboxNotificationContentInternal):19:19 -> a +com.batch.android.PushNotificationType -> com.batch.android.PushNotificationType: + com.batch.android.PushNotificationType[] $VALUES -> b + int value -> a + 1:21:void ():15:35 -> + 22:22:void ():10:10 -> + 1:2:void (java.lang.String,int,int):47:48 -> + 1:10:java.util.EnumSet fromValue(int):54:63 -> fromValue + 1:2:int toValue(java.util.EnumSet):72:73 -> toValue + 1:1:com.batch.android.PushNotificationType valueOf(java.lang.String):10:10 -> valueOf + 1:1:com.batch.android.PushNotificationType[] values():10:10 -> values +com.batch.android.PushRegistrationProviderAvailabilityException -> com.batch.android.PushRegistrationProviderAvailabilityException: + 1:1:void (java.lang.String):9:9 -> +com.batch.android.PushWebservice -> com.batch.android.v: + com.batch.android.push.Registration registration -> s + com.batch.android.webservice.listener.PushWebserviceListener listener -> t + java.lang.String TAG -> u + 1:11:void (android.content.Context,com.batch.android.push.Registration,com.batch.android.webservice.listener.PushWebserviceListener):43:53 -> + 12:12:void (android.content.Context,com.batch.android.push.Registration,com.batch.android.webservice.listener.PushWebserviceListener):49:49 -> + 13:13:void (android.content.Context,com.batch.android.push.Registration,com.batch.android.webservice.listener.PushWebserviceListener):45:45 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():164:164 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():169:169 -> B + 1:1:java.lang.String getSpecificRetryCountKey():174:174 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():139:139 -> F + 1:1:java.lang.String getPropertyParameterKey():134:134 -> H + 1:3:java.util.List getQueries():60:62 -> I + 1:1:java.lang.String getTaskIdentifier():127:127 -> a + 1:1:java.lang.String getCryptorModeParameterKey():149:149 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():144:144 -> p + 1:49:void run():70:118 -> run + 50:50:void run():112:112 -> run + 51:65:void run():81:95 -> run + 66:66:void run():92:92 -> run + 67:67:void run():89:89 -> run + 68:103:void run():86:121 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():154:154 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():159:159 -> y +com.batch.android.PushWebservice$1 -> com.batch.android.v$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():84:84 -> +com.batch.android.StartWebservice -> com.batch.android.w: + java.lang.String TAG -> w + boolean userActivity -> v + com.batch.android.webservice.listener.StartWebserviceListener listener -> s + java.lang.String pushId -> u + boolean fromPush -> t + 1:9:void (android.content.Context,boolean,java.lang.String,boolean,com.batch.android.webservice.listener.StartWebserviceListener):64:72 -> + 10:10:void (android.content.Context,boolean,java.lang.String,boolean,com.batch.android.webservice.listener.StartWebserviceListener):66:66 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():189:189 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():194:194 -> B + 1:1:java.lang.String getSpecificRetryCountKey():199:199 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():164:164 -> F + 1:1:java.lang.String getPropertyParameterKey():159:159 -> H + 1:8:java.util.List getQueries():79:86 -> I + 1:1:java.lang.String getTaskIdentifier():152:152 -> a + 1:1:java.lang.String getCryptorModeParameterKey():174:174 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():169:169 -> p + 1:49:void run():95:143 -> run + 50:50:void run():137:137 -> run + 51:65:void run():106:120 -> run + 66:66:void run():117:117 -> run + 67:67:void run():114:114 -> run + 68:103:void run():111:146 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():179:179 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():184:184 -> y +com.batch.android.StartWebservice$1 -> com.batch.android.w$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():109:109 -> +com.batch.android.TrackerWebservice -> com.batch.android.x: + java.lang.String TAG -> v + java.util.List events -> t + com.batch.android.webservice.listener.TrackerWebserviceListener listener -> s + boolean canBypassOptOut -> u + 1:12:void (android.content.Context,com.batch.android.webservice.listener.TrackerWebserviceListener,java.util.List,boolean):35:46 -> + 13:13:void (android.content.Context,com.batch.android.webservice.listener.TrackerWebserviceListener,java.util.List,boolean):41:41 -> + 14:14:void (android.content.Context,com.batch.android.webservice.listener.TrackerWebserviceListener,java.util.List,boolean):37:37 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():156:156 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():161:161 -> B + 1:1:java.lang.String getSpecificRetryCountKey():166:166 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():131:131 -> F + 1:1:java.lang.String getPropertyParameterKey():126:126 -> H + 1:3:java.util.List getQueries():58:60 -> I + 1:1:java.lang.String getTaskIdentifier():119:119 -> a + 1:1:boolean canBypassOptOut():53:53 -> i + 1:1:java.lang.String getCryptorModeParameterKey():141:141 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():136:136 -> p + 1:41:void run():68:108 -> run + 42:56:void run():79:93 -> run + 57:57:void run():90:90 -> run + 58:58:void run():87:87 -> run + 59:88:void run():84:113 -> run + 89:93:void run():110:114 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():146:146 -> v + 1:1:java.lang.String getReadCryptorTypeParameterKey():151:151 -> y +com.batch.android.TrackerWebservice$1 -> com.batch.android.x$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():82:82 -> +com.batch.android.User -> com.batch.android.y: + android.content.Context context -> a + 1:6:void (android.content.Context):31:36 -> + 7:7:void (android.content.Context):33:33 -> + 1:3:void setCustomID(java.lang.String):96:98 -> a + 4:4:java.lang.String getCustomID():108:108 -> a + 1:3:void setLanguage(java.lang.String):48:50 -> b + 4:4:java.lang.String getLanguage():60:60 -> b + 1:3:void setRegion(java.lang.String):72:74 -> c + 4:4:java.lang.String getRegion():84:84 -> c + 1:7:long getVersion():119:125 -> d + 1:2:long incrementVersion():137:138 -> e + 1:22:void sendChangeEvent():144:165 -> f +com.batch.android.UserAction -> com.batch.android.UserAction: + com.batch.android.UserActionRunnable runnable -> b + java.lang.String identifier -> a + 1:17:void (java.lang.String,com.batch.android.UserActionRunnable):22:38 -> + 18:18:void (java.lang.String,com.batch.android.UserActionRunnable):34:34 -> + 19:19:void (java.lang.String,com.batch.android.UserActionRunnable):29:29 -> + 20:20:void (java.lang.String,com.batch.android.UserActionRunnable):25:25 -> + 1:1:java.lang.String getIdentifier():43:43 -> getIdentifier + 1:1:com.batch.android.UserActionRunnable getRunnable():48:48 -> getRunnable +com.batch.android.UserDataAccessor -> com.batch.android.z: + 1:1:void ():19:19 -> + 1:37:void fetchTagCollections(android.content.Context,com.batch.android.BatchTagCollectionsFetchListener,boolean):31:67 -> a + 38:38:void fetchTagCollections(android.content.Context,com.batch.android.BatchTagCollectionsFetchListener,boolean):28:28 -> a + 39:64:void lambda$fetchTagCollections$1(android.content.Context,boolean,com.batch.android.BatchTagCollectionsFetchListener):33:58 -> a + 65:67:void lambda$fetchTagCollections$0(com.batch.android.BatchTagCollectionsFetchListener,java.util.Map):47:49 -> a + 68:139:void fetchAttributes(android.content.Context,com.batch.android.BatchAttributesFetchListener,boolean):81:152 -> a + 140:140:void fetchAttributes(android.content.Context,com.batch.android.BatchAttributesFetchListener,boolean):78:78 -> a + 141:169:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):83:111 -> a + 170:170:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):108:108 -> a + 171:171:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):105:105 -> a + 172:172:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):102:102 -> a + 173:173:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):99:99 -> a + 174:221:void lambda$fetchAttributes$3(android.content.Context,boolean,com.batch.android.BatchAttributesFetchListener):96:143 -> a + 222:224:void lambda$fetchAttributes$2(com.batch.android.BatchAttributesFetchListener,java.util.HashMap):132:134 -> a +com.batch.android.UserDataAccessor$1 -> com.batch.android.z$a: + int[] $SwitchMap$com$batch$android$user$AttributeType -> a + 1:1:void ():94:94 -> +com.batch.android.WebserviceLauncher -> com.batch.android.a0: + java.lang.String TAG -> a + 1:1:void ():33:33 -> + 1:4:boolean launchStartWebservice(com.batch.android.runtime.RuntimeManager,boolean,java.lang.String,boolean):48:51 -> a + 5:16:boolean launchStartWebservice(com.batch.android.runtime.RuntimeManager,boolean,java.lang.String,boolean):49:60 -> a + 17:19:com.batch.android.core.TaskRunnable initTrackerWebservice(com.batch.android.runtime.RuntimeManager,java.util.List,com.batch.android.webservice.listener.TrackerWebserviceListener):79:81 -> a + 20:22:com.batch.android.core.TaskRunnable initDisplayReceiptWebservice(android.content.Context,com.batch.android.post.DisplayReceiptPostDataProvider,com.batch.android.webservice.listener.DisplayReceiptWebserviceListener):100:102 -> a + 23:25:com.batch.android.core.TaskRunnable initOptOutTrackerWebservice(android.content.Context,java.util.List,com.batch.android.webservice.listener.TrackerWebserviceListener):120:122 -> a + 26:28:com.batch.android.core.TaskRunnable initMetricWebservice(android.content.Context,com.batch.android.post.MetricPostDataProvider,com.batch.android.webservice.listener.MetricWebserviceListener):141:143 -> a + 29:31:boolean launchPushWebservice(com.batch.android.runtime.RuntimeManager,com.batch.android.push.Registration):154:156 -> a + 32:37:boolean launchPushWebservice(com.batch.android.runtime.RuntimeManager,com.batch.android.push.Registration):155:160 -> a + 38:41:boolean launchAttributesSendWebservice(com.batch.android.runtime.RuntimeManager,long,java.util.Map,java.util.Map):173:176 -> a + 42:53:boolean launchAttributesSendWebservice(com.batch.android.runtime.RuntimeManager,long,java.util.Map,java.util.Map):174:185 -> a + 54:57:boolean launchAttributesCheckWebservice(com.batch.android.runtime.RuntimeManager,long,java.lang.String):197:200 -> a + 58:68:boolean launchAttributesCheckWebservice(com.batch.android.runtime.RuntimeManager,long,java.lang.String):198:208 -> a + 69:73:boolean launchLocalCampaignsWebservice(com.batch.android.runtime.RuntimeManager):216:220 -> a + 74:82:boolean launchLocalCampaignsWebservice(com.batch.android.runtime.RuntimeManager):217:225 -> a + 83:90:boolean launchLocalCampaignsJITWebservice(com.batch.android.runtime.RuntimeManager,java.util.List,com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener):235:242 -> a +com.batch.android.WebserviceMetrics -> com.batch.android.b0: + java.util.Map metrics -> a + java.util.Map webservicesStartTime -> b + java.util.Map shortNames -> d + java.lang.String TAG -> c + 1:10:void ():106:115 -> + 1:12:void ():18:29 -> + 1:9:void onWebserviceStarted(com.batch.android.core.Webservice):43:51 -> a + 10:10:void onWebserviceStarted(com.batch.android.core.Webservice):40:40 -> a + 11:31:void onWebserviceFinished(com.batch.android.core.Webservice,boolean):65:85 -> a + 32:32:void onWebserviceFinished(com.batch.android.core.Webservice,boolean):81:81 -> a + 33:33:void onWebserviceFinished(com.batch.android.core.Webservice,boolean):62:62 -> a + 34:38:java.util.Map getMetrics():94:98 -> a +com.batch.android.WebserviceMetrics$1 -> com.batch.android.b0$a: +com.batch.android.WebserviceMetrics$Metric -> com.batch.android.b0$b: + long time -> b + boolean success -> a + 1:1:void (boolean,long,com.batch.android.WebserviceMetrics$1):124:124 -> + 2:4:void (boolean,long):141:143 -> +com.batch.android.WebserviceParameterUtils -> com.batch.android.c0: + java.lang.String TAG -> a + 1:1:void ():23:23 -> + 1:116:java.util.Map buildIds(android.content.Context):54:169 -> a + 1:1:com.batch.android.json.JSONObject getWebserviceIdsAsJson(android.content.Context):42:42 -> b + 1:1:java.util.Map getWebserviceIdsAsMap(android.content.Context):33:33 -> c +com.batch.android.actions.ClipboardActionRunnable -> com.batch.android.b.a: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> c + java.lang.String BASE_ERROR_MSG -> b + 1:1:void ():18:18 -> + 1:17:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):33:49 -> performAction +com.batch.android.actions.DeeplinkActionRunnable -> com.batch.android.b.b: + java.lang.String IDENTIFIER -> c + com.batch.android.module.ActionModule actionModule -> a + java.lang.String TAG -> b + java.lang.String ARGUMENT_SHOW_LINK_INAPP -> e + java.lang.String ARGUMENT_DEEPLINK_URL -> d + 1:2:void (com.batch.android.module.ActionModule):29:30 -> + 1:17:void launchDeeplink(android.content.Context,java.lang.String,boolean):35:51 -> a + 18:48:void launchDeeplink(android.content.Context,java.lang.String,boolean):42:72 -> a + 49:54:void launchDeeplink(android.content.Context,java.lang.String,boolean):63:68 -> a + 55:80:void launchDeeplink(android.content.Context,java.lang.String,boolean) -> a + 1:16:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):91:106 -> performAction + 17:34:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):103:120 -> performAction + 35:35:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):113:113 -> performAction + 36:36:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):111:111 -> performAction +com.batch.android.actions.GroupActionRunnable -> com.batch.android.b.c: + com.batch.android.module.ActionModule actionModule -> a + java.lang.String IDENTIFIER -> b + 1:2:void (com.batch.android.module.ActionModule):23:24 -> + 1:35:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):44:78 -> performAction +com.batch.android.actions.LocalCampaignsRefreshActionRunnable -> com.batch.android.b.d: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> b + 1:1:void ():15:15 -> + 1:5:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):27:31 -> performAction +com.batch.android.actions.NotificationPermissionActionRunnable -> com.batch.android.b.e: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> b + 1:1:void ():13:13 -> + 1:9:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):27:35 -> performAction + 10:17:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):33:40 -> performAction + 18:22:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):38:42 -> performAction +com.batch.android.actions.RatingActionRunnable -> com.batch.android.b.f: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> b + 1:1:void ():25:25 -> + 1:8:void lambda$performAction$0(android.content.Context,java.lang.Exception):40:47 -> a + 9:15:void lambda$performAction$0(android.content.Context,java.lang.Exception):44:50 -> a + 16:29:void lambda$tryOpenPlayStoreInAppRating$2(android.content.Context,com.batch.android.core.Promise):59:72 -> a + 30:51:void lambda$tryOpenPlayStoreInAppRating$2(android.content.Context,com.batch.android.core.Promise):65:86 -> a + 52:61:void lambda$tryOpenPlayStoreInAppRating$1(com.batch.android.core.Promise,com.google.android.play.core.review.ReviewManager,android.app.Activity,com.google.android.play.core.tasks.Task):73:82 -> a + 62:65:void openStore(android.content.Context):92:95 -> a + 1:1:com.batch.android.core.Promise tryOpenPlayStoreInAppRating(android.content.Context):55:55 -> b + 1:5:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):35:39 -> performAction +com.batch.android.actions.RatingActionRunnable$RatingActionRunnableException -> com.batch.android.b.f$a: + 1:1:void (java.lang.String,java.lang.Throwable):102:102 -> +com.batch.android.actions.UserDataBuiltinActionRunnable -> com.batch.android.b.g: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> b + 1:1:void ():16:16 -> + 1:47:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):29:75 -> performAction +com.batch.android.actions.UserEventBuiltinActionRunnable -> com.batch.android.b.h: + java.lang.String TAG -> a + java.lang.String IDENTIFIER -> b + 1:1:void ():21:21 -> + 1:9:java.util.Date parseDate(java.lang.String):28:36 -> a + 1:59:void performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):50:108 -> performAction +com.batch.android.adsidentifier.GCMAdsIdentifierProvider -> com.batch.android.c.a: + android.content.Context context -> a + 1:2:void (android.content.Context):15:16 -> + 1:1:android.content.Context access$000(com.batch.android.adsidentifier.GCMAdsIdentifierProvider):11:11 -> a + 2:2:boolean isGMSAdvertisingIdClientPresent():36:36 -> a + 1:8:void checkAvailability():21:28 -> checkAvailability + 9:9:void checkAvailability():22:22 -> checkAvailability + 1:3:void getAdsIdentifier(com.batch.android.AdsIdentifierProvider$AdsIdentifierListener):52:54 -> getAdsIdentifier + 4:4:void getAdsIdentifier(com.batch.android.AdsIdentifierProvider$AdsIdentifierListener):46:46 -> getAdsIdentifier +com.batch.android.adsidentifier.GCMAdsIdentifierProvider$1 -> com.batch.android.c.a$a: + com.batch.android.adsidentifier.GCMAdsIdentifierProvider this$0 -> b + com.batch.android.AdsIdentifierProvider$AdsIdentifierListener val$listener -> a + 1:1:void (com.batch.android.adsidentifier.GCMAdsIdentifierProvider,com.batch.android.AdsIdentifierProvider$AdsIdentifierListener):55:55 -> + 1:1:java.lang.String getTaskIdentifier():93:93 -> a + 1:25:void run():62:86 -> run +com.batch.android.annotation.PublicSDK -> com.batch.android.d.a: +com.batch.android.compat.LocalBroadcastManager -> com.batch.android.e.a: + android.content.Context mAppContext -> a + java.lang.String TAG -> f + android.os.Handler mHandler -> e + int MSG_EXEC_PENDING_BROADCASTS -> h + java.util.HashMap mReceivers -> b + boolean DEBUG -> g + java.util.ArrayList mPendingBroadcasts -> d + java.util.HashMap mActions -> c + 1:1:void (android.content.Context):94:94 -> + 2:14:void (android.content.Context):85:97 -> + 1:1:void access$000(com.batch.android.compat.LocalBroadcastManager):49:49 -> a + 2:19:void registerReceiver(android.content.BroadcastReceiver,android.content.IntentFilter):119:136 -> a + 20:43:void unregisterReceiver(android.content.BroadcastReceiver):148:171 -> a + 44:103:boolean sendBroadcast(android.content.Intent):184:243 -> a + 104:104:boolean sendBroadcast(android.content.Intent):240:240 -> a + 105:105:boolean sendBroadcast(android.content.Intent):237:237 -> a + 106:137:boolean sendBroadcast(android.content.Intent):231:262 -> a + 138:150:void executePendingBroadcasts():280:292 -> a + 151:151:void executePendingBroadcasts():288:288 -> a + 1:2:void sendBroadcastSync(android.content.Intent):272:273 -> b +com.batch.android.compat.LocalBroadcastManager$1 -> com.batch.android.e.a$a: + com.batch.android.compat.LocalBroadcastManager this$0 -> a + 1:1:void (com.batch.android.compat.LocalBroadcastManager,android.os.Looper):97:97 -> + 1:6:void handleMessage(android.os.Message):100:105 -> handleMessage + 7:7:void handleMessage(android.os.Message):102:102 -> handleMessage +com.batch.android.compat.LocalBroadcastManager$BroadcastRecord -> com.batch.android.e.a$b: + android.content.Intent intent -> a + java.util.ArrayList receivers -> b + 1:3:void (android.content.Intent,java.util.ArrayList):74:76 -> +com.batch.android.compat.LocalBroadcastManager$ReceiverRecord -> com.batch.android.e.a$c: + android.content.IntentFilter filter -> a + android.content.BroadcastReceiver receiver -> b + boolean broadcasting -> c + 1:3:void (android.content.IntentFilter,android.content.BroadcastReceiver):57:59 -> + 1:1:java.lang.String toString():64:64 -> toString +com.batch.android.compat.WakefulBroadcastReceiver -> com.batch.android.e.b: + android.util.SparseArray mActiveWakeLocks -> b + java.lang.String EXTRA_WAKE_LOCK_ID -> a + int mNextId -> c + 1:2:void ():63:64 -> + 1:1:void ():59:59 -> + 1:20:boolean completeWakefulIntent(android.content.Intent):119:138 -> completeWakefulIntent + 1:17:android.content.ComponentName startWakefulService(android.content.Context,android.content.Intent):81:97 -> startWakefulService + 18:26:android.content.ComponentName startWakefulService(android.content.Context,android.content.Intent):95:103 -> startWakefulService +com.batch.android.core.ByteArrayHelper -> com.batch.android.f.a: + char[] hexArray -> b + java.lang.String UTF_8 -> a + 1:1:void ():26:26 -> + 1:1:void ():16:16 -> + 1:6:byte[] concat(byte[],byte[]):38:43 -> a + 7:9:byte[] getUTF8Bytes(java.lang.String):72:74 -> a + 10:13:java.lang.String SHA1Base64Encoded(byte[]):130:133 -> a + 14:14:java.lang.String SHA1Base64Encoded(byte[]):126:126 -> a + 15:24:byte[] fromInputStream(java.io.InputStream):138:138 -> a + 1:10:java.lang.String bytesToHex(byte[]):87:96 -> b + 11:16:byte[] hexToBytes(java.lang.String):106:111 -> b + 1:3:java.lang.String getUTF8String(byte[]):58:60 -> c +com.batch.android.core.Cryptor -> com.batch.android.f.b: + java.lang.String encrypt(java.lang.String) -> a + byte[] encrypt(byte[]) -> a + java.lang.String decrypt(java.lang.String) -> b + byte[] decrypt(byte[]) -> b + byte[] decryptToByte(java.lang.String) -> c +com.batch.android.core.CryptorFactory -> com.batch.android.f.c: + java.lang.String DEFAULT_PRIVATE_KEY_PART -> a + 1:1:void ():10:10 -> + 1:1:com.batch.android.core.Cryptor getCryptorForType(java.lang.String):26:26 -> a + 2:2:com.batch.android.core.Cryptor getCryptorForType(java.lang.String,java.lang.String):37:37 -> a + 3:3:com.batch.android.core.Cryptor getCryptorForTypeValue(int):47:47 -> a + 4:4:com.batch.android.core.Cryptor getCryptorForTypeValue(int,java.lang.String):58:58 -> a + 5:5:com.batch.android.core.Cryptor getCryptorForType(com.batch.android.core.CryptorFactory$CryptorType):68:68 -> a + 6:17:com.batch.android.core.Cryptor getCryptorForType(com.batch.android.core.CryptorFactory$CryptorType,java.lang.String):84:95 -> a + 18:18:com.batch.android.core.Cryptor getCryptorForType(com.batch.android.core.CryptorFactory$CryptorType,java.lang.String):93:93 -> a + 19:19:com.batch.android.core.Cryptor getCryptorForType(com.batch.android.core.CryptorFactory$CryptorType,java.lang.String):91:91 -> a + 20:20:com.batch.android.core.Cryptor getCryptorForType(com.batch.android.core.CryptorFactory$CryptorType,java.lang.String):89:89 -> a + 21:24:byte[] buildDefaultKey():107:110 -> a +com.batch.android.core.CryptorFactory$1 -> com.batch.android.f.c$a: + int[] $SwitchMap$com$batch$android$core$CryptorFactory$CryptorType -> a + 1:1:void ():87:87 -> +com.batch.android.core.CryptorFactory$CryptorType -> com.batch.android.f.c$b: + com.batch.android.core.CryptorFactory$CryptorType EAS_HEX -> c + com.batch.android.core.CryptorFactory$CryptorType EAS -> b + com.batch.android.core.CryptorFactory$CryptorType EAS_BASE64_GZIP -> e + com.batch.android.core.CryptorFactory$CryptorType EAS_BASE64 -> d + com.batch.android.core.CryptorFactory$CryptorType[] $VALUES -> f + int value -> a + 1:13:void ():123:135 -> + 14:14:void ():119:119 -> + 1:2:void (java.lang.String,int,int):141:142 -> + 1:1:int getValue():148:148 -> a + 2:2:com.batch.android.core.CryptorFactory$CryptorType fromString(java.lang.String):161:161 -> a + 3:4:com.batch.android.core.CryptorFactory$CryptorType fromValue(int):174:175 -> a + 1:1:com.batch.android.core.CryptorFactory$CryptorType valueOf(java.lang.String):119:119 -> valueOf + 1:1:com.batch.android.core.CryptorFactory$CryptorType[] values():119:119 -> values +com.batch.android.core.DateProvider -> com.batch.android.f.d: + com.batch.android.date.BatchDate getCurrentDate() -> a +com.batch.android.core.DeeplinkHelper -> com.batch.android.f.e: + 1:1:void ():17:17 -> + 1:4:boolean customTabSupportsURI(android.net.Uri):46:49 -> a + 5:19:android.content.Intent getIntent(java.lang.String,boolean,boolean):66:80 -> a + 20:24:android.content.Intent getFallbackIntent(android.content.Context):93:97 -> a + 1:13:android.content.Intent getCustomTabIntent(android.net.Uri):25:37 -> b +com.batch.android.core.DiscoveryServiceHelper -> com.batch.android.f.f: + java.lang.String TAG -> a + 1:1:void ():13:13 -> + 1:10:java.util.List getComponentNames(android.content.Context,java.lang.Class,java.lang.String,java.lang.String):23:32 -> a + 11:27:android.os.Bundle getMetadata(android.content.Context,java.lang.Class):40:56 -> a +com.batch.android.core.EASBase64Cryptor -> com.batch.android.f.g: + java.lang.String TAG -> d + 1:1:void (java.lang.String):17:17 -> + 1:3:byte[] encrypt(byte[]):25:27 -> a + 4:6:java.lang.String encrypt(java.lang.String):35:37 -> a + 1:3:byte[] decrypt(byte[]):45:47 -> b + 4:6:java.lang.String decrypt(java.lang.String):55:57 -> b + 1:3:byte[] decryptToByte(java.lang.String):65:67 -> c +com.batch.android.core.EASBase64GzipCryptor -> com.batch.android.f.h: + java.lang.String TAG -> d + 1:1:void (java.lang.String):22:22 -> + 1:3:byte[] encrypt(byte[]):58:60 -> a + 4:6:java.lang.String encrypt(java.lang.String):68:70 -> a + 1:3:byte[] decrypt(byte[]):78:80 -> b + 4:6:java.lang.String decrypt(java.lang.String):88:90 -> b + 1:3:byte[] decryptToByte(java.lang.String):98:100 -> c + 1:8:byte[] gzip(byte[]):29:36 -> e + 9:9:byte[] gzip(byte[]):28:28 -> e + 1:12:byte[] ungzip(byte[]):41:52 -> f + 13:13:byte[] ungzip(byte[]):40:40 -> f +com.batch.android.core.EASCryptor -> com.batch.android.f.i: + java.lang.String cipherAlgorithm -> a + javax.crypto.spec.SecretKeySpec privateKey -> b + java.lang.String TAG -> c + 1:25:void (java.lang.String):31:55 -> + 26:26:void (java.lang.String):37:37 -> + 27:27:void (java.lang.String):33:33 -> + 1:3:byte[] encrypt(byte[]):63:65 -> a + 4:4:java.lang.String encrypt(java.lang.String):72:72 -> a + 1:3:byte[] decrypt(byte[]):78:80 -> b + 4:4:java.lang.String decrypt(java.lang.String):87:87 -> b + 1:1:byte[] decryptToByte(java.lang.String):92:92 -> c + 2:5:byte[] decryptAES(byte[]):117:120 -> c + 1:4:byte[] encryptAES(byte[]):104:107 -> d +com.batch.android.core.EASHexCryptor -> com.batch.android.f.j: + java.lang.String TAG -> d + 1:1:void (java.lang.String):15:15 -> + 1:3:byte[] encrypt(byte[]):23:25 -> a + 4:6:java.lang.String encrypt(java.lang.String):33:35 -> a + 1:3:byte[] decrypt(byte[]):43:45 -> b + 4:6:java.lang.String decrypt(java.lang.String):53:55 -> b + 1:3:byte[] decryptToByte(java.lang.String):63:65 -> c +com.batch.android.core.ExcludedActivityHelper -> com.batch.android.f.k: + java.util.Map checkedActivities -> d + android.content.Intent intent -> a + java.lang.String EXCLUDED_ACTIVITY_META_DATA -> c + java.lang.String TAG -> b + 1:1:void ():34:34 -> + 1:1:void ():16:16 -> + 1:19:boolean activityIsExcludedFromManifest(android.app.Activity):59:77 -> a + 20:20:boolean hasIntent():86:86 -> a + 1:5:void saveIntentIfNeeded(android.app.Activity):42:46 -> b + 6:7:android.content.Intent popIntent():95:96 -> b +com.batch.android.core.FixedSizeArrayList -> com.batch.android.f.l: + int maxSize -> a + 1:2:void (int):25:26 -> + 1:5:boolean add(java.lang.Object):30:34 -> add +com.batch.android.core.ForwardReadableInputStream -> com.batch.android.f.m: + int maxReadPosition -> d + int[] firstBytes -> a + java.io.InputStream wrappedInputStream -> b + int readPosition -> c + 1:1:void (java.io.InputStream,int):26:26 -> + 2:9:void (java.io.InputStream,int):23:30 -> + 1:1:int[] getFirstBytes():57:57 -> a + 1:5:void readFirstBytes(int):35:39 -> c + 6:6:void readFirstBytes(int):37:37 -> c + 1:6:int read():45:50 -> read +com.batch.android.core.GenericHelper -> com.batch.android.f.n: + 1:1:void ():18:18 -> + 1:1:boolean checkPermission(java.lang.String,android.content.Context):28:28 -> a + 2:14:java.lang.String readMD5(byte[]):61:73 -> a + 15:24:java.lang.String readMD5(java.lang.String):83:92 -> a + 25:29:java.lang.Float getScreenDensity(android.content.Context):103:107 -> a + 30:32:int DPtoPixel(int,android.content.Context):151:153 -> a + 33:33:int DPtoPixel(int,android.content.Context):144:144 -> a + 1:3:boolean isWakeLockPermissionAvailable(android.content.Context):34:36 -> b + 4:6:float pixelToDP(int,android.content.Context):129:131 -> b + 7:7:float pixelToDP(int,android.content.Context):122:122 -> b + 1:4:boolean targets12LOrOlder(android.content.Context):45:48 -> c +com.batch.android.core.GooglePlayServicesHelper -> com.batch.android.f.o: + java.lang.Integer libVersionCached -> f + boolean versionChecked -> e + int FCM_ID_VERSION -> d + int PUSH_ID_VERSION -> b + int INSTANCE_ID_VERSION -> c + int ADVERTISING_ID_VERSION -> a + 1:1:void ():13:13 -> + 1:18:java.lang.String getGooglePlayServicesAvailabilityString(java.lang.Integer):56:73 -> a + 19:25:java.lang.String getGooglePlayServicesAvailabilityString(java.lang.Integer):65:71 -> a + 26:26:java.lang.String getGooglePlayServicesAvailabilityString(java.lang.Integer):63:63 -> a + 27:35:java.lang.String getGooglePlayServicesAvailabilityString(java.lang.Integer):61:69 -> a + 36:45:java.lang.Integer getGooglePlayServicesAvailabilityInteger(android.content.Context):81:90 -> a + 46:69:java.lang.String getInstancePushToken(android.content.Context,java.lang.String):236:259 -> a + 70:77:java.lang.String getInstancePushToken(android.content.Context,java.lang.String):256:263 -> a + 78:80:boolean isInvalidSenderException(java.lang.Exception):277:279 -> a + 1:21:java.lang.Integer getGooglePlayServicesLibVersion(android.content.Context):106:126 -> b + 22:26:java.lang.Integer getGooglePlayServicesLibVersion(android.content.Context):123:127 -> b + 27:27:java.lang.Integer getGooglePlayServicesLibVersion(android.content.Context):126:126 -> b + 28:53:java.lang.String getPushToken(android.content.Context,java.lang.String):179:204 -> b + 54:61:java.lang.String getPushToken(android.content.Context,java.lang.String):202:209 -> b + 1:11:boolean isAdvertisingIDAvailable(android.content.Context):139:149 -> c + 1:6:java.lang.Integer isFCMAvailable(android.content.Context):292:297 -> d + 1:6:java.lang.Integer isInstanceIdPushAvailable(android.content.Context):223:228 -> e + 1:8:java.lang.Integer isPushAvailable(android.content.Context):161:168 -> f +com.batch.android.core.InternalPushData -> com.batch.android.f.p: + java.lang.String IS_SILENT_KEY -> f + java.lang.String LANDING_KEY -> h + java.lang.String CUSTOM_BIG_IMAGE_KEY -> j + java.lang.String PRIORITY_KEY -> l + java.lang.String IS_GROUP_SUMMARY_KEY -> n + java.lang.String TYPE_KEY -> p + java.lang.String VARIANT_KEY -> r + java.lang.String VISIBILITY_KEY -> t + java.lang.String FORMAT_ARGS_KEY -> v + java.lang.String OLD_BIG_PICTURE_ICON_BEHAVIOUR -> x + java.lang.String jsonPayload -> a + java.lang.String SCHEME_KEY -> c + java.lang.String INSTALL_ID_KEY -> e + java.lang.String IS_LOCAL_CAMPAIGNS_REFRESH_KEY -> g + java.lang.String CUSTOM_BIG_ICON_KEY -> i + java.lang.String ACTION_KEY -> k + java.lang.String GROUP_NAME_KEY -> m + java.lang.String OPEN_DATA_KEY -> o + java.lang.String EXPERIMENT_KEY -> q + java.lang.String CHANNEL_KEY -> s + java.lang.String FORMAT_KEY -> u + java.lang.String RECEIPT_KEY -> w + com.batch.android.json.JSONObject payload -> b + java.lang.String BATCH_BUNDLE_KEY -> y + java.lang.String ID_KEY -> d + 1:10:void (java.lang.String):143:152 -> + 11:11:void (java.lang.String):145:145 -> + 12:18:void (com.batch.android.json.JSONObject):156:162 -> + 19:19:void (com.batch.android.json.JSONObject):158:158 -> + 1:1:boolean hasScheme():224:224 -> A + 1:1:boolean isGroupSummary():487:487 -> B + 1:1:boolean isLocalCampainsRefresh():217:217 -> C + 1:2:boolean isSchemeEmpty():228:229 -> D + 1:1:boolean isSilent():209:209 -> E + 1:1:boolean shouldUseLegacyBigPictureIconBehaviour():584:584 -> F + 1:1:com.batch.android.core.InternalPushData getPushDataForReceiverIntent(android.content.Intent):171:171 -> a + 2:2:com.batch.android.core.InternalPushData getPushDataForReceiverIntent(android.content.Intent):168:168 -> a + 3:6:com.batch.android.core.InternalPushData getPushDataForReceiverBundle(android.os.Bundle):175:178 -> a + 7:11:com.batch.android.core.InternalPushData getPushDataForFirebaseMessage(com.google.firebase.messaging.RemoteMessage):190:194 -> a + 12:50:java.util.List getActions():341:379 -> a + 51:51:java.lang.String nullSafeGetString(com.batch.android.json.JSONObject,java.lang.String):593:593 -> a + 52:52:com.batch.android.json.JSONArray nullSafeGetJSONArray(java.lang.String):609:609 -> a + 1:1:java.lang.String getChannel():452:452 -> b + 2:2:com.batch.android.json.JSONObject nullSafeGetJSONObject(java.lang.String):601:601 -> b + 1:15:java.util.List getCustomBigIconAvailableDensity():273:287 -> c + 16:16:java.lang.String nullSafeGetString(java.lang.String):588:588 -> c + 1:6:java.lang.String getCustomBigIconURL():264:269 -> d + 1:15:java.util.List getCustomBigImageAvailableDensity():317:331 -> e + 1:6:java.lang.String getCustomBigImageURL():308:313 -> f + 1:8:java.util.Map getExtraParameters():529:536 -> g + 1:2:java.lang.String getGroup():474:475 -> h + 1:1:java.lang.String getInstallId():241:241 -> i + 1:1:java.lang.String getJsonPayload():202:202 -> j + 1:1:com.batch.android.json.JSONObject getLandingMessage():249:249 -> k + 1:1:com.batch.android.core.InternalPushData$Format getNotificationFormat():515:515 -> l + 1:1:com.batch.android.json.JSONObject getNotificationFormatArguments():523:523 -> m + 1:4:java.util.Map getOpenData():549:552 -> n + 1:17:com.batch.android.core.InternalPushData$Priority getPriority():422:438 -> o + 18:18:com.batch.android.core.InternalPushData$Priority getPriority():436:436 -> o + 19:19:com.batch.android.core.InternalPushData$Priority getPriority():434:434 -> o + 20:33:com.batch.android.core.InternalPushData$Priority getPriority():432:445 -> o + 1:1:java.lang.String getPushId():237:237 -> p + 1:7:java.util.Map getReceiptEventData():565:571 -> q + 1:6:long getReceiptMaxDelay():413:418 -> r + 1:6:long getReceiptMinDelay():404:409 -> s + 1:13:com.batch.android.core.InternalPushData$ReceiptMode getReceiptMode():387:399 -> t + 14:14:com.batch.android.core.InternalPushData$ReceiptMode getReceiptMode():396:396 -> t + 15:15:com.batch.android.core.InternalPushData$ReceiptMode getReceiptMode():394:394 -> t + 1:1:java.lang.String getScheme():233:233 -> u + 1:10:com.batch.android.BatchNotificationSource getSource():456:465 -> v + 1:1:int getVisibility():499:499 -> w + 1:8:boolean hasCustomBigIcon():253:260 -> x + 1:8:boolean hasCustomBigImage():297:304 -> y + 1:1:boolean hasLandingMessage():245:245 -> z +com.batch.android.core.InternalPushData$1 -> com.batch.android.f.p$a: + int[] $SwitchMap$com$batch$android$core$InternalPushData$Priority -> a + 1:1:void ():632:632 -> +com.batch.android.core.InternalPushData$Format -> com.batch.android.f.p$b: + com.batch.android.core.InternalPushData$Format DEFAULT -> a + com.batch.android.core.InternalPushData$Format APEN -> b + com.batch.android.core.InternalPushData$Format[] $VALUES -> c + 1:3:void ():667:669 -> + 4:4:void ():666:666 -> + 1:1:void (java.lang.String,int):666:666 -> + 1:4:com.batch.android.core.InternalPushData$Format fromString(java.lang.String):672:675 -> a + 1:1:com.batch.android.core.InternalPushData$Format valueOf(java.lang.String):666:666 -> valueOf + 1:1:com.batch.android.core.InternalPushData$Format[] values():666:666 -> values +com.batch.android.core.InternalPushData$Priority -> com.batch.android.f.p$c: + com.batch.android.core.InternalPushData$Priority HIGH -> e + com.batch.android.core.InternalPushData$Priority MAX -> f + com.batch.android.core.InternalPushData$Priority UNDEFINED -> a + com.batch.android.core.InternalPushData$Priority DEFAULT -> b + com.batch.android.core.InternalPushData$Priority MIN -> c + com.batch.android.core.InternalPushData$Priority LOW -> d + com.batch.android.core.InternalPushData$Priority[] $VALUES -> g + 1:6:void ():619:624 -> + 7:7:void ():618:618 -> + 1:1:void (java.lang.String,int):618:618 -> + 1:5:int toAndroidPriority():628:632 -> a + 1:1:int toSupportPriority():649:649 -> b + 1:1:com.batch.android.core.InternalPushData$Priority valueOf(java.lang.String):618:618 -> valueOf + 1:1:com.batch.android.core.InternalPushData$Priority[] values():618:618 -> values +com.batch.android.core.InternalPushData$ReceiptMode -> com.batch.android.f.p$d: + com.batch.android.core.InternalPushData$ReceiptMode DISPLAY -> b + com.batch.android.core.InternalPushData$ReceiptMode FORCE -> c + com.batch.android.core.InternalPushData$ReceiptMode DEFAULT -> a + com.batch.android.core.InternalPushData$ReceiptMode[] $VALUES -> d + 1:3:void ():680:682 -> + 4:4:void ():679:679 -> + 1:1:void (java.lang.String,int):679:679 -> + 1:1:com.batch.android.core.InternalPushData$ReceiptMode valueOf(java.lang.String):679:679 -> valueOf + 1:1:com.batch.android.core.InternalPushData$ReceiptMode[] values():679:679 -> values +com.batch.android.core.KVUserPreferencesStorage -> com.batch.android.f.q: + com.batch.android.core.Cryptor cryptor -> b + android.content.SharedPreferences preferences -> a + java.lang.String TAG -> c + java.lang.String SHARED_PREFERENCES_FILENAME -> d + 1:8:void (android.content.Context):39:46 -> + 9:9:void (android.content.Context):41:41 -> + 1:6:java.lang.String get(java.lang.String,java.lang.String):66:71 -> a + 7:7:boolean contains(java.lang.String):75:75 -> a + 1:4:boolean persist(java.lang.String,java.lang.String):53:56 -> b + 5:5:java.lang.String get(java.lang.String):62:62 -> b + 1:1:void remove(java.lang.String):80:80 -> c +com.batch.android.core.Logger -> com.batch.android.f.r: + com.batch.android.LoggerDelegate loggerDelegate -> c + java.lang.String PUBLIC_TAG -> a + java.lang.String INTERNAL_TAG -> b + boolean dev -> d + 1:1:void ():35:35 -> + 1:1:void ():14:14 -> + 1:1:boolean shouldEnableDevLogs():41:41 -> a + 2:2:boolean shouldLogForLevel(com.batch.android.LoggerLevel):47:47 -> a + 3:11:void error(java.lang.String,java.lang.String,java.lang.Throwable):244:252 -> a + 12:12:void error(java.lang.String,java.lang.Throwable):264:264 -> a + 13:21:void error(java.lang.String,java.lang.String):274:282 -> a + 22:22:void error(java.lang.String):293:293 -> a + 1:9:void info(java.lang.String,java.lang.String,java.lang.Throwable):120:128 -> b + 10:10:void info(java.lang.String,java.lang.Throwable):140:140 -> b + 11:19:void info(java.lang.String,java.lang.String):150:158 -> b + 20:20:void info(java.lang.String):169:169 -> b + 1:9:void internal(java.lang.String,java.lang.String,java.lang.Throwable):306:314 -> c + 10:10:void internal(java.lang.String,java.lang.Throwable):326:326 -> c + 11:19:void internal(java.lang.String,java.lang.String):336:344 -> c + 20:20:void internal(java.lang.String):355:355 -> c + 1:9:void verbose(java.lang.String,java.lang.String,java.lang.Throwable):58:66 -> d + 10:10:void verbose(java.lang.String,java.lang.Throwable):78:78 -> d + 11:19:void verbose(java.lang.String,java.lang.String):88:96 -> d + 20:20:void verbose(java.lang.String):107:107 -> d + 1:9:void warning(java.lang.String,java.lang.String,java.lang.Throwable):182:190 -> e + 10:10:void warning(java.lang.String,java.lang.Throwable):202:202 -> e + 11:19:void warning(java.lang.String,java.lang.String):212:220 -> e + 20:20:void warning(java.lang.String):231:231 -> e +com.batch.android.core.MessagePackWebservice -> com.batch.android.f.s: + java.lang.String MSGPACK_SCHEMA_VERSION -> m + com.batch.android.post.MessagePackPostDataProvider dataProvider -> l + 1:5:void (android.content.Context,com.batch.android.post.MessagePackPostDataProvider,java.lang.String,java.lang.String[]):21:25 -> + 6:6:void (android.content.Context,com.batch.android.post.MessagePackPostDataProvider,java.lang.String,java.lang.String[]):23:23 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():82:82 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():87:87 -> B + 1:1:java.lang.String getSpecificRetryCountKey():92:92 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():67:67 -> F + 1:1:com.batch.android.post.MessagePackPostDataProvider getPostDataProvider():52:52 -> G + 1:3:java.lang.String[] addSchemaVersion(java.lang.String[]):36:38 -> b + 1:1:java.lang.String getCryptorModeParameterKey():77:77 -> o + 1:1:java.lang.String getCryptorTypeParameterKey():72:72 -> p + 1:3:java.util.Map getHeaders():44:46 -> r + 1:1:java.lang.String getPostCryptorTypeParameterKey():57:57 -> v + 1:1:com.batch.android.post.PostDataProvider getPostDataProvider():9:9 -> w + 1:1:java.lang.String getReadCryptorTypeParameterKey():62:62 -> y +com.batch.android.core.NamedThreadFactory -> com.batch.android.f.t: + java.util.concurrent.ThreadFactory defaultFactory -> b + java.lang.String suffix -> a + 1:1:void ():13:13 -> + 1:1:void ():17:17 -> + 2:2:void ():15:15 -> + 3:3:void (java.lang.String):19:19 -> + 4:9:void (java.lang.String):15:20 -> + 1:5:java.lang.Thread newThread(java.lang.Runnable):25:29 -> newThread +com.batch.android.core.NotificationAuthorizationStatus -> com.batch.android.f.u: + java.lang.String TAG -> a + 1:1:void ():20:20 -> + 1:11:boolean canAppShowNotifications(android.content.Context,com.batch.android.BatchNotificationChannelsManager):31:41 -> a + 12:29:boolean canAppShowNotificationsForChannel(android.content.Context,java.lang.String):47:64 -> a + 30:33:boolean areAppNotificationsEnabled(android.content.Context,android.app.NotificationManager):74:77 -> a + 34:47:boolean areBatchNotificationsEnabled(android.content.Context):86:99 -> a + 48:51:boolean isDefaultChannelEnabled(android.app.NotificationManager,com.batch.android.BatchNotificationChannelsManager):110:113 -> a + 52:52:boolean isDefaultChannelEnabled(android.app.NotificationManager,com.batch.android.BatchNotificationChannelsManager):111:111 -> a + 53:74:boolean canChannelShowNotifications(android.app.NotificationManager,java.lang.String,boolean):129:150 -> a +com.batch.android.core.NotificationPermissionHelper -> com.batch.android.f.v: + boolean experimentalUseChannelCreationOnOldTargets -> a + java.lang.String TAG -> c + boolean experimentalForceChannelCreation -> b + java.lang.String PERMISSION_NOTIFICATION -> e + java.lang.String BASE_TARGET_LOG_MESSAGE -> d + 1:11:void ():11:21 -> + 1:61:void requestPermission(android.content.Context):25:85 -> a + 62:62:void lambda$requestPermission$0(android.app.Activity):81:81 -> a + 1:1:void requestPermissionFromOlderSDK(android.content.Context):94:94 -> b + 2:2:void requestPermissionFromOlderSDK(android.content.Context):93:93 -> b +com.batch.android.core.ObjectUserPreferencesStorage -> com.batch.android.f.w: + com.batch.android.core.Cryptor cryptor -> b + android.content.SharedPreferences preferences -> a + java.lang.String TAG -> c + java.lang.String SHARED_PREFERENCES_FILENAME -> d + 1:8:void (android.content.Context):47:54 -> + 9:9:void (android.content.Context):49:49 -> + 1:3:boolean persist(java.lang.String,java.io.Serializable):61:63 -> a + 4:4:boolean contains(java.lang.String):77:77 -> a + 5:22:java.lang.String serialize(java.io.Serializable):102:119 -> a + 23:36:java.lang.String serialize(java.io.Serializable):109:122 -> a + 37:37:java.lang.String serialize(java.io.Serializable):96:96 -> a + 1:19:java.lang.Object deserialize(java.lang.String):142:160 -> b + 20:33:java.lang.Object deserialize(java.lang.String):150:163 -> b + 1:3:java.lang.Object get(java.lang.String):70:72 -> c + 1:1:void remove(java.lang.String):82:82 -> d +com.batch.android.core.PackageUtils -> com.batch.android.f.x: + 1:1:void ():9:9 -> + 1:1:boolean isPackageInstalled(android.content.pm.PackageManager,java.lang.String):17:17 -> a +com.batch.android.core.ParameterKeys -> com.batch.android.f.y: + java.lang.String DEFAULT_READ_TIMEOUT_KEY -> I0 + java.lang.String LIB_CURRENTVERSION_KEY -> j1 + java.lang.String IMAGE_WS_READ_TIMEOUT_KEY -> I + java.lang.String TRACKER_WS_PROPERTY_KEY -> j + java.lang.String LOCAL_CAMPAIGNS_WS_INITIAL_DELAY -> E0 + java.lang.String USER_DATA_CHANGESET -> f1 + java.lang.String METRIC_WS_RETRYCOUNT_KEY -> A0 + java.lang.String PUSH_REGISTRATION_PROVIDER_KEY -> b1 + java.lang.String ATTR_SEND_WS_CONNECT_TIMEOUT_KEY -> Q + java.lang.String TRACKER_WS_READ_TIMEOUT_KEY -> r + java.lang.String ATTR_CHECK_WS_RETRYCOUNT_KEY -> Y + java.lang.String MESSAGE_PACK_WS_RETRYCOUNT_KEY -> v0 + java.lang.String PUSH_WS_CONNECT_TIMEOUT_KEY -> z + java.lang.String MESSAGE_PACK_WS_READ_CRYPTORTYPE_KEY -> r0 + java.lang.String START_WS_PROPERTY_KEY -> a + java.lang.String INBOX_WS_RETRYCOUNT_KEY -> n0 + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_READ_TIMEOUT_KEY -> j0 + java.lang.String START_WS_READ_TIMEOUT_KEY -> i + java.lang.String IMAGE_WS_CONNECT_TIMEOUT_KEY -> H + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_POST_CRYPTORTYPE_KEY -> f0 + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_PROPERTY_KEY -> b0 + java.lang.String TRACKER_WS_CONNECT_TIMEOUT_KEY -> q + java.lang.String ATTR_SEND_WS_RETRYCOUNT_KEY -> P + java.lang.String DISPLAY_RECEIPT_WS_CRYPTORTYPE_KEY -> y0 + java.lang.String EVENT_TRACKER_STATE -> Z0 + java.lang.String PUSH_WS_RETRYCOUNT_KEY -> y + java.lang.String ATTR_CHECK_WS_READ_CRYPTORTYPE_KEY -> X + java.lang.String EVENT_TRACKER_INITIAL_DELAY -> V0 + java.lang.String SCHEME_CODE_PATTERN -> R0 + java.lang.String SERVER_ID_KEY -> N0 + java.lang.String DEFAULT_CONNECT_TIMEOUT_KEY -> H0 + java.lang.String USER_PROFILE_REGION_KEY -> i1 + java.lang.String ATTR_SEND_WS_URLSORTER_PATTERN_KEY -> K + java.lang.String LOCAL_CAMPAIGNS_JIT_WS_CONNECT_TIMEOUT_KEY -> D0 + java.lang.String PUSH_NOTIF_TYPE -> e1 + java.lang.String TRACKER_WS_CRYPTORTYPE_KEY -> l + java.lang.String PUSH_REGISTRATION_ID_KEY -> a1 + java.lang.String ATTR_CHECK_WS_PROPERTY_KEY -> S + java.lang.String PUSH_WS_URLSORTER_PATTERN_KEY -> t + java.lang.String MESSAGE_PACK_WS_CRYPTORMODE_KEY -> u0 + java.lang.String MESSAGE_PACK_WS_POST_CRYPTORTYPE_KEY -> q0 + java.lang.String START_WS_CRYPTORTYPE_KEY -> c + java.lang.String IMAGE_WS_URLSORTER_PATTERN_KEY -> B + java.lang.String INBOX_WS_POST_CRYPTORTYPE_KEY -> m0 + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_CONNECT_TIMEOUT_KEY -> i0 + java.lang.String TRACKER_WS_URLSORTER_PATTERN_KEY -> k + java.lang.String ATTR_SEND_WS_PROPERTY_KEY -> J + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_CRYPTORMODE_KEY -> e0 + java.lang.String ATTR_CHECK_WS_READ_TIMEOUT_KEY -> a0 + java.lang.String PUSH_WS_PROPERTY_KEY -> s + java.lang.String ATTR_SEND_WS_READ_TIMEOUT_KEY -> R + java.lang.String DISPLAY_RECEIPT_WS_RETRYCOUNT_KEY -> z0 + java.lang.String EVENT_TRACKER_EVENTS_LIMIT -> Y0 + java.lang.String ATTR_CHECK_WS_CONNECT_TIMEOUT_KEY -> Z + java.lang.String SERVER_TIMESTAMP -> U0 + java.lang.String TASK_EXECUTOR_THREADTTL -> Q0 + java.lang.String PUSH_WS_READ_TIMEOUT_KEY -> A + java.lang.String START_WS_URLSORTER_PATTERN_KEY -> b + java.lang.String INSTALL_TIMESTAMP_KEY -> M0 + java.lang.String START_WS_READ_CRYPTORTYPE_KEY -> f + java.lang.String DEFAULT_RETRY_NUMBER_KEY -> G0 + java.lang.String USER_PROFILE_LANGUAGE_KEY -> h1 + java.lang.String ATTR_SEND_WS_CRYPTORMODE_KEY -> M + java.lang.String LOCAL_CAMPAIGNS_JIT_WS_READ_TIMEOUT_KEY -> C0 + java.lang.String PUSH_APP_VERSION_KEY -> d1 + java.lang.String TRACKER_WS_POST_CRYPTORTYPE_KEY -> n + java.lang.String ATTR_CHECK_WS_CRYPTORTYPE_KEY -> U + java.lang.String PUSH_WS_CRYPTORMODE_KEY -> v + java.lang.String MESSAGE_PACK_WS_READ_TIMEOUT_KEY -> x0 + java.lang.String MESSAGE_PACK_WS_CRYPTORTYPE_KEY -> t0 + java.lang.String INBOX_WS_READ_TIMEOUT_KEY -> p0 + java.lang.String START_WS_POST_CRYPTORTYPE_KEY -> e + java.lang.String INBOX_WS_READ_CRYPTORTYPE_KEY -> l0 + java.lang.String IMAGE_WS_CRYPTORMODE_KEY -> D + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_RETRYCOUNT_KEY -> h0 + java.lang.String TRACKER_WS_CRYPTORMODE_KEY -> m + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_CRYPTORTYPE_KEY -> d0 + java.lang.String ATTR_SEND_WS_CRYPTORTYPE_KEY -> L + java.lang.String PUSH_WS_CRYPTORTYPE_KEY -> u + java.lang.String ATTR_CHECK_WS_URLSORTER_PATTERN_KEY -> T + java.lang.String EVENT_TRACKER_BATCH_QUANTITY -> X0 + java.lang.String USER_DATA_VERSION -> T0 + java.lang.String TASK_EXECUTOR_MAX_POOL -> P0 + java.lang.String IMAGE_WS_CRYPTORTYPE_KEY -> C + java.lang.String INSTALL_ID_KEY -> L0 + java.lang.String START_WS_CRYPTORMODE_KEY -> d + java.lang.String IMAGE_WS_RETRYCOUNT_KEY -> G + java.lang.String WEBSERVICE_IDS_PARAMETERS -> J0 + java.lang.String LIB_PREVIOUSVERSION_KEY -> k1 + java.lang.String START_WS_CONNECT_TIMEOUT_KEY -> h + java.lang.String WS_CIPHERV2_LAST_FAILURE_KEY -> F0 + java.lang.String USER_DATA_TRANSACTION_ID -> g1 + java.lang.String ATTR_SEND_WS_READ_CRYPTORTYPE_KEY -> O + java.lang.String LOCAL_CAMPAIGNS_JIT_WS_RETRYCOUNT_KEY -> B0 + java.lang.String PUSH_REGISTRATION_SENDERID_KEY -> c1 + java.lang.String TRACKER_WS_RETRYCOUNT_KEY -> p + java.lang.String ATTR_CHECK_WS_POST_CRYPTORTYPE_KEY -> W + java.lang.String PUSH_WS_READ_CRYPTORTYPE_KEY -> x + java.lang.String MESSAGE_PACK_WS_CONNECT_TIMEOUT_KEY -> w0 + java.lang.String MESSAGE_PACK_WS_URLSORTER_PATTERN_KEY -> s0 + java.lang.String INBOX_WS_CONNECT_TIMEOUT_KEY -> o0 + java.lang.String INBOX_WS_URLSORTER_PATTERN_KEY -> k0 + java.lang.String START_WS_RETRYCOUNT_KEY -> g + java.lang.String IMAGE_WS_READ_CRYPTORTYPE_KEY -> F + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_READ_CRYPTORTYPE_KEY -> g0 + java.lang.String ATTR_LOCAL_CAMPAIGNS_WS_URLSORTER_PATTERN_KEY -> c0 + java.lang.String TRACKER_WS_READ_CRYPTORTYPE_KEY -> o + java.lang.String ATTR_SEND_WS_POST_CRYPTORTYPE_KEY -> N + java.lang.String PUSH_WS_POST_CRYPTORTYPE_KEY -> w + java.lang.String ATTR_CHECK_WS_CRYPTORMODE_KEY -> V + java.lang.String EVENT_TRACKER_MAX_DELAY -> W0 + java.lang.String CUSTOM_ID -> S0 + java.lang.String TASK_EXECUTOR_MIN_POOL -> O0 + java.lang.String IMAGE_WS_POST_CRYPTORTYPE_KEY -> E + java.lang.String WEBSERVICE_IDS_ADVANCED_PARAMETERS -> K0 + 1:1:void ():9:9 -> +com.batch.android.core.Parameters -> com.batch.android.f.z: + android.content.Context applicationContext -> a + java.lang.String COMMON_EXTERNAL_CRYPT_BASE_KEY_V2 -> f + int API_LEVEL -> j + java.lang.String LIBRARY_BUNDLE -> l + java.lang.String PLUGIN_VERSION_ENVIRONEMENT_VAR -> n + java.lang.String BASE_WS_URL -> p + java.lang.String TRACKER_WS_URL -> r + java.lang.String ATTR_SEND_WS_URL -> t + java.lang.String LOCAL_CAMPAIGNS_WS_URL -> v + java.util.Map appParameters -> B + java.lang.String INBOX_SYNC_WS_URL -> x + java.lang.String METRIC_WS_URL -> z + boolean ENABLE_WS_INTERCEPTOR -> h + java.lang.String COMMON_INTERNAL_CRYPT_BASE_KEY -> c + java.lang.String COMMON_EXTERNAL_CRYPT_BASE_KEY -> e + java.lang.String SDK_VERSION -> i + int MESSAGING_API_LEVEL -> k + java.lang.String DOMAIN_URL -> m + java.lang.String BRIDGE_VERSION_ENVIRONEMENT_VAR -> o + java.lang.String START_WS_URL -> q + java.lang.String PUSH_WS_URL -> s + java.lang.String ATTR_CHECK_WS_URL -> u + java.lang.String INBOX_FETCH_WS_URL -> w + java.util.Map cacheParameters -> b + java.lang.String DISPLAY_RECEIPT_WS_URL -> y + boolean ENABLE_DEV_LOGS -> g + java.lang.String LOCAL_CAMPAIGNS_JIT_WS_URL -> A + java.lang.String PARAMETERS_KEY_PREFIX -> C + java.lang.String COMMON_EXTERNAL_CRYPT_SIGNATURE_KEY -> d + 1:129:void ():60:188 -> + 1:10:void (android.content.Context):217:226 -> + 11:11:void (android.content.Context):219:219 -> + 1:13:java.lang.String get(java.lang.String):242:254 -> a + 14:14:java.lang.String get(java.lang.String):247:247 -> a + 15:15:java.lang.String get(java.lang.String):239:239 -> a + 16:17:java.lang.String get(java.lang.String,java.lang.String):270:271 -> a + 18:23:void set(java.lang.String,java.lang.String,boolean):294:299 -> a + 24:24:void set(java.lang.String,java.lang.String,boolean):296:296 -> a + 25:25:void set(java.lang.String,java.lang.String,boolean):291:291 -> a + 26:26:void set(java.lang.String,java.lang.String,boolean):287:287 -> a + 1:5:void remove(java.lang.String):313:317 -> b + 6:6:void remove(java.lang.String):315:315 -> b + 7:7:void remove(java.lang.String):310:310 -> b +com.batch.android.core.PatternURLSorter -> com.batch.android.f.a0: + java.util.List pattern -> a + 1:1:void ():27:27 -> + 2:2:void ():20:20 -> + 3:3:void (java.util.List):34:34 -> + 4:20:void (java.util.List):20:36 -> + 21:21:void (java.lang.String):45:45 -> + 22:49:void (java.lang.String):20:47 -> + 1:1:java.util.List getKeysOrdered(java.util.List):60:60 -> a + 2:2:java.util.List getKeysOrdered(java.util.Set):70:70 -> a + 3:3:java.util.List getKeysOrdered(java.util.Map):80:80 -> a + 4:27:java.util.List order(java.util.Collection):92:115 -> a + 28:28:java.util.List order(java.util.Collection):93:93 -> a +com.batch.android.core.Promise -> com.batch.android.f.b0: + java.lang.Object resolvedValue -> b + java.util.ArrayDeque thenQueue -> d + java.util.ArrayDeque catchQueue -> e + com.batch.android.core.Promise$Status status -> a + java.lang.Exception rejectException -> c + 1:1:void ():21:21 -> + 2:7:void ():14:19 -> + 8:8:void (com.batch.android.core.Promise$ExecutorRunnable):23:23 -> + 9:28:void (com.batch.android.core.Promise$ExecutorRunnable):14:33 -> + 29:29:void (com.batch.android.core.Promise$ExecutorRunnable):28:28 -> + 30:30:void (com.batch.android.core.Promise$DeferredResultExecutorRunnable):36:36 -> + 31:57:void (com.batch.android.core.Promise$DeferredResultExecutorRunnable):14:40 -> + 1:11:void resolve(java.lang.Object):57:67 -> a + 12:22:void reject(java.lang.Exception):72:82 -> a + 23:28:com.batch.android.core.Promise then(com.batch.android.core.Promise$ThenRunnable):87:92 -> a + 29:29:com.batch.android.core.Promise then(com.batch.android.core.Promise$ThenRunnable):89:89 -> a + 30:35:com.batch.android.core.Promise catchException(com.batch.android.core.Promise$CatchRunnable):100:105 -> a + 36:36:com.batch.android.core.Promise catchException(com.batch.android.core.Promise$CatchRunnable):102:102 -> a + 37:37:com.batch.android.core.Promise$Status getStatus():113:113 -> a + 1:2:com.batch.android.core.Promise resolved(java.lang.Object):45:46 -> b + 3:4:com.batch.android.core.Promise rejected(java.lang.Exception):51:52 -> b +com.batch.android.core.Promise$1 -> com.batch.android.f.b0$a: + int[] $SwitchMap$com$batch$android$core$Promise$Status -> a + 1:1:void ():87:87 -> +com.batch.android.core.Promise$CatchRunnable -> com.batch.android.f.b0$b: + void run(java.lang.Exception) -> a +com.batch.android.core.Promise$DeferredResultExecutorRunnable -> com.batch.android.f.b0$c: + void run(com.batch.android.core.Promise) -> a +com.batch.android.core.Promise$ExecutorRunnable -> com.batch.android.f.b0$d: +com.batch.android.core.Promise$Status -> com.batch.android.f.b0$e: + com.batch.android.core.Promise$Status[] $VALUES -> d + com.batch.android.core.Promise$Status REJECTED -> c + com.batch.android.core.Promise$Status PENDING -> a + com.batch.android.core.Promise$Status RESOLVED -> b + 1:3:void ():140:142 -> + 4:4:void ():139:139 -> + 1:1:void (java.lang.String,int):139:139 -> + 1:1:com.batch.android.core.Promise$Status valueOf(java.lang.String):139:139 -> valueOf + 1:1:com.batch.android.core.Promise$Status[] values():139:139 -> values +com.batch.android.core.Promise$ThenRunnable -> com.batch.android.f.b0$f: + void run(java.lang.Object) -> a +com.batch.android.core.PushImageCache -> com.batch.android.f.c0: + java.lang.String TAG -> a + int MAX_IMAGES_STORED -> b + java.lang.String IMAGES_CACHE_FOLDER -> c + 1:1:void ():14:14 -> + 1:1:java.lang.String getFilePathForIdentifier(android.content.Context,java.lang.String):46:46 -> a + 2:12:void storeImageInCache(android.content.Context,java.lang.String,android.graphics.Bitmap):60:70 -> a + 13:16:void storeImageInCache(android.content.Context,java.lang.String,android.graphics.Bitmap):68:71 -> a + 17:19:java.lang.String buildIdentifierForURL(java.lang.String):95:97 -> a + 20:39:void clearImagesIfNeeded(android.content.Context):111:130 -> a + 40:44:void clearImagesIfNeeded(android.content.Context):128:132 -> a + 45:45:int lambda$clearImagesIfNeeded$0(java.io.File,java.io.File):121:121 -> a + 1:1:java.lang.String getPushImageCacheFolder(android.content.Context):35:35 -> b + 2:3:android.graphics.Bitmap getImageFromCache(android.content.Context,java.lang.String):83:84 -> b +com.batch.android.core.ReflectionHelper -> com.batch.android.f.d0: + 1:1:void ():19:19 -> + 1:1:boolean isAndroidXAppCompatActivityPresent():34:34 -> a + 2:3:boolean isInstanceOfCoordinatorLayout(java.lang.Object):46:47 -> a + 4:5:boolean optOutOfSmartReply(androidx.core.app.NotificationCompat$Builder):55:56 -> a + 6:7:void optOutOfDarkMode(android.view.View):64:65 -> a + 1:1:boolean isAndroidXFragmentPresent():25:25 -> b + 2:16:void optOutOfDarkModeRecursively(android.view.View):70:84 -> b + 1:1:boolean isGMSGoogleCloudMessagingPresent():95:95 -> c + 1:1:boolean isGMSInstanceIDPresent():104:104 -> d +com.batch.android.core.ResponseHelper -> com.batch.android.f.e0: + java.lang.String TAG -> a + 1:1:void ():9:9 -> + 1:3:com.batch.android.json.JSONObject asJson(byte[]):25:27 -> a + 4:4:com.batch.android.json.JSONObject asJson(byte[]):21:21 -> a + 1:3:java.lang.String asString(byte[]):44:46 -> b + 4:4:java.lang.String asString(byte[]):40:40 -> b +com.batch.android.core.SecureDateProvider -> com.batch.android.f.f0: + java.util.Date mServerDate -> b + long mElapsedRealtime -> c + boolean mSecureDateEnabled -> a + 1:2:void ():38:39 -> + 1:5:void initServerDate(java.util.Date):76:80 -> a + 6:6:com.batch.android.date.BatchDate getCurrentDate():101:101 -> a + 1:1:boolean canEnableSecureDate():92:92 -> b + 1:6:java.util.Date getDate():49:54 -> c + 7:7:java.util.Date getDate():52:52 -> c + 1:1:boolean isSecureDateAvailable():67:67 -> d +com.batch.android.core.SystemDateProvider -> com.batch.android.f.g0: + 1:1:void ():6:6 -> + 1:1:com.batch.android.date.BatchDate getCurrentDate():10:10 -> a +com.batch.android.core.SystemParameterHelper -> com.batch.android.f.h0: + java.lang.String TAG -> a + 1:1:void ():24:24 -> + 1:3:java.lang.String getAppVersion(android.content.Context):168:170 -> a + 4:4:java.lang.String getBridgeVersion():367:367 -> a + 5:100:java.lang.String getValue(java.lang.String,android.content.Context):498:593 -> a + 101:107:java.lang.String getValue(java.lang.String,android.content.Context):578:584 -> a + 108:108:java.lang.String getValue(java.lang.String,android.content.Context):574:574 -> a + 109:109:java.lang.String getValue(java.lang.String,android.content.Context):571:571 -> a + 110:110:java.lang.String getValue(java.lang.String,android.content.Context):568:568 -> a + 111:111:java.lang.String getValue(java.lang.String,android.content.Context):565:565 -> a + 112:112:java.lang.String getValue(java.lang.String,android.content.Context):562:562 -> a + 113:113:java.lang.String getValue(java.lang.String,android.content.Context):559:559 -> a + 114:114:java.lang.String getValue(java.lang.String,android.content.Context):556:556 -> a + 115:115:java.lang.String getValue(java.lang.String,android.content.Context):553:553 -> a + 116:116:java.lang.String getValue(java.lang.String,android.content.Context):550:550 -> a + 117:117:java.lang.String getValue(java.lang.String,android.content.Context):547:547 -> a + 118:118:java.lang.String getValue(java.lang.String,android.content.Context):544:544 -> a + 119:119:java.lang.String getValue(java.lang.String,android.content.Context):541:541 -> a + 120:120:java.lang.String getValue(java.lang.String,android.content.Context):538:538 -> a + 121:121:java.lang.String getValue(java.lang.String,android.content.Context):535:535 -> a + 122:122:java.lang.String getValue(java.lang.String,android.content.Context):532:532 -> a + 123:123:java.lang.String getValue(java.lang.String,android.content.Context):529:529 -> a + 124:124:java.lang.String getValue(java.lang.String,android.content.Context):526:526 -> a + 125:125:java.lang.String getValue(java.lang.String,android.content.Context):523:523 -> a + 126:126:java.lang.String getValue(java.lang.String,android.content.Context):520:520 -> a + 127:127:java.lang.String getValue(java.lang.String,android.content.Context):517:517 -> a + 128:128:java.lang.String getValue(java.lang.String,android.content.Context):514:514 -> a + 129:129:java.lang.String getValue(java.lang.String,android.content.Context):511:511 -> a + 130:130:java.lang.String getValue(java.lang.String,android.content.Context):508:508 -> a + 131:131:java.lang.String getValue(java.lang.String,android.content.Context):500:500 -> a + 1:1:java.lang.String getDeviceBrand():140:140 -> b + 2:4:java.lang.Integer getAppVersionCode(android.content.Context):184:186 -> b + 5:10:java.lang.Integer getAppVersionCode(android.content.Context):185:190 -> b + 1:1:java.lang.String getBundleName(android.content.Context):35:35 -> c + 2:2:java.lang.String getDeviceCountry():86:86 -> c + 1:1:java.lang.String getDeviceDate():95:95 -> d + 2:6:android.net.ConnectivityManager getConnectivityManager(android.content.Context):206:210 -> d + 1:19:java.lang.String getDeviceLanguage():57:75 -> e + 20:23:java.lang.Long getFirstInstallDate(android.content.Context):106:109 -> e + 1:4:java.lang.Long getLastUpdateDate(android.content.Context):124:127 -> f + 5:5:java.lang.String getDeviceModel():153:153 -> f + 1:1:java.lang.String getDeviceTimezone():45:45 -> g + 2:7:java.lang.String getNetworkCountryIso(android.content.Context):308:313 -> g + 1:1:java.lang.String getOSVersion():202:202 -> h + 2:11:android.net.NetworkInfo getNetworkInfos(android.content.Context):325:334 -> h + 1:1:java.lang.String getPluginVersion():376:376 -> i + 2:24:java.lang.Integer getNetworkKind(android.content.Context):458:480 -> i + 25:25:java.lang.Integer getNetworkKind(android.content.Context):477:477 -> i + 1:6:java.lang.String getNetworkOperatorName(android.content.Context):287:292 -> j + 1:1:int getScreenHeight(android.content.Context):390:390 -> k + 1:1:int getScreenOrientation(android.content.Context):444:444 -> l + 1:12:android.graphics.Point getScreenSize(android.content.Context):419:430 -> m + 1:1:int getScreenWidth(android.content.Context):404:404 -> n + 1:6:java.lang.String getSimCountryIso(android.content.Context):266:271 -> o + 1:1:java.lang.String getSimOperator(android.content.Context):250:250 -> p + 1:6:java.lang.String getSimOperatorName(android.content.Context):231:236 -> q + 1:1:android.telephony.TelephonyManager getTelephonyManager(android.content.Context):214:214 -> r + 1:6:java.lang.Boolean isNetRoaming(android.content.Context):350:355 -> s +com.batch.android.core.SystemParameterHelper$1 -> com.batch.android.f.h0$a: + int[] $SwitchMap$com$batch$android$core$SystemParameterShortName -> a + 1:1:void ():506:506 -> +com.batch.android.core.SystemParameterShortName -> com.batch.android.f.i0: + com.batch.android.core.SystemParameterShortName DEVICE_TYPE -> h + com.batch.android.core.SystemParameterShortName SCREEN_HEIGHT -> G + com.batch.android.core.SystemParameterShortName BRAND -> f + com.batch.android.core.SystemParameterShortName PLUGIN_VERSION -> E + com.batch.android.core.SystemParameterShortName INSTALL_ID -> l + com.batch.android.core.SystemParameterShortName DEVICE_REGION -> j + com.batch.android.core.SystemParameterShortName NETWORK_KIND -> I + com.batch.android.core.SystemParameterShortName[] $VALUES -> J + com.batch.android.core.SystemParameterShortName FIRST_INSTALL_DATE -> d + com.batch.android.core.SystemParameterShortName CUSTOM_USER_ID -> C + com.batch.android.core.SystemParameterShortName BUNDLE_NAME -> b + com.batch.android.core.SystemParameterShortName API_LEVEL -> A + com.batch.android.core.SystemParameterShortName NETWORK_NAME -> x + com.batch.android.core.SystemParameterShortName SIM_OPERATOR -> v + com.batch.android.core.SystemParameterShortName ROAMING -> z + com.batch.android.core.SystemParameterShortName SESSION_ID -> p + java.lang.String shortName -> a + com.batch.android.core.SystemParameterShortName SERVER_ID -> n + com.batch.android.core.SystemParameterShortName OS_VERSION -> t + com.batch.android.core.SystemParameterShortName APPLICATION_VERSION -> r + com.batch.android.core.SystemParameterShortName SCREEN_ORIENTATION -> H + com.batch.android.core.SystemParameterShortName SDK_LEVEL -> g + com.batch.android.core.SystemParameterShortName SCREEN_WIDTH -> F + com.batch.android.core.SystemParameterShortName LAST_UPDATE_DATE -> e + com.batch.android.core.SystemParameterShortName DEVICE_DATE -> k + com.batch.android.core.SystemParameterShortName DEVICE_LANGUAGE -> i + com.batch.android.core.SystemParameterShortName BRIDGE_VERSION -> D + com.batch.android.core.SystemParameterShortName DEVICE_TIMEZONE -> c + com.batch.android.core.SystemParameterShortName MESSAGING_API_LEVEL -> B + com.batch.android.core.SystemParameterShortName SIM_COUNTRY -> w + com.batch.android.core.SystemParameterShortName SIM_OPERATOR_NAME -> u + com.batch.android.core.SystemParameterShortName NETWORK_COUNTRY -> y + com.batch.android.core.SystemParameterShortName ADVERTISING_ID -> o + com.batch.android.core.SystemParameterShortName DEVICE_INSTALL_DATE -> m + com.batch.android.core.SystemParameterShortName APPLICATION_CODE -> s + com.batch.android.core.SystemParameterShortName ADVERTISING_ID_OPTIN -> q + 1:84:void ():8:91 -> + 85:85:void ():7:7 -> + 1:2:void (java.lang.String,int,java.lang.String):103:104 -> + 1:7:com.batch.android.core.SystemParameterShortName fromShortValue(java.lang.String):119:125 -> a + 8:8:com.batch.android.core.SystemParameterShortName fromShortValue(java.lang.String):116:116 -> a + 1:1:com.batch.android.core.SystemParameterShortName valueOf(java.lang.String):7:7 -> valueOf + 1:1:com.batch.android.core.SystemParameterShortName[] values():7:7 -> values +com.batch.android.core.TLSSocketFactory -> com.batch.android.f.j0: + java.util.List enabledProtocols -> c + javax.net.ssl.SSLSocketFactory internalSSLSocketFactory -> a + java.lang.String[] protocols -> b + 1:10:void ():25:34 -> + 1:9:void ():38:46 -> + 1:2:java.net.Socket enableTLSOnSocket(java.net.Socket):92:93 -> a + 1:1:java.net.Socket createSocket():61:61 -> createSocket + 2:2:java.net.Socket createSocket(java.net.Socket,java.lang.String,int,boolean):66:66 -> createSocket + 3:3:java.net.Socket createSocket(java.lang.String,int):71:71 -> createSocket + 4:4:java.net.Socket createSocket(java.lang.String,int,java.net.InetAddress,int):77:77 -> createSocket + 5:5:java.net.Socket createSocket(java.net.InetAddress,int):82:82 -> createSocket + 6:6:java.net.Socket createSocket(java.net.InetAddress,int,java.net.InetAddress,int):88:88 -> createSocket + 1:1:java.lang.String[] getDefaultCipherSuites():51:51 -> getDefaultCipherSuites + 1:1:java.lang.String[] getSupportedCipherSuites():56:56 -> getSupportedCipherSuites +com.batch.android.core.TaskExecutor -> com.batch.android.f.k0: + java.util.Map futures -> a + android.content.Context context -> b + java.lang.String INTENT_WORK_FINISHED -> c + 1:1:void (android.content.Context,int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue):63:63 -> + 2:32:void (android.content.Context,int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue):38:68 -> + 33:33:void (android.content.Context,int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue):65:65 -> + 1:6:com.batch.android.core.TaskExecutor provide(android.content.Context):73:78 -> a + 7:48:java.util.concurrent.Future submit(com.batch.android.core.TaskRunnable):94:135 -> a + 49:49:java.util.concurrent.Future submit(com.batch.android.core.TaskRunnable):91:91 -> a + 50:52:boolean isBusy():144:146 -> a + 1:15:void afterExecute(java.lang.Runnable,java.lang.Throwable):159:173 -> afterExecute + 16:23:void afterExecute(java.lang.Runnable,java.lang.Throwable):166:173 -> afterExecute + 24:27:void afterExecute(java.lang.Runnable,java.lang.Throwable):171:174 -> afterExecute + 1:1:void execute(java.lang.Runnable):151:151 -> execute +com.batch.android.core.TaskRunnable -> com.batch.android.f.l0: + java.lang.String getTaskIdentifier() -> a +com.batch.android.core.URLBuilder -> com.batch.android.f.m0: + com.batch.android.core.URLBuilder$CryptorMode cryptorMode -> c + java.util.Map getParameters -> b + java.lang.String baseURL -> a + java.lang.String TAG -> d + 1:8:void (java.lang.String,com.batch.android.core.URLBuilder$CryptorMode,java.lang.String[]):44:51 -> + 9:9:void (java.lang.String,com.batch.android.core.URLBuilder$CryptorMode,java.lang.String[]):46:46 -> + 1:34:void parseURL(java.lang.String,java.lang.String[]):71:104 -> a + 35:36:void parseURL(java.lang.String,java.lang.String[]):91:92 -> a + 37:46:java.util.Map parseQuery(java.lang.String):115:124 -> a + 47:55:void addGETParameter(java.lang.String,java.lang.String):140:148 -> a + 56:56:void addGETParameter(java.lang.String,java.lang.String):145:145 -> a + 57:57:void addGETParameter(java.lang.String,java.lang.String):141:141 -> a + 58:58:java.net.URL build():172:172 -> a + 59:71:java.net.URL build(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):183:195 -> a + 72:76:void buildRawQuery(com.batch.android.core.PatternURLSorter,java.lang.StringBuilder):270:274 -> a + 77:77:void addParameter(java.lang.StringBuilder,java.lang.String,java.lang.String):285:285 -> a + 78:78:void cleanURL(java.lang.StringBuilder):294:294 -> a + 1:1:void removeGETParameter(java.lang.String):161:161 -> b + 2:2:void removeGETParameter(java.lang.String):158:158 -> b + 3:48:java.lang.String buildQuery(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):211:256 -> b + 49:55:java.lang.String buildQuery(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):245:251 -> b + 56:62:java.lang.String buildQuery(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):234:240 -> b + 63:65:java.lang.String buildQuery(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):227:229 -> b + 66:66:java.lang.String buildQuery(com.batch.android.core.PatternURLSorter,com.batch.android.core.Cryptor):208:208 -> b +com.batch.android.core.URLBuilder$1 -> com.batch.android.f.m0$a: + int[] $SwitchMap$com$batch$android$core$URLBuilder$CryptorMode -> a + 1:1:void ():223:223 -> +com.batch.android.core.URLBuilder$CryptorMode -> com.batch.android.f.m0$b: + com.batch.android.core.URLBuilder$CryptorMode VALUE -> c + com.batch.android.core.URLBuilder$CryptorMode ALL -> b + com.batch.android.core.URLBuilder$CryptorMode[] $VALUES -> e + int value -> a + com.batch.android.core.URLBuilder$CryptorMode EACH -> d + 1:11:void ():307:317 -> + 12:12:void ():303:303 -> + 1:2:void (java.lang.String,int,int):329:330 -> + 1:1:int getValue():339:339 -> a + 2:3:com.batch.android.core.URLBuilder$CryptorMode fromValue(int):349:350 -> a + 1:1:com.batch.android.core.URLBuilder$CryptorMode valueOf(java.lang.String):303:303 -> valueOf + 1:1:com.batch.android.core.URLBuilder$CryptorMode[] values():303:303 -> values +com.batch.android.core.Webservice -> com.batch.android.f.n0: + java.util.Map headers -> c + java.lang.String TAG -> h + com.batch.android.core.URLBuilder builder -> b + int DEFAULT_RETRY_AFTER -> j + int WEBSERVICE_ERROR_INVALID_CIPHER -> i + boolean isDowngradedCipher -> f + com.batch.android.module.OptOutModule optOutModule -> g + java.lang.String id -> a + com.batch.android.core.Webservice$RequestType type -> e + com.batch.android.core.Webservice$Interceptor wsInterceptor -> k + android.content.Context applicationContext -> d + 1:1:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):113:113 -> + 2:31:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):103:132 -> + 32:32:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):123:123 -> + 33:33:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):119:119 -> + 34:34:void (android.content.Context,com.batch.android.core.Webservice$RequestType,java.lang.String,java.lang.String[]):115:115 -> + java.lang.String getSpecificConnectTimeoutKey() -> A + java.lang.String getSpecificReadTimeoutKey() -> B + java.lang.String getSpecificRetryCountKey() -> C + 1:35:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():619:653 -> D + 36:67:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():649:680 -> D + 68:68:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():639:639 -> D + 69:69:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():631:631 -> D + 70:70:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():627:627 -> D + 71:71:com.batch.android.json.JSONObject getStandardResponseBodyIfValid():623:623 -> D + 1:11:com.batch.android.core.PatternURLSorter getURLSorter():268:278 -> E + java.lang.String getURLSorterPatternParameterKey() -> F + void setWsInterceptor(com.batch.android.core.Webservice$Interceptor) -> a + 1:8:void addGetParameter(java.lang.String,java.lang.String):166:173 -> a + 9:11:java.lang.String[] addBatchApiKey(java.lang.String[]):183:185 -> a + 12:31:void sendRetrySignal(com.batch.android.core.Webservice$WebserviceError):564:583 -> a + 32:32:void sendRetrySignal(com.batch.android.core.Webservice$WebserviceError):580:580 -> a + 33:57:void sendRetrySignal(com.batch.android.core.Webservice$WebserviceError):570:594 -> a + 58:58:void onRetry(com.batch.android.core.WebserviceErrorCause):604:604 -> a + 59:75:com.batch.android.core.Webservice$WebserviceError$Reason getResponseErrorCause(int):722:738 -> a + 76:78:java.lang.String encode(java.lang.String):749:751 -> a + 79:86:byte[] buildPostParameters(com.batch.android.post.PostDataProvider):875:882 -> a + 87:114:void addRequestSignatures(java.net.HttpURLConnection,byte[]):895:922 -> a + 115:148:java.lang.String getSignatureBody(java.net.HttpURLConnection,java.util.List):926:959 -> a + 149:152:java.lang.String formatDate(java.util.Date):1199:1202 -> a + boolean isResponseValid(int) -> b + 1:14:void addDefaultHeaders():214:227 -> b + void addDefaultParameters() -> c + boolean shouldRetry(int) -> c + 1:3:void addHeaders():235:237 -> d + 1:7:void addParameters():147:153 -> e + 1:72:java.net.HttpURLConnection buildConnection():781:852 -> f + 73:73:java.net.HttpURLConnection buildConnection():850:850 -> f + 1:5:void buildParameters():861:865 -> g + 1:3:java.net.URL buildURL():761:763 -> h + boolean canBypassOptOut() -> i + 1:2:void enabledDowngradedMode():889:890 -> j + 1:110:byte[] executeRequest():417:526 -> k + 111:136:byte[] executeRequest():501:526 -> k + 137:210:byte[] executeRequest():453:526 -> k + 211:211:byte[] executeRequest():447:447 -> k + 212:296:byte[] executeRequest():442:526 -> k + 297:323:byte[] executeRequest():511:537 -> k + 324:337:byte[] executeRequest():515:528 -> k + 1:5:com.batch.android.json.JSONObject getBasicJsonResponseBody():691:695 -> l + 1:10:int getConnectTimeout():971:980 -> m + 11:11:int getConnectTimeout():979:979 -> m + 1:14:com.batch.android.core.Cryptor getCryptor():296:309 -> n + java.lang.String getCryptorModeParameterKey() -> o + java.lang.String getCryptorTypeParameterKey() -> p + 1:16:com.batch.android.core.URLBuilder$CryptorMode getGetCryptorMode():325:340 -> q + java.util.Map getHeaders() -> r + 1:9:int getMaxRetryCount():1023:1031 -> s + java.util.Map getParameters() -> t + 1:14:com.batch.android.core.WebserviceCryptor getPostCryptor():356:369 -> u + java.lang.String getPostCryptorTypeParameterKey() -> v + com.batch.android.post.PostDataProvider getPostDataProvider() -> w + 1:14:com.batch.android.core.WebserviceCryptor getReadCryptor():385:398 -> x + java.lang.String getReadCryptorTypeParameterKey() -> y + 1:9:int getReadTimeout():998:1006 -> z +com.batch.android.core.Webservice$1 -> com.batch.android.f.n0$a: + int[] $SwitchMap$com$batch$android$core$Webservice$WebserviceError$Reason -> a + 1:1:void ():567:567 -> +com.batch.android.core.Webservice$Interceptor -> com.batch.android.f.n0$b: + java.net.HttpURLConnection onBuildHttpConnection(java.net.HttpURLConnection) -> a + java.net.URL onBuildURL(java.net.URL) -> a + void onError(java.lang.String,java.net.HttpURLConnection,com.batch.android.core.Webservice$WebserviceError) -> a + void onPreConnect(java.lang.String,java.net.HttpURLConnection,byte[],long) -> a + void onSuccess(java.lang.String,java.net.HttpURLConnection,byte[],long) -> b +com.batch.android.core.Webservice$RequestType -> com.batch.android.f.n0$c: + com.batch.android.core.Webservice$RequestType[] $VALUES -> c + com.batch.android.core.Webservice$RequestType POST -> b + com.batch.android.core.Webservice$RequestType GET -> a + 1:6:void ():1051:1056 -> + 7:7:void ():1047:1047 -> + 1:1:void (java.lang.String,int):1047:1047 -> + 1:1:com.batch.android.core.Webservice$RequestType valueOf(java.lang.String):1047:1047 -> valueOf + 1:1:com.batch.android.core.Webservice$RequestType[] values():1047:1047 -> values +com.batch.android.core.Webservice$WebserviceError -> com.batch.android.f.n0$d: + com.batch.android.core.Webservice$WebserviceError$Reason reason -> a + int retryAfter -> b + 1:1:void (com.batch.android.core.Webservice$WebserviceError$Reason,java.lang.Throwable):1090:1090 -> + 2:16:void (com.batch.android.core.Webservice$WebserviceError$Reason,java.lang.Throwable):1081:1095 -> + 17:17:void (com.batch.android.core.Webservice$WebserviceError$Reason,java.lang.Throwable):1092:1092 -> + 18:18:void (com.batch.android.core.Webservice$WebserviceError$Reason):1102:1102 -> + 19:45:void (com.batch.android.core.Webservice$WebserviceError$Reason):1081:1107 -> + 46:46:void (com.batch.android.core.Webservice$WebserviceError$Reason):1104:1104 -> + 1:1:com.batch.android.core.Webservice$WebserviceError$Reason access$000(com.batch.android.core.Webservice$WebserviceError):1063:1063 -> a + 2:2:com.batch.android.core.Webservice$WebserviceError$Reason getReason():1118:1118 -> a + 3:3:void setRetryAfter(int):1186:1186 -> a + 1:1:int getRetryAfterInMillis():1179:1179 -> b +com.batch.android.core.Webservice$WebserviceError$Reason -> com.batch.android.f.n0$d$a: + com.batch.android.core.Webservice$WebserviceError$Reason NETWORK_ERROR -> a + com.batch.android.core.Webservice$WebserviceError$Reason NOT_FOUND_ERROR -> d + com.batch.android.core.Webservice$WebserviceError$Reason INVALID_API_KEY -> e + com.batch.android.core.Webservice$WebserviceError$Reason SERVER_ERROR -> b + com.batch.android.core.Webservice$WebserviceError$Reason TOO_MANY_REQUESTS -> c + com.batch.android.core.Webservice$WebserviceError$Reason FORBIDDEN -> h + com.batch.android.core.Webservice$WebserviceError$Reason SDK_OPTED_OUT -> i + com.batch.android.core.Webservice$WebserviceError$Reason DEACTIVATED_API_KEY -> f + com.batch.android.core.Webservice$WebserviceError$Reason UNEXPECTED_ERROR -> g + com.batch.android.core.Webservice$WebserviceError$Reason[] $VALUES -> j + 1:41:void ():1131:1171 -> + 42:42:void ():1127:1127 -> + 1:1:void (java.lang.String,int):1127:1127 -> + 1:1:com.batch.android.core.Webservice$WebserviceError$Reason valueOf(java.lang.String):1127:1127 -> valueOf + 1:1:com.batch.android.core.Webservice$WebserviceError$Reason[] values():1127:1127 -> values +com.batch.android.core.WebserviceCryptor -> com.batch.android.f.o0: + com.batch.android.core.CryptorFactory$CryptorType cryptorType -> a + java.lang.String PRIVATE_KEY_PART_V2 -> c + java.lang.String PRIVATE_KEY_PART -> b + java.lang.String VERSION -> d + 1:1:void (int):40:40 -> + 2:7:void (com.batch.android.core.CryptorFactory$CryptorType):46:51 -> + 8:8:void (com.batch.android.core.CryptorFactory$CryptorType):48:48 -> + 1:10:byte[] decryptData(byte[],com.batch.android.core.Webservice,java.net.HttpURLConnection):69:78 -> a + 11:11:byte[] decryptData(byte[],com.batch.android.core.Webservice,java.net.HttpURLConnection):75:75 -> a + 12:12:byte[] decryptData(byte[],com.batch.android.core.Webservice,java.net.HttpURLConnection):71:71 -> a + 13:13:byte[] decryptData(byte[],com.batch.android.core.Webservice,java.net.HttpURLConnection):66:66 -> a + 14:19:byte[] decryptDataForVersion(java.lang.String,java.lang.String,java.lang.String,com.batch.android.core.Webservice):93:98 -> a + 20:29:byte[] encryptData(byte[],com.batch.android.core.Webservice):113:122 -> a + 30:33:byte[] buildPrivateKey(com.batch.android.core.Webservice):137:140 -> a + 34:34:java.lang.String buildKey(java.lang.String,com.batch.android.core.Webservice):167:167 -> a + 35:43:java.lang.String randomChars(int):197:205 -> a + 1:4:byte[] buildPrivateKeyV2(com.batch.android.core.Webservice):153:156 -> b + 5:5:java.lang.String buildKeyV2(java.lang.String,com.batch.android.core.Webservice):178:178 -> b + 1:1:java.lang.String generatePublicKey(java.lang.String,com.batch.android.core.Webservice):187:187 -> c +com.batch.android.core.WebserviceErrorCause -> com.batch.android.f.p0: + com.batch.android.core.WebserviceErrorCause PARSING_ERROR -> a + com.batch.android.core.WebserviceErrorCause[] $VALUES -> f + com.batch.android.core.WebserviceErrorCause SSL_HANDSHAKE_FAILURE -> d + com.batch.android.core.WebserviceErrorCause OTHER -> e + com.batch.android.core.WebserviceErrorCause SERVER_ERROR -> b + com.batch.android.core.WebserviceErrorCause NETWORK_TIMEOUT -> c + 1:21:void ():11:31 -> + 22:22:void ():7:7 -> + 1:1:void (java.lang.String,int):7:7 -> + 1:1:com.batch.android.core.WebserviceErrorCause valueOf(java.lang.String):7:7 -> valueOf + 1:1:com.batch.android.core.WebserviceErrorCause[] values():7:7 -> values +com.batch.android.core.WebserviceSignature -> com.batch.android.f.q0: + java.lang.String TAG -> a + java.lang.String PRIVATE_SIGNATURE_KEY_PART -> b + 1:1:void ():9:9 -> + 1:3:java.lang.String encryptSignatureData(java.lang.String):20:22 -> a + 4:11:java.lang.String encryptSignatureData(java.lang.String):21:28 -> a + 12:17:byte[] buildPrivateSignatureKey():42:47 -> a + 18:20:byte[] encryptHMAC(java.security.Key,byte[]):58:60 -> a +com.batch.android.core.stores.GooglePlayStoreApplication -> com.batch.android.g.a: + 1:1:void ():10:10 -> + 1:7:void open(android.content.Context):15:21 -> a +com.batch.android.core.stores.HuaweiAppGalleryApplication -> com.batch.android.g.b: + 1:1:void ():10:10 -> + 1:7:void open(android.content.Context):15:21 -> a +com.batch.android.core.stores.StoreApplication -> com.batch.android.g.c: + void open(android.content.Context) -> a +com.batch.android.core.stores.StoreApplicationFactory -> com.batch.android.g.d: + 1:1:void ():10:10 -> + 1:5:com.batch.android.core.stores.StoreApplication getMainStore(android.content.Context):16:20 -> a + 1:1:boolean isHuaweiAppGalleryInstalled(android.content.Context):30:30 -> b + 1:1:boolean isPlayStoreInstalled(android.content.Context):26:26 -> c +com.batch.android.date.BatchDate -> com.batch.android.h.a: + long timestamp -> a + 1:2:void (long):9:10 -> + 1:1:void setTime(long):14:14 -> a + 2:2:long getTime():18:18 -> a + 3:4:int compareTo(com.batch.android.date.BatchDate):42:43 -> a + 1:1:int compareTo(java.lang.Object):5:5 -> compareTo + 1:7:boolean equals(java.lang.Object):26:32 -> equals + 1:1:int hashCode():37:37 -> hashCode +com.batch.android.date.TimezoneAwareDate -> com.batch.android.h.b: + 1:1:void ():8:8 -> + 2:2:void (long):12:12 -> + 1:1:long getTime():17:17 -> a +com.batch.android.date.UTCDate -> com.batch.android.h.c: + 1:1:void ():6:6 -> + 2:2:void (long):10:10 -> +com.batch.android.debug.BatchDebugActivity -> com.batch.android.debug.BatchDebugActivity: + int LOCAL_CAMPAIGN_DEBUG_FRAGMENT -> f + int USER_DATA_DEBUG_FRAGMENT -> d + int LOCAL_CAMPAIGNS_DEBUG_FRAGMENT -> e + int MAIN_DEBUG_FRAGMENT -> b + int IDENTIFIER_DEBUG_FRAGMENT -> c + androidx.fragment.app.Fragment[] fragments -> a + 1:9:void ():21:29 -> + 1:18:void switchFragment(int,boolean,java.lang.String):32:49 -> a + 19:19:void switchFragment(int,boolean,java.lang.String):45:45 -> a + 20:20:void switchFragment(int,boolean,java.lang.String):42:42 -> a + 21:21:void switchFragment(int,boolean,java.lang.String):39:39 -> a + 22:50:void switchFragment(int,boolean,java.lang.String):36:64 -> a + 51:51:void switchFragment(int,boolean):70:70 -> a + 52:52:void onMenuSelected(int):75:75 -> a + 53:53:void onCampaignMenuSelected(java.lang.String):80:80 -> a + 1:7:void onCreate(android.os.Bundle):85:91 -> onCreate + 1:2:void onDestroy():108:109 -> onDestroy + 1:2:void onStart():96:97 -> onStart + 1:2:void onStop():102:103 -> onStop +com.batch.android.debug.FindMyInstallationHelper -> com.batch.android.i.a: + java.util.List timestamps -> a + boolean isEnabled -> e + int MAX_DELAY_BETWEEN_FOREGROUNDS -> d + java.lang.String TAG -> b + int MIN_FOREGROUND -> c + 1:24:void ():20:43 -> + 1:9:void notifyForeground():49:57 -> a + 10:27:void copyInstallationIDToClipboard(android.content.Context):87:104 -> a + 28:32:void copyInstallationIDToClipboard(android.content.Context):102:106 -> a + 1:5:boolean shouldCopyInstallationID():69:73 -> b +com.batch.android.debug.OnMenuSelectedListener -> com.batch.android.i.b: + void onCampaignMenuSelected(java.lang.String) -> a + void onMenuSelected(int) -> a +com.batch.android.debug.adapter.CollectionAdapter -> com.batch.android.j.a: + android.content.Context context -> b + android.view.LayoutInflater inflater -> a + java.util.List tagCollections -> c + 1:4:void (android.content.Context):26:29 -> + 1:1:com.batch.android.debug.adapter.CollectionAdapter$TagCollection getItem(int):39:39 -> a + 2:14:void add(java.lang.String,java.util.Set):69:81 -> a + 15:16:void clear():85:86 -> a + 1:1:int getCount():34:34 -> getCount + 1:1:java.lang.Object getItem(int):18:18 -> getItem + 1:11:android.view.View getView(int,android.view.View,android.view.ViewGroup):54:64 -> getView +com.batch.android.debug.adapter.CollectionAdapter$TagCollection -> com.batch.android.j.a$a: + java.lang.String name -> a + com.batch.android.debug.adapter.CollectionAdapter this$0 -> c + android.widget.ArrayAdapter tagAdapter -> b + 1:4:void (com.batch.android.debug.adapter.CollectionAdapter,java.lang.String,android.widget.ArrayAdapter):94:97 -> + 1:1:java.lang.String getName():101:101 -> a + 1:1:android.widget.ArrayAdapter getTagAdapter():105:105 -> b +com.batch.android.debug.fragment.IdentifierDebugFragment -> com.batch.android.k.a: + android.widget.TextView sdkVersion -> a + android.widget.TextView advertisingId -> c + android.widget.TextView installId -> b + android.widget.TextView pushToken -> d + 1:1:void ():18:18 -> + 1:7:java.lang.String getShareString():31:37 -> a + 8:8:java.lang.String getShareString():34:34 -> a + 9:24:java.lang.String getShareString():33:48 -> a + 25:25:java.lang.String getShareString():45:45 -> a + 26:39:java.lang.String getShareString():44:57 -> a + 40:40:java.lang.String getShareString():54:54 -> a + 41:56:java.lang.String getShareString():53:68 -> a + 57:57:java.lang.String getShareString():66:66 -> a + 58:71:java.lang.String getShareString():65:78 -> a + 72:72:java.lang.String getShareString():75:75 -> a + 73:73:java.lang.String getShareString():74:74 -> a + 1:1:com.batch.android.debug.fragment.IdentifierDebugFragment newInstance():26:26 -> b + 1:17:void onActivityCreated(android.os.Bundle):106:122 -> onActivityCreated + 1:6:void onClick(android.view.View):128:133 -> onClick + 1:8:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):93:100 -> onCreateView +com.batch.android.debug.fragment.LocalCampaignDebugFragment -> com.batch.android.k.b: + android.widget.TextView token -> a + java.lang.String CAMPAIGN_TOKEN_KEY -> h + android.widget.TextView endDate -> c + android.widget.TextView startDate -> b + android.widget.TextView gracePeriod -> e + android.widget.TextView capping -> d + android.widget.TextView trigger -> f + com.batch.android.localcampaigns.CampaignManager campaignManager -> g + 1:1:void ():21:21 -> + 1:6:com.batch.android.debug.fragment.LocalCampaignDebugFragment newInstance(java.lang.String,com.batch.android.localcampaigns.CampaignManager):35:40 -> a + 7:7:void setCampaignManager(com.batch.android.localcampaigns.CampaignManager):45:45 -> a + 8:11:com.batch.android.localcampaigns.model.LocalCampaign getCurrentCampaign():49:52 -> a + 12:13:java.lang.String formatDate(com.batch.android.date.BatchDate):61:62 -> a + 14:46:void displayCampaign(com.batch.android.localcampaigns.model.LocalCampaign):187:219 -> a + 1:8:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):66:73 -> b + 9:9:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):71:71 -> b + 10:23:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):70:83 -> b + 24:24:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):80:80 -> b + 25:40:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):79:94 -> b + 41:41:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):91:91 -> b + 42:55:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):90:103 -> b + 56:56:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):100:100 -> b + 57:72:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):99:114 -> b + 73:73:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):111:111 -> b + 74:87:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):110:123 -> b + 88:88:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):120:120 -> b + 89:104:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):119:134 -> b + 105:105:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):131:131 -> b + 106:120:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):130:144 -> b + 121:121:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):141:141 -> b + 122:137:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):140:155 -> b + 138:138:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):151:151 -> b + 139:159:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):150:170 -> b + 160:160:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):167:167 -> b + 161:174:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):166:179 -> b + 175:175:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):176:176 -> b + 176:176:java.lang.String getShareString(com.batch.android.localcampaigns.model.LocalCampaign):175:175 -> b + 1:5:void onActivityCreated(android.os.Bundle):244:248 -> onActivityCreated + 1:8:void onClick(android.view.View):254:261 -> onClick + 1:9:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):230:238 -> onCreateView +com.batch.android.debug.fragment.LocalCampaignsDebugFragment -> com.batch.android.k.c: + com.batch.android.webservice.listener.LocalCampaignsWebserviceListener webserviceListener -> f + java.lang.String TAG -> g + android.widget.TextView title -> a + com.batch.android.debug.OnMenuSelectedListener listener -> d + android.widget.ListView campaignList -> b + android.widget.ArrayAdapter campaignAdapter -> c + com.batch.android.localcampaigns.CampaignManager campaignManager -> e + 1:13:void ():32:44 -> + 1:1:void access$000(com.batch.android.debug.fragment.LocalCampaignsDebugFragment):32:32 -> a + 2:3:com.batch.android.debug.fragment.LocalCampaignsDebugFragment newInstance(com.batch.android.localcampaigns.CampaignManager):67:68 -> a + 4:24:void loadLocalCampaigns():91:111 -> a + 25:25:void lambda$onCreateView$0(android.widget.AdapterView,android.view.View,int,long):135:135 -> a + 26:26:void lambda$onCreateView$1(android.view.View):140:140 -> a + 1:1:void setCampaignManager(com.batch.android.localcampaigns.CampaignManager):73:73 -> b + 2:10:void refreshLocalCampaigns():78:86 -> b + 1:2:void onActivityCreated(android.os.Bundle):147:148 -> onActivityCreated + 1:5:void onAttach(android.content.Context):116:120 -> onAttach + 1:9:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):131:139 -> onCreateView +com.batch.android.debug.fragment.LocalCampaignsDebugFragment$1 -> com.batch.android.k.c$a: + com.batch.android.debug.fragment.LocalCampaignsDebugFragment this$0 -> b + com.batch.android.webservice.listener.LocalCampaignsWebserviceListener sdkImpl -> a + 1:2:void (com.batch.android.debug.fragment.LocalCampaignsDebugFragment):44:45 -> + 1:4:void onSuccess(java.util.List):49:52 -> a + 5:8:void onError(com.batch.android.FailReason):58:61 -> a + 9:9:void lambda$onError$1():61:61 -> a + 1:1:void lambda$onSuccess$0():52:52 -> b +com.batch.android.debug.fragment.MainDebugFragment -> com.batch.android.k.d: + com.batch.android.debug.OnMenuSelectedListener listener -> a + 1:1:void ():15:15 -> + 1:1:com.batch.android.debug.fragment.MainDebugFragment newInstance():20:20 -> a + 2:2:void lambda$onCreateView$0(android.view.View):43:43 -> a + 1:1:void lambda$onCreateView$1(android.view.View):48:48 -> b + 1:1:void lambda$onCreateView$2(android.view.View):53:53 -> c + 1:5:void onAttach(android.content.Context):25:29 -> onAttach + 1:13:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):40:52 -> onCreateView +com.batch.android.debug.fragment.UserDataDebugFragment -> com.batch.android.k.e: + android.widget.TextView customUserId -> a + com.batch.android.debug.adapter.CollectionAdapter collectionAdapter -> e + android.widget.ListView attributeList -> b + android.widget.ArrayAdapter attributeAdapter -> d + android.widget.ListView collectionList -> c + 1:1:void ():25:25 -> + 1:1:android.widget.ArrayAdapter access$000(com.batch.android.debug.fragment.UserDataDebugFragment):25:25 -> a + 2:2:java.lang.String access$100(com.batch.android.debug.fragment.UserDataDebugFragment,com.batch.android.BatchUserAttribute):25:25 -> a + 3:7:java.lang.String formatAttribute(com.batch.android.BatchUserAttribute):39:43 -> a + 8:18:void loadAttributes():47:57 -> a + 19:19:void loadAttributes():56:56 -> a + 1:1:com.batch.android.debug.adapter.CollectionAdapter access$200(com.batch.android.debug.fragment.UserDataDebugFragment):25:25 -> b + 2:11:void loadCollections():78:87 -> b + 12:12:void loadCollections():86:86 -> b + 1:1:com.batch.android.debug.fragment.UserDataDebugFragment newInstance():35:35 -> c + 1:11:void onActivityCreated(android.os.Bundle):122:132 -> onActivityCreated + 1:4:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):113:116 -> onCreateView +com.batch.android.debug.fragment.UserDataDebugFragment$1 -> com.batch.android.k.e$a: + com.batch.android.debug.fragment.UserDataDebugFragment this$0 -> a + 1:1:void (com.batch.android.debug.fragment.UserDataDebugFragment):58:58 -> + 1:2:void onError():70:71 -> onError + 1:5:void onSuccess(java.util.Map):61:65 -> onSuccess +com.batch.android.debug.fragment.UserDataDebugFragment$2 -> com.batch.android.k.e$b: + com.batch.android.debug.fragment.UserDataDebugFragment this$0 -> a + 1:1:void (com.batch.android.debug.fragment.UserDataDebugFragment):88:88 -> + 1:2:void onError():99:100 -> onError + 1:4:void onSuccess(java.util.Map):91:94 -> onSuccess +com.batch.android.debug.view.NestedListView -> com.batch.android.debug.view.NestedListView: + android.view.ViewGroup$LayoutParams layoutParams -> b + int MAXIMUM_LIST_ITEMS_VIEWABLE -> c + int listViewTouchAction -> a + 1:5:void (android.content.Context,android.util.AttributeSet):19:23 -> + 1:32:void onMeasure(int,int):40:71 -> onMeasure + 1:3:void onScroll(android.widget.AbsListView,int,int,int):28:30 -> onScroll + 1:3:boolean onTouch(android.view.View,android.view.MotionEvent):76:78 -> onTouch +com.batch.android.di.DI -> com.batch.android.l.a: + java.util.Map singletonInstances -> a + com.batch.android.di.DI instance -> c + java.lang.String TAG -> b + 1:2:void ():29:30 -> + 1:1:void clear():34:34 -> a + 2:3:java.lang.Object getSingletonInstance(java.lang.Class):46:47 -> a + 4:4:void addSingletonInstance(java.lang.Class,java.lang.Object):61:61 -> a + 1:4:com.batch.android.di.DI getInstance():15:18 -> b + 1:2:void reset():22:23 -> c +com.batch.android.di.providers.ActionModuleProvider -> com.batch.android.m.a: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.ActionModule get():14:19 -> a + 1:1:com.batch.android.module.ActionModule getSingleton():25:25 -> b +com.batch.android.di.providers.ActionOutputProvider -> com.batch.android.m.b: + 1:1:void ():10:10 -> + 1:1:com.batch.android.localcampaigns.output.ActionOutput get(com.batch.android.json.JSONObject):13:13 -> a +com.batch.android.di.providers.AdvertisingIDProvider -> com.batch.android.m.c: + 1:1:void ():11:11 -> + 1:6:com.batch.android.AdvertisingID get():14:19 -> a + 1:1:com.batch.android.AdvertisingID getSingleton():25:25 -> b +com.batch.android.di.providers.BatchModuleMasterProvider -> com.batch.android.m.d: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.BatchModuleMaster get():14:19 -> a + 1:1:com.batch.android.module.BatchModuleMaster getSingleton():25:25 -> b +com.batch.android.di.providers.BatchNotificationChannelsManagerProvider -> com.batch.android.m.e: + 1:1:void ():11:11 -> + 1:6:com.batch.android.BatchNotificationChannelsManager get():14:19 -> a + 1:1:com.batch.android.BatchNotificationChannelsManager getSingleton():25:25 -> b +com.batch.android.di.providers.CampaignManagerProvider -> com.batch.android.m.f: + 1:1:void ():11:11 -> + 1:6:com.batch.android.localcampaigns.CampaignManager get():14:19 -> a + 1:1:com.batch.android.localcampaigns.CampaignManager getSingleton():25:25 -> b +com.batch.android.di.providers.DisplayReceiptModuleProvider -> com.batch.android.m.g: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.DisplayReceiptModule get():14:19 -> a + 1:1:com.batch.android.module.DisplayReceiptModule getSingleton():25:25 -> b +com.batch.android.di.providers.EmbeddedBannerContainerProvider -> com.batch.android.m.h: + 1:1:void ():13:13 -> + 1:1:com.batch.android.messaging.view.formats.EmbeddedBannerContainer get(android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):18:18 -> a +com.batch.android.di.providers.EventDispatcherModuleProvider -> com.batch.android.m.i: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.EventDispatcherModule get():14:19 -> a + 1:1:com.batch.android.module.EventDispatcherModule getSingleton():25:25 -> b +com.batch.android.di.providers.InboxDatasourceProvider -> com.batch.android.m.j: + 1:1:void ():12:12 -> + 1:6:com.batch.android.inbox.InboxDatasource get(android.content.Context):15:20 -> a + 7:7:com.batch.android.inbox.InboxDatasource getSingleton():26:26 -> a +com.batch.android.di.providers.InboxFetcherInternalProvider -> com.batch.android.m.k: + 1:1:void ():11:11 -> + 1:1:com.batch.android.inbox.InboxFetcherInternal get(android.content.Context,java.lang.String):14:14 -> a + 2:2:com.batch.android.inbox.InboxFetcherInternal get(android.content.Context,java.lang.String,boolean):20:20 -> a + 3:3:com.batch.android.inbox.InboxFetcherInternal get(android.content.Context,java.lang.String,java.lang.String):26:26 -> a + 4:4:com.batch.android.inbox.InboxFetcherInternal get(android.content.Context,java.lang.String,java.lang.String,boolean):32:32 -> a +com.batch.android.di.providers.KVUserPreferencesStorageProvider -> com.batch.android.m.l: + 1:1:void ():12:12 -> + 1:6:com.batch.android.core.KVUserPreferencesStorage get(android.content.Context):15:20 -> a + 7:7:com.batch.android.core.KVUserPreferencesStorage getSingleton():26:26 -> a +com.batch.android.di.providers.LandingOutputProvider -> com.batch.android.m.m: + 1:1:void ():10:10 -> + 1:1:com.batch.android.localcampaigns.output.LandingOutput get(com.batch.android.json.JSONObject):13:13 -> a +com.batch.android.di.providers.LocalBroadcastManagerProvider -> com.batch.android.m.n: + 1:1:void ():12:12 -> + 1:6:com.batch.android.compat.LocalBroadcastManager get(android.content.Context):15:20 -> a + 7:7:com.batch.android.compat.LocalBroadcastManager getSingleton():26:26 -> a +com.batch.android.di.providers.LocalCampaignsModuleProvider -> com.batch.android.m.o: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.LocalCampaignsModule get():14:19 -> a + 1:1:com.batch.android.module.LocalCampaignsModule getSingleton():25:25 -> b +com.batch.android.di.providers.LocalCampaignsWebserviceListenerImplProvider -> com.batch.android.m.p: + 1:1:void ():9:9 -> + 1:1:com.batch.android.webservice.listener.impl.LocalCampaignsWebserviceListenerImpl get():12:12 -> a +com.batch.android.di.providers.MessagingAnalyticsDelegateProvider -> com.batch.android.m.q: + 1:1:void ():11:11 -> + 1:1:com.batch.android.MessagingAnalyticsDelegate get(com.batch.android.messaging.model.Message,com.batch.android.BatchMessage):14:14 -> a +com.batch.android.di.providers.MessagingModuleProvider -> com.batch.android.m.r: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.MessagingModule get():14:19 -> a + 1:1:com.batch.android.module.MessagingModule getSingleton():25:25 -> b +com.batch.android.di.providers.MetricManagerProvider -> com.batch.android.m.s: + 1:1:void ():11:11 -> + 1:6:com.batch.android.metrics.MetricManager get():14:19 -> a + 1:1:com.batch.android.metrics.MetricManager getSingleton():25:25 -> b +com.batch.android.di.providers.ObjectUserPreferencesStorageProvider -> com.batch.android.m.t: + 1:1:void ():12:12 -> + 1:6:com.batch.android.core.ObjectUserPreferencesStorage get(android.content.Context):15:20 -> a + 7:7:com.batch.android.core.ObjectUserPreferencesStorage getSingleton():26:26 -> a +com.batch.android.di.providers.OptOutModuleProvider -> com.batch.android.m.u: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.OptOutModule get():14:19 -> a + 1:1:com.batch.android.module.OptOutModule getSingleton():25:25 -> b +com.batch.android.di.providers.ParametersProvider -> com.batch.android.m.v: + 1:1:void ():12:12 -> + 1:6:com.batch.android.core.Parameters get(android.content.Context):15:20 -> a + 7:7:com.batch.android.core.Parameters getSingleton():26:26 -> a +com.batch.android.di.providers.PushModuleProvider -> com.batch.android.m.w: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.PushModule get():14:19 -> a + 1:1:com.batch.android.module.PushModule getSingleton():25:25 -> b +com.batch.android.di.providers.RuntimeManagerProvider -> com.batch.android.m.x: + 1:1:void ():11:11 -> + 1:6:com.batch.android.runtime.RuntimeManager get():14:19 -> a + 1:1:com.batch.android.runtime.RuntimeManager getSingleton():25:25 -> b +com.batch.android.di.providers.SQLUserDatasourceProvider -> com.batch.android.m.y: + 1:1:void ():12:12 -> + 1:6:com.batch.android.user.SQLUserDatasource get(android.content.Context):15:20 -> a + 7:7:com.batch.android.user.SQLUserDatasource getSingleton():26:26 -> a +com.batch.android.di.providers.SecureDateProviderProvider -> com.batch.android.m.z: + 1:1:void ():11:11 -> + 1:6:com.batch.android.core.SecureDateProvider get():14:19 -> a + 1:1:com.batch.android.core.SecureDateProvider getSingleton():25:25 -> b +com.batch.android.di.providers.TaskExecutorProvider -> com.batch.android.m.a0: + 1:1:void ():12:12 -> + 1:6:com.batch.android.core.TaskExecutor get(android.content.Context):15:20 -> a + 7:7:com.batch.android.core.TaskExecutor getSingleton():26:26 -> a +com.batch.android.di.providers.TrackerModuleProvider -> com.batch.android.m.b0: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.TrackerModule get():14:19 -> a + 1:1:com.batch.android.module.TrackerModule getSingleton():25:25 -> b +com.batch.android.di.providers.UserModuleProvider -> com.batch.android.m.c0: + 1:1:void ():11:11 -> + 1:6:com.batch.android.module.UserModule get():14:19 -> a + 1:1:com.batch.android.module.UserModule getSingleton():25:25 -> b +com.batch.android.di.providers.WebserviceMetricsProvider -> com.batch.android.m.d0: + 1:1:void ():11:11 -> + 1:6:com.batch.android.WebserviceMetrics get():14:19 -> a + 1:1:com.batch.android.WebserviceMetrics getSingleton():25:25 -> b +com.batch.android.displayreceipt.CacheHelper -> com.batch.android.n.a: + long MAX_AGE_FROM_CACHE -> e + java.lang.String TAG -> a + int MAX_READ_RECEIPT_FROM_CACHE -> d + java.lang.String CACHE_FILE_FORMAT -> c + java.lang.String CACHE_DIR -> b + 1:1:void ():21:21 -> + 1:2:java.lang.String generateNewFilename(long):48:49 -> a + 3:7:java.lang.Long getTimestampFromFilename(java.lang.String):54:58 -> a + 8:14:java.io.File write(android.content.Context,long,byte[]):82:88 -> a + 15:23:boolean write(java.io.File,byte[]):96:96 -> a + 26:26:boolean write(java.io.File,byte[]):99:99 -> a + 27:39:boolean deleteDirectory(java.io.File):114:126 -> a + 40:41:boolean deleteAll(android.content.Context):136:137 -> a + 42:55:java.util.List getCachedFiles(android.content.Context,boolean):150:163 -> a + 56:78:java.util.List filterCachedFiles(java.io.File[]):171:193 -> a + 79:79:int lambda$filterCachedFiles$0(java.util.Map$Entry,java.util.Map$Entry):189:189 -> a + 1:3:java.io.File getCacheDir(android.content.Context):38:40 -> b + 4:9:byte[] read(java.io.File):68:73 -> b + 10:13:byte[] read(java.io.File):71:74 -> b +com.batch.android.displayreceipt.DisplayReceipt -> com.batch.android.n.b: + java.lang.String TAG -> f + java.util.Map od -> d + long timestamp -> a + java.util.Map ed -> e + boolean replay -> b + int sendAttempt -> c + 1:6:void (long,boolean,int,java.util.Map,java.util.Map):28:33 -> + 1:1:void setReplay(boolean):37:37 -> a + 2:2:java.util.Map getEd():49:49 -> a + 3:4:byte[] packAndWrite(java.io.File):65:66 -> a + 5:5:void writeTo(com.batch.android.msgpack.core.MessageBufferPacker):73:73 -> a + 6:20:void pack(com.batch.android.msgpack.core.MessageBufferPacker,long,boolean,int,java.util.Map,java.util.Map):84:98 -> a + 21:26:byte[] pack(long,boolean,int,java.util.Map,java.util.Map):108:108 -> a + 31:31:byte[] pack(long,boolean,int,java.util.Map,java.util.Map):113:113 -> a + 32:63:com.batch.android.displayreceipt.DisplayReceipt unpack(byte[]):120:120 -> a + 94:94:com.batch.android.displayreceipt.DisplayReceipt unpack(byte[]):151:151 -> a + 1:1:java.util.Map getOd():45:45 -> b + 1:1:int getSendAttempt():61:61 -> c + 1:1:long getTimestamp():53:53 -> d + 1:1:void incrementSendAttempt():41:41 -> e + 1:1:boolean isReplay():57:57 -> f +com.batch.android.event.CollapsibleEvent -> com.batch.android.o.a: + 1:1:void (android.content.Context,long,java.lang.String,com.batch.android.json.JSONObject):15:15 -> + 2:2:void (java.lang.String,java.lang.String,java.util.Date,java.util.TimeZone,java.lang.String,com.batch.android.event.Event$State,java.lang.Long,java.util.Date,java.lang.String):29:29 -> +com.batch.android.event.Event -> com.batch.android.o.b: + java.util.Date secureDate -> f + java.lang.String parameters -> g + java.lang.String session -> i + java.util.Date date -> c + long servertime -> e + com.batch.android.event.Event$State state -> h + java.lang.String id -> a + java.util.TimeZone timezone -> d + java.lang.String name -> b + 1:35:void (android.content.Context,long,java.lang.String,com.batch.android.json.JSONObject):72:106 -> + 36:41:void (android.content.Context,long,java.lang.String,com.batch.android.json.JSONObject):104:109 -> + 42:42:void (android.content.Context,long,java.lang.String,com.batch.android.json.JSONObject):74:74 -> + 43:52:void (java.lang.String,java.lang.String,java.util.Date,java.util.TimeZone,java.lang.String,com.batch.android.event.Event$State,java.lang.Long,java.util.Date,java.lang.String):133:142 -> + 1:1:java.util.Date getDate():156:156 -> a + 1:1:java.lang.String getId():148:148 -> b + 1:1:java.lang.String getName():152:152 -> c + 1:1:java.lang.String getParameters():168:168 -> d + 1:1:java.util.Date getSecureDate():160:160 -> e + 1:1:long getServerTimestamp():176:176 -> f + 1:1:java.lang.String getSessionID():184:184 -> g + 1:1:com.batch.android.event.Event$State getState():172:172 -> h + 1:1:java.util.TimeZone getTimezone():164:164 -> i + 1:1:boolean isOld():180:180 -> j +com.batch.android.event.Event$State -> com.batch.android.o.b$a: + com.batch.android.event.Event$State OLD -> d + com.batch.android.event.Event$State[] $VALUES -> e + com.batch.android.event.Event$State SENDING -> c + com.batch.android.event.Event$State NEW -> b + int value -> a + 1:11:void ():197:207 -> + 12:12:void ():193:193 -> + 1:2:void (java.lang.String,int,int):213:214 -> + 1:1:int getValue():218:218 -> a + 2:3:com.batch.android.event.Event$State fromValue(int):224:225 -> a + 1:1:com.batch.android.event.Event$State valueOf(java.lang.String):193:193 -> valueOf + 1:1:com.batch.android.event.Event$State[] values():193:193 -> values +com.batch.android.event.EventSender -> com.batch.android.o.c: + java.lang.String TAG -> g + java.util.concurrent.ExecutorService sendExecutor -> e + com.batch.android.runtime.RuntimeManager runtimeManager -> a + com.batch.android.event.RetryTimer retryTimer -> f + java.util.concurrent.atomic.AtomicBoolean hasNewEvents -> d + java.util.concurrent.atomic.AtomicBoolean isSending -> c + com.batch.android.event.EventSender$EventSenderListener listener -> b + 1:1:void (com.batch.android.runtime.RuntimeManager,com.batch.android.event.EventSender$EventSenderListener):54:54 -> + 2:32:void (com.batch.android.runtime.RuntimeManager,com.batch.android.event.EventSender$EventSenderListener):35:65 -> + 33:33:void (com.batch.android.runtime.RuntimeManager,com.batch.android.event.EventSender$EventSenderListener):60:60 -> + 34:34:void (com.batch.android.runtime.RuntimeManager,com.batch.android.event.EventSender$EventSenderListener):56:56 -> + 1:1:com.batch.android.event.RetryTimer access$000(com.batch.android.event.EventSender):20:20 -> a + 2:11:void send(boolean):81:90 -> a + 12:12:void retry():163:163 -> a + 13:13:com.batch.android.core.TaskRunnable getWebserviceTask(java.util.List,com.batch.android.webservice.listener.TrackerWebserviceListener):174:174 -> a + 1:1:java.util.concurrent.atomic.AtomicBoolean access$100(com.batch.android.event.EventSender):20:20 -> b + 2:3:void hasNewEvents():154:155 -> b + 1:1:com.batch.android.event.EventSender$EventSenderListener access$200(com.batch.android.event.EventSender):20:20 -> c + 2:49:void lambda$send$0():97:144 -> c + 1:2:void lambda$send$1():92:93 -> d + 1:1:void send():72:72 -> e +com.batch.android.event.EventSender$1 -> com.batch.android.o.c$a: + com.batch.android.event.EventSender this$0 -> a + 1:1:void (com.batch.android.event.EventSender):110:110 -> + 1:4:void onSuccess(java.util.List):114:117 -> a + 5:8:void onFailure(com.batch.android.FailReason,java.util.List):127:130 -> a + 9:10:void lambda$onFailure$1(java.util.List,com.batch.android.runtime.State):131:132 -> a + 11:11:void onFinish():140:140 -> a + 1:2:void lambda$onSuccess$0(java.util.List,com.batch.android.runtime.State):118:119 -> b +com.batch.android.event.EventSender$EventSenderListener -> com.batch.android.o.c$b: + java.util.List getEventsToSend() -> a + void onEventsSendFailure(java.util.List) -> a + void onEventsSendSuccess(java.util.List) -> b +com.batch.android.event.InternalEvents -> com.batch.android.o.d: + java.lang.String INSTALL_DATA_CHANGED -> g + java.lang.String PROFILE_CHANGED -> f + java.lang.String LOCATION_CHANGED -> i + java.lang.String INSTALL_DATA_CHANGED_TRACK_FAILURE -> h + java.lang.String INBOX_MARK_AS_DELETED -> k + java.lang.String INBOX_MARK_AS_READ -> j + java.lang.String OPT_IN -> m + java.lang.String INBOX_MARK_ALL_AS_READ -> l + java.lang.String OPT_OUT_AND_WIPE_DATA -> o + java.lang.String OPT_OUT -> n + java.lang.String FIND_MY_INSTALLATION -> p + java.lang.String START -> a + java.lang.String OPEN_FROM_PUSH -> c + java.lang.String STOP -> b + java.lang.String LOCAL_CAMPAIGN_VIEWED -> e + java.lang.String MESSAGING -> d + 1:1:void ():8:8 -> +com.batch.android.event.RetryTimer -> com.batch.android.o.e: + java.util.TimerTask retryTask -> f + java.lang.String TAG -> h + com.batch.android.event.RetryTimer$RetryTimerListener listener -> g + int MAX_RETRIES -> i + int nextRetryDelay -> d + int initialRetryDelay -> b + int maxRetryDelay -> c + int retries -> a + java.util.Timer retryTimer -> e + 1:1:void (android.content.Context,com.batch.android.event.RetryTimer$RetryTimerListener):56:56 -> + 2:48:void (android.content.Context,com.batch.android.event.RetryTimer$RetryTimerListener):24:70 -> + 49:49:void (android.content.Context,com.batch.android.event.RetryTimer$RetryTimerListener):62:62 -> + 50:50:void (android.content.Context,com.batch.android.event.RetryTimer$RetryTimerListener):58:58 -> + 1:1:int access$008(com.batch.android.event.RetryTimer):13:13 -> a + 2:9:void incrementDelay():126:133 -> a + 1:1:com.batch.android.event.RetryTimer$RetryTimerListener access$100(com.batch.android.event.RetryTimer):13:13 -> b + 2:2:boolean isWaiting():79:79 -> b + 1:18:void reschedule():87:104 -> c + 1:7:void reset():113:119 -> d +com.batch.android.event.RetryTimer$1 -> com.batch.android.o.e$a: + com.batch.android.event.RetryTimer this$0 -> a + 1:1:void (com.batch.android.event.RetryTimer):92:92 -> + 1:2:void run():95:96 -> run +com.batch.android.event.RetryTimer$RetryTimerListener -> com.batch.android.o.e$b: + void retry() -> a +com.batch.android.eventdispatcher.DispatcherDiscoveryService -> com.batch.android.eventdispatcher.DispatcherDiscoveryService: + 1:1:void ():11:11 -> +com.batch.android.eventdispatcher.DispatcherSerializer -> com.batch.android.p.a: + java.lang.String CUSTOM_DISPATCHER_NAME -> f + java.lang.String FIREBASE_DISPATCHER_NAME -> a + java.util.List knownDispatchers -> g + java.lang.String MIXPANEL_DISPATCHER_NAME -> c + java.lang.String AT_INTERNET_DISPATCHER_NAME -> b + java.lang.String BATCH_PLUGINS_DISPATCHER_NAME -> e + java.lang.String GOOGLE_ANALYTICS_DISPATCHER_NAME -> d + 1:1:void ():27:27 -> + 1:1:void ():14:14 -> + 1:10:com.batch.android.json.JSONObject serialize(java.util.Set):43:52 -> a +com.batch.android.eventdispatcher.MessagingEventPayload -> com.batch.android.p.b: + com.batch.android.messaging.model.Action action -> d + com.batch.android.json.JSONObject payload -> b + com.batch.android.json.JSONObject customPayload -> c + java.lang.String buttonAnalyticsId -> e + com.batch.android.BatchMessage message -> a + 1:1:void (com.batch.android.BatchMessage,com.batch.android.json.JSONObject,com.batch.android.json.JSONObject):26:26 -> + 2:7:void (com.batch.android.BatchMessage,com.batch.android.json.JSONObject,com.batch.android.json.JSONObject,com.batch.android.messaging.model.Action,java.lang.String):35:40 -> + 8:8:void (com.batch.android.BatchMessage,com.batch.android.json.JSONObject,com.batch.android.json.JSONObject,com.batch.android.messaging.model.Action):44:44 -> + 1:6:java.lang.String getCustomValue(java.lang.String):82:87 -> getCustomValue + 1:2:java.lang.String getDeeplink():65:66 -> getDeeplink + 1:1:com.batch.android.BatchMessage getMessagingPayload():93:93 -> getMessagingPayload + 1:2:java.lang.String getTrackingId():50:51 -> getTrackingId + 1:1:java.lang.String getWebViewAnalyticsID():59:59 -> getWebViewAnalyticsID + 1:1:boolean isPositiveAction():73:73 -> isPositiveAction +com.batch.android.eventdispatcher.PushEventPayload -> com.batch.android.p.c: + com.batch.android.BatchPushPayload payload -> a + boolean isOpening -> b + 1:1:void (com.batch.android.BatchPushPayload):20:20 -> + 2:4:void (com.batch.android.BatchPushPayload,boolean):23:25 -> + 1:5:java.lang.String getCustomValue(java.lang.String):55:59 -> getCustomValue + 1:1:java.lang.String getDeeplink():44:44 -> getDeeplink + 1:1:com.batch.android.BatchPushPayload getPushPayload():71:71 -> getPushPayload + 1:1:boolean isPositiveAction():49:49 -> isPositiveAction +com.batch.android.inbox.FetcherType -> com.batch.android.q.a: + com.batch.android.inbox.FetcherType[] $VALUES -> d + com.batch.android.inbox.FetcherType INSTALLATION -> b + com.batch.android.inbox.FetcherType USER_IDENTIFIER -> c + int value -> a + 1:2:void ():4:5 -> + 3:3:void () -> + 1:2:void (java.lang.String,int,int):9:10 -> + 1:1:int getValue():14:14 -> a + 1:6:java.lang.String toWSPathElement():18:23 -> b + 1:1:com.batch.android.inbox.FetcherType valueOf(java.lang.String):3:3 -> valueOf + 1:1:com.batch.android.inbox.FetcherType[] values():3:3 -> values +com.batch.android.inbox.FetcherType$1 -> com.batch.android.q.a$a: + int[] $SwitchMap$com$batch$android$inbox$FetcherType -> a + 1:1:void ():18:18 -> +com.batch.android.inbox.InboxCandidateNotificationInternal -> com.batch.android.q.b: + java.lang.String identifier -> a + boolean isUnread -> b + 1:3:void (java.lang.String,boolean):14:16 -> +com.batch.android.inbox.InboxDatabaseHelper -> com.batch.android.q.c: + java.lang.String COLUMN_INSTALL_ID -> g + java.lang.String COLUMN_FETCHER_ID -> f + java.lang.String TABLE_NOTIFICATIONS -> i + java.lang.String COLUMN_CUSTOM_ID -> h + java.lang.String COLUMN_SEND_ID -> k + java.lang.String COLUMN_NOTIFICATION_ID -> j + java.lang.String COLUMN_BODY -> m + java.lang.String COLUMN_TITLE -> l + java.lang.String COLUMN_DELETED -> o + java.lang.String COLUMN_UNREAD -> n + java.lang.String COLUMN_PAYLOAD -> q + java.lang.String COLUMN_DATE -> p + java.lang.String DATABASE_NAME -> r + java.lang.String COLUMN_DB_ID -> a + java.lang.String COLUMN_FETCHER_TYPE -> c + java.lang.String TABLE_FETCHERS -> b + int DATABASE_VERSION -> s + java.lang.String TABLE_FETCHERS_NOTIFICATIONS -> e + java.lang.String COLUMN_FETCHER_IDENTIFIER -> d + 1:1:void (android.content.Context):41:41 -> + 1:51:void onCreate(android.database.sqlite.SQLiteDatabase):46:96 -> onCreate + 1:1:void onUpgrade(android.database.sqlite.SQLiteDatabase,int,int):135:135 -> onUpgrade +com.batch.android.inbox.InboxDatasource -> com.batch.android.q.d: + android.content.Context context -> a + com.batch.android.inbox.InboxDatabaseHelper databaseHelper -> c + android.database.sqlite.SQLiteDatabase database -> b + java.lang.String TAG -> d + 1:8:void (android.content.Context):48:55 -> + 9:9:void (android.content.Context):50:50 -> + 1:51:java.util.List getNotifications(java.util.List,long):92:142 -> a + 52:60:java.util.List getNotifications(java.util.List,long):135:143 -> a + 61:75:long getNotificationTime(java.lang.String):151:165 -> a + 76:92:long getNotificationTime(java.lang.String):150:166 -> a + 93:124:long getFetcherID(com.batch.android.inbox.FetcherType,java.lang.String):180:211 -> a + 125:148:long getFetcherID(com.batch.android.inbox.FetcherType,java.lang.String):204:227 -> a + 149:168:long getFetcherID(com.batch.android.inbox.FetcherType,java.lang.String):203:222 -> a + 169:211:java.util.List getCandidateNotifications(java.lang.String,int,long):243:285 -> a + 212:221:java.util.List getCandidateNotifications(java.lang.String,int,long):283:292 -> a + 222:273:java.util.List getCandidateNotifications(java.lang.String,int,long):282:333 -> a + 274:280:java.util.List getCandidateNotifications(java.lang.String,int,long):328:334 -> a + 281:283:boolean insertResponse(com.batch.android.inbox.InboxWebserviceResponse,long):351:353 -> a + 284:331:boolean insert(com.batch.android.inbox.InboxNotificationContentInternal,long):367:414 -> a + 332:341:boolean insert(com.batch.android.inbox.InboxNotificationContentInternal,long):411:420 -> a + 342:342:boolean insert(com.batch.android.inbox.InboxNotificationContentInternal,long):373:373 -> a + 343:381:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):436:474 -> a + 382:383:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):469:470 -> a + 384:385:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):465:466 -> a + 386:387:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):461:462 -> a + 388:391:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):455:458 -> a + 392:393:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):451:452 -> a + 394:395:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):447:448 -> a + 396:455:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):443:502 -> a + 456:474:java.lang.String updateNotification(com.batch.android.json.JSONObject,long):495:513 -> a + 475:498:int markAllAsRead(long,long):526:549 -> a + 499:499:int markAllAsRead(long,long):529:529 -> a + 500:510:boolean deleteNotifications(java.util.List):592:602 -> a + 511:519:boolean deleteNotifications(java.util.List):600:608 -> a + 520:531:boolean deleteNotifications(java.util.List):606:617 -> a + 532:536:boolean deleteNotifications(java.util.List):614:618 -> a + 537:544:boolean cleanDatabase():627:634 -> a + 545:565:boolean cleanDatabase():630:650 -> a + 566:588:boolean cleanDatabase():629:651 -> a + 589:591:com.batch.android.inbox.InboxCandidateNotificationInternal parseCandidateNotification(android.database.Cursor):718:720 -> a + 592:600:java.lang.String createInClause(int):732:740 -> a + 1:3:void close():76:78 -> b + 4:6:void markNotificationAsDeleted(java.lang.String):575:577 -> b + 7:47:com.batch.android.inbox.InboxNotificationContentInternal parseNotification(android.database.Cursor):664:704 -> b + 1:1:android.database.sqlite.SQLiteDatabase getDatabase():88:88 -> c + 2:4:void markNotificationAsRead(java.lang.String):559:561 -> c + 1:8:void wipeData():62:69 -> d +com.batch.android.inbox.InboxFetchWebserviceClient -> com.batch.android.q.e: + com.batch.android.webservice.listener.InboxWebserviceListener listener -> q + java.lang.String authentication -> p + java.lang.String TAG -> r + long fetcherId -> o + 1:11:void (android.content.Context,com.batch.android.inbox.FetcherType,java.lang.String,java.lang.String,java.lang.Integer,java.lang.String,long,com.batch.android.webservice.listener.InboxWebserviceListener):52:62 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():238:238 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():243:243 -> B + 1:1:java.lang.String getSpecificRetryCountKey():248:248 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():213:213 -> F + java.lang.String getPropertyParameterKey() -> H + 1:1:java.lang.String getTaskIdentifier():79:79 -> a + 1:45:com.batch.android.inbox.InboxNotificationContentInternal parseNotification(com.batch.android.json.JSONObject):153:197 -> c + 1:24:com.batch.android.inbox.InboxWebserviceResponse parseResponse(com.batch.android.json.JSONObject):116:139 -> d + 25:33:com.batch.android.inbox.InboxWebserviceResponse parseResponse(com.batch.android.json.JSONObject):136:144 -> d + java.lang.String getCryptorModeParameterKey() -> o + java.lang.String getCryptorTypeParameterKey() -> p + 1:3:java.util.Map getHeaders():68:70 -> r + 1:27:void run():85:111 -> run + 28:29:void run():107:108 -> run + 30:39:void run():95:104 -> run + java.lang.String getPostCryptorTypeParameterKey() -> v + com.batch.android.post.PostDataProvider getPostDataProvider() -> w + 1:1:java.lang.String getReadCryptorTypeParameterKey():233:233 -> y +com.batch.android.inbox.InboxFetcherInternal -> com.batch.android.q.f: + java.lang.String authKey -> g + java.lang.String identifier -> f + boolean filterSilentNotifications -> n + android.content.Context context -> b + boolean isDatabaseCleaned -> p + int fetchLimit -> j + int maxPageSize -> i + boolean endReached -> l + java.lang.String TAG -> o + long fetcherId -> d + java.util.concurrent.Executor fetchExecutor -> k + com.batch.android.module.TrackerModule trackerModule -> a + com.batch.android.inbox.FetcherType fetcherType -> e + java.util.List fetchedNotifications -> h + java.lang.String cursor -> c + com.batch.android.inbox.InboxDatasource datasource -> m + 1:1:void (com.batch.android.module.TrackerModule,com.batch.android.inbox.InboxDatasource,android.content.Context,java.lang.String):73:73 -> + 2:40:void (com.batch.android.module.TrackerModule,com.batch.android.inbox.InboxDatasource,android.content.Context,java.lang.String):44:82 -> + 41:41:void (com.batch.android.module.TrackerModule,com.batch.android.inbox.InboxDatasource,android.content.Context,java.lang.String,java.lang.String):115:115 -> + 42:123:void (com.batch.android.module.TrackerModule,com.batch.android.inbox.InboxDatasource,android.content.Context,java.lang.String,java.lang.String):44:125 -> + 1:1:java.util.List access$000(com.batch.android.inbox.InboxFetcherInternal,com.batch.android.inbox.InboxWebserviceResponse,boolean):34:34 -> a + 2:2:java.util.List access$100(com.batch.android.inbox.InboxFetcherInternal,java.util.List):34:34 -> a + 3:3:java.lang.String access$200(com.batch.android.inbox.InboxFetcherInternal):34:34 -> a + 4:6:com.batch.android.inbox.InboxFetcherInternal provide(android.content.Context,java.lang.String):88:90 -> a + 7:10:com.batch.android.inbox.InboxFetcherInternal provide(android.content.Context,java.lang.String,boolean):103:106 -> a + 11:13:com.batch.android.inbox.InboxFetcherInternal provide(android.content.Context,java.lang.String,java.lang.String):135:137 -> a + 14:17:com.batch.android.inbox.InboxFetcherInternal provide(android.content.Context,java.lang.String,java.lang.String,boolean):152:155 -> a + 18:18:void setFetchLimit(int):163:163 -> a + 19:19:void setFilterSilentNotifications(boolean):167:167 -> a + 20:48:void markAsDeleted(com.batch.android.BatchInboxNotificationContent):220:248 -> a + 49:58:java.util.List convertInternalModelsToPublic(java.util.List):255:264 -> a + 59:98:void fetchNewNotifications(com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener):271:310 -> a + 99:147:void fetchNextPage(com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener):314:362 -> a + 148:164:void fetch(java.lang.String,com.batch.android.webservice.listener.InboxWebserviceListener):366:382 -> a + 165:195:void lambda$fetch$0(com.batch.android.webservice.listener.InboxWebserviceListener,java.lang.String):383:413 -> a + 196:227:void lambda$sync$1(com.batch.android.webservice.listener.InboxWebserviceListener,java.lang.String,java.util.List):428:459 -> a + 228:264:java.util.List getEventDatas(com.batch.android.inbox.InboxNotificationContentInternal):471:507 -> a + 265:267:java.util.List getPublicFetchedNotifications():516:518 -> a + 268:275:java.util.List handleFetchSuccess(com.batch.android.inbox.InboxWebserviceResponse,boolean):525:532 -> a + 276:353:java.util.List handleFetchSuccess(com.batch.android.inbox.InboxWebserviceResponse,boolean):527:604 -> a + 1:1:void setMaxPageSize(int):159:159 -> b + 2:2:boolean isEndReached():171:171 -> b + 3:30:void markAsRead(com.batch.android.BatchInboxNotificationContent):175:202 -> b + 31:39:boolean sync(java.lang.String,com.batch.android.webservice.listener.InboxWebserviceListener):419:427 -> b + 1:11:void markAllAsRead():206:216 -> c +com.batch.android.inbox.InboxFetcherInternal$1 -> com.batch.android.q.f$a: + com.batch.android.inbox.InboxFetcherInternal this$0 -> a + 1:1:void (com.batch.android.inbox.InboxFetcherInternal):272:272 -> +com.batch.android.inbox.InboxFetcherInternal$2 -> com.batch.android.q.f$b: + com.batch.android.inbox.InboxFetcherInternal this$0 -> b + com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener val$userListener -> a + 1:1:void (com.batch.android.inbox.InboxFetcherInternal,com.batch.android.BatchInboxFetcher$OnNewNotificationsFetchedListener):287:287 -> + 1:6:void onSuccess(com.batch.android.inbox.InboxWebserviceResponse):290:295 -> a + 7:14:void onSuccess(com.batch.android.inbox.InboxWebserviceResponse):293:300 -> a + 15:15:void onFailure(java.lang.String):307:307 -> a +com.batch.android.inbox.InboxFetcherInternal$3 -> com.batch.android.q.f$c: + com.batch.android.inbox.InboxFetcherInternal this$0 -> a + 1:1:void (com.batch.android.inbox.InboxFetcherInternal):325:325 -> +com.batch.android.inbox.InboxFetcherInternal$4 -> com.batch.android.q.f$d: + com.batch.android.inbox.InboxFetcherInternal this$0 -> b + com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener val$finalListener -> a + 1:1:void (com.batch.android.inbox.InboxFetcherInternal,com.batch.android.BatchInboxFetcher$OnNextPageFetchedListener):338:338 -> + 1:7:void onSuccess(com.batch.android.inbox.InboxWebserviceResponse):341:347 -> a + 8:15:void onSuccess(com.batch.android.inbox.InboxWebserviceResponse):345:352 -> a + 16:16:void onFailure(java.lang.String):359:359 -> a +com.batch.android.inbox.InboxFetcherInternal$ResultHandlingError -> com.batch.android.q.f$e: + com.batch.android.inbox.InboxFetcherInternal this$0 -> b + java.lang.String publicMesssage -> a + 1:3:void (com.batch.android.inbox.InboxFetcherInternal,java.lang.String,java.lang.String):611:613 -> + 1:1:java.lang.String getPublicMessage():617:617 -> a +com.batch.android.inbox.InboxNotificationContentInternal -> com.batch.android.q.g: + java.util.Date date -> f + boolean isDeleted -> e + java.util.List duplicateIdentifiers -> i + java.lang.String title -> a + com.batch.android.BatchNotificationSource source -> c + java.lang.String body -> b + java.util.Map payload -> g + com.batch.android.inbox.NotificationIdentifiers identifiers -> h + boolean isUnread -> d + 1:5:void (com.batch.android.BatchNotificationSource,java.util.Date,java.util.Map,com.batch.android.inbox.NotificationIdentifiers):47:51 -> + 1:3:android.os.Bundle getReceiverLikePayload():56:58 -> a + 4:7:void addDuplicateIdentifiers(com.batch.android.inbox.NotificationIdentifiers):64:67 -> a + 1:7:boolean isValid():71:77 -> b +com.batch.android.inbox.InboxSyncWebserviceClient -> com.batch.android.q.h: + com.batch.android.post.InboxSyncPostDataProvider dataProvider -> r + java.util.List candidates -> q + java.lang.String authentication -> p + com.batch.android.webservice.listener.InboxWebserviceListener listener -> s + long fetcherId -> o + java.lang.String TAG -> t + 1:13:void (android.content.Context,com.batch.android.inbox.FetcherType,java.lang.String,java.lang.String,java.lang.Integer,java.lang.String,long,java.util.List,com.batch.android.webservice.listener.InboxWebserviceListener):59:71 -> + 1:1:java.lang.String getSpecificConnectTimeoutKey():250:250 -> A + 1:1:java.lang.String getSpecificReadTimeoutKey():255:255 -> B + 1:1:java.lang.String getSpecificRetryCountKey():260:260 -> C + 1:1:java.lang.String getURLSorterPatternParameterKey():225:225 -> F + java.lang.String getPropertyParameterKey() -> H + 1:1:java.lang.String getTaskIdentifier():88:88 -> a + 1:2:boolean isCandidates(java.lang.String):205:206 -> b + 1:66:com.batch.android.inbox.InboxWebserviceResponse computeResponse(com.batch.android.json.JSONObject):120:185 -> c + 67:77:com.batch.android.inbox.InboxWebserviceResponse computeResponse(com.batch.android.json.JSONObject):182:192 -> c + 78:89:com.batch.android.inbox.InboxWebserviceResponse computeResponse(com.batch.android.json.JSONObject):189:200 -> c + java.lang.String getCryptorModeParameterKey() -> o + java.lang.String getCryptorTypeParameterKey() -> p + 1:3:java.util.Map getHeaders():77:79 -> r + 1:21:void run():94:114 -> run + 22:23:void run():110:111 -> run + 24:33:void run():98:107 -> run + 1:1:java.lang.String getPostCryptorTypeParameterKey():240:240 -> v + 1:1:com.batch.android.post.PostDataProvider getPostDataProvider():215:215 -> w + 1:1:java.lang.String getReadCryptorTypeParameterKey():245:245 -> y +com.batch.android.inbox.InboxWebserviceResponse -> com.batch.android.q.i: + java.util.List notifications -> d + boolean hasMore -> a + java.lang.String cursor -> c + boolean didTimeout -> b + 1:10:void ():11:20 -> +com.batch.android.inbox.NotificationIdentifiers -> com.batch.android.q.j: + java.lang.String identifier -> a + java.lang.String installID -> c + java.util.Map additionalData -> e + java.lang.String sendID -> b + java.lang.String customID -> d + 1:3:void (java.lang.String,java.lang.String):30:32 -> + 1:1:boolean isValid():36:36 -> a +com.batch.android.inbox.ResponseParsingException -> com.batch.android.q.k: + 1:1:void ():5:5 -> + 2:2:void (java.lang.String):8:8 -> + 3:3:void (java.lang.String,java.lang.Throwable):12:12 -> + 4:4:void (java.lang.Throwable):16:16 -> +com.batch.android.json.JSON -> com.batch.android.json.JSON: + 1:1:void ():22:22 -> + 1:2:double checkDouble(double):28:29 -> checkDouble + 1:8:java.lang.Boolean toBoolean(java.lang.Object):35:42 -> toBoolean + 1:7:java.lang.Double toDouble(java.lang.Object):49:55 -> toDouble + 1:7:java.lang.Integer toInteger(java.lang.Object):62:68 -> toInteger + 1:7:java.lang.Long toLong(java.lang.Object):75:81 -> toLong + 1:4:java.lang.String toString(java.lang.Object):88:91 -> toString + 1:9:com.batch.android.json.JSONException typeMismatch(java.lang.Object,java.lang.Object,java.lang.String):99:107 -> typeMismatch + 10:16:com.batch.android.json.JSONException typeMismatch(java.lang.Object,java.lang.String):116:122 -> typeMismatch +com.batch.android.json.JSONArray -> com.batch.android.json.JSONArray: + 1:2:void ():58:59 -> + 3:6:void (java.util.Collection):72:75 -> + 7:16:void (com.batch.android.json.JSONTokener):89:98 -> + 17:17:void (java.lang.String):110:110 -> + 18:25:void (java.lang.Object):116:123 -> + 26:26:void (java.lang.Object):118:118 -> + 1:5:void checkedPut(java.lang.Object):195:199 -> checkedPut + 1:1:boolean equals(java.lang.Object):623:623 -> equals + 1:7:java.lang.Object get(int):289:295 -> get + 1:6:boolean getBoolean(int):329:334 -> getBoolean + 7:7:boolean getBoolean(int):332:332 -> getBoolean + 1:6:double getDouble(int):363:368 -> getDouble + 7:7:double getDouble(int):366:366 -> getDouble + 1:6:int getInt(int):397:402 -> getInt + 7:7:int getInt(int):400:400 -> getInt + 1:5:com.batch.android.json.JSONArray getJSONArray(int):498:502 -> getJSONArray + 1:5:com.batch.android.json.JSONObject getJSONObject(int):523:527 -> getJSONObject + 1:6:long getLong(int):431:436 -> getLong + 7:7:long getLong(int):434:434 -> getLong + 1:4:java.lang.String getString(int):464:467 -> getString + 1:1:int hashCode():629:629 -> hashCode + 1:2:boolean isNull(int):276:277 -> isNull + 1:10:java.lang.String join(java.lang.String):568:577 -> join + 1:1:int length():131:131 -> length + 1:4:java.lang.Object opt(int):304:307 -> opt + 1:1:boolean optBoolean(int):342:342 -> optBoolean + 2:4:boolean optBoolean(int,boolean):350:352 -> optBoolean + 1:1:double optDouble(int):376:376 -> optDouble + 2:4:double optDouble(int,double):384:386 -> optDouble + 1:1:int optInt(int):410:410 -> optInt + 2:4:int optInt(int,int):418:420 -> optInt + 1:2:com.batch.android.json.JSONArray optJSONArray(int):511:512 -> optJSONArray + 1:2:com.batch.android.json.JSONObject optJSONObject(int):536:537 -> optJSONObject + 1:1:long optLong(int):444:444 -> optLong + 2:4:long optLong(int,long):452:454 -> optLong + 1:1:java.lang.String optString(int):477:477 -> optString + 2:3:java.lang.String optString(int,java.lang.String):485:486 -> optString + 1:1:com.batch.android.json.JSONArray put(boolean):140:140 -> put + 2:2:com.batch.android.json.JSONArray put(double):152:152 -> put + 3:3:com.batch.android.json.JSONArray put(int):162:162 -> put + 4:4:com.batch.android.json.JSONArray put(long):172:172 -> put + 5:5:com.batch.android.json.JSONArray put(java.lang.Object):187:187 -> put + 6:6:com.batch.android.json.JSONArray put(int,boolean):210:210 -> put + 7:7:com.batch.android.json.JSONArray put(int,double):223:223 -> put + 8:8:com.batch.android.json.JSONArray put(int,int):234:234 -> put + 9:9:com.batch.android.json.JSONArray put(int,long):245:245 -> put + 10:17:com.batch.android.json.JSONArray put(int,java.lang.Object):260:267 -> put + 1:4:java.lang.Object remove(int):315:318 -> remove + 1:8:com.batch.android.json.JSONObject toJSONObject(com.batch.android.json.JSONArray):548:555 -> toJSONObject + 1:3:java.lang.String toString():587:589 -> toString + 4:6:java.lang.String toString(int):608:610 -> toString + 1:5:void writeTo(com.batch.android.json.JSONStringer):614:618 -> writeTo +com.batch.android.json.JSONException -> com.batch.android.json.JSONException: + 1:1:void (java.lang.String):50:50 -> +com.batch.android.json.JSONHelper -> com.batch.android.json.JSONHelper: + 1:1:void ():16:16 -> + 1:3:java.util.List jsonArrayToArray(com.batch.android.json.JSONArray):47:49 -> jsonArrayToArray + 1:5:java.util.Map jsonObjectToMap(com.batch.android.json.JSONObject):37:41 -> jsonObjectToMap + 1:4:java.lang.Object jsonObjectToObject(java.lang.Object):27:30 -> jsonObjectToObject +com.batch.android.json.JSONObject -> com.batch.android.json.JSONObject: + 1:18:void ():87:104 -> + 1:2:void ():121:122 -> + 3:14:void (java.util.Map):135:146 -> + 15:15:void (java.util.Map):144:144 -> + 16:17:void (com.batch.android.json.JSONTokener):159:160 -> + 18:18:void (java.lang.String):172:172 -> + 19:23:void (com.batch.android.json.JSONObject,java.lang.String[]):181:185 -> + 24:28:void (com.batch.android.json.JSONObject):194:198 -> + 1:13:com.batch.android.json.JSONObject accumulate(java.lang.String,java.lang.Object):334:346 -> accumulate + 1:14:com.batch.android.json.JSONObject append(java.lang.String,java.lang.Object):362:375 -> append + 15:15:com.batch.android.json.JSONObject append(java.lang.String,java.lang.Object):372:372 -> append + 1:1:java.lang.String checkName(java.lang.String):382:382 -> checkName + 1:3:java.lang.Object get(java.lang.String):428:430 -> get + 1:6:boolean getBoolean(java.lang.String):451:456 -> getBoolean + 7:7:boolean getBoolean(java.lang.String):454:454 -> getBoolean + 1:6:double getDouble(java.lang.String):496:501 -> getDouble + 7:7:double getDouble(java.lang.String):499:499 -> getDouble + 1:6:int getInt(java.lang.String):541:546 -> getInt + 7:7:int getInt(java.lang.String):544:544 -> getInt + 1:5:com.batch.android.json.JSONArray getJSONArray(java.lang.String):680:684 -> getJSONArray + 1:5:com.batch.android.json.JSONObject getJSONObject(java.lang.String):705:709 -> getJSONObject + 1:6:long getLong(java.lang.String):588:593 -> getLong + 7:7:long getLong(java.lang.String):591:591 -> getLong + 1:4:java.lang.String getString(java.lang.String):635:638 -> getString + 1:1:boolean has(java.lang.String):411:411 -> has + 1:1:boolean hasNonNull(java.lang.String):419:419 -> hasNonNull + 1:2:boolean isNull(java.lang.String):402:403 -> isNull + 1:1:java.util.Set keySet():765:765 -> keySet + 1:1:java.util.Iterator keys():751:751 -> keys + 1:1:int length():231:231 -> length + 1:1:com.batch.android.json.JSONArray names():773:773 -> names + 1:14:java.lang.String numberToString(java.lang.Number):831:844 -> numberToString + 15:15:java.lang.String numberToString(java.lang.Number):828:828 -> numberToString + 1:1:java.lang.Object opt(java.lang.String):440:440 -> opt + 1:1:boolean optBoolean(java.lang.String):464:464 -> optBoolean + 2:4:boolean optBoolean(java.lang.String,boolean):472:474 -> optBoolean + 1:1:double optDouble(java.lang.String):509:509 -> optDouble + 2:4:double optDouble(java.lang.String,double):517:519 -> optDouble + 1:1:int optInt(java.lang.String):554:554 -> optInt + 2:4:int optInt(java.lang.String,int):562:564 -> optInt + 1:2:com.batch.android.json.JSONArray optJSONArray(java.lang.String):693:694 -> optJSONArray + 1:2:com.batch.android.json.JSONObject optJSONObject(java.lang.String):718:719 -> optJSONObject + 1:1:long optLong(java.lang.String):613:613 -> optLong + 2:4:long optLong(java.lang.String,long):623:625 -> optLong + 1:1:java.lang.String optString(java.lang.String):648:648 -> optString + 2:3:java.lang.String optString(java.lang.String,java.lang.String):656:657 -> optString + 1:1:com.batch.android.json.JSONObject put(java.lang.String,boolean):241:241 -> put + 2:2:com.batch.android.json.JSONObject put(java.lang.String,double):254:254 -> put + 3:3:com.batch.android.json.JSONObject put(java.lang.String,int):265:265 -> put + 4:4:com.batch.android.json.JSONObject put(java.lang.String,long):276:276 -> put + 5:12:com.batch.android.json.JSONObject put(java.lang.String,java.lang.Object):293:300 -> put + 1:1:com.batch.android.json.JSONObject putOpt(java.lang.String,java.lang.Object):312:312 -> putOpt + 1:10:java.lang.String quote(java.lang.String):856:865 -> quote + 1:5:void readFromTokener(com.batch.android.json.JSONTokener):219:223 -> readFromTokener + 1:9:void readObject(java.io.ObjectInputStream):932:940 -> readObject + 1:3:java.lang.Boolean reallyOptBoolean(java.lang.String,java.lang.Boolean):482:484 -> reallyOptBoolean + 1:3:java.lang.Double reallyOptDouble(java.lang.String,java.lang.Double):527:529 -> reallyOptDouble + 1:3:java.lang.Integer reallyOptInteger(java.lang.String,java.lang.Integer):572:574 -> reallyOptInteger + 1:3:java.lang.Long reallyOptLong(java.lang.String,java.lang.Long):601:603 -> reallyOptLong + 1:3:java.lang.String reallyOptString(java.lang.String,java.lang.String):666:668 -> reallyOptString + 1:1:java.lang.Object remove(java.lang.String):394:394 -> remove + 1:11:com.batch.android.json.JSONArray toJSONArray(com.batch.android.json.JSONArray):728:738 -> toJSONArray + 1:3:java.lang.String toString():783:785 -> toString + 4:6:java.lang.String toString(int):807:809 -> toString + 1:32:java.lang.Object wrap(java.lang.Object):883:914 -> wrap + 1:6:void writeObject(java.io.ObjectOutputStream):923:928 -> writeObject + 7:7:void writeObject(java.io.ObjectOutputStream):925:925 -> writeObject + 1:5:void writeTo(com.batch.android.json.JSONStringer):813:817 -> writeTo +com.batch.android.json.JSONObject$1 -> com.batch.android.json.JSONObject$a: + 1:1:void ():104:104 -> + 1:1:java.lang.String toString():112:112 -> toString +com.batch.android.json.JSONStringer -> com.batch.android.json.JSONStringer: + 1:1:void ():125:125 -> + 2:60:void ():68:126 -> + 61:61:void (int):129:129 -> + 62:126:void (int):68:132 -> + 1:1:com.batch.android.json.JSONStringer array():142:142 -> array + 1:8:void beforeKey():375:382 -> beforeKey + 9:9:void beforeKey():379:379 -> beforeKey + 1:16:void beforeValue():391:406 -> beforeValue + 1:10:com.batch.android.json.JSONStringer close(com.batch.android.json.JSONStringer$Scope,com.batch.android.json.JSONStringer$Scope,java.lang.String):192:201 -> close + 1:1:com.batch.android.json.JSONStringer endArray():151:151 -> endArray + 1:1:com.batch.android.json.JSONStringer endObject():170:170 -> endObject + 1:2:com.batch.android.json.JSONStringer key(java.lang.String):365:366 -> key + 3:3:com.batch.android.json.JSONStringer key(java.lang.String):363:363 -> key + 1:7:void newline():345:351 -> newline + 1:1:com.batch.android.json.JSONStringer object():161:161 -> object + 1:6:com.batch.android.json.JSONStringer open(com.batch.android.json.JSONStringer$Scope,java.lang.String):178:183 -> open + 1:4:com.batch.android.json.JSONStringer$Scope peek():209:212 -> peek + 5:5:com.batch.android.json.JSONStringer$Scope peek():210:210 -> peek + 1:1:void replaceTop(com.batch.android.json.JSONStringer$Scope):219:219 -> replaceTop + 1:34:void string(java.lang.String):301:334 -> string + 35:50:void string(java.lang.String):315:330 -> string + 51:51:void string(java.lang.String):324:324 -> string + 52:75:void string(java.lang.String):318:341 -> string + 1:1:java.lang.String toString():422:422 -> toString + 1:20:com.batch.android.json.JSONStringer value(java.lang.Object):231:250 -> value + 21:21:com.batch.android.json.JSONStringer value(java.lang.Object):246:246 -> value + 22:22:com.batch.android.json.JSONStringer value(java.lang.Object):232:232 -> value + 23:27:com.batch.android.json.JSONStringer value(boolean):262:266 -> value + 28:28:com.batch.android.json.JSONStringer value(boolean):263:263 -> value + 29:33:com.batch.android.json.JSONStringer value(double):278:282 -> value + 34:34:com.batch.android.json.JSONStringer value(double):279:279 -> value + 35:39:com.batch.android.json.JSONStringer value(long):292:296 -> value + 40:40:com.batch.android.json.JSONStringer value(long):293:293 -> value +com.batch.android.json.JSONStringer$Scope -> com.batch.android.json.JSONStringer$a: + com.batch.android.json.JSONStringer$Scope NONEMPTY_OBJECT -> e + com.batch.android.json.JSONStringer$Scope NULL -> f + com.batch.android.json.JSONStringer$Scope[] $VALUES -> g + com.batch.android.json.JSONStringer$Scope EMPTY_OBJECT -> c + com.batch.android.json.JSONStringer$Scope DANGLING_KEY -> d + com.batch.android.json.JSONStringer$Scope EMPTY_ARRAY -> a + com.batch.android.json.JSONStringer$Scope NONEMPTY_ARRAY -> b + 1:31:void ():80:110 -> + 32:32:void ():75:75 -> + 1:1:void (java.lang.String,int):75:75 -> + 1:1:com.batch.android.json.JSONStringer$Scope valueOf(java.lang.String):75:75 -> valueOf + 1:1:com.batch.android.json.JSONStringer$Scope[] values():75:75 -> values +com.batch.android.json.JSONTokener -> com.batch.android.json.JSONTokener: + 1:6:void (java.lang.String):83:88 -> + 1:2:void back():580:581 -> back + 1:1:boolean more():465:465 -> more + 1:1:char next():474:474 -> next + 2:4:char next(char):482:484 -> next + 5:9:java.lang.String next(int):512:516 -> next + 10:10:java.lang.String next(int):513:513 -> next + 1:1:char nextClean():496:496 -> nextClean + 1:28:int nextCleanInternal():117:144 -> nextCleanInternal + 29:34:int nextCleanInternal():134:139 -> nextCleanInternal + 35:53:int nextCleanInternal():137:155 -> nextCleanInternal + 1:25:java.lang.String nextString(char):197:221 -> nextString + 26:37:java.lang.String nextString(char):214:225 -> nextString + 1:1:java.lang.String nextTo(java.lang.String):540:540 -> nextTo + 2:2:java.lang.String nextTo(java.lang.String):538:538 -> nextTo + 3:3:java.lang.String nextTo(char):547:547 -> nextTo + 1:4:java.lang.String nextToInternal(java.lang.String):326:329 -> nextToInternal + 5:11:java.lang.String nextToInternal(java.lang.String):327:333 -> nextToInternal + 1:14:java.lang.Object nextValue():99:112 -> nextValue + 15:20:java.lang.Object nextValue():104:109 -> nextValue + 21:21:java.lang.Object nextValue():102:102 -> nextValue + 1:35:com.batch.android.json.JSONArray readArray():397:431 -> readArray + 36:42:com.batch.android.json.JSONArray readArray():408:414 -> readArray + 43:43:com.batch.android.json.JSONArray readArray():405:405 -> readArray + 1:12:char readEscapeCharacter():235:246 -> readEscapeCharacter + 13:13:char readEscapeCharacter():239:239 -> readEscapeCharacter + 1:21:java.lang.Object readLiteral():272:292 -> readLiteral + 22:51:java.lang.Object readLiteral():289:318 -> readLiteral + 52:52:java.lang.Object readLiteral():275:275 -> readLiteral + 1:18:com.batch.android.json.JSONObject readObject():341:358 -> readObject + 19:47:com.batch.android.json.JSONObject readObject():357:385 -> readObject + 1:2:void skipPast(java.lang.String):556:557 -> skipPast + 1:3:char skipTo(char):566:568 -> skipTo + 1:3:void skipToEndOfLine():171:171 -> skipToEndOfLine + 6:6:void skipToEndOfLine():174:174 -> skipToEndOfLine + 1:1:com.batch.android.json.JSONException syntaxError(java.lang.String):441:441 -> syntaxError + 1:1:java.lang.String toString():450:450 -> toString +com.batch.android.lisp.AndOperatorHandler -> com.batch.android.r.a: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():235:235 -> + 1:16:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):239:254 -> a + 17:24:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):250:257 -> a +com.batch.android.lisp.CachingContext -> com.batch.android.r.b: + com.batch.android.lisp.EvaluationContext context -> a + java.util.Map cache -> b + com.batch.android.lisp.Value NULL_VALUE -> c + 1:1:void ():17:17 -> + 1:3:void (com.batch.android.lisp.EvaluationContext):19:21 -> + 1:15:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):26:40 -> a +com.batch.android.lisp.ContainsAllOperatorHandler -> com.batch.android.r.c: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():431:431 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):435:435 -> a + 2:2:boolean lambda$run$0(java.util.Set,java.util.Set):438:438 -> a +com.batch.android.lisp.ContainsOperatorHandler -> com.batch.android.r.d: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():406:406 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):410:410 -> a + 2:3:boolean lambda$run$0(java.util.Set,java.util.Set):414:415 -> a +com.batch.android.lisp.EqualOperatorHandler -> com.batch.android.r.e: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():287:287 -> + 1:34:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):291:324 -> a +com.batch.android.lisp.ErrorValue -> com.batch.android.r.f: + com.batch.android.lisp.ErrorValue$Type type -> a + java.lang.String message -> b + 1:3:void (com.batch.android.lisp.ErrorValue$Type,java.lang.String):28:30 -> + 1:5:boolean equals(java.lang.Object):37:41 -> equals + 1:1:java.lang.String toString():47:47 -> toString +com.batch.android.lisp.ErrorValue$1 -> com.batch.android.r.f$a: + int[] $SwitchMap$com$batch$android$lisp$ErrorValue$Type -> a + 1:1:void ():12:12 -> +com.batch.android.lisp.ErrorValue$Type -> com.batch.android.r.f$b: + com.batch.android.lisp.ErrorValue$Type Internal -> a + com.batch.android.lisp.ErrorValue$Type Parser -> c + com.batch.android.lisp.ErrorValue$Type Error -> b + com.batch.android.lisp.ErrorValue$Type[] $VALUES -> d + 1:3:void ():6:8 -> + 4:4:void ():5:5 -> + 1:1:void (java.lang.String,int):5:5 -> + 1:9:java.lang.String toString():12:20 -> toString + 10:10:java.lang.String toString():18:18 -> toString + 11:11:java.lang.String toString():16:16 -> toString + 12:12:java.lang.String toString():14:14 -> toString + 1:1:com.batch.android.lisp.ErrorValue$Type valueOf(java.lang.String):5:5 -> valueOf + 1:1:com.batch.android.lisp.ErrorValue$Type[] values():5:5 -> values +com.batch.android.lisp.EvaluationContext -> com.batch.android.r.g: + com.batch.android.lisp.Value resolveVariableNamed(java.lang.String) -> a +com.batch.android.lisp.EventContext -> com.batch.android.r.h: + java.lang.String eventName -> a + com.batch.android.BatchEventData data -> c + java.lang.String eventLabel -> b + boolean isPublicEvent -> d + 1:9:void (java.lang.String,java.lang.String,com.batch.android.BatchEventData):16:24 -> + 1:16:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):29:44 -> a + 17:19:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):37:39 -> a + 20:26:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):35:41 -> a + 27:31:com.batch.android.lisp.Value converted():72:76 -> a + 1:5:com.batch.android.lisp.Value label():52:56 -> b + 6:19:com.batch.android.lisp.Value dataForRawVariableName(java.lang.String):80:93 -> b + 20:35:com.batch.android.lisp.Value dataForRawVariableName(java.lang.String):84:99 -> b + 1:9:com.batch.android.lisp.Value tags():60:68 -> c + 10:12:java.lang.String extractAttributeFromVariableName(java.lang.String):106:108 -> c +com.batch.android.lisp.GreaterThanOperatorHandler -> com.batch.android.r.i: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():346:346 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):350:350 -> a + 2:2:boolean lambda$run$0(java.lang.Number,java.lang.Number):354:354 -> a +com.batch.android.lisp.GreaterThanOrEqualOperatorHandler -> com.batch.android.r.j: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():360:360 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):364:364 -> a + 2:2:boolean lambda$run$0(java.lang.Number,java.lang.Number):368:368 -> a +com.batch.android.lisp.IfOperatorHandler -> com.batch.android.r.k: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():201:201 -> + 1:26:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):205:230 -> a + 27:27:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):207:207 -> a +com.batch.android.lisp.LessThanOperatorHandler -> com.batch.android.r.l: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():373:373 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):377:377 -> a + 2:2:boolean lambda$run$0(java.lang.Number,java.lang.Number):381:381 -> a +com.batch.android.lisp.LessThanOrEqualOperatorHandler -> com.batch.android.r.m: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():387:387 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):391:391 -> a + 2:2:boolean lambda$run$0(java.lang.Number,java.lang.Number):395:395 -> a +com.batch.android.lisp.LowerOperatorHandler -> com.batch.android.r.n: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():443:443 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):447:447 -> a + 2:2:java.lang.String lambda$run$0(java.lang.String):450:450 -> a +com.batch.android.lisp.MetaContext -> com.batch.android.r.o: + java.util.ArrayList contexts -> a + 1:2:void (java.util.ArrayList):16:17 -> + 1:2:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):23:24 -> a +com.batch.android.lisp.NativeAttributeContext -> com.batch.android.r.p: + android.content.Context context -> a + 1:2:void (android.content.Context):10:11 -> + 1:7:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):16:22 -> a +com.batch.android.lisp.NotOperatorHandler -> com.batch.android.r.q: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():328:328 -> + 1:11:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):332:342 -> a + 12:12:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):339:339 -> a +com.batch.android.lisp.NumberOperation -> com.batch.android.r.r: +# {"id":"sourceFile","fileName":"Protocols.java"} + boolean performOperation(java.lang.Number,java.lang.Number) -> a +com.batch.android.lisp.Operator -> com.batch.android.r.s: + com.batch.android.lisp.OperatorHandler handler -> b + java.lang.String symbol -> a + 1:3:void (java.lang.String,com.batch.android.lisp.OperatorHandler):9:11 -> +com.batch.android.lisp.OperatorHandler -> com.batch.android.r.t: + com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList) -> a +com.batch.android.lisp.OperatorProvider -> com.batch.android.r.u: +# {"id":"sourceFile","fileName":"Operators.java"} + java.util.HashMap _operators -> a + java.text.NumberFormat numberFormatter -> b + 1:3:void ():17:19 -> + 1:1:com.batch.android.lisp.Operator operatorForSymbol(java.lang.String):24:24 -> a + 2:16:void setupOperators():28:42 -> a + 17:17:void addOperator(com.batch.android.lisp.Operator):46:46 -> a + 18:23:java.lang.String numberToString(java.lang.Number):50:55 -> a + 24:65:com.batch.android.lisp.Value performNumberOperationOnValues(java.util.ArrayList,java.lang.String,com.batch.android.lisp.NumberOperation):63:104 -> a + 66:109:com.batch.android.lisp.Value performSetOperationOnValues(java.util.ArrayList,java.lang.String,com.batch.android.lisp.SetOperation):108:151 -> a + 110:110:com.batch.android.lisp.Value performSetOperationOnValues(java.util.ArrayList,java.lang.String,com.batch.android.lisp.SetOperation):136:136 -> a + 111:111:com.batch.android.lisp.Value performSetOperationOnValues(java.util.ArrayList,java.lang.String,com.batch.android.lisp.SetOperation):132:132 -> a + 112:146:com.batch.android.lisp.Value performStringOperationOnValues(java.util.ArrayList,java.lang.String,com.batch.android.lisp.StringOperation):163:197 -> a +com.batch.android.lisp.OperatorValue -> com.batch.android.r.v: + com.batch.android.lisp.Operator operator -> a + 1:2:void (com.batch.android.lisp.Operator):7:8 -> + 1:4:boolean equals(java.lang.Object):15:18 -> equals + 1:1:java.lang.String toString():24:24 -> toString +com.batch.android.lisp.OrOperatorHandler -> com.batch.android.r.w: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():261:261 -> + 1:16:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):265:280 -> a + 17:24:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):276:283 -> a +com.batch.android.lisp.ParseStringOperatorHandler -> com.batch.android.r.x: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():470:470 -> + 1:16:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):474:489 -> a +com.batch.android.lisp.Parser -> com.batch.android.r.y: + com.batch.android.lisp.OperatorProvider operators -> f + char TOKEN_DELIMITER_VARIABLE -> h + java.text.NumberFormat numberFormatter -> g + char TOKEN_DELIMITER_LIST_START -> j + char TOKEN_DELIMITER_STRING -> i + char TOKEN_DELIMITER_STRING_ARRAY_START -> k + boolean endReached -> e + boolean isConsumed -> a + int _pos -> b + int _maxPos -> c + java.lang.String input -> d + 1:9:void (java.lang.String):27:35 -> + 1:9:java.lang.Character getNextChar():53:61 -> a + 10:10:com.batch.android.lisp.ErrorValue errorUnexpectedEOF(java.lang.String):274:274 -> a + 1:11:com.batch.android.lisp.Value parse():39:49 -> b + 12:12:com.batch.android.lisp.ErrorValue errorWithMessage(java.lang.String):264:264 -> b + 1:54:com.batch.android.lisp.Value parseList():68:121 -> c + 55:69:com.batch.android.lisp.Value parseList():78:92 -> c + 70:105:com.batch.android.lisp.Value parseList():90:125 -> c + 106:106:com.batch.android.lisp.ErrorValue errorWithPositionAndMessage(java.lang.String):269:269 -> c + 1:28:com.batch.android.lisp.Value parseString():161:188 -> d + 29:32:com.batch.android.lisp.Value parseString():176:179 -> d + 33:33:com.batch.android.lisp.Value parseString():173:173 -> d + 34:49:com.batch.android.lisp.Value parseString():170:185 -> d + 50:70:com.batch.android.lisp.Value parseString():182:202 -> d + 71:72:com.batch.android.lisp.PrimitiveValue parseNumber(java.lang.String):225:226 -> d + 1:29:com.batch.android.lisp.Value parseStringArray():129:157 -> e + 30:36:com.batch.android.lisp.OperatorValue parseOperator(java.lang.String):234:240 -> e + 1:7:com.batch.android.lisp.PrimitiveValue parseSpecial(java.lang.String):207:213 -> f + 8:13:com.batch.android.lisp.PrimitiveValue parseSpecial(java.lang.String):211:216 -> f + 14:29:com.batch.android.lisp.Value parseVariable():244:259 -> f + 1:1:java.lang.String stringByTrimmingWhiteSpaceAndNewline(java.lang.String):279:279 -> g +com.batch.android.lisp.PrimitiveValue -> com.batch.android.r.z: + com.batch.android.lisp.PrimitiveValue$Type type -> a + java.lang.Object value -> b + 1:3:void (com.batch.android.lisp.PrimitiveValue$Type,java.lang.Object):42:44 -> + 4:4:void (java.lang.String):48:48 -> + 5:5:void (java.lang.Double):52:52 -> + 6:6:void (java.lang.Integer):56:56 -> + 7:7:void (java.lang.Boolean):60:60 -> + 8:8:void (java.util.Set):64:64 -> + 1:1:com.batch.android.lisp.PrimitiveValue nilValue():39:39 -> a + 1:5:boolean equals(java.lang.Object):71:75 -> equals + 1:10:java.lang.String toString():83:92 -> toString +com.batch.android.lisp.PrimitiveValue$1 -> com.batch.android.r.z$a: + int[] $SwitchMap$com$batch$android$lisp$PrimitiveValue$Type -> a + 1:1:void ():18:18 -> +com.batch.android.lisp.PrimitiveValue$Type -> com.batch.android.r.z$b: + com.batch.android.lisp.PrimitiveValue$Type Bool -> d + com.batch.android.lisp.PrimitiveValue$Type[] $VALUES -> f + com.batch.android.lisp.PrimitiveValue$Type Double -> c + com.batch.android.lisp.PrimitiveValue$Type String -> b + com.batch.android.lisp.PrimitiveValue$Type Nil -> a + com.batch.android.lisp.PrimitiveValue$Type StringSet -> e + 1:5:void ():10:14 -> + 6:6:void ():9:9 -> + 1:1:void (java.lang.String,int):9:9 -> + 1:13:java.lang.String toString():18:30 -> toString + 14:14:java.lang.String toString():28:28 -> toString + 15:15:java.lang.String toString():26:26 -> toString + 16:16:java.lang.String toString():24:24 -> toString + 17:17:java.lang.String toString():22:22 -> toString + 18:18:java.lang.String toString():20:20 -> toString + 1:1:com.batch.android.lisp.PrimitiveValue$Type valueOf(java.lang.String):9:9 -> valueOf + 1:1:com.batch.android.lisp.PrimitiveValue$Type[] values():9:9 -> values +com.batch.android.lisp.Reduceable -> com.batch.android.r.a0: + com.batch.android.lisp.Value reduce(com.batch.android.lisp.EvaluationContext) -> a +com.batch.android.lisp.SExpression -> com.batch.android.r.b0: + java.util.ArrayList values -> a + 1:2:void (java.util.ArrayList):9:10 -> + 1:42:com.batch.android.lisp.Value reduce(com.batch.android.lisp.EvaluationContext):26:67 -> a + 1:4:boolean equals(java.lang.Object):17:20 -> equals + 1:13:java.lang.String toString():72:84 -> toString +com.batch.android.lisp.SetOperation -> com.batch.android.r.c0: +# {"id":"sourceFile","fileName":"Protocols.java"} + boolean performOperation(java.util.Set,java.util.Set) -> a +com.batch.android.lisp.StringOperation -> com.batch.android.r.d0: +# {"id":"sourceFile","fileName":"Protocols.java"} + java.lang.String performOperation(java.lang.String) -> a +com.batch.android.lisp.UpperOperatorHandler -> com.batch.android.r.e0: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():455:455 -> + 1:1:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):459:459 -> a + 2:2:java.lang.String lambda$run$0(java.lang.String):462:462 -> a +com.batch.android.lisp.UserAttributeContext -> com.batch.android.r.f0: + java.util.Map attributes -> b + java.util.Map tagCollections -> c + com.batch.android.user.UserDatasource dataSource -> a + 1:2:void (com.batch.android.user.UserDatasource):15:16 -> + 1:27:com.batch.android.lisp.Value resolveVariableNamed(java.lang.String):24:50 -> a + 28:29:void fetchAttributes():58:59 -> a + 30:57:com.batch.android.lisp.Value attributeToValue(com.batch.android.user.UserAttribute):71:98 -> a + 58:59:com.batch.android.lisp.Value attributeToValue(com.batch.android.user.UserAttribute):93:94 -> a + 60:61:com.batch.android.lisp.Value attributeToValue(com.batch.android.user.UserAttribute):88:89 -> a + 62:63:com.batch.android.lisp.Value attributeToValue(com.batch.android.user.UserAttribute):82:83 -> a + 64:89:com.batch.android.lisp.Value attributeToValue(com.batch.android.user.UserAttribute):76:101 -> a + 1:2:void fetchTags():64:65 -> b +com.batch.android.lisp.UserAttributeContext$1 -> com.batch.android.r.f0$a: + int[] $SwitchMap$com$batch$android$user$AttributeType -> a + 1:1:void ():74:74 -> +com.batch.android.lisp.Value -> com.batch.android.r.g0: + 1:1:void ():24:24 -> + 1:5:java.lang.String escapedString(java.lang.String):27:31 -> a + 6:25:java.lang.String setToString(java.util.Set):36:55 -> a +com.batch.android.lisp.VariableValue -> com.batch.android.r.h0: + java.lang.String name -> a + 1:2:void (java.lang.String):10:11 -> + 1:3:com.batch.android.lisp.Value reduce(com.batch.android.lisp.EvaluationContext):33:35 -> a + 1:4:boolean equals(java.lang.Object):18:21 -> equals + 1:1:java.lang.String toString():28:28 -> toString +com.batch.android.lisp.WriteToStringOperatorHandler -> com.batch.android.r.i0: +# {"id":"sourceFile","fileName":"Operators.java"} + 1:1:void ():497:497 -> + 1:28:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):501:528 -> a + 29:35:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):520:526 -> a + 36:42:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):512:518 -> a + 43:43:com.batch.android.lisp.Value run(com.batch.android.lisp.EvaluationContext,java.util.ArrayList):510:510 -> a +com.batch.android.lisp.WriteToStringOperatorHandler$1 -> com.batch.android.r.i0$a: +# {"id":"sourceFile","fileName":"Operators.java"} + int[] $SwitchMap$com$batch$android$lisp$PrimitiveValue$Type -> a + 1:1:void ():506:506 -> +com.batch.android.localcampaigns.CampaignManager -> com.batch.android.s.a: + int MAX_CAMPAIGNS_JIT_THRESHOLD -> o + int DEFAULT_RETRY_AFTER -> m + java.lang.Object campaignListLock -> f + java.lang.String TAG -> k + long nextAvailableJITTimestamp -> g + java.lang.String PERSISTENCE_LOCAL_CAMPAIGNS_FILE_NAME -> l + com.batch.android.localcampaigns.persistence.LocalCampaignsPersistence persistor -> c + com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings cappings -> e + com.batch.android.localcampaigns.LocalCampaignsTracker viewTracker -> b + java.util.concurrent.atomic.AtomicBoolean campaignsLoaded -> h + java.util.Set watchedEventNames -> i + com.batch.android.core.DateProvider dateProvider -> a + java.util.List campaignList -> d + java.util.Map syncedJITCampaigns -> j + long CACHE_EXPIRATION_DELAY -> n + int MIN_DELAY_BETWEEN_JIT_SYNC -> p + int JIT_CAMPAIGN_CACHE_PERIOD -> q + 1:1:void ():70:70 -> + 1:1:void (com.batch.android.localcampaigns.LocalCampaignsTracker):124:124 -> + 2:37:void (com.batch.android.localcampaigns.LocalCampaignsTracker):90:125 -> + 1:1:long access$002(com.batch.android.localcampaigns.CampaignManager,long):56:56 -> a + 2:2:com.batch.android.core.DateProvider access$100(com.batch.android.localcampaigns.CampaignManager):56:56 -> a + 3:11:void deleteAllCampaigns(android.content.Context,boolean):175:183 -> a + 12:39:java.util.List getEligibleCampaignsSortedByPriority(com.batch.android.localcampaigns.signal.Signal):197:224 -> a + 40:51:java.util.List getEligibleCampaignsSortedByPriority(com.batch.android.localcampaigns.signal.Signal):222:233 -> a + 52:53:int lambda$getEligibleCampaignsSortedByPriority$0(com.batch.android.localcampaigns.model.LocalCampaign,com.batch.android.localcampaigns.model.LocalCampaign):225:226 -> a + 54:65:void verifyCampaignsEligibilityFromServer(java.util.List,com.batch.android.localcampaigns.CampaignManager$JITElectionCampaignListener):284:295 -> a + 66:66:void verifyCampaignsEligibilityFromServer(java.util.List,com.batch.android.localcampaigns.CampaignManager$JITElectionCampaignListener):294:294 -> a + 67:84:com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State getSyncedJITCampaignState(com.batch.android.localcampaigns.model.LocalCampaign):357:374 -> a + 85:85:boolean isEventWatched(java.lang.String):382:382 -> a + 86:86:void setCappings(com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings):405:405 -> a + 87:117:java.util.List cleanCampaignList(java.util.List):416:446 -> a + 118:132:boolean isCampaignOverCapping(com.batch.android.localcampaigns.model.LocalCampaign,boolean):458:472 -> a + 133:133:void lambda$saveCampaignsAsync$1(android.content.Context,com.batch.android.query.response.LocalCampaignsResponse):602:602 -> a + 134:136:void deleteSavedCampaigns(android.content.Context):607:609 -> a + 137:137:boolean areCampaignsLoaded():665:665 -> a + 1:1:java.util.Map access$200(com.batch.android.localcampaigns.CampaignManager):56:56 -> b + 2:3:com.batch.android.localcampaigns.model.LocalCampaign getFirstCampaignNotRequiringJITSync(java.util.List):266:267 -> b + 4:40:boolean isCampaignDisplayable(com.batch.android.localcampaigns.model.LocalCampaign):488:524 -> b + 41:41:boolean isCampaignDisplayable(com.batch.android.localcampaigns.model.LocalCampaign):509:509 -> b + 42:52:void saveCampaigns(android.content.Context,com.batch.android.query.response.LocalCampaignsResponse):587:597 -> b + 53:53:void saveCampaigns(android.content.Context,com.batch.android.query.response.LocalCampaignsResponse):594:594 -> b + 54:54:void deleteSavedCampaignsAsync(android.content.Context):614:614 -> b + 55:59:void closeViewTracker():681:685 -> b + 1:8:java.util.List getFirstEligibleCampaignsRequiringSync(java.util.List):243:250 -> c + 9:9:java.util.List getCampaignList():389:389 -> c + 10:10:void saveCampaignsAsync(android.content.Context,com.batch.android.query.response.LocalCampaignsResponse):602:602 -> c + 11:13:boolean hasSavedCampaigns(android.content.Context):619:621 -> c + 1:29:void updateCampaignList(java.util.List):140:168 -> d + 30:30:com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings getCappings():397:397 -> d + 31:31:void lambda$deleteSavedCampaignsAsync$2(android.content.Context):614:614 -> d + 1:30:boolean loadSavedCampaignResponse(android.content.Context):629:658 -> e + 31:31:boolean loadSavedCampaignResponse(android.content.Context):631:631 -> e + 32:32:com.batch.android.localcampaigns.ViewTracker getViewTracker():690:690 -> e + 1:1:boolean isJITServiceAvailable():348:348 -> f + 1:22:boolean isOverGlobalCappings():536:557 -> g + 1:4:void openViewTracker():669:672 -> h + 1:1:com.batch.android.localcampaigns.CampaignManager provide():130:130 -> i + 1:9:void updateWatchedEventNames():574:582 -> j +com.batch.android.localcampaigns.CampaignManager$1 -> com.batch.android.s.a$a: + java.util.List val$eligibleCampaignsRequiringSync -> b + com.batch.android.localcampaigns.CampaignManager this$0 -> c + com.batch.android.localcampaigns.CampaignManager$JITElectionCampaignListener val$listener -> a + 1:1:void (com.batch.android.localcampaigns.CampaignManager,com.batch.android.localcampaigns.CampaignManager$JITElectionCampaignListener,java.util.List):297:297 -> + 1:23:void onSuccess(java.util.List):301:323 -> a + 24:28:void onFailure(com.batch.android.core.Webservice$WebserviceError):331:335 -> a +com.batch.android.localcampaigns.CampaignManager$JITElectionCampaignListener -> com.batch.android.s.a$b: + void onCampaignElected(com.batch.android.localcampaigns.model.LocalCampaign) -> a +com.batch.android.localcampaigns.LocalCampaignTrackDbHelper -> com.batch.android.s.b: + java.lang.String SQL_CREATE_TRIGGER_VIEW_EVENT_DELETE_ROWS -> f + java.lang.String SQL_CREATE_ENTRIES -> c + java.lang.String DATABASE_NAME -> b + java.lang.String SQL_CREATE_VIEW_EVENTS_TABLE -> e + int DATABASE_VERSION -> a + java.lang.String SQL_DELETE_ENTRIES -> d + 1:1:void (android.content.Context):101:101 -> + 1:8:java.lang.String getTableAsString(android.database.sqlite.SQLiteDatabase):129:136 -> a + 9:20:java.lang.String getTableAsString(android.database.sqlite.SQLiteDatabase):135:146 -> a + 1:3:void onCreate(android.database.sqlite.SQLiteDatabase):106:108 -> onCreate + 1:2:void onUpgrade(android.database.sqlite.SQLiteDatabase,int,int):114:115 -> onUpgrade +com.batch.android.localcampaigns.LocalCampaignTrackDbHelper$LocalCampaignEntry -> com.batch.android.s.b$a: + java.lang.String COLUMN_NAME_VE_CAMPAIGN_ID -> g + java.lang.String TABLE_VIEW_EVENTS_NAME -> f + java.lang.String TRIGGER_VIEW_EVENTS_NAME -> i + java.lang.String COLUMN_NAME_VE_TIMESTAMP -> h + java.lang.String TABLE_NAME -> a + java.lang.String COLUMN_NAME_CAMPAIGN_KIND -> c + java.lang.String COLUMN_NAME_CAMPAIGN_ID -> b + java.lang.String COLUMN_NAME_CAMPAIGN_COUNT -> e + java.lang.String COLUMN_NAME_CAMPAIGN_LAST_OCCURRENCE -> d + 1:1:void ():14:14 -> +com.batch.android.localcampaigns.LocalCampaignsSQLTracker -> com.batch.android.s.c: + java.lang.String TAG -> f + com.batch.android.core.DateProvider dateProvider -> d + android.database.sqlite.SQLiteDatabase database -> c + boolean open -> e + com.batch.android.localcampaigns.LocalCampaignTrackDbHelper dbHelper -> b + 1:1:void ():25:25 -> + 2:5:void ():23:26 -> + 6:6:void (com.batch.android.core.DateProvider):30:30 -> + 7:15:void (com.batch.android.core.DateProvider):23:31 -> + 1:2:void open(android.content.Context):35:36 -> a + 3:7:void close():40:44 -> a + 8:8:void setDateProvider(com.batch.android.core.DateProvider):56:56 -> a + 9:36:java.util.Map getViewCounts(java.util.List):139:166 -> a + 37:58:java.util.Map getViewCounts(java.util.List):154:175 -> a + 59:75:long campaignLastOccurrence(java.lang.String):183:199 -> a + 76:85:int getNumberOfViewEventsSince(long):206:215 -> a + 86:98:int getNumberOfViewEventsSince(long):208:220 -> a + 1:21:com.batch.android.localcampaigns.ViewTracker$CountedViewEvent trackViewEvent(java.lang.String):68:88 -> b + 22:47:com.batch.android.localcampaigns.ViewTracker$CountedViewEvent trackViewEvent(java.lang.String):74:99 -> b + 48:48:com.batch.android.localcampaigns.ViewTracker$CountedViewEvent trackViewEvent(java.lang.String):91:91 -> b + 49:50:void deleteViewEvents():225:226 -> b + 1:23:com.batch.android.localcampaigns.ViewTracker$CountedViewEvent getViewEvent(java.lang.String):108:130 -> c + 24:32:void ensureWritableDatabase():230:238 -> c + 33:33:void ensureWritableDatabase():232:232 -> c + 1:1:com.batch.android.core.DateProvider getDateProvider():52:52 -> d + 1:1:boolean isOpen():48:48 -> e +com.batch.android.localcampaigns.LocalCampaignsTracker -> com.batch.android.s.d: + int sessionViewsCount -> g + 1:7:void ():5:11 -> + 1:2:com.batch.android.localcampaigns.ViewTracker$CountedViewEvent trackViewEvent(java.lang.String):36:37 -> b + 1:1:int getSessionViewsCount():25:25 -> f + 1:1:void resetSessionViewsCount():17:17 -> g +com.batch.android.localcampaigns.ViewTracker -> com.batch.android.s.e: + int KIND_VIEW -> a + long campaignLastOccurrence(java.lang.String) -> a + int getNumberOfViewEventsSince(long) -> a + java.util.Map getViewCounts(java.util.List) -> a + com.batch.android.localcampaigns.ViewTracker$CountedViewEvent trackViewEvent(java.lang.String) -> b + com.batch.android.localcampaigns.ViewTracker$CountedViewEvent getViewEvent(java.lang.String) -> c +com.batch.android.localcampaigns.ViewTracker$CountedViewEvent -> com.batch.android.s.e$a: + java.lang.String campaignID -> a + long lastOccurrence -> c + int count -> b + 1:1:void (java.lang.String):61:61 -> + 2:7:void (java.lang.String):57:62 -> +com.batch.android.localcampaigns.ViewTrackerUnavailableException -> com.batch.android.s.f: + 1:1:void ():5:5 -> +com.batch.android.localcampaigns.model.LocalCampaign -> com.batch.android.t.a: + java.lang.Integer maximumAPILevel -> c + com.batch.android.localcampaigns.model.LocalCampaign$Output output -> i + boolean requiresJustInTimeSync -> o + java.lang.Integer capping -> h + java.lang.String publicToken -> m + com.batch.android.json.JSONObject customPayload -> n + boolean persist -> l + int minimumDisplayInterval -> g + int priority -> d + java.lang.String TAG -> p + java.lang.Integer minimumAPILevel -> b + java.lang.String id -> a + com.batch.android.json.JSONObject eventData -> j + com.batch.android.date.BatchDate startDate -> e + com.batch.android.date.BatchDate endDate -> f + java.util.List triggers -> k + 1:107:void ():15:121 -> + 1:1:void displayMessage():160:160 -> a + 1:3:void generateOccurrenceID():136:138 -> b +com.batch.android.localcampaigns.model.LocalCampaign$Output -> com.batch.android.t.a$a: + com.batch.android.json.JSONObject payload -> a + 1:2:void (com.batch.android.json.JSONObject):171:172 -> + boolean displayMessage(com.batch.android.localcampaigns.model.LocalCampaign) -> a +com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult -> com.batch.android.t.a$b: + long timestamp -> a + boolean eligible -> b + 1:2:void (long):209:210 -> +com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State -> com.batch.android.t.a$b$a: + com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State ELIGIBLE -> a + com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State[] $VALUES -> d + com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State REQUIRES_SYNC -> c + com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State NOT_ELIGIBLE -> b + 1:3:void ():194:196 -> + 4:4:void ():193:193 -> + 1:1:void (java.lang.String,int):193:193 -> + 1:1:com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State valueOf(java.lang.String):193:193 -> valueOf + 1:1:com.batch.android.localcampaigns.model.LocalCampaign$SyncedJITResult$State[] values():193:193 -> values +com.batch.android.localcampaigns.model.LocalCampaign$Trigger -> com.batch.android.t.a$c: + java.lang.String getType() -> k +com.batch.android.localcampaigns.output.ActionOutput -> com.batch.android.u.a: + 1:1:void (com.batch.android.json.JSONObject):20:20 -> + 1:1:com.batch.android.localcampaigns.output.ActionOutput provide(com.batch.android.json.JSONObject):25:25 -> a + 2:34:boolean displayMessage(com.batch.android.localcampaigns.model.LocalCampaign):30:62 -> a +com.batch.android.localcampaigns.output.LandingOutput -> com.batch.android.u.b: + com.batch.android.module.MessagingModule messagingModule -> b + 1:2:void (com.batch.android.module.MessagingModule,com.batch.android.json.JSONObject):21:22 -> + 1:1:com.batch.android.localcampaigns.output.LandingOutput provide(com.batch.android.json.JSONObject):27:27 -> a + 2:19:boolean displayMessage(com.batch.android.localcampaigns.model.LocalCampaign):34:51 -> a +com.batch.android.localcampaigns.persistence.LocalCampaignsFilePersistence -> com.batch.android.v.a: + java.lang.String TAG -> a + int PERSISTENCE_CURRENT_FILE_VERSION -> d + java.lang.String PERSISTENCE_SAVE_VERSION_KEY -> c + java.lang.String PERSISTENCE_TMP_FILE_PREFIX -> b + 1:1:void ():19:19 -> + 1:82:void persistData(android.content.Context,com.batch.android.json.JSONObject,java.lang.String):38:119 -> a + 83:120:com.batch.android.json.JSONObject loadData(android.content.Context,java.lang.String):129:166 -> a + 121:121:com.batch.android.json.JSONObject loadData(android.content.Context,java.lang.String):151:151 -> a + 122:122:com.batch.android.json.JSONObject loadData(android.content.Context,java.lang.String):143:143 -> a + 1:1:boolean hasSavedData(android.content.Context,java.lang.String):32:32 -> b + 1:6:void deleteData(android.content.Context,java.lang.String):174:179 -> c +com.batch.android.localcampaigns.persistence.LocalCampaignsPersistence -> com.batch.android.v.b: + com.batch.android.json.JSONObject loadData(android.content.Context,java.lang.String) -> a + void persistData(android.content.Context,com.batch.android.json.JSONObject,java.lang.String) -> a + boolean hasSavedData(android.content.Context,java.lang.String) -> b + void deleteData(android.content.Context,java.lang.String) -> c +com.batch.android.localcampaigns.persistence.PersistenceException -> com.batch.android.v.c: + 1:1:void ():5:5 -> + 2:2:void (java.lang.String):8:8 -> + 3:3:void (java.lang.String,java.lang.Throwable):12:12 -> + 4:4:void (java.lang.Throwable):16:16 -> +com.batch.android.localcampaigns.serialization.LocalCampaignDeserializer -> com.batch.android.w.a: + java.lang.String TAG -> a + 1:1:void ():20:20 -> + 1:77:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):36:112 -> a + 78:78:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):67:67 -> a + 79:79:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):62:62 -> a + 80:80:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):47:47 -> a + 81:81:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):40:40 -> a + 82:82:com.batch.android.localcampaigns.model.LocalCampaign deserialize(com.batch.android.json.JSONObject):33:33 -> a + 83:91:java.util.List deserializeList(com.batch.android.json.JSONArray):124:132 -> a + 1:16:com.batch.android.localcampaigns.model.LocalCampaign$Output parseOutput(com.batch.android.json.JSONObject):147:162 -> b + 17:17:com.batch.android.localcampaigns.model.LocalCampaign$Output parseOutput(com.batch.android.json.JSONObject):150:150 -> b + 18:29:java.util.List parseTriggers(com.batch.android.json.JSONArray):175:186 -> b + 1:21:com.batch.android.localcampaigns.model.LocalCampaign$Trigger parseTrigger(com.batch.android.json.JSONObject):199:219 -> c + 22:26:com.batch.android.localcampaigns.model.LocalCampaign$Trigger parseTrigger(com.batch.android.json.JSONObject):213:217 -> c + 27:27:com.batch.android.localcampaigns.model.LocalCampaign$Trigger parseTrigger(com.batch.android.json.JSONObject):215:215 -> c + 28:28:com.batch.android.localcampaigns.model.LocalCampaign$Trigger parseTrigger(com.batch.android.json.JSONObject):211:211 -> c + 29:29:com.batch.android.localcampaigns.model.LocalCampaign$Trigger parseTrigger(com.batch.android.json.JSONObject):202:202 -> c +com.batch.android.localcampaigns.serialization.LocalCampaignSerializer -> com.batch.android.w.b: + 1:1:void ():12:12 -> + 1:44:com.batch.android.json.JSONObject serialize(com.batch.android.localcampaigns.model.LocalCampaign):22:65 -> a + 45:48:com.batch.android.json.JSONObject parseOutput(com.batch.android.localcampaigns.model.LocalCampaign$Output):92:95 -> a + 49:52:com.batch.android.json.JSONArray parseTriggers(java.util.List):108:111 -> a + 53:58:com.batch.android.json.JSONObject parseTrigger(com.batch.android.localcampaigns.model.LocalCampaign$Trigger):124:129 -> a + 1:4:com.batch.android.json.JSONArray serializeList(java.util.List):76:79 -> b +com.batch.android.localcampaigns.signal.EventTrackedSignal -> com.batch.android.x.a: + com.batch.android.json.JSONObject parameters -> b + java.lang.String name -> a + 1:3:void (java.lang.String,com.batch.android.json.JSONObject):20:22 -> + 1:3:boolean satisfiesTrigger(com.batch.android.localcampaigns.model.LocalCampaign$Trigger):26:28 -> a +com.batch.android.localcampaigns.signal.NewSessionSignal -> com.batch.android.x.b: + 1:1:void ():11:11 -> + 1:1:boolean satisfiesTrigger(com.batch.android.localcampaigns.model.LocalCampaign$Trigger):15:15 -> a +com.batch.android.localcampaigns.signal.PublicEventTrackedSignal -> com.batch.android.x.c: + java.lang.String label -> c + 1:11:void (com.batch.android.localcampaigns.signal.EventTrackedSignal):20:30 -> + 12:12:void (com.batch.android.localcampaigns.signal.EventTrackedSignal):28:28 -> + 1:3:boolean satisfiesTrigger(com.batch.android.localcampaigns.model.LocalCampaign$Trigger):38:40 -> a + 4:4:boolean isPublic(com.batch.android.localcampaigns.signal.EventTrackedSignal):45:45 -> a +com.batch.android.localcampaigns.signal.Signal -> com.batch.android.x.d: + boolean satisfiesTrigger(com.batch.android.localcampaigns.model.LocalCampaign$Trigger) -> a +com.batch.android.localcampaigns.trigger.EventLocalCampaignTrigger -> com.batch.android.y.a: + java.lang.String name -> a + java.lang.String label -> b + 1:3:void (java.lang.String,java.lang.String):27:29 -> + 1:5:boolean isSatisfied(java.lang.String,java.lang.String):36:40 -> a + 1:1:java.lang.String getType():49:49 -> k +com.batch.android.localcampaigns.trigger.NextSessionTrigger -> com.batch.android.y.b: + 1:1:void ():8:8 -> + 1:1:java.lang.String getType():12:12 -> k +com.batch.android.messaging.AsyncImageDownloadTask -> com.batch.android.z.a: + com.batch.android.messaging.model.MessagingError lastError -> a + java.lang.ref.WeakReference weakListener -> b + java.lang.String TAG -> c + 1:1:void (com.batch.android.messaging.AsyncImageDownloadTask$ImageDownloadListener):82:82 -> + 2:50:void (com.batch.android.messaging.AsyncImageDownloadTask$ImageDownloadListener):35:83 -> + 1:76:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):96:171 -> a + 77:109:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):139:171 -> a + 110:140:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):141:171 -> a + 141:160:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):146:165 -> a + 161:172:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):160:171 -> a + 173:181:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):157:165 -> a + 182:202:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):154:174 -> a + 203:203:com.batch.android.messaging.AsyncImageDownloadTask$Result doInBackground(java.lang.String[]):106:106 -> a + 204:209:void onPostExecute(com.batch.android.messaging.AsyncImageDownloadTask$Result):181:186 -> a + 1:1:java.lang.Object doInBackground(java.lang.Object[]):30:30 -> doInBackground + 1:1:void onPostExecute(java.lang.Object):30:30 -> onPostExecute + 1:3:void onPreExecute():88:90 -> onPreExecute +com.batch.android.messaging.AsyncImageDownloadTask$BitmapResult -> com.batch.android.z.a$a: + 1:1:void (java.lang.String,android.graphics.Bitmap):59:59 -> +com.batch.android.messaging.AsyncImageDownloadTask$GIFResult -> com.batch.android.z.a$b: + 1:1:void (java.lang.String,byte[]):66:66 -> +com.batch.android.messaging.AsyncImageDownloadTask$ImageDownloadListener -> com.batch.android.z.a$c: + void onImageDownloadError(com.batch.android.messaging.model.MessagingError) -> a + void onImageDownloadSuccess(com.batch.android.messaging.AsyncImageDownloadTask$Result) -> b + void onImageDownloadStart() -> c +com.batch.android.messaging.AsyncImageDownloadTask$Result -> com.batch.android.z.a$d: + java.lang.Object value -> b + java.lang.String key -> a + 1:3:void (java.lang.String,java.lang.Object):42:44 -> + 1:1:java.lang.Object get():52:52 -> a + 1:1:java.lang.String getKey():48:48 -> b +com.batch.android.messaging.ModalContentPanGestureDetector -> com.batch.android.z.b: + boolean shouldDismissOnTouchUp -> m + boolean allowHorizontalPanning -> n + int touchSlop -> l + float initialInterceptYOffset -> i + float initialInterceptXOffset -> h + float initialSwipeYOffset -> g + float initialSwipeXOffset -> f + boolean isPanning -> k + android.view.GestureDetector detector -> b + float SPRING_STIFFNESS -> w + float SCALE_RATIO_DISMISS_THRESHOLD -> v + float SMALLEST_SCALE_RATIO -> u + com.batch.android.messaging.ModalContentPanGestureDetector$OnDismissListener dismissListener -> a + android.os.Vibrator vibrator -> d + boolean supportsAndroidXAnimation -> e + float DISMISS_THRESHOLD_MINIMUM_VELOCITY -> t + float DISMISSABLE_TARGET_ALPHA -> s + android.view.View targetView -> c + java.lang.Object[] cancellationAnimations -> j + float SCALE_PAN_MULTIPLIER -> r + float TRANSLATION_PAN_MULTIPLIER -> q + long ANIMATION_DURATION_FAST -> p + long ANIMATION_DURATION -> o + 1:1:void (android.content.Context,boolean):100:100 -> + 2:63:void (android.content.Context,boolean):52:113 -> + 1:2:void attach(com.batch.android.messaging.view.DelegatedTouchEventViewGroup,android.view.View):124:125 -> a + 3:3:void setDismissListener(com.batch.android.messaging.ModalContentPanGestureDetector$OnDismissListener):129:129 -> a + 4:7:void beginPan(float,float):143:146 -> a + 8:19:void cancelCancellationAnimation():193:204 -> a + 20:46:boolean onInterceptTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup):211:237 -> a + 47:47:boolean onInterceptTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup):215:215 -> a + 48:149:boolean onTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup,boolean):254:355 -> a + 150:202:boolean onTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup,boolean):264:316 -> a + 203:238:boolean onTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup,boolean):314:349 -> a + 239:338:boolean onTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup,boolean):260:359 -> a + 1:2:void dismiss():133:134 -> b + 3:3:boolean hasPassedTouchSlop(float,float):139:139 -> b + 1:6:void shouldDismissChanged():365:370 -> c + 1:24:void startCancelAnimation():150:173 -> d + 1:12:void startFallbackCancelAnimation():178:189 -> e + 1:4:void vibrate():374:377 -> f + 1:11:boolean onFling(android.view.MotionEvent,android.view.MotionEvent,float,float):404:414 -> onFling +com.batch.android.messaging.ModalContentPanGestureDetector$OnDismissListener -> com.batch.android.z.b$a: + void onPanDismiss() -> e +com.batch.android.messaging.PayloadParser -> com.batch.android.z.c: + java.lang.String TAG -> a + 1:1:void ():35:35 -> + 1:13:com.batch.android.messaging.model.AlertMessage parseAlertPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.AlertMessage):145:157 -> a + 14:53:com.batch.android.messaging.model.UniversalMessage parseUniversalPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.UniversalMessage):166:205 -> a + 54:54:com.batch.android.messaging.model.BannerMessage parseBannerPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.BannerMessage):213:213 -> a + 55:55:com.batch.android.messaging.model.ModalMessage parseModalPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.ModalMessage):219:219 -> a + 56:92:void parseBaseBannerPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.BaseBannerMessage):225:261 -> a + 93:93:void parseBaseBannerPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.BaseBannerMessage):258:258 -> a + 94:114:void parseBaseBannerPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.BaseBannerMessage):255:275 -> a + 115:130:com.batch.android.messaging.model.ImageMessage parseImagePayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.ImageMessage):281:296 -> a + 131:149:com.batch.android.messaging.model.ImageMessage parseImagePayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.ImageMessage):294:312 -> a + 150:154:com.batch.android.messaging.model.ImageMessage parseImagePayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.ImageMessage):303:307 -> a + 155:155:com.batch.android.messaging.model.ImageMessage parseImagePayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.ImageMessage):289:289 -> a + 156:180:com.batch.android.messaging.model.WebViewMessage parseWebViewPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.WebViewMessage):319:343 -> a + 181:182:com.batch.android.messaging.model.WebViewMessage parseWebViewPayload(com.batch.android.json.JSONObject,com.batch.android.messaging.model.WebViewMessage):327:328 -> a + 183:190:com.batch.android.messaging.model.Action parseAction(com.batch.android.json.JSONObject):350:357 -> a + 191:197:android.text.Spanned parseHtmlString(java.lang.String):378:384 -> a + 1:45:com.batch.android.messaging.model.Message parseBasePayload(com.batch.android.json.JSONObject):94:138 -> b + 46:46:com.batch.android.messaging.model.Message parseBasePayload(com.batch.android.json.JSONObject):111:111 -> b + 1:9:com.batch.android.messaging.model.CTA parseCTA(com.batch.android.json.JSONObject):361:369 -> c + 1:40:com.batch.android.messaging.model.Message parsePayload(com.batch.android.json.JSONObject):47:86 -> d + 41:41:com.batch.android.messaging.model.Message parsePayload(com.batch.android.json.JSONObject):49:49 -> d + 42:42:com.batch.android.messaging.model.Message parsePayload(com.batch.android.json.JSONObject):41:41 -> d +com.batch.android.messaging.PayloadParsingException -> com.batch.android.z.d: + 1:1:void ():9:9 -> + 2:2:void (java.lang.String):12:12 -> + 3:3:void (java.lang.String,java.lang.Throwable):16:16 -> + 4:4:void (java.lang.Throwable):20:20 -> +com.batch.android.messaging.Size2D -> com.batch.android.messaging.Size2D: + int height -> b + int width -> a + 1:1:void ():53:53 -> + 1:3:void (int,int):15:17 -> + 4:6:void (android.os.Parcel):20:22 -> + 1:5:boolean equals(java.lang.Object):30:34 -> equals + 1:1:int hashCode():39:39 -> hashCode + 1:2:void writeToParcel(android.os.Parcel,int):44:45 -> writeToParcel +com.batch.android.messaging.Size2D$1 -> com.batch.android.messaging.Size2D$a: + 1:1:void ():53:53 -> + 1:1:com.batch.android.messaging.Size2D createFromParcel(android.os.Parcel):56:56 -> a + 2:2:com.batch.android.messaging.Size2D[] newArray(int):61:61 -> a + 1:1:java.lang.Object createFromParcel(android.os.Parcel):53:53 -> createFromParcel + 1:1:java.lang.Object[] newArray(int):53:53 -> newArray +com.batch.android.messaging.WebViewActionListener -> com.batch.android.z.e: + void onCloseAction() -> a + void onDismissAction(java.lang.String) -> a + void onErrorAction(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String) -> a + void onOpenDeeplinkAction(java.lang.String,java.lang.Boolean,java.lang.String) -> a + void onPerformAction(java.lang.String,com.batch.android.json.JSONObject,java.lang.String) -> a +com.batch.android.messaging.WebViewHelper -> com.batch.android.z.f: + 1:1:void ():7:7 -> + 1:2:java.lang.String getAnalyticsIDFromURL(java.lang.String):12:13 -> a +com.batch.android.messaging.css.CSSParsingException -> com.batch.android.a0.a: + 1:1:void ():5:5 -> + 2:2:void (java.lang.String):8:8 -> + 3:3:void (java.lang.String,java.lang.Throwable):12:12 -> + 4:4:void (java.lang.Throwable):16:16 -> +com.batch.android.messaging.css.DOMNode -> com.batch.android.a0.b: + java.util.List classes -> c + java.lang.String type -> a + java.lang.String identifier -> b + 1:2:void ():17:18 -> + 3:7:void (java.lang.String,java.lang.String[]):21:25 -> + 1:23:boolean matchesSelector(java.lang.String):30:52 -> a +com.batch.android.messaging.css.Declaration -> com.batch.android.a0.c: + java.lang.String name -> a + java.lang.String value -> b + 1:1:void ():3:3 -> +com.batch.android.messaging.css.Document -> com.batch.android.a0.d: + java.util.List mediaQueries -> b + java.util.List rulesets -> a + java.util.regex.Pattern MEDIA_QUERY_PATTERN -> d + java.lang.String TAG -> c + 1:1:void ():21:21 -> + 1:3:void ():29:31 -> + 1:1:java.util.Map getFlatRules(com.batch.android.messaging.css.DOMNode,android.graphics.Point):36:36 -> a + 2:101:java.util.Map getFlatRules(java.util.List):42:141 -> a + 102:122:java.util.List getRules(com.batch.android.messaging.css.DOMNode,java.util.List):160:180 -> a + 123:151:boolean matchesMediaQuery(java.lang.String,android.graphics.Point):188:216 -> a + 152:167:boolean matchesSizeMediaQuery(android.graphics.Point,java.lang.String,java.lang.String,java.lang.String,int):239:254 -> a + 1:5:java.util.List getRules(com.batch.android.messaging.css.DOMNode,android.graphics.Point):147:151 -> b +com.batch.android.messaging.css.ImportFileProvider -> com.batch.android.a0.e: + java.lang.String getContent(java.lang.String) -> a +com.batch.android.messaging.css.MediaQuery -> com.batch.android.a0.f: + java.util.List rulesets -> b + java.lang.String rule -> a + 1:2:void ():12:13 -> +com.batch.android.messaging.css.Parser -> com.batch.android.a0.g: + java.lang.String currentToken -> i + com.batch.android.messaging.css.Parser$State state -> c + com.batch.android.messaging.css.Ruleset currentRuleset -> f + com.batch.android.messaging.css.ImportFileProvider importFileProvider -> a + com.batch.android.messaging.css.Parser$Substate substate -> d + boolean shouldMergePreviousToken -> j + com.batch.android.messaging.css.MediaQuery currentMediaQuery -> e + com.batch.android.messaging.css.Declaration currentDeclaration -> g + com.batch.android.messaging.css.Document currentDocument -> h + java.util.regex.Pattern IMPORT_PATTERN -> k + java.lang.String rawStylesheet -> b + 1:1:void ():12:12 -> + 1:1:void (com.batch.android.messaging.css.ImportFileProvider,java.lang.String):30:30 -> + 2:7:void (com.batch.android.messaging.css.ImportFileProvider,java.lang.String):28:33 -> + 1:11:void fillImports():55:65 -> a + 12:18:void fillImports():63:69 -> a + 19:20:void consumeToken(java.lang.String):95:96 -> a + 21:40:void consumeSpecialToken(char):100:119 -> a + 41:41:void consumeSpecialToken(char):116:116 -> a + 42:42:void consumeSpecialToken(char):113:113 -> a + 43:43:void consumeSpecialToken(char):110:110 -> a + 44:44:void consumeSpecialToken(char):107:107 -> a + 1:4:com.batch.android.messaging.css.Document parse():37:40 -> b + 1:2:void recoverLineEndingIfPossible():239:240 -> c + 1:7:void reset():45:51 -> d + 1:18:void scan():73:90 -> e + 1:25:void switchOutOfPropertyNameState():194:218 -> f + 1:14:void switchOutOfPropertyValueState():222:235 -> g + 1:33:void switchOutOfRulesetState():157:189 -> h + 1:26:void switchToRulesetState():127:152 -> i + 1:1:void throwGenericParsingException():245:245 -> j +com.batch.android.messaging.css.Parser$1 -> com.batch.android.a0.g$a: + int[] $SwitchMap$com$batch$android$messaging$css$Parser$SpecialToken -> a + 1:1:void ():102:102 -> +com.batch.android.messaging.css.Parser$SpecialToken -> com.batch.android.a0.g$b: + com.batch.android.messaging.css.Parser$SpecialToken NEW_LINE -> f + com.batch.android.messaging.css.Parser$SpecialToken PROPERTY_END -> e + com.batch.android.messaging.css.Parser$SpecialToken BLOCK_START -> b + com.batch.android.messaging.css.Parser$SpecialToken UNKNOWN -> a + com.batch.android.messaging.css.Parser$SpecialToken PROPERTY_SEPARATOR -> d + com.batch.android.messaging.css.Parser$SpecialToken BLOCK_END -> c + com.batch.android.messaging.css.Parser$SpecialToken[] $VALUES -> g + 1:6:void ():265:270 -> + 7:7:void ():264:264 -> + 1:1:void (java.lang.String,int):264:264 -> + 1:1:com.batch.android.messaging.css.Parser$SpecialToken fromCharacter(char):285:285 -> a + 2:4:com.batch.android.messaging.css.Parser$SpecialToken fromCharacter(char):279:281 -> a + 5:5:com.batch.android.messaging.css.Parser$SpecialToken fromCharacter(char):277:277 -> a + 6:14:com.batch.android.messaging.css.Parser$SpecialToken fromCharacter(char):275:283 -> a + 1:1:com.batch.android.messaging.css.Parser$SpecialToken valueOf(java.lang.String):264:264 -> valueOf + 1:1:com.batch.android.messaging.css.Parser$SpecialToken[] values():264:264 -> values +com.batch.android.messaging.css.Parser$State -> com.batch.android.a0.g$c: + com.batch.android.messaging.css.Parser$State MEDIA_QUERY -> b + com.batch.android.messaging.css.Parser$State[] $VALUES -> c + com.batch.android.messaging.css.Parser$State ROOT -> a + 1:2:void ():253:254 -> + 3:3:void ():252:252 -> + 1:1:void (java.lang.String,int):252:252 -> + 1:1:com.batch.android.messaging.css.Parser$State valueOf(java.lang.String):252:252 -> valueOf + 1:1:com.batch.android.messaging.css.Parser$State[] values():252:252 -> values +com.batch.android.messaging.css.Parser$Substate -> com.batch.android.a0.g$d: + com.batch.android.messaging.css.Parser$Substate[] $VALUES -> e + com.batch.android.messaging.css.Parser$Substate PROPERTY_VALUE -> d + com.batch.android.messaging.css.Parser$Substate PROPERTY_NAME -> c + com.batch.android.messaging.css.Parser$Substate RULESET -> b + com.batch.android.messaging.css.Parser$Substate SELECTOR -> a + 1:4:void ():258:261 -> + 5:5:void ():257:257 -> + 1:1:void (java.lang.String,int):257:257 -> + 1:1:com.batch.android.messaging.css.Parser$Substate valueOf(java.lang.String):257:257 -> valueOf + 1:1:com.batch.android.messaging.css.Parser$Substate[] values():257:257 -> values +com.batch.android.messaging.css.Ruleset -> com.batch.android.a0.h: + java.util.List declarations -> b + java.lang.String selector -> a + 1:2:void ():12:13 -> +com.batch.android.messaging.css.Variable -> com.batch.android.a0.i: + 1:1:void ():3:3 -> +com.batch.android.messaging.css.builtin.BuiltinStyleProvider -> com.batch.android.b0.a: + java.util.Map metaStyles -> a + 1:1:void ():15:15 -> + 1:1:void ():13:13 -> + 1:36:java.lang.String getContent(java.lang.String):20:55 -> a + 37:50:java.lang.String getContent(java.lang.String):46:59 -> a + 51:55:java.lang.String getContent(java.lang.String):44:48 -> a + 56:56:java.lang.String getContent(java.lang.String):42:42 -> a + 57:68:java.lang.String getContent(java.lang.String):40:51 -> a + 69:73:java.util.Map generateMetaStyles():66:70 -> a +com.batch.android.messaging.css.builtin.BuiltinStyles -> com.batch.android.b0.b: + java.lang.String IMAGE1_BASE -> g + java.lang.String BANNER_ICON_ADDON -> f + java.lang.String IMAGE1_FULLSCREEN -> i + java.lang.String IMAGE1_DETACHED -> h + java.lang.String WEBVIEW1 -> j + java.lang.String GENERIC1_H_CTA -> a + java.lang.String GENERIC1_BASE -> c + java.lang.String GENERIC1_V_CTA -> b + java.lang.String MODAL1 -> e + java.lang.String BANNER1 -> d + 1:1:void ():8:8 -> +com.batch.android.messaging.fragment.AlertTemplateFragment -> com.batch.android.c0.a: + java.lang.String TAG -> l + 1:1:void ():29:29 -> + 1:2:com.batch.android.messaging.fragment.AlertTemplateFragment newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.AlertMessage):23:24 -> a + 3:3:void lambda$onCreateDialog$0(android.content.DialogInterface,int):63:63 -> a + 4:5:void lambda$onCreateDialog$1(com.batch.android.messaging.model.AlertMessage,android.content.DialogInterface,int):69:70 -> a + boolean canAutoClose() -> g + int getAutoCloseDelayMillis() -> i + void onAutoCloseCountdownStarted() -> l + void performAutoClose() -> m + 1:44:android.app.Dialog onCreateDialog(android.os.Bundle):35:78 -> onCreateDialog +com.batch.android.messaging.fragment.BaseDialogFragment -> com.batch.android.c0.b: + android.util.LruCache imageCache -> h + android.os.Handler autoCloseHandler -> e + java.lang.String TAG -> i + com.batch.android.module.MessagingModule messagingModule -> f + java.lang.String STATE_AUTOCLOSE_TARGET_UPTIME_KEY -> k + java.lang.String BUNDLE_KEY_MESSAGE_MODEL -> j + com.batch.android.MessagingAnalyticsDelegate analyticsDelegate -> g + com.batch.android.messaging.model.Message messageModel -> a + java.lang.ref.WeakReference eventListener -> b + long autoCloseAtUptime -> d + boolean automaticallyBeginAutoClose -> c + 1:1:void ():52:52 -> + 2:20:void ():37:55 -> + 1:4:void setMessageArguments(com.batch.android.BatchMessage,com.batch.android.messaging.model.Message):59:62 -> a + 5:5:void setDialogEventListener(com.batch.android.messaging.fragment.DialogEventListener):121:121 -> a + 6:6:void put(com.batch.android.messaging.AsyncImageDownloadTask$Result):128:128 -> a + 1:1:com.batch.android.messaging.AsyncImageDownloadTask$Result get(java.lang.String):134:134 -> b + 1:10:void beginAutoCloseCountdown():200:209 -> f + boolean canAutoClose() -> g + 1:2:void dismissSafely():188:189 -> h + int getAutoCloseDelayMillis() -> i + 1:6:com.batch.android.messaging.model.Message getMessageModel():111:116 -> j + 1:3:com.batch.android.BatchMessage getPayloadMessage():101:103 -> k + void onAutoCloseCountdownStarted() -> l + void performAutoClose() -> m + 1:4:void scheduleAutoCloseTask():213:216 -> n + 1:3:void unscheduleAutoCloseTask():221:223 -> o + 1:3:void onCancel(android.content.DialogInterface):179:181 -> onCancel + 1:19:void onCreate(android.os.Bundle):67:85 -> onCreate + 1:15:void onDismiss(android.content.DialogInterface):159:173 -> onDismiss + 1:6:void onSaveInstanceState(android.os.Bundle):91:96 -> onSaveInstanceState + 1:7:void onStart():141:147 -> onStart + 1:2:void onStop():153:154 -> onStop +com.batch.android.messaging.fragment.DialogEventListener -> com.batch.android.c0.c: +com.batch.android.messaging.fragment.ImageTemplateFragment -> com.batch.android.c0.d: + com.batch.android.messaging.css.Document style -> m + com.batch.android.messaging.AsyncImageDownloadTask heroDownloadTask -> s + boolean darkStatusbar -> n + boolean showStatusbar -> o + boolean statusbarBackgroundTranslucent -> p + android.graphics.Bitmap heroBitmap -> r + com.batch.android.messaging.view.formats.ImageFormatView imageFormatView -> l + java.lang.Integer statusbarBackgroundColor -> q + java.lang.String TAG -> u + boolean dismissed -> t + 1:1:void ():61:61 -> + 2:22:void ():42:62 -> + 1:2:com.batch.android.messaging.fragment.ImageTemplateFragment newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.ImageMessage):56:57 -> a + 3:22:android.view.View getImageFormatView(android.content.Context):149:168 -> a + 23:28:android.view.View getImageFormatView(android.content.Context):166:171 -> a + 29:31:void onCloseAction():223:225 -> a + 1:8:void onGlobalAction():231:238 -> b + 9:11:void onErrorAction(com.batch.android.messaging.model.MessagingError):245:247 -> b + 1:1:void onImageDisplayedAction():253:253 -> d + 1:2:void dismiss():125:126 -> dismiss + 1:2:void dismissAllowingStateLoss():137:138 -> dismissAllowingStateLoss + 1:3:void onPanDismiss():258:260 -> e + 1:1:boolean canAutoClose():201:201 -> g + 1:2:void dismissSafely():143:144 -> h + 1:1:int getAutoCloseDelayMillis():206:206 -> i + 1:2:void onAutoCloseCountdownStarted():194:195 -> l + 1:4:void performAutoClose():211:214 -> m + 1:11:void onCreate(android.os.Bundle):67:77 -> onCreate + 1:3:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):87:89 -> onCreateView + 1:6:void onDestroyView():104:109 -> onDestroyView + 1:1:void onDismiss(android.content.DialogInterface):114:114 -> onDismiss + 1:3:void onStart():96:98 -> onStart + 1:9:com.batch.android.messaging.css.Document getStyle():176:184 -> p + 10:17:com.batch.android.messaging.css.Document getStyle():180:187 -> p +com.batch.android.messaging.fragment.ListenableDialog -> com.batch.android.c0.e: + void setDialogEventListener(com.batch.android.messaging.fragment.DialogEventListener) -> a +com.batch.android.messaging.fragment.ModalTemplateFragment -> com.batch.android.c0.f: + com.batch.android.messaging.css.Document style -> m + com.batch.android.messaging.AsyncImageDownloadTask heroDownloadTask -> s + boolean darkStatusbar -> n + boolean showStatusbar -> o + boolean statusbarBackgroundTranslucent -> p + android.graphics.Bitmap heroBitmap -> r + com.batch.android.messaging.view.formats.BannerView bannerView -> l + java.lang.Integer statusbarBackgroundColor -> q + java.lang.String TAG -> u + boolean dismissed -> t + 1:1:void ():67:67 -> + 2:13:void ():48:59 -> + 1:2:com.batch.android.messaging.fragment.ModalTemplateFragment newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.ModalMessage):62:63 -> a + 3:20:android.view.View getBannerView(android.content.Context):170:187 -> a + 21:26:android.view.View getBannerView(android.content.Context):185:190 -> a + 27:29:void onCloseAction():273:275 -> a + 30:33:void onCTAAction(int,com.batch.android.messaging.model.CTA):281:284 -> a + 1:8:void onGlobalAction():290:297 -> b + 1:2:void dismiss():146:147 -> dismiss + 1:2:void dismissAllowingStateLoss():158:159 -> dismissAllowingStateLoss + 1:2:void onPanDismiss():304:305 -> e + 1:1:boolean canAutoClose():251:251 -> g + 1:2:void dismissSafely():164:165 -> h + 1:1:int getAutoCloseDelayMillis():256:256 -> i + 1:2:void onAutoCloseCountdownStarted():244:245 -> l + 1:4:void performAutoClose():261:264 -> m + 1:5:void onCreate(android.os.Bundle):71:75 -> onCreate + 6:12:void onCreate(android.os.Bundle):73:79 -> onCreate + 1:12:android.app.Dialog onCreateDialog(android.os.Bundle):84:95 -> onCreateDialog + 1:3:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):108:110 -> onCreateView + 1:6:void onDestroyView():125:130 -> onDestroyView + 1:1:void onDismiss(android.content.DialogInterface):135:135 -> onDismiss + 1:3:void onStart():117:119 -> onStart + 1:9:com.batch.android.messaging.css.Document getStyle():195:203 -> p + 10:17:com.batch.android.messaging.css.Document getStyle():199:206 -> p + 1:25:void refreshStatusbarStyle():210:234 -> q +com.batch.android.messaging.fragment.UniversalTemplateFragment -> com.batch.android.c0.g: + com.batch.android.messaging.AsyncImageDownloadTask heroDownloadTask -> s + boolean darkStatusbar -> n + boolean showStatusbar -> o + boolean statusbarBackgroundTranslucent -> p + boolean mediaPlayerPrepared -> u + com.batch.android.messaging.view.formats.UniversalRootView view -> l + boolean dismissed -> w + android.view.Surface videoSurface -> v + com.batch.android.messaging.AsyncImageDownloadTask$Result heroDownloadResult -> r + com.batch.android.messaging.css.Document style -> m + java.lang.String BUNDLE_KEY_MESSAGE_MODEL -> y + java.lang.String TAG -> x + java.lang.Integer statusbarBackgroundColor -> q + android.media.MediaPlayer mediaPlayer -> t + 1:1:void ():83:83 -> + 2:17:void ():60:75 -> + 1:2:com.batch.android.messaging.fragment.UniversalTemplateFragment newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.UniversalMessage):78:79 -> a + 3:14:android.view.View getUniversalView(android.content.Context):235:246 -> a + 15:18:void onCloseAction():341:344 -> a + 19:24:void onCTAAction(int,com.batch.android.messaging.model.CTA):351:356 -> a + 25:26:void onImageDownloadError(com.batch.android.messaging.model.MessagingError):374:375 -> a + 1:2:void onImageDownloadSuccess(com.batch.android.messaging.AsyncImageDownloadTask$Result):368:369 -> b + 1:1:void onImageDownloadStart():362:362 -> c + 2:3:void displayImage(com.batch.android.messaging.AsyncImageDownloadTask$Result):379:380 -> c + 1:2:void dismiss():211:212 -> dismiss + 1:2:void dismissAllowingStateLoss():223:224 -> dismissAllowingStateLoss + 1:1:boolean canAutoClose():319:319 -> g + 1:2:void dismissSafely():229:230 -> h + 1:1:int getAutoCloseDelayMillis():324:324 -> i + 1:2:void onAutoCloseCountdownStarted():312:313 -> l + 1:4:void performAutoClose():329:332 -> m + 1:7:void onCreate(android.os.Bundle):87:93 -> onCreate + 8:19:void onCreate(android.os.Bundle):89:100 -> onCreate + 1:12:android.app.Dialog onCreateDialog(android.os.Bundle):105:116 -> onCreateDialog + 1:47:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):129:175 -> onCreateView + 1:6:void onDestroyView():183:188 -> onDestroyView + 1:7:void onDismiss(android.content.DialogInterface):193:199 -> onDismiss + 1:2:void onPrepared(android.media.MediaPlayer):387:388 -> onPrepared + 1:6:void onSurfaceTextureAvailable(android.graphics.SurfaceTexture,int,int):402:407 -> onSurfaceTextureAvailable + 1:7:boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture):415:421 -> onSurfaceTextureDestroyed + 1:9:com.batch.android.messaging.css.Document getStyle():250:258 -> p + 10:17:com.batch.android.messaging.css.Document getStyle():254:261 -> p + 1:25:void refreshStatusbarStyle():265:289 -> q + 1:5:boolean shouldWaitForHeroImage():296:300 -> r + 1:3:void startPlayingVideo():394:396 -> s +com.batch.android.messaging.fragment.WebViewTemplateFragment -> com.batch.android.c0.h: + com.batch.android.messaging.css.Document style -> m + boolean darkStatusbar -> n + boolean showStatusbar -> o + boolean statusbarBackgroundTranslucent -> p + com.batch.android.messaging.view.formats.WebFormatView webView -> l + boolean dismissed -> r + int developmentMenuReloadItemID -> s + java.lang.Integer statusbarBackgroundColor -> q + java.lang.String TAG -> t + 1:1:void ():75:75 -> + 2:21:void ():57:76 -> + void lambda$showDevelopmentError$0(android.content.DialogInterface,int) -> a + 1:2:com.batch.android.messaging.fragment.WebViewTemplateFragment newInstance(com.batch.android.BatchMessage,com.batch.android.messaging.model.WebViewMessage):70:71 -> a + 3:20:android.view.View getWebFormatView(android.content.Context):202:219 -> a + 21:26:android.view.View getWebFormatView(android.content.Context):217:222 -> a + 27:27:void lambda$showDevelopmentError$1(com.batch.android.messaging.model.MessagingError,android.content.DialogInterface):330:330 -> a + 28:30:void onCloseAction():339:341 -> a + 31:31:void onDismissAction(java.lang.String):347:347 -> a + 32:35:void onErrorAction(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):356:359 -> a + 36:48:void onOpenDeeplinkAction(java.lang.String,java.lang.Boolean,java.lang.String):369:381 -> a + 49:55:void onPerformAction(java.lang.String,com.batch.android.json.JSONObject,java.lang.String):389:395 -> a + 1:17:boolean showDevelopmentError(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):287:303 -> b + 18:18:boolean showDevelopmentError(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):295:295 -> b + 19:19:boolean showDevelopmentError(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):292:292 -> b + 20:63:boolean showDevelopmentError(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):289:332 -> b + 1:3:void dismissForError(com.batch.android.messaging.model.MessagingError):273:275 -> c + 1:2:void dismiss():178:179 -> dismiss + 1:2:void dismissAllowingStateLoss():190:191 -> dismissAllowingStateLoss + boolean canAutoClose() -> g + 1:2:void dismissSafely():196:197 -> h + int getAutoCloseDelayMillis() -> i + void onAutoCloseCountdownStarted() -> l + void performAutoClose() -> m + 1:3:void onCreate(android.os.Bundle):81:83 -> onCreate + 1:7:void onCreateContextMenu(android.view.ContextMenu,android.view.View,android.view.ContextMenu$ContextMenuInfo):150:156 -> onCreateContextMenu + 1:12:android.app.Dialog onCreateDialog(android.os.Bundle):121:132 -> onCreateDialog + 1:14:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle):94:107 -> onCreateView + 1:6:void onDestroyView():140:145 -> onDestroyView + 1:2:boolean onMenuItemClick(android.view.MenuItem):163:164 -> onMenuItemClick + 1:2:void onSaveInstanceState(android.os.Bundle):115:116 -> onSaveInstanceState + 1:9:com.batch.android.messaging.css.Document getStyle():258:266 -> p + 10:17:com.batch.android.messaging.css.Document getStyle():262:269 -> p + 1:25:void refreshStatusbarStyle():227:251 -> q +com.batch.android.messaging.fragment.WebViewTemplateFragment$1 -> com.batch.android.c0.h$a: + int[] $SwitchMap$com$batch$android$BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause -> a + 1:1:void ():287:287 -> +com.batch.android.messaging.gif.BasicBitmapProvider -> com.batch.android.d0.a: + 1:1:void ():9:9 -> + void release(byte[]) -> a + void release(int[]) -> a + 1:1:android.graphics.Bitmap obtain(int,int,android.graphics.Bitmap$Config):14:14 -> a + 2:2:void release(android.graphics.Bitmap):19:19 -> a + 3:3:byte[] obtainByteArray(int):25:25 -> a + 1:1:int[] obtainIntArray(int):36:36 -> b +com.batch.android.messaging.gif.GifDecoder -> com.batch.android.d0.b: + int STATUS_PARTIAL_DECODE -> d + int TOTAL_ITERATION_COUNT_FOREVER -> e + int STATUS_FORMAT_ERROR -> b + int STATUS_OPEN_ERROR -> c + int STATUS_OK -> a + int getDelay(int) -> a + int read(java.io.InputStream,int) -> a + int read(byte[]) -> a + void setData(com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer) -> a + void setData(com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer,int) -> a + void setData(com.batch.android.messaging.gif.GifHeader,byte[]) -> a + void setDefaultBitmapConfig(android.graphics.Bitmap$Config) -> a + java.nio.ByteBuffer getData() -> e + int getCurrentFrameIndex() -> f + int getFrameCount() -> g + int getByteSize() -> h + int getNextDelay() -> i + int getLoopCount() -> j + android.graphics.Bitmap getNextFrame() -> k + int getWidth() -> l + void advance() -> m + int getNetscapeLoopCount() -> n + int getTotalIterationCount() -> o + int getHeight() -> p + void resetFrameIndex() -> q + int getStatus() -> r +com.batch.android.messaging.gif.GifDecoder$BitmapProvider -> com.batch.android.d0.b$a: + android.graphics.Bitmap obtain(int,int,android.graphics.Bitmap$Config) -> a + byte[] obtainByteArray(int) -> a + void release(android.graphics.Bitmap) -> a + void release(byte[]) -> a + void release(int[]) -> a + int[] obtainIntArray(int) -> b +com.batch.android.messaging.gif.GifDecoder$GifDecodeStatus -> com.batch.android.d0.b$b: +com.batch.android.messaging.gif.GifDrawable -> com.batch.android.d0.c: + java.util.Queue nextFrames -> g + int MESSAGE_RAN_OUT_OF_MEMORY -> n + int BUFFER_SIZE -> l + int MESSAGE_FRAME_PRODUCED -> m + long nextFrameDeadline -> h + com.batch.android.messaging.gif.GifDrawable$FrameInfo currentFrame -> f + com.batch.android.messaging.gif.GifDecoder gifDecoder -> e + int dpi -> b + java.util.concurrent.Executor frameProducerExecutor -> k + android.graphics.Paint paint -> a + java.lang.Runnable produceNextFrameRunnable -> j + boolean animating -> c + android.os.Handler mainThreadHandler -> i + boolean ranOutOfMemory -> d + 1:1:void (android.content.Context,com.batch.android.messaging.gif.GifDecoder):58:58 -> + 2:28:void (android.content.Context,com.batch.android.messaging.gif.GifDecoder):38:64 -> + 1:1:void access$000(com.batch.android.messaging.gif.GifDrawable,com.batch.android.messaging.gif.GifDrawable$FrameInfo):25:25 -> a + 2:2:void access$100(com.batch.android.messaging.gif.GifDrawable):25:25 -> a + 3:14:void produceNextFrame():72:83 -> a + 15:15:void onFrameProduced(com.batch.android.messaging.gif.GifDrawable$FrameInfo):89:89 -> a + 1:9:void ranOutOfMemory():130:138 -> b + 1:28:void requestNewFrameIfNeeded():94:121 -> c + 1:4:void draw(android.graphics.Canvas):149:152 -> draw + 1:4:int getIntrinsicHeight():175:178 -> getIntrinsicHeight + 1:4:int getIntrinsicWidth():184:187 -> getIntrinsicWidth + 1:1:int getOpacity():166:166 -> getOpacity + 1:1:boolean isRunning():210:210 -> isRunning + 1:1:void setAlpha(int):158:158 -> setAlpha + 1:5:void start():196:200 -> start + 1:1:void stop():205:205 -> stop +com.batch.android.messaging.gif.GifDrawable$1 -> com.batch.android.d0.c$a: + com.batch.android.messaging.gif.GifDrawable this$0 -> a + 1:1:void (com.batch.android.messaging.gif.GifDrawable,android.os.Looper):43:43 -> + 1:4:void handleMessage(android.os.Message):46:49 -> handleMessage +com.batch.android.messaging.gif.GifDrawable$FrameInfo -> com.batch.android.d0.c$b: + android.graphics.Bitmap bitmap -> a + int delay -> b + 1:3:void (android.graphics.Bitmap,int):218:220 -> +com.batch.android.messaging.gif.GifFrame -> com.batch.android.d0.d: + int DISPOSAL_BACKGROUND -> n + int DISPOSAL_PREVIOUS -> o + int DISPOSAL_UNSPECIFIED -> l + int DISPOSAL_NONE -> m + int bufferFrameStart -> j + int transIndex -> h + int delay -> i + int dispose -> g + int ih -> d + int iy -> b + int iw -> c + int ix -> a + boolean interlace -> e + boolean transparency -> f + int[] lct -> k + 1:1:void ():13:13 -> +com.batch.android.messaging.gif.GifFrame$GifDisposalMethod -> com.batch.android.d0.d$a: +com.batch.android.messaging.gif.GifHeader -> com.batch.android.d0.e: + int NETSCAPE_LOOP_COUNT_FOREVER -> n + com.batch.android.messaging.gif.GifFrame currentFrame -> d + int NETSCAPE_LOOP_COUNT_DOES_NOT_EXIST -> o + int bgColor -> l + int loopCount -> m + int bgIndex -> j + int pixelAspect -> k + int gctSize -> i + int width -> f + int height -> g + int[] gct -> a + int status -> b + int frameCount -> c + java.util.List frames -> e + boolean gctFlag -> h + 1:51:void ():15:65 -> + 1:1:int getHeight():68:68 -> a + 1:1:int getNumFrames():76:76 -> b + 1:1:int getStatus():84:84 -> c + 1:1:int getWidth():72:72 -> d +com.batch.android.messaging.gif.GifHeaderParser -> com.batch.android.d0.f: + int GCE_MASK_DISPOSAL_METHOD -> n + int GCE_DISPOSAL_METHOD_SHIFT -> o + int LABEL_COMMENT_EXTENSION -> l + int LABEL_PLAIN_TEXT_EXTENSION -> m + int LABEL_GRAPHIC_CONTROL_EXTENSION -> j + int LABEL_APPLICATION_EXTENSION -> k + int EXTENSION_INTRODUCER -> h + int TRAILER -> i + int MASK_INT_LOWEST_BYTE -> f + int IMAGE_SEPARATOR -> g + int blockSize -> d + java.nio.ByteBuffer rawData -> b + com.batch.android.messaging.gif.GifHeader header -> c + byte[] block -> a + int MAX_BLOCK_SIZE -> x + int MIN_FRAME_DELAY -> v + int DEFAULT_FRAME_DELAY -> w + int LSD_MASK_GCT_FLAG -> t + int LSD_MASK_GCT_SIZE -> u + int DESCRIPTOR_MASK_INTERLACE_FLAG -> r + int DESCRIPTOR_MASK_LCT_SIZE -> s + java.lang.String TAG -> e + int GCE_MASK_TRANSPARENT_COLOR_FLAG -> p + int DESCRIPTOR_MASK_LCT_FLAG -> q + 1:114:void ():21:134 -> + 1:3:com.batch.android.messaging.gif.GifHeader parse(java.nio.ByteBuffer):137:139 -> a + 4:7:com.batch.android.messaging.gif.GifHeaderParser setData(byte[]):152:155 -> a + 8:9:void clear():161:162 -> a + 10:30:int[] readColorTable(int):432:452 -> a + 1:4:com.batch.android.messaging.gif.GifHeaderParser setData(java.nio.ByteBuffer):143:146 -> b + 5:57:void readContents(int):217:269 -> b + 58:92:void readContents(int):225:259 -> b + 93:106:void readContents(int):239:252 -> b + 107:127:void readContents(int):235:255 -> b + 128:128:boolean err():526:526 -> b + 1:5:boolean isAnimated():197:201 -> c + 1:16:com.batch.android.messaging.gif.GifHeader parseHeader():174:189 -> d + 17:17:com.batch.android.messaging.gif.GifHeader parseHeader():175:175 -> d + 1:3:int read():510:512 -> e + 1:41:void readBitmap():318:358 -> f + 1:16:void readBlock():484:499 -> g + 1:1:void readContents():208:208 -> h + 1:32:void readGraphicControlExt():279:310 -> i + 1:12:void readHeader():380:391 -> j + 1:20:void readLSD():400:419 -> k + 1:8:void readNetscapeExt():366:373 -> l + 1:1:int readShort():522:522 -> m + 1:4:void reset():166:169 -> n + 1:3:void skip():474:476 -> o + 1:3:void skipImageData():463:465 -> p +com.batch.android.messaging.gif.GifHelper -> com.batch.android.d0.g: + int NEEDED_BYTES_FOR_TYPE_CHECK -> a + 1:1:void ():8:8 -> + 1:8:boolean isPotentiallyAGif(int[]):19:26 -> a + 9:14:boolean dataStartsWith(int[],byte[]):34:39 -> a + 15:19:com.batch.android.messaging.gif.GifDrawable getDrawableForBytes(android.content.Context,byte[],boolean):53:57 -> a +com.batch.android.messaging.gif.StandardGifDecoder -> com.batch.android.d0.h: + byte[] mainPixels -> o + com.batch.android.messaging.gif.GifHeader header -> r + short[] prefix -> l + java.nio.ByteBuffer rawData -> i + byte[] suffix -> m + android.graphics.Bitmap$Config bitmapConfig -> z + int COLOR_TRANSPARENT_BLACK -> G + int BYTES_PER_INTEGER -> E + int NULL_CODE -> C + int[] act -> f + com.batch.android.messaging.gif.GifHeaderParser parser -> k + int downsampledHeight -> w + byte[] block -> j + int[] mainScratch -> p + int status -> u + int framePointer -> q + android.graphics.Bitmap previousImage -> s + byte[] pixelStack -> n + int MASK_INT_LOWEST_BYTE -> F + int INITIAL_FRAME_POINTER -> D + int MAX_STACK_SIZE -> B + com.batch.android.messaging.gif.GifDecoder$BitmapProvider bitmapProvider -> h + boolean savePrevious -> t + int[] pct -> g + int downsampledWidth -> x + java.lang.Boolean isFirstFrameTransparent -> y + int sampleSize -> v + java.lang.String TAG -> A + 1:1:void (com.batch.android.messaging.gif.GifDecoder$BitmapProvider,java.nio.ByteBuffer):139:139 -> + 2:2:void (com.batch.android.messaging.gif.GifDecoder$BitmapProvider,com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer):144:144 -> + 3:4:void (com.batch.android.messaging.gif.GifDecoder$BitmapProvider,com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer,int):153:154 -> + 5:5:void (com.batch.android.messaging.gif.GifDecoder$BitmapProvider):157:157 -> + 6:72:void (com.batch.android.messaging.gif.GifDecoder$BitmapProvider):93:159 -> + 1:2:int getDelay(int):191:192 -> a + 3:27:int read(java.io.InputStream,int):312:336 -> a + 28:28:void setData(com.batch.android.messaging.gif.GifHeader,byte[]):361:361 -> a + 29:29:void setData(com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer):366:366 -> a + 30:54:void setData(com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer,int):375:399 -> a + 55:55:void setData(com.batch.android.messaging.gif.GifHeader,java.nio.ByteBuffer,int):372:372 -> a + 56:59:com.batch.android.messaging.gif.GifHeaderParser getHeaderParser():404:407 -> a + 60:65:int read(byte[]):413:418 -> a + 66:72:void setDefaultBitmapConfig(android.graphics.Bitmap$Config):424:430 -> a + 73:120:android.graphics.Bitmap setPixels(com.batch.android.messaging.gif.GifFrame,com.batch.android.messaging.gif.GifFrame):439:486 -> a + 121:139:android.graphics.Bitmap setPixels(com.batch.android.messaging.gif.GifFrame,com.batch.android.messaging.gif.GifFrame):483:501 -> a + 140:155:android.graphics.Bitmap setPixels(com.batch.android.messaging.gif.GifFrame,com.batch.android.messaging.gif.GifFrame):499:514 -> a + 156:245:void copyCopyIntoScratchRobust(com.batch.android.messaging.gif.GifFrame):564:653 -> a + 246:280:int averageColorsNear(int,int,int):668:702 -> a + 1:42:void copyIntoScratchFast(com.batch.android.messaging.gif.GifFrame):519:560 -> b + 43:45:android.graphics.Bitmap getNextBitmap():864:866 -> b + 1:123:void decodeBitmapData(com.batch.android.messaging.gif.GifFrame):717:839 -> c + 124:128:int readBlock():855:859 -> c + 1:15:void clear():341:355 -> clear + 1:1:int readByte():846:846 -> d + 1:1:java.nio.ByteBuffer getData():175:175 -> e + 1:1:int getCurrentFrameIndex():213:213 -> f + 1:1:int getFrameCount():208:208 -> g + 1:1:int getByteSize():248:248 -> h + 1:5:int getNextDelay():199:203 -> i + 1:1:int getLoopCount():224:224 -> j + 1:51:android.graphics.Bitmap getNextFrame():254:304 -> k + 52:53:android.graphics.Bitmap getNextFrame():264:265 -> k + 1:1:int getWidth():164:164 -> l + 1:1:void advance():185:185 -> m + 1:1:int getNetscapeLoopCount():232:232 -> n + 1:1:int getTotalIterationCount():237:237 -> o + 1:1:int getHeight():169:169 -> p + 1:1:void resetFrameIndex():218:218 -> q + 1:1:int getStatus():180:180 -> r +com.batch.android.messaging.model.Action -> com.batch.android.e0.a: + com.batch.android.json.JSONObject args -> b + java.lang.String action -> a + 1:3:void (java.lang.String,com.batch.android.json.JSONObject):13:15 -> + 1:1:boolean isDismissAction():19:19 -> a +com.batch.android.messaging.model.AlertMessage -> com.batch.android.e0.b: + java.lang.String titleText -> g + com.batch.android.messaging.model.CTA acceptCTA -> i + java.lang.String cancelButtonText -> h + 1:1:void ():5:5 -> +com.batch.android.messaging.model.BannerMessage -> com.batch.android.e0.c: + 1:1:void ():5:5 -> +com.batch.android.messaging.model.BaseBannerMessage -> com.batch.android.e0.d: + java.lang.String css -> g + long globalTapDelay -> j + boolean showCloseButton -> o + java.lang.String titleText -> h + boolean allowSwipeToDismiss -> k + java.lang.String imageDescription -> m + java.lang.String imageURL -> l + com.batch.android.messaging.model.BaseBannerMessage$CTADirection ctaDirection -> q + java.util.List ctas -> n + com.batch.android.messaging.model.Action globalTapAction -> i + int autoCloseDelay -> p + 1:15:void ():7:21 -> +com.batch.android.messaging.model.BaseBannerMessage$CTADirection -> com.batch.android.e0.d$a: + com.batch.android.messaging.model.BaseBannerMessage$CTADirection HORIZONTAL -> a + com.batch.android.messaging.model.BaseBannerMessage$CTADirection VERTICAL -> b + com.batch.android.messaging.model.BaseBannerMessage$CTADirection[] $VALUES -> c + 1:2:void ():24:25 -> + 3:3:void ():23:23 -> + 1:1:void (java.lang.String,int):23:23 -> + 1:1:com.batch.android.messaging.model.BaseBannerMessage$CTADirection valueOf(java.lang.String):23:23 -> valueOf + 1:1:com.batch.android.messaging.model.BaseBannerMessage$CTADirection[] values():23:23 -> values +com.batch.android.messaging.model.CTA -> com.batch.android.e0.e: + java.lang.String label -> c + 1:2:void (java.lang.String,java.lang.String,com.batch.android.json.JSONObject):13:14 -> +com.batch.android.messaging.model.ImageMessage -> com.batch.android.e0.f: + java.lang.String css -> g + int autoCloseDelay -> n + long globalTapDelay -> i + boolean isFullscreen -> o + java.lang.String imageURL -> k + boolean allowSwipeToDismiss -> j + java.lang.String imageDescription -> l + com.batch.android.messaging.Size2D imageSize -> m + com.batch.android.messaging.model.Action globalTapAction -> h + 1:1:void ():6:6 -> +com.batch.android.messaging.model.Message -> com.batch.android.e0.g: + com.batch.android.json.JSONObject eventData -> e + com.batch.android.messaging.model.Message$Source source -> f + java.lang.String messageIdentifier -> a + java.lang.String bodyText -> c + java.lang.String devTrackingIdentifier -> b + java.lang.String bodyRawHtml -> d + 1:12:void ():10:21 -> + 1:5:java.lang.CharSequence getBody():28:32 -> a + 1:12:android.text.Spanned getSpannedBody():37:48 -> b +com.batch.android.messaging.model.Message$Source -> com.batch.android.e0.g$a: + com.batch.android.messaging.model.Message$Source UNKNOWN -> a + com.batch.android.messaging.model.Message$Source LOCAL -> c + com.batch.android.messaging.model.Message$Source[] $VALUES -> d + com.batch.android.messaging.model.Message$Source LANDING -> b + 1:3:void ():56:58 -> + 4:4:void ():55:55 -> + 1:1:void (java.lang.String,int):55:55 -> + 1:1:com.batch.android.messaging.model.Message$Source valueOf(java.lang.String):55:55 -> valueOf + 1:1:com.batch.android.messaging.model.Message$Source[] values():55:55 -> values +com.batch.android.messaging.model.MessagingError -> com.batch.android.e0.h: + com.batch.android.messaging.model.MessagingError[] $VALUES -> f + com.batch.android.messaging.model.MessagingError CLIENT_NETWORK -> e + com.batch.android.messaging.model.MessagingError INVALID_RESPONSE -> d + com.batch.android.messaging.model.MessagingError SERVER_FAILURE -> c + com.batch.android.messaging.model.MessagingError UNKNOWN -> b + int code -> a + 1:16:void ():10:25 -> + 17:17:void ():6:6 -> + 1:2:void (java.lang.String,int,int):29:30 -> + 1:1:com.batch.android.messaging.model.MessagingError valueOf(java.lang.String):6:6 -> valueOf + 1:1:com.batch.android.messaging.model.MessagingError[] values():6:6 -> values +com.batch.android.messaging.model.ModalMessage -> com.batch.android.e0.i: + 1:1:void ():5:5 -> +com.batch.android.messaging.model.UniversalMessage -> com.batch.android.e0.j: + java.lang.String css -> g + java.lang.String titleText -> i + java.lang.String headingText -> h + java.lang.String subtitleText -> j + java.lang.String videoURL -> m + java.lang.String heroImageURL -> l + java.lang.Boolean showCloseButton -> o + java.lang.String heroDescription -> n + java.lang.Boolean attachCTAsBottom -> p + java.lang.Boolean flipHeroVertical -> s + java.lang.Boolean flipHeroHorizontal -> t + java.lang.Boolean stackCTAsHorizontally -> q + java.lang.Boolean stretchCTAsHorizontally -> r + java.lang.Double heroSplitRatio -> u + int autoCloseDelay -> v + java.util.List ctas -> k + 1:9:void ():9:17 -> + 1:6:java.lang.String getVoiceString():32:37 -> c +com.batch.android.messaging.model.WebViewMessage -> com.batch.android.e0.k: + java.lang.String css -> g + java.lang.String url -> h + boolean openDeeplinksInApp -> j + boolean devMode -> k + int timeout -> i + 1:1:void ():5:5 -> +com.batch.android.messaging.view.AnimatedCloseButton -> com.batch.android.messaging.view.a: + long duration -> v + long animationEndDate -> u + boolean animating -> t + 1:1:void (android.content.Context):21:21 -> + 2:4:void (android.content.Context):16:18 -> + 5:5:void (android.content.Context,android.util.AttributeSet):25:25 -> + 6:8:void (android.content.Context,android.util.AttributeSet):16:18 -> + 9:9:void (android.content.Context,android.util.AttributeSet,int):29:29 -> + 10:12:void (android.content.Context,android.util.AttributeSet,int):16:18 -> + 13:13:void (android.content.Context,android.util.AttributeSet,int,int):34:34 -> + 14:16:void (android.content.Context,android.util.AttributeSet,int,int):16:18 -> + 1:5:void animateForDuration(long):38:42 -> a + 1:1:boolean isAnimating():46:46 -> d + 1:12:void onAnimationFrame():52:63 -> e + 1:3:void onDraw(android.graphics.Canvas):69:71 -> onDraw + 1:11:void onRestoreInstanceState(android.os.Parcelable):89:99 -> onRestoreInstanceState + 1:4:android.os.Parcelable onSaveInstanceState():80:83 -> onSaveInstanceState +com.batch.android.messaging.view.AnimatedCountdownSavedState -> com.batch.android.messaging.view.AnimatedCountdownSavedState: + long animationEndDate -> b + long duration -> c + boolean animating -> a + 1:1:void ():64:64 -> + 1:1:void (android.os.Parcel):20:20 -> + 2:8:void (android.os.Parcel):15:21 -> + 9:9:void (android.os.Parcel,java.lang.ClassLoader):27:27 -> + 10:23:void (android.os.Parcel,java.lang.ClassLoader):15:28 -> + 24:24:void (android.os.Parcelable):33:33 -> + 25:27:void (android.os.Parcelable):15:17 -> + 1:3:void readParcel(android.os.Parcel,java.lang.ClassLoader):37:39 -> a + 1:1:java.lang.String toString():53:53 -> toString + 1:4:void writeToParcel(android.os.Parcel,int):44:47 -> writeToParcel +com.batch.android.messaging.view.AnimatedCountdownSavedState$1 -> com.batch.android.messaging.view.AnimatedCountdownSavedState$a: + 1:1:void ():64:64 -> + 1:1:com.batch.android.messaging.view.AnimatedCountdownSavedState createFromParcel(android.os.Parcel):67:67 -> a + 2:2:com.batch.android.messaging.view.AnimatedCountdownSavedState[] newArray(int):71:71 -> a + 1:1:java.lang.Object createFromParcel(android.os.Parcel):64:64 -> createFromParcel + 1:1:java.lang.Object[] newArray(int):64:64 -> newArray +com.batch.android.messaging.view.CloseButton -> com.batch.android.messaging.view.CloseButton: + boolean showBorder -> n + float countdownProgress -> f + java.lang.String TAG -> o + int computedGlyphPadding -> g + int glyphPadding -> d + int glyphWidth -> e + int backgroundColor -> b + android.graphics.RectF countdownOval -> l + int glyphColor -> c + int padding -> a + android.graphics.RectF borderOval -> m + android.graphics.Paint borderPaint -> j + android.graphics.Paint glyphPaint -> i + android.graphics.Paint backgroundPaint -> h + android.graphics.drawable.Drawable foregoundDrawable -> k + int UNSCALED_GLYPH_PADDING_PX -> r + int UNSCALED_GLYPH_WIDTH_PX -> s + int DEFAULT_SIZE_DP -> p + int DEFAULT_PADDING_DP -> q + 1:1:void (android.content.Context):66:66 -> + 2:32:void (android.content.Context):37:67 -> + 33:33:void (android.content.Context,android.util.AttributeSet):71:71 -> + 34:69:void (android.content.Context,android.util.AttributeSet):37:72 -> + 70:70:void (android.content.Context,android.util.AttributeSet,int):76:76 -> + 71:111:void (android.content.Context,android.util.AttributeSet,int):37:77 -> + 112:112:void (android.content.Context,android.util.AttributeSet,int,int):82:82 -> + 113:159:void (android.content.Context,android.util.AttributeSet,int,int):37:83 -> + 1:33:void init():87:119 -> a + 34:71:void applyStyleRules(java.util.Map):322:359 -> a + 1:9:void recomputeMetrics():144:152 -> b + 10:17:void recomputeMetrics():151:158 -> b + 18:18:void recomputeMetrics():156:156 -> b + 19:32:void recomputeMetrics():155:168 -> b + 1:18:void refreshPaint():123:140 -> c + 1:5:void draw(android.graphics.Canvas):292:296 -> draw + 1:3:void drawableHotspotChanged(float,float):395:397 -> drawableHotspotChanged + 1:7:void drawableStateChanged():370:376 -> drawableStateChanged + 1:1:android.view.ViewOutlineProvider getOutlineProvider():249:249 -> getOutlineProvider + 1:1:int getPadding():212:212 -> getPadding + 1:3:void jumpDrawablesToCurrentState():386:388 -> jumpDrawablesToCurrentState + 1:7:void onDraw(android.graphics.Canvas):264:270 -> onDraw + 8:19:void onDraw(android.graphics.Canvas):266:277 -> onDraw + 20:33:void onDraw(android.graphics.Canvas):273:286 -> onDraw + 1:16:void onMeasure(int,int):302:317 -> onMeasure + 1:5:void onSizeChanged(int,int,int,int):254:258 -> onSizeChanged + 1:2:void setBackgroundColor(int):173:174 -> setBackgroundColor + 1:2:void setCountdownProgress(float):221:222 -> setCountdownProgress + 1:2:void setForegoundDrawable(android.graphics.drawable.Drawable):183:184 -> setForegoundDrawable + 1:2:void setGlyphColor(int):178:179 -> setGlyphColor + 1:3:void setGlyphPadding(int):231:233 -> setGlyphPadding + 1:3:void setGlyphWidth(int):242:244 -> setGlyphWidth + 1:1:void setPadding(int,int,int,int):202:202 -> setPadding + 2:3:void setPadding(int):207:208 -> setPadding + 1:2:void setShowBorder(boolean):191:192 -> setShowBorder + 1:1:boolean verifyDrawable(android.graphics.drawable.Drawable):381:381 -> verifyDrawable +com.batch.android.messaging.view.CloseButton$1 -> com.batch.android.messaging.view.CloseButton$a: + com.batch.android.messaging.view.CloseButton this$0 -> a + 1:1:void (com.batch.android.messaging.view.CloseButton):89:89 -> + 1:6:void getOutline(android.view.View,android.graphics.Outline):92:92 -> getOutline +com.batch.android.messaging.view.CountdownView -> com.batch.android.f0.a: + long animationEndDate -> b + long duration -> c + int MAX_PROGRESS -> e + boolean animating -> a + java.lang.String TAG -> d + 1:1:void (android.content.Context):35:35 -> + 2:10:void (android.content.Context):30:38 -> + 1:8:void applyStyleRules(java.util.Map):43:50 -> a + 9:13:void animateForDuration(long):57:61 -> a + 14:25:void onAnimationFrame():71:82 -> a + 1:1:boolean isAnimating():65:65 -> isAnimating + 1:3:void onDraw(android.graphics.Canvas):88:90 -> onDraw + 1:11:void onRestoreInstanceState(android.os.Parcelable):119:129 -> onRestoreInstanceState + 1:4:android.os.Parcelable onSaveInstanceState():110:113 -> onSaveInstanceState + 1:4:void setColor(int):99:102 -> setColor +com.batch.android.messaging.view.DelegatedTouchEventViewGroup -> com.batch.android.f0.b: + boolean superOnTouchEvent(android.view.MotionEvent) -> a + boolean superOnInterceptTouchEvent(android.view.MotionEvent) -> b +com.batch.android.messaging.view.DelegatedTouchEventViewGroup$Delegate -> com.batch.android.f0.b$a: + boolean onInterceptTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup) -> a + boolean onTouchEvent(android.view.MotionEvent,com.batch.android.messaging.view.DelegatedTouchEventViewGroup,boolean) -> a +com.batch.android.messaging.view.FixedRatioFrameLayout -> com.batch.android.f0.c: + com.batch.android.messaging.Size2D targetSize -> a + 1:2:void (android.content.Context,com.batch.android.messaging.Size2D):21:22 -> + 3:3:void (android.content.Context,android.util.AttributeSet):26:26 -> + 4:4:void (android.content.Context,android.util.AttributeSet,int):30:30 -> + 5:5:void (android.content.Context,android.util.AttributeSet,int,int):40:40 -> + 1:1:void init(com.batch.android.messaging.Size2D):44:44 -> a + 1:30:void onMeasure(int,int):57:86 -> onMeasure + 31:31:void onMeasure(int,int):84:84 -> onMeasure + 1:5:void setTargetSize(com.batch.android.messaging.Size2D):48:52 -> setTargetSize +com.batch.android.messaging.view.FlexboxLayout -> com.batch.android.f0.d: + int FLEX_WRAP_NOWRAP -> n + int FLEX_DIRECTION_COLUMN -> l + android.util.SparseIntArray mOrderCache -> g + int FLEX_DIRECTION_ROW -> j + int mAlignItems -> d + int ALIGN_CONTENT_SPACE_AROUND -> E + int mFlexWrap -> b + int ALIGN_CONTENT_CENTER -> C + int ALIGN_CONTENT_FLEX_START -> A + int[] mReorderedIndices -> f + int ALIGN_ITEMS_BASELINE -> y + int ALIGN_ITEMS_FLEX_END -> w + java.util.List mFlexLines -> h + int JUSTIFY_CONTENT_SPACE_AROUND -> u + int JUSTIFY_CONTENT_CENTER -> s + int JUSTIFY_CONTENT_FLEX_START -> q + int FLEX_WRAP_WRAP -> o + int FLEX_DIRECTION_COLUMN_REVERSE -> m + int FLEX_DIRECTION_ROW_REVERSE -> k + int ALIGN_CONTENT_STRETCH -> F + int ALIGN_CONTENT_SPACE_BETWEEN -> D + int mAlignContent -> e + int ALIGN_CONTENT_FLEX_END -> B + int mJustifyContent -> c + int mFlexDirection -> a + boolean[] mChildrenFrozen -> i + int ALIGN_ITEMS_STRETCH -> z + int ALIGN_ITEMS_CENTER -> x + int ALIGN_ITEMS_FLEX_START -> v + int JUSTIFY_CONTENT_SPACE_BETWEEN -> t + int JUSTIFY_CONTENT_FLEX_END -> r + int FLEX_WRAP_WRAP_REVERSE -> p + 1:1:void (android.content.Context):240:240 -> + 2:2:void (android.content.Context,android.util.AttributeSet):244:244 -> + 3:3:void (android.content.Context,android.util.AttributeSet,int):248:248 -> + 4:4:void (android.content.Context,android.util.AttributeSet,int):230:230 -> + 1:20:int[] createReorderedIndices(android.view.View,int,android.view.ViewGroup$LayoutParams):323:342 -> a + 21:34:int[] createReorderedIndices(android.view.View,int,android.view.ViewGroup$LayoutParams):333:346 -> a + 35:37:int[] createReorderedIndices():356:358 -> a + 38:47:int[] sortOrdersIntoReorderedIndices(int,java.util.List):362:371 -> a + 48:55:java.util.List createOrders(int):379:386 -> a + 56:102:void measureHorizontal(int,int):431:477 -> a + 103:110:void measureHorizontal(int,int):475:482 -> a + 111:136:void measureHorizontal(int,int):480:505 -> a + 137:172:void measureHorizontal(int,int):500:535 -> a + 173:214:void measureHorizontal(int,int):533:574 -> a + 215:237:void checkSizeConstraints(android.view.View):702:724 -> a + 238:238:void checkSizeConstraints(android.view.View):722:722 -> a + 239:241:void addFlexLineIfLastFlexItem(int,int,com.batch.android.messaging.view.FlexboxLayout$FlexLine):730:732 -> a + 242:242:void determineMainSize(int,int,int):774:774 -> a + 243:250:void determineMainSize(int,int,int):764:771 -> a + 251:280:void determineMainSize(int,int,int):753:782 -> a + 281:366:int expandFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):811:896 -> a + 367:372:int expandFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):894:899 -> a + 373:402:int expandFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):831:860 -> a + 403:452:int expandFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):858:907 -> a + 453:453:int expandFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):812:812 -> a + 454:454:void determineCrossSize(int,int,int,int):1068:1068 -> a + 455:456:void determineCrossSize(int,int,int,int):1064:1065 -> a + 457:580:void determineCrossSize(int,int,int,int):1059:1182 -> a + 581:586:void stretchViewHorizontally(android.view.View,int):1272:1277 -> a + 587:587:void stretchViewHorizontally(android.view.View,int):1275:1275 -> a + 588:588:boolean isWrapRequired(int,int,int,int,int,com.batch.android.messaging.view.FlexboxLayout$LayoutParams):1409:1409 -> a + 589:636:void layoutHorizontal(boolean,int,int,int,int):1493:1540 -> a + 637:646:void layoutHorizontal(boolean,int,int,int,int):1527:1536 -> a + 647:647:void layoutHorizontal(boolean,int,int,int,int):1523:1523 -> a + 648:693:void layoutHorizontal(boolean,int,int,int,int):1519:1564 -> a + 694:712:void layoutHorizontal(boolean,int,int,int,int):1557:1575 -> a + 713:734:void layoutHorizontal(boolean,int,int,int,int):1568:1589 -> a + 735:754:void layoutHorizontal(boolean,int,int,int,int):1581:1600 -> a + 755:771:void layoutHorizontal(boolean,int,int,int,int):1592:1608 -> a + 772:825:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1645:1698 -> a + 826:837:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1694:1705 -> a + 838:838:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1701:1701 -> a + 839:839:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1676:1676 -> a + 840:853:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1674:1687 -> a + 854:854:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1683:1683 -> a + 855:857:void layoutSingleChildHorizontal(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int,int,int):1656:1658 -> a + 858:906:void layoutVertical(boolean,boolean,int,int,int,int):1735:1783 -> a + 907:916:void layoutVertical(boolean,boolean,int,int,int,int):1770:1779 -> a + 917:917:void layoutVertical(boolean,boolean,int,int,int,int):1766:1766 -> a + 918:964:void layoutVertical(boolean,boolean,int,int,int,int):1762:1808 -> a + 965:984:void layoutVertical(boolean,boolean,int,int,int,int):1800:1819 -> a + 985:1006:void layoutVertical(boolean,boolean,int,int,int,int):1811:1832 -> a + 1007:1026:void layoutVertical(boolean,boolean,int,int,int,int):1824:1843 -> a + 1027:1043:void layoutVertical(boolean,boolean,int,int,int,int):1835:1851 -> a + 1044:1090:void layoutSingleChildVertical(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,boolean,int,int,int,int,int):1889:1935 -> a + 1091:1093:void layoutSingleChildVertical(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,boolean,int,int,int,int,int):1909:1911 -> a + 1094:1106:void layoutSingleChildVertical(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,boolean,int,int,int,int,int):1908:1920 -> a + 1107:1107:void layoutSingleChildVertical(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,boolean,int,int,int,int,int):1917:1917 -> a + 1108:1110:void layoutSingleChildVertical(android.view.View,com.batch.android.messaging.view.FlexboxLayout$FlexLine,boolean,int,int,int,int,int):1901:1903 -> a + 1111:1111:com.batch.android.messaging.view.FlexboxLayout$LayoutParams generateLayoutParams(android.util.AttributeSet):1953:1953 -> a + 1:2:void addView(android.view.View,int,android.view.ViewGroup$LayoutParams):301:302 -> addView + 1:4:android.view.View getReorderedChildAt(int):289:292 -> b + 5:18:boolean isOrderChangedFromLastMeasurement():398:411 -> b + 19:62:void measureVertical(int,int):590:633 -> b + 63:70:void measureVertical(int,int):631:638 -> b + 71:96:void measureVertical(int,int):636:661 -> b + 97:131:void measureVertical(int,int):656:690 -> b + 132:212:int shrinkFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):936:1016 -> b + 213:218:int shrinkFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):1014:1019 -> b + 219:248:int shrinkFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):956:985 -> b + 249:293:int shrinkFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):983:1027 -> b + 294:294:int shrinkFlexItems(com.batch.android.messaging.view.FlexboxLayout$FlexLine,int,int,int,int):938:938 -> b + 295:300:void stretchViewVertically(android.view.View,int):1256:1261 -> b + 301:301:void stretchViewVertically(android.view.View,int):1259:1259 -> b + 302:320:void setMeasuredDimensionForFlex(int,int,int,int):1298:1316 -> b + 321:322:void setMeasuredDimensionForFlex(int,int,int,int):1312:1313 -> b + 323:360:void setMeasuredDimensionForFlex(int,int,int,int):1307:1344 -> b + 361:361:void setMeasuredDimensionForFlex(int,int,int,int):1340:1340 -> b + 362:411:void setMeasuredDimensionForFlex(int,int,int,int):1330:1379 -> b + 412:412:void setMeasuredDimensionForFlex(int,int,int,int):1375:1375 -> b + 413:432:void setMeasuredDimensionForFlex(int,int,int,int):1362:1381 -> b + 1:20:void stretchViews(int,int):1205:1224 -> c + 21:21:void stretchViews(int,int):1221:1221 -> c + 22:47:void stretchViews(int,int):1217:1242 -> c + 48:48:void stretchViews(int,int):1239:1239 -> c + 49:49:void stretchViews(int,int):1235:1235 -> c + 1:1:boolean checkLayoutParams(android.view.ViewGroup$LayoutParams):1948:1948 -> checkLayoutParams + 1:1:android.view.ViewGroup$LayoutParams generateLayoutParams(android.util.AttributeSet):66:66 -> generateLayoutParams + 2:2:android.view.ViewGroup$LayoutParams generateLayoutParams(android.view.ViewGroup$LayoutParams):1958:1958 -> generateLayoutParams + 1:1:int getAlignContent():2011:2011 -> getAlignContent + 1:1:int getAlignItems():1999:1999 -> getAlignItems + 1:1:int getFlexDirection():1963:1963 -> getFlexDirection + 1:1:int getFlexWrap():1975:1975 -> getFlexWrap + 1:1:int getJustifyContent():1987:1987 -> getJustifyContent + 1:2:int getLargestMainSize():1422:1423 -> getLargestMainSize + 1:2:int getSumOfCrossSize():1435:1436 -> getSumOfCrossSize + 1:27:void onLayout(boolean,int,int,int,int):1443:1469 -> onLayout + 28:31:void onLayout(boolean,int,int,int,int):1463:1466 -> onLayout + 32:35:void onLayout(boolean,int,int,int,int):1456:1459 -> onLayout + 36:36:void onLayout(boolean,int,int,int,int):1452:1452 -> onLayout + 37:37:void onLayout(boolean,int,int,int,int):1448:1448 -> onLayout + 1:21:void onMeasure(int,int):253:273 -> onMeasure + 22:22:void onMeasure(int,int):270:270 -> onMeasure + 23:33:void onMeasure(int,int):266:276 -> onMeasure + 1:3:void setAlignContent(int):2015:2017 -> setAlignContent + 1:3:void setAlignItems(int):2003:2005 -> setAlignItems + 1:3:void setFlexDirection(int):1967:1969 -> setFlexDirection + 1:3:void setFlexWrap(int):1979:1981 -> setFlexWrap + 1:3:void setJustifyContent(int):1991:1993 -> setJustifyContent +com.batch.android.messaging.view.FlexboxLayout$1 -> com.batch.android.f0.d$a: +com.batch.android.messaging.view.FlexboxLayout$AlignContent -> com.batch.android.f0.d$b: +com.batch.android.messaging.view.FlexboxLayout$AlignItems -> com.batch.android.f0.d$c: +com.batch.android.messaging.view.FlexboxLayout$FlexDirection -> com.batch.android.f0.d$d: +com.batch.android.messaging.view.FlexboxLayout$FlexLine -> com.batch.android.f0.d$e: + float totalFlexShrink -> e + float totalFlexGrow -> d + int maxBaseline -> f + java.util.List indicesAlignSelfStretch -> g + int crossSize -> b + int itemCount -> c + int mainSize -> a + 1:35:void ():2185:2219 -> + 36:36:void (com.batch.android.messaging.view.FlexboxLayout$1):2185:2185 -> +com.batch.android.messaging.view.FlexboxLayout$FlexWrap -> com.batch.android.f0.d$f: +com.batch.android.messaging.view.FlexboxLayout$JustifyContent -> com.batch.android.f0.d$g: +com.batch.android.messaging.view.FlexboxLayout$LayoutParams -> com.batch.android.f0.d$h: + float FLEX_GROW_DEFAULT -> l + int ALIGN_SELF_AUTO -> o + boolean wrapBefore -> j + int ORDER_DEFAULT -> k + int maxWidth -> h + float flexBasisPercent -> e + int maxHeight -> i + int minWidth -> f + float flexShrink -> c + int minHeight -> g + float flexGrow -> b + int alignSelf -> d + int order -> a + int ALIGN_SELF_STRETCH -> t + int MAX_SIZE -> u + int ALIGN_SELF_CENTER -> r + int ALIGN_SELF_BASELINE -> s + float FLEX_BASIS_PERCENT_DEFAULT -> n + int ALIGN_SELF_FLEX_START -> p + float FLEX_SHRINK_DEFAULT -> m + int ALIGN_SELF_FLEX_END -> q + 1:1:void (android.content.Context,android.util.AttributeSet):2126:2126 -> + 2:60:void (android.content.Context,android.util.AttributeSet):2053:2111 -> + 61:61:void (com.batch.android.messaging.view.FlexboxLayout$LayoutParams):2130:2130 -> + 62:149:void (com.batch.android.messaging.view.FlexboxLayout$LayoutParams):2053:2140 -> + 150:150:void (android.view.ViewGroup$LayoutParams):2144:2144 -> + 151:209:void (android.view.ViewGroup$LayoutParams):2053:2111 -> + 210:210:void (int,int):2148:2148 -> + 211:269:void (int,int):2053:2111 -> +com.batch.android.messaging.view.FlexboxLayout$Order -> com.batch.android.f0.d$i: + int order -> b + int index -> a + 1:1:void ():2156:2156 -> + 2:2:void (com.batch.android.messaging.view.FlexboxLayout$1):2156:2156 -> + 1:4:int compareTo(com.batch.android.messaging.view.FlexboxLayout$Order):2170:2173 -> a + 1:1:int compareTo(java.lang.Object):2156:2156 -> compareTo + 1:1:java.lang.String toString():2178:2178 -> toString +com.batch.android.messaging.view.MaximumHeightScrollView -> com.batch.android.f0.e: + int maxHeightPx -> a + 1:1:void (android.content.Context):17:17 -> + 2:2:void (android.content.Context):14:14 -> + 3:3:void (android.content.Context,android.util.AttributeSet):21:21 -> + 4:4:void (android.content.Context,android.util.AttributeSet):14:14 -> + 5:5:void (android.content.Context,android.util.AttributeSet,int):25:25 -> + 6:6:void (android.content.Context,android.util.AttributeSet,int):14:14 -> + 7:7:void (android.content.Context,android.util.AttributeSet,int,int):31:31 -> + 8:8:void (android.content.Context,android.util.AttributeSet,int,int):14:14 -> + 1:7:void onMeasure(int,int):41:47 -> onMeasure + 1:1:void setMaxHeight(int):35:35 -> setMaxHeight +com.batch.android.messaging.view.PannableBannerFrameLayout -> com.batch.android.f0.f: + java.lang.Object cancellationAnimation -> h + int touchSlop -> l + int FLING_VELOCITY_DISMISS_THRESHOLD -> m + boolean isPanning -> i + int cancellationAnimationDuration -> j + float initialInterceptYOffset -> g + int dismissAnimationDuration -> k + float initialSwipeYOffset -> f + android.view.GestureDetector detector -> b + com.batch.android.messaging.view.PannableBannerFrameLayout$OnDismissListener dismissListener -> d + com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection dismissDirection -> c + boolean isPannable -> e + boolean supportsAndroidXAnimation -> a + float PAN_HEIGHT_DISMISS_RATIO_THRESHOLD -> n + 1:1:void (android.content.Context):86:86 -> + 2:37:void (android.content.Context):52:87 -> + 38:38:void (android.content.Context,android.util.AttributeSet):91:91 -> + 39:79:void (android.content.Context,android.util.AttributeSet):52:92 -> + 80:80:void (android.content.Context,android.util.AttributeSet,int):96:96 -> + 81:126:void (android.content.Context,android.util.AttributeSet,int):52:97 -> + 1:1:com.batch.android.messaging.view.PannableBannerFrameLayout$OnDismissListener access$000(com.batch.android.messaging.view.PannableBannerFrameLayout):28:28 -> a + 2:2:boolean hasYPassedTouchSlop(float,float):296:296 -> a + 3:4:void beginPan(float):300:301 -> a + 5:10:void cancelCancellationAnimation():330:335 -> a + 1:40:void dismiss():340:379 -> b + 1:15:void setup():101:115 -> c + 1:10:void startCancelAnimation():305:314 -> d + 1:8:void startFallbackCancelAnimation():319:326 -> e + 1:15:boolean onFling(android.view.MotionEvent,android.view.MotionEvent,float,float):275:289 -> onFling + 1:26:boolean onInterceptTouchEvent(android.view.MotionEvent):133:158 -> onInterceptTouchEvent + 27:27:boolean onInterceptTouchEvent(android.view.MotionEvent):142:142 -> onInterceptTouchEvent + 1:67:boolean onTouchEvent(android.view.MotionEvent):172:238 -> onTouchEvent + 68:115:boolean onTouchEvent(android.view.MotionEvent):185:232 -> onTouchEvent + 116:177:boolean onTouchEvent(android.view.MotionEvent):181:242 -> onTouchEvent + 1:1:void setDismissDirection(com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection):120:120 -> setDismissDirection + 1:1:void setDismissListener(com.batch.android.messaging.view.PannableBannerFrameLayout$OnDismissListener):124:124 -> setDismissListener + 1:1:void setPannable(boolean):128:128 -> setPannable +com.batch.android.messaging.view.PannableBannerFrameLayout$1 -> com.batch.android.f0.f$a: + com.batch.android.messaging.view.PannableBannerFrameLayout this$0 -> a + 1:1:void (com.batch.android.messaging.view.PannableBannerFrameLayout):352:352 -> + 1:2:void onAnimationEnd(android.animation.Animator):358:359 -> onAnimationEnd +com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection -> com.batch.android.f0.f$b: + com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection TOP -> a + com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection BOTTOM -> b + com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection[] $VALUES -> c + 1:2:void ():386:387 -> + 3:3:void ():385:385 -> + 1:1:void (java.lang.String,int):385:385 -> + 1:1:com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection valueOf(java.lang.String):385:385 -> valueOf + 1:1:com.batch.android.messaging.view.PannableBannerFrameLayout$DismissDirection[] values():385:385 -> values +com.batch.android.messaging.view.PannableBannerFrameLayout$OnDismissListener -> com.batch.android.f0.f$c: + void onDismiss(com.batch.android.messaging.view.PannableBannerFrameLayout) -> a +com.batch.android.messaging.view.PositionableGradientDrawable -> com.batch.android.f0.g: + com.batch.android.messaging.view.PositionableGradientDrawable$GradientState mGradientState -> a + boolean mGradientIsDirty -> k + android.graphics.Rect mPadding -> c + android.graphics.Paint mLayerPaint -> j + android.graphics.PorterDuffColorFilter mTintFilter -> f + android.graphics.Paint mStrokePaint -> d + int RADIUS_TYPE_FRACTION_PARENT -> y + android.graphics.Paint mFillPaint -> b + int RADIUS_TYPE_PIXELS -> w + int RADIAL_GRADIENT -> u + float mGradientRadius -> o + int RING -> s + int OVAL -> q + boolean mPathIsDirty -> n + android.graphics.ColorFilter mColorFilter -> e + boolean mMutated -> l + int mAlpha -> g + android.graphics.Path mPath -> h + android.graphics.RectF mRect -> i + float DEFAULT_THICKNESS_RATIO -> A + float DEFAULT_INNER_RADIUS_RATIO -> z + android.graphics.Path mRingPath -> m + int RADIUS_TYPE_FRACTION -> x + int SWEEP_GRADIENT -> v + int LINEAR_GRADIENT -> t + int LINE -> r + int RECTANGLE -> p + 1:1:void (com.batch.android.messaging.view.PositionableGradientDrawable$GradientState,android.content.res.Resources,com.batch.android.messaging.view.PositionableGradientDrawable$1):48:48 -> + 2:2:void ():165:165 -> + 3:3:void (com.batch.android.messaging.view.PositionableGradientDrawable$Orientation,int[],float[]):173:173 -> + 4:4:void (com.batch.android.messaging.view.PositionableGradientDrawable$GradientState,android.content.res.Resources):1350:1350 -> + 5:1253:void (com.batch.android.messaging.view.PositionableGradientDrawable$GradientState,android.content.res.Resources):105:1353 -> + boolean isOpaque(int) -> a + 1:3:void setCornerRadii(float[]):202:204 -> a + 4:6:void setCornerRadius(float):221:223 -> a + 7:7:void setStroke(int,android.content.res.ColorStateList):255:255 -> a + 8:9:void setStroke(int,int,float,float):273:274 -> a + 10:18:void setStroke(int,android.content.res.ColorStateList,float,float):293:301 -> a + 19:21:void setSize(int,int):332:334 -> a + 22:24:void setGradientCenter(float,float):383:385 -> a + 25:27:void setUseLevel(boolean):433:435 -> a + 28:30:void setOrientation(com.batch.android.messaging.view.PositionableGradientDrawable$Orientation):460:462 -> a + 31:36:void setColors(int[],float[]):480:485 -> a + 37:42:void buildPathIfDirty():634:639 -> a + 43:88:android.graphics.Path buildRing(com.batch.android.messaging.view.PositionableGradientDrawable$GradientState):644:689 -> a + 89:98:void setColor(android.content.res.ColorStateList):725:734 -> a + 99:141:void updateLocalState(android.content.res.Resources):1357:1399 -> a + 1:1:void setStroke(int,int):239:239 -> b + 2:14:void setStrokeInternal(int,int,float,float):305:317 -> b + 15:17:void setGradientRadius(float):400:402 -> b + 18:18:int modulateAlpha(int):439:439 -> b + 19:19:void clearMutated():1104:1104 -> b + 1:3:void setColor(int):706:708 -> c + 4:72:boolean ensureValidRect():874:942 -> c + 73:75:boolean ensureValidRect():933:935 -> c + 76:79:boolean ensureValidRect():927:930 -> c + 80:83:boolean ensureValidRect():921:924 -> c + 84:87:boolean ensureValidRect():915:918 -> c + 88:90:boolean ensureValidRect():909:911 -> c + 91:94:boolean ensureValidRect():903:906 -> c + 95:215:boolean ensureValidRect():897:1017 -> c + 1:3:void setGradientType(int):365:367 -> d + 4:9:float getGradientRadius():412:417 -> d + 1:129:void draw(android.graphics.Canvas):490:618 -> draw + 130:133:void draw(android.graphics.Canvas):607:610 -> draw + 134:136:void draw(android.graphics.Canvas):600:602 -> draw + 137:192:void draw(android.graphics.Canvas):573:628 -> draw + 1:4:void setShape(int):348:351 -> e + 5:5:com.batch.android.messaging.view.PositionableGradientDrawable$Orientation getOrientation():447:447 -> e + 1:5:boolean isOpaqueForState():1037:1041 -> f + 1:1:int getAlpha():804:804 -> getAlpha + 1:1:int getChangingConfigurations():791:791 -> getChangingConfigurations + 1:1:android.graphics.ColorFilter getColorFilter():817:817 -> getColorFilter + 1:2:android.graphics.drawable.Drawable$ConstantState getConstantState():1032:1033 -> getConstantState + 1:1:int getIntrinsicHeight():1027:1027 -> getIntrinsicHeight + 1:1:int getIntrinsicWidth():1022:1022 -> getIntrinsicWidth + 1:1:int getOpacity():844:844 -> getOpacity + 1:35:void getOutline(android.graphics.Outline):1050:1084 -> getOutline + 36:36:void getOutline(android.graphics.Outline):1074:1074 -> getOutline + 37:48:void getOutline(android.graphics.Outline):1060:1071 -> getOutline + 1:5:boolean getPadding(android.graphics.Rect):178:182 -> getPadding + 1:6:boolean isStateful():780:785 -> isStateful + 1:4:android.graphics.drawable.Drawable mutate():1091:1094 -> mutate + 1:4:void onBoundsChange(android.graphics.Rect):851:854 -> onBoundsChange + 1:4:boolean onLevelChange(int):859:862 -> onLevelChange + 1:31:boolean onStateChange(int[]):741:771 -> onStateChange + 1:3:void setAlpha(int):796:798 -> setAlpha + 1:3:void setColorFilter(android.graphics.ColorFilter):822:824 -> setColorFilter + 1:3:void setDither(boolean):809:811 -> setDither + 1:3:void setTintList(android.content.res.ColorStateList):830:832 -> setTintList + 1:3:void setTintMode(android.graphics.PorterDuff$Mode):837:839 -> setTintMode +com.batch.android.messaging.view.PositionableGradientDrawable$1 -> com.batch.android.f0.g$a: + int[] $SwitchMap$com$batch$android$messaging$view$PositionableGradientDrawable$Orientation -> a + 1:1:void ():895:895 -> +com.batch.android.messaging.view.PositionableGradientDrawable$GradientState -> com.batch.android.f0.g$b: + int mStrokeWidth -> l + float[] mTempPositions -> j + int mAngle -> d + int mShape -> b + int[] mGradientColors -> h + float mCenterX -> y + int[] mThemeAttrs -> I + android.graphics.PorterDuff$Mode mTintMode -> H + float mThicknessRatio -> u + boolean mOpaqueOverBounds -> E + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation mOrientation -> e + android.content.res.ColorStateList mStrokeColors -> g + int mThickness -> w + int[] mAttrPadding -> O + float mRadius -> o + int mHeight -> s + int[] mAttrGradient -> K + boolean mUseLevel -> C + float mStrokeDashWidth -> m + float[] mRadiusArray -> p + int[] mAttrStroke -> M + float[] mPositions -> k + boolean mDither -> x + float mGradientRadius -> A + int mGradientRadiusType -> B + int mGradient -> c + int mChangingConfigurations -> a + float mCenterY -> z + int[] mTempColors -> i + android.content.res.ColorStateList mSolidColors -> f + float mInnerRadiusRatio -> t + int mInnerRadius -> v + int[] mAttrCorners -> N + boolean mOpaqueOverShape -> F + android.content.res.ColorStateList mTint -> G + int mWidth -> r + int[] mAttrSize -> J + float mStrokeDashGap -> n + android.graphics.Rect mPadding -> q + int[] mAttrSolid -> L + boolean mUseLevelForShape -> D + 1:1:void (com.batch.android.messaging.view.PositionableGradientDrawable$Orientation,int[],float[]):1156:1156 -> + 2:51:void (com.batch.android.messaging.view.PositionableGradientDrawable$Orientation,int[],float[]):1110:1159 -> + 52:52:void (com.batch.android.messaging.view.PositionableGradientDrawable$GradientState):1162:1162 -> + 53:152:void (com.batch.android.messaging.view.PositionableGradientDrawable$GradientState):1110:1209 -> + 1:1:void access$100(com.batch.android.messaging.view.PositionableGradientDrawable$GradientState):1107:1107 -> a + 2:2:void setGradientType(int):1256:1256 -> a + 3:4:void setGradientCenter(float,float):1260:1261 -> a + 5:7:void setGradientColors(int[]):1265:1267 -> a + 8:10:void setSolidColors(android.content.res.ColorStateList):1276:1278 -> a + 11:30:void computeOpacity():1282:1301 -> a + 31:35:void setStroke(int,android.content.res.ColorStateList,float,float):1305:1309 -> a + 36:37:void setCornerRadius(float):1316:1317 -> a + 38:40:void setCornerRadii(float[]):1321:1323 -> a + 41:42:void setSize(int,int):1328:1329 -> a + 43:44:void setGradientRadius(float,int):1333:1334 -> a + 1:2:void setShape(int):1251:1252 -> b + 3:4:void setGradientPositions(float[]):1271:1272 -> b + 1:9:boolean canApplyTheme():1214:1222 -> canApplyTheme + 1:9:int getChangingConfigurations():1238:1246 -> getChangingConfigurations + 1:1:android.graphics.drawable.Drawable newDrawable():1228:1228 -> newDrawable + 2:2:android.graphics.drawable.Drawable newDrawable(android.content.res.Resources):1233:1233 -> newDrawable +com.batch.android.messaging.view.PositionableGradientDrawable$Orientation -> com.batch.android.f0.g$c: + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation TR_BL -> b + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation TOP_BOTTOM -> a + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation BR_TL -> d + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation RIGHT_LEFT -> c + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation BL_TR -> f + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation BOTTOM_TOP -> e + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation TL_BR -> h + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation LEFT_RIGHT -> g + com.batch.android.messaging.view.PositionableGradientDrawable$Orientation[] $VALUES -> i + 1:29:void ():133:161 -> + 30:30:void ():129:129 -> + 1:1:void (java.lang.String,int):129:129 -> + 1:1:com.batch.android.messaging.view.PositionableGradientDrawable$Orientation valueOf(java.lang.String):129:129 -> valueOf + 1:1:com.batch.android.messaging.view.PositionableGradientDrawable$Orientation[] values():129:129 -> values +com.batch.android.messaging.view.formats.BannerView -> com.batch.android.g0.a: + android.content.Context context -> a + android.graphics.Point screenSizeDP -> e + int BODY_MAX_HEIGHT_DP -> n + int IMAGE_FADE_IN_ANIMATION_DURATION -> l + long uptimeWhenShown -> k + int BODY_MIN_HEIGHT_DP -> m + com.batch.android.messaging.view.roundimage.RoundedImageView imageView -> i + com.batch.android.messaging.model.BaseBannerMessage message -> b + com.batch.android.messaging.view.CountdownView countdownView -> h + com.batch.android.messaging.view.helper.ImageHelper$Cache imageCache -> c + com.batch.android.messaging.view.styled.SeparatedFlexboxLayout contentLayout -> g + com.batch.android.messaging.view.formats.BannerView$OnActionListener actionListener -> j + com.batch.android.messaging.view.formats.BannerView$VerticalEdge pinnedVerticalEdge -> f + com.batch.android.messaging.css.Document style -> d + 1:15:void (android.content.Context,com.batch.android.messaging.model.BaseBannerMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.css.DOMNode,com.batch.android.messaging.view.helper.ImageHelper$Cache):99:113 -> + 16:54:void (android.content.Context,com.batch.android.messaging.model.BaseBannerMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.css.DOMNode,com.batch.android.messaging.view.helper.ImageHelper$Cache):112:150 -> + void onImageDownloadError(com.batch.android.messaging.model.MessagingError) -> a + 1:2:void lambda$makeCTALayout$2(int,com.batch.android.messaging.model.CTA,android.view.View):291:292 -> a + 3:16:android.view.View getStyledFlexboxSubview(android.util.Pair):316:329 -> a + 17:23:void addCloseButton():366:372 -> a + 24:41:void addCloseButton():371:388 -> a + 42:43:void lambda$addCloseButton$3(android.view.View):384:385 -> a + 44:50:com.batch.android.messaging.view.formats.BannerView$VerticalEdge getPinnedVerticalEdge(java.util.Map):415:421 -> a + 51:51:java.util.Map getRulesForView(com.batch.android.messaging.css.DOMNode):434:434 -> a + 52:54:java.util.Map getRulesForSeparator(com.batch.android.messaging.view.styled.SeparatedFlexboxLayout,java.lang.String):439:439 -> a + 55:61:void displayImage(com.batch.android.messaging.AsyncImageDownloadTask$Result):489:495 -> a + 1:1:void lambda$makeContentLayout$1(android.view.View):220:220 -> b + 2:54:com.batch.android.messaging.view.styled.SeparatedFlexboxLayout makeCTALayout(java.util.Map):257:309 -> b + 55:72:void addCountdownView():393:410 -> b + 73:76:void onImageDownloadSuccess(com.batch.android.messaging.AsyncImageDownloadTask$Result):479:482 -> b + void onImageDownloadStart() -> c + 1:1:void lambda$new$0(android.view.View):142:142 -> c + 2:76:com.batch.android.messaging.view.styled.SeparatedFlexboxLayout makeContentLayout(java.util.Map):176:250 -> c + 1:26:void addImage():334:359 -> d + 1:1:boolean canAutoClose():166:166 -> e + 1:1:boolean mustWaitTapDelay():445:445 -> f + 1:9:void onGlobalTap():449:457 -> g + 1:1:com.batch.android.messaging.view.styled.SeparatedFlexboxLayout getContentView():158:158 -> getContentView + 1:1:com.batch.android.messaging.view.formats.BannerView$VerticalEdge getPinnedVerticalEdge():430:430 -> getPinnedVerticalEdge + 1:1:void onShown():162:162 -> h + 1:2:void startAutoCloseCountdown():170:171 -> i + 1:6:void onAttachedToWindow():463:468 -> onAttachedToWindow + 1:1:void setActionListener(com.batch.android.messaging.view.formats.BannerView$OnActionListener):154:154 -> setActionListener +com.batch.android.messaging.view.formats.BannerView$OnActionListener -> com.batch.android.g0.a$a: + void onCTAAction(int,com.batch.android.messaging.model.CTA) -> a + void onCloseAction() -> a + void onGlobalAction() -> b +com.batch.android.messaging.view.formats.BannerView$VerticalEdge -> com.batch.android.g0.a$b: + com.batch.android.messaging.view.formats.BannerView$VerticalEdge BOTTOM -> b + com.batch.android.messaging.view.formats.BannerView$VerticalEdge[] $VALUES -> c + com.batch.android.messaging.view.formats.BannerView$VerticalEdge TOP -> a + 1:2:void ():500:501 -> + 3:3:void ():499:499 -> + 1:1:void (java.lang.String,int):499:499 -> + 1:1:com.batch.android.messaging.view.formats.BannerView$VerticalEdge valueOf(java.lang.String):499:499 -> valueOf + 1:1:com.batch.android.messaging.view.formats.BannerView$VerticalEdge[] values():499:499 -> values +com.batch.android.messaging.view.formats.EmbeddedBannerContainer -> com.batch.android.g0.b: + android.content.Context context -> a + boolean alreadyDismissed -> i + com.batch.android.messaging.view.formats.EmbeddedBannerContainer$BaseView rootView -> e + com.batch.android.messaging.view.formats.BannerView bannerView -> f + java.lang.Object autoCloseHandlerToken -> o + android.view.ViewGroup parentView -> b + com.batch.android.messaging.model.BannerMessage message -> d + com.batch.android.MessagingAnalyticsDelegate analyticsDelegate -> k + com.batch.android.BatchMessage payloadMessage -> c + android.os.Handler mainThreadHandler -> n + boolean alreadyShown -> h + android.util.LruCache imageCache -> l + android.content.BroadcastReceiver dismissReceiver -> m + int IN_OUT_ANIMATION_DURATION_MS -> p + com.batch.android.messaging.view.formats.BannerView$VerticalEdge pinnedVerticalEdge -> g + com.batch.android.module.MessagingModule messagingModule -> j + 1:1:void (com.batch.android.module.MessagingModule,android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):119:119 -> + 2:58:void (com.batch.android.module.MessagingModule,android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):71:127 -> + 59:96:void (com.batch.android.module.MessagingModule,android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):125:162 -> + 97:113:void (com.batch.android.module.MessagingModule,android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):159:175 -> + 114:114:void (com.batch.android.module.MessagingModule,android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):133:133 -> + 1:1:boolean access$000(com.batch.android.messaging.view.formats.EmbeddedBannerContainer):52:52 -> a + 2:3:com.batch.android.messaging.view.formats.EmbeddedBannerContainer provide(android.view.View,com.batch.android.BatchMessage,com.batch.android.messaging.model.BannerMessage,com.batch.android.MessagingAnalyticsDelegate,boolean):101:102 -> a + 4:17:android.view.ViewGroup findBestParentView(android.view.View):185:198 -> a + 18:54:void dismiss(boolean):306:342 -> a + 55:56:void onCloseAction():359:360 -> a + 57:59:void onCTAAction(int,com.batch.android.messaging.model.CTA):365:367 -> a + 60:62:void onDismiss(com.batch.android.messaging.view.PannableBannerFrameLayout):383:385 -> a + 63:63:void put(com.batch.android.messaging.AsyncImageDownloadTask$Result):391:391 -> a + 1:1:android.content.BroadcastReceiver access$100(com.batch.android.messaging.view.formats.EmbeddedBannerContainer):52:52 -> b + 2:2:void dismissOnMainThread(boolean):302:302 -> b + 3:8:void onGlobalAction():372:377 -> b + 9:9:com.batch.android.messaging.AsyncImageDownloadTask$Result get(java.lang.String):397:397 -> b + 1:1:android.content.Context access$200(com.batch.android.messaging.view.formats.EmbeddedBannerContainer):52:52 -> c + 2:2:void lambda$dismissOnMainThread$0(boolean):302:302 -> c + 3:3:int layoutGravityForPinnedEdge():354:354 -> c + 1:1:void access$300(com.batch.android.messaging.view.formats.EmbeddedBannerContainer):52:52 -> d + 2:3:com.batch.android.messaging.view.formats.BannerView makeBannerView():206:207 -> d + 1:1:void access$400(com.batch.android.messaging.view.formats.EmbeddedBannerContainer):52:52 -> e + 2:4:void performAutoClose():295:297 -> e + 1:4:void removeFromParent():346:349 -> f + 1:5:void scheduleAutoClose():281:285 -> g + 1:66:void show():212:277 -> h + 1:1:void unscheduleAutoClose():291:291 -> i +com.batch.android.messaging.view.formats.EmbeddedBannerContainer$1 -> com.batch.android.g0.b$a: + com.batch.android.messaging.view.formats.EmbeddedBannerContainer this$0 -> a + 1:1:void (com.batch.android.messaging.view.formats.EmbeddedBannerContainer):80:80 -> + 1:2:void onReceive(android.content.Context,android.content.Intent):83:84 -> onReceive +com.batch.android.messaging.view.formats.EmbeddedBannerContainer$2 -> com.batch.android.g0.b$b: + com.batch.android.messaging.view.formats.EmbeddedBannerContainer this$0 -> a + 1:1:void (com.batch.android.messaging.view.formats.EmbeddedBannerContainer):265:265 -> + 1:2:void onViewDetachedFromWindow(android.view.View):271:272 -> onViewDetachedFromWindow +com.batch.android.messaging.view.formats.EmbeddedBannerContainer$3 -> com.batch.android.g0.b$c: + com.batch.android.messaging.view.formats.EmbeddedBannerContainer this$0 -> a + 1:1:void (com.batch.android.messaging.view.formats.EmbeddedBannerContainer):317:317 -> + 1:1:void onAnimationCancel(android.animation.Animator):328:328 -> onAnimationCancel + 1:1:void onAnimationEnd(android.animation.Animator):323:323 -> onAnimationEnd +com.batch.android.messaging.view.formats.EmbeddedBannerContainer$BaseView -> com.batch.android.g0.b$d: + 1:1:void (android.content.Context):406:406 -> + 1:2:void onAttachedToWindow():411:412 -> onAttachedToWindow +com.batch.android.messaging.view.formats.ImageFormatView -> com.batch.android.g0.c: + android.content.Context context -> a + android.graphics.Point screenSizeDP -> e + android.widget.RelativeLayout rootContainerView -> g + com.batch.android.messaging.view.roundimage.RoundedImageView imageView -> j + long uptimeWhenShown -> l + com.batch.android.messaging.view.helper.ImageHelper$Cache imageCache -> c + com.batch.android.messaging.view.formats.ImageFormatView$ImageContainerView imageContainerView -> h + com.batch.android.messaging.view.formats.ImageFormatView$OnActionListener actionListener -> k + android.widget.ProgressBar imageViewLoader -> i + com.batch.android.core.Promise viewShownPromise -> m + com.batch.android.messaging.model.ImageMessage message -> b + float MODAL_CONTAINER_MARGIN_DP -> q + com.batch.android.messaging.view.AnimatedCloseButton closeButton -> f + float CLOSE_PADDING_DP -> p + int IMAGE_FADE_IN_ANIMATION_DURATION -> r + float FULLSCREEN_CLOSE_BUTTON_MARGIN_DP -> o + float CLOSE_SIZE_DP -> n + com.batch.android.messaging.css.Document style -> d + 1:1:void (android.content.Context,com.batch.android.messaging.model.ImageMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.view.helper.ImageHelper$Cache):97:97 -> + 2:46:void (android.content.Context,com.batch.android.messaging.model.ImageMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.view.helper.ImageHelper$Cache):82:126 -> + 1:1:java.util.Map getRulesForView(com.batch.android.messaging.css.DOMNode):157:157 -> a + 2:9:void addBackgroundView():163:170 -> a + 10:40:com.batch.android.messaging.view.formats.ImageFormatView$ImageContainerView addImageContainer(android.widget.RelativeLayout):193:223 -> a + 41:55:android.widget.ProgressBar addImageLoader(android.widget.FrameLayout):245:259 -> a + 56:90:com.batch.android.messaging.view.AnimatedCloseButton addCloseButton(android.widget.RelativeLayout,android.view.View):264:298 -> a + 91:92:void lambda$addCloseButton$1(android.view.View):294:295 -> a + 93:96:void onImageDownloadError(com.batch.android.messaging.model.MessagingError):349:352 -> a + 97:122:void displayImage(com.batch.android.messaging.AsyncImageDownloadTask$Result):357:382 -> a + 123:127:void lambda$displayImage$2(java.lang.Void):383:387 -> a + 1:14:android.widget.RelativeLayout addRootContainerView():174:187 -> b + 15:15:void lambda$addImageContainer$0(android.view.View):221:221 -> b + 16:28:com.batch.android.messaging.view.roundimage.RoundedImageView addImageView(android.widget.FrameLayout):228:240 -> b + 29:30:void onImageDownloadSuccess(com.batch.android.messaging.AsyncImageDownloadTask$Result):343:344 -> b + void onImageDownloadStart() -> c + 1:1:boolean canAutoClose():146:146 -> d + 1:1:boolean mustWaitTapDelay():307:307 -> e + 1:9:void onGlobalTap():311:319 -> f + 1:1:void onShown():142:142 -> g + 1:1:android.view.View getPanEffectsView():138:138 -> getPanEffectsView + 1:1:com.batch.android.messaging.view.formats.ImageFormatView$ImageContainerView getPannableView():134:134 -> getPannableView + 1:3:void startAutoCloseCountdown():150:152 -> h + 1:7:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):401:407 -> onApplyWindowInsets + 8:17:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):403:412 -> onApplyWindowInsets + 1:5:void onAttachedToWindow():329:333 -> onAttachedToWindow + 1:1:void setActionListener(com.batch.android.messaging.view.formats.ImageFormatView$OnActionListener):130:130 -> setActionListener +com.batch.android.messaging.view.formats.ImageFormatView$ImageContainerView -> com.batch.android.g0.c$a: + com.batch.android.messaging.view.DelegatedTouchEventViewGroup$Delegate delegate -> b + 1:1:void (android.content.Context,com.batch.android.messaging.Size2D):440:440 -> + 1:1:boolean superOnTouchEvent(android.view.MotionEvent):474:474 -> a + 1:1:boolean superOnInterceptTouchEvent(android.view.MotionEvent):469:469 -> b + 1:4:boolean onInterceptTouchEvent(android.view.MotionEvent):445:448 -> onInterceptTouchEvent + 1:4:boolean onTouchEvent(android.view.MotionEvent):455:458 -> onTouchEvent + 1:1:void setTouchEventDelegate(com.batch.android.messaging.view.DelegatedTouchEventViewGroup$Delegate):464:464 -> setTouchEventDelegate +com.batch.android.messaging.view.formats.ImageFormatView$OnActionListener -> com.batch.android.g0.c$b: + void onCloseAction() -> a + void onErrorAction(com.batch.android.messaging.model.MessagingError) -> b + void onGlobalAction() -> b + void onImageDisplayedAction() -> d +com.batch.android.messaging.view.formats.UniversalRootView -> com.batch.android.g0.d: + android.widget.FrameLayout heroLayout -> e + long TAP_DELAY_MILLIS -> B + boolean waitForHeroImage -> q + com.batch.android.messaging.view.styled.SeparatedFlexboxLayout contentLayout -> f + com.batch.android.messaging.AsyncImageDownloadTask$Result heroDownloadResult -> r + int HERO_LAYOUT_ID -> A + android.graphics.Point screenSizeDP -> u + long drawTimeMillis -> y + com.batch.android.messaging.css.Document style -> p + android.view.View heroPlaceholder -> m + com.batch.android.messaging.model.UniversalMessage message -> o + java.util.Map ctasStyleRules -> i + int originalContentPaddingTop -> w + boolean landscape -> b + com.batch.android.messaging.view.AnimatedCloseButton closeButton -> j + com.batch.android.messaging.view.roundimage.RoundedImageView heroImageView -> l + double DEFAULT_HERO_SPLIT_RATIO -> z + android.view.TextureView$SurfaceTextureListener surfaceHolderCallback -> t + com.batch.android.messaging.view.formats.UniversalRootView$OnActionListener actionListener -> s + android.content.Context context -> d + com.batch.android.messaging.view.styled.SeparatedFlexboxLayout ctasLayout -> g + android.view.TextureView videoView -> k + android.widget.ProgressBar heroLoader -> n + int originalCloseMarginTop -> x + int topInset -> v + boolean childRelayoutingNeeded -> c + java.util.Map contentStyleRules -> h + 1:1:void (android.content.Context,com.batch.android.messaging.model.UniversalMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.AsyncImageDownloadTask$Result,boolean):109:109 -> + 2:60:void (android.content.Context,com.batch.android.messaging.model.UniversalMessage,com.batch.android.messaging.css.Document,com.batch.android.messaging.AsyncImageDownloadTask$Result,boolean):68:126 -> + 1:2:void lambda$createViews$0(android.view.View):187:188 -> a + 3:4:void lambda$setupContentLayout$1(int,com.batch.android.messaging.model.CTA,android.view.View):281:282 -> a + 5:20:android.view.View getConfiguredView(android.util.Pair):317:332 -> a + 21:21:boolean canAutoClose():554:554 -> a + 22:29:void onHeroDownloaded(com.batch.android.messaging.AsyncImageDownloadTask$Result):581:588 -> a + 30:30:java.util.Map getRulesForView(com.batch.android.messaging.css.DOMNode):640:640 -> a + 31:33:java.util.Map getRulesForSeparator(com.batch.android.messaging.view.styled.SeparatedFlexboxLayout,java.lang.String):645:645 -> a + 1:40:void createViews():158:197 -> b + 1:4:void displayHero():546:549 -> c + 1:1:boolean mustWaitTapDelay():636:636 -> d + 1:5:void dispatchDraw(android.graphics.Canvas):149:153 -> dispatchDraw + 1:1:void onHeroBitmapStartsDownloading():577:577 -> e + 1:109:void setupContentLayout():203:311 -> f + 1:16:void setupCtaLayoutIfNeeded():421:436 -> g + 1:79:void setupHeroLayout():338:416 -> h + 1:99:void setupVariableLayoutParameters():444:542 -> i + 1:1:boolean shouldApplyWindowInsetToContent():629:629 -> j + 1:3:void startAutoCloseCountdown():558:560 -> k + 1:6:void updateLayoutInsets():611:616 -> l + 7:18:void updateLayoutInsets():612:623 -> l + 1:8:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):595:602 -> onApplyWindowInsets + 9:15:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):598:604 -> onApplyWindowInsets + 1:3:void onDraw(android.graphics.Canvas):142:144 -> onDraw + 1:6:void onSizeChanged(int,int,int,int):131:136 -> onSizeChanged + 1:1:void setActionListener(com.batch.android.messaging.view.formats.UniversalRootView$OnActionListener):565:565 -> setActionListener + 1:5:void setSurfaceHolderCallback(android.view.TextureView$SurfaceTextureListener):569:573 -> setSurfaceHolderCallback +com.batch.android.messaging.view.formats.UniversalRootView$OnActionListener -> com.batch.android.g0.d$a: + void onCTAAction(int,com.batch.android.messaging.model.CTA) -> a + void onCloseAction() -> a +com.batch.android.messaging.view.formats.WebFormatView -> com.batch.android.g0.e: + android.content.Context context -> a + android.widget.RelativeLayout rootContainerView -> f + boolean timeoutDone -> j + java.lang.String STATE_TIMEOUT_DONE_KEY -> l + com.batch.android.messaging.model.WebViewMessage message -> b + android.widget.ProgressBar webViewLoader -> g + android.graphics.Point screenSizeDP -> d + com.batch.android.messaging.WebViewActionListener actionListener -> k + com.batch.android.messaging.view.AnimatedCloseButton closeButton -> e + float FULLSCREEN_CLOSE_BUTTON_MARGIN_DP -> o + com.batch.android.messaging.css.Document style -> c + com.batch.android.messaging.view.styled.WebView webView -> i + float CLOSE_PADDING_DP -> n + android.os.Handler timeoutHandler -> h + float CLOSE_SIZE_DP -> m + 1:1:void (android.content.Context,com.batch.android.messaging.model.WebViewMessage,com.batch.android.messaging.css.Document,com.batch.android.BatchMessagingWebViewJavascriptBridge):100:100 -> + 2:249:void (android.content.Context,com.batch.android.messaging.model.WebViewMessage,com.batch.android.messaging.css.Document,com.batch.android.BatchMessagingWebViewJavascriptBridge):84:331 -> + 1:1:com.batch.android.messaging.WebViewActionListener access$000(com.batch.android.messaging.view.formats.WebFormatView):63:63 -> a + 2:2:boolean access$402(com.batch.android.messaging.view.formats.WebFormatView,boolean):63:63 -> a + 3:3:void access$500(com.batch.android.messaging.view.formats.WebFormatView,java.lang.String,int):63:63 -> a + 4:4:void access$600(com.batch.android.messaging.view.formats.WebFormatView,com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):63:63 -> a + 5:23:void handleWebViewError(java.lang.String,int):358:376 -> a + 24:25:void closeMessageWithError(com.batch.android.BatchMessagingWebViewJavascriptBridge$DevelopmentErrorCause,com.batch.android.messaging.model.MessagingError,java.lang.String):396:397 -> a + 26:29:void restoreState(android.os.Bundle):428:431 -> a + 30:30:java.util.Map getRulesForView(com.batch.android.messaging.css.DOMNode):444:444 -> a + 31:37:android.widget.RelativeLayout addRootContainerView():450:456 -> a + 38:61:com.batch.android.messaging.view.AnimatedCloseButton addCloseButton(android.widget.RelativeLayout):519:542 -> a + 62:62:void lambda$addCloseButton$0(android.view.View):539:539 -> a + boolean canAutoClose() -> b + 1:1:void access$100(com.batch.android.messaging.view.formats.WebFormatView):63:63 -> b + 2:6:void saveState(android.os.Bundle):419:423 -> b + 7:17:com.batch.android.messaging.view.styled.WebView addWebView(android.widget.RelativeLayout):461:471 -> b + 1:1:void access$200(com.batch.android.messaging.view.formats.WebFormatView):63:63 -> c + 2:3:void closeMessage():380:381 -> c + 4:36:android.widget.ProgressBar addWebViewLoader(android.widget.RelativeLayout):476:508 -> c + 1:1:androidx.appcompat.app.AlertDialog$Builder access$300(com.batch.android.messaging.view.formats.WebFormatView):63:63 -> d + 2:3:void dismissMessage():386:387 -> d + 1:1:androidx.appcompat.app.AlertDialog$Builder makeAlertBuilder():440:440 -> e + 1:2:void performTimeout():409:410 -> f + 1:2:void removeWebViewLoader():513:514 -> g + 1:1:android.view.View getCloseButton():335:335 -> getCloseButton + 1:3:void scheduleTimeout():402:404 -> h + 1:15:void startLoading():339:353 -> i + 1:7:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):555:561 -> onApplyWindowInsets + 8:17:android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets):557:566 -> onApplyWindowInsets + 1:1:void setActionListener(com.batch.android.messaging.WebViewActionListener):415:415 -> setActionListener +com.batch.android.messaging.view.formats.WebFormatView$1 -> com.batch.android.g0.e$a: + android.content.Context val$context -> a + com.batch.android.messaging.view.formats.WebFormatView this$0 -> b + 1:1:void (com.batch.android.messaging.view.formats.WebFormatView,android.content.Context):130:130 -> + 1:1:void lambda$onJsAlert$0(android.webkit.JsResult,android.content.DialogInterface,int):170:170 -> a + 2:2:void lambda$onJsAlert$1(android.webkit.JsResult,android.content.DialogInterface):174:174 -> a + 3:4:void lambda$onJsPrompt$4(android.widget.EditText,android.webkit.JsPromptResult,android.content.DialogInterface,int):218:219 -> a + 5:5:void lambda$onJsPrompt$5(android.webkit.JsPromptResult,android.content.DialogInterface,int):225:225 -> a + 6:6:void lambda$onJsPrompt$6(android.webkit.JsPromptResult,android.content.DialogInterface):229:229 -> a + 1:1:void lambda$onJsConfirm$2(android.webkit.JsResult,android.content.DialogInterface,int):189:189 -> b + 2:2:void lambda$onJsConfirm$3(android.webkit.JsResult,android.content.DialogInterface):193:193 -> b + 1:3:void onCloseWindow(android.webkit.WebView):148:150 -> onCloseWindow + 1:6:boolean onCreateWindow(android.webkit.WebView,boolean,boolean,android.os.Message):138:143 -> onCreateWindow + 1:14:boolean onJsAlert(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):164:177 -> onJsAlert + 1:14:boolean onJsConfirm(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):183:196 -> onJsConfirm + 1:25:boolean onJsPrompt(android.webkit.WebView,java.lang.String,java.lang.String,java.lang.String,android.webkit.JsPromptResult):208:232 -> onJsPrompt + 1:3:void onProgressChanged(android.webkit.WebView,int):156:158 -> onProgressChanged +com.batch.android.messaging.view.formats.WebFormatView$2 -> com.batch.android.g0.e$b: + com.batch.android.messaging.view.formats.WebFormatView this$0 -> b + boolean mainFrameFinished -> a + 1:2:void (com.batch.android.messaging.view.formats.WebFormatView):239:240 -> + 1:5:void onBatchPageStartedDrawing():248:252 -> a + 1:2:void onPageCommitVisible(android.webkit.WebView,java.lang.String):258:259 -> onPageCommitVisible + 1:4:void onPageFinished(android.webkit.WebView,java.lang.String):265:268 -> onPageFinished + 1:8:void onReceivedError(android.webkit.WebView,int,java.lang.String,java.lang.String):279:286 -> onReceivedError + 9:11:void onReceivedError(android.webkit.WebView,android.webkit.WebResourceRequest,android.webkit.WebResourceError):322:324 -> onReceivedError + 1:6:void onReceivedHttpError(android.webkit.WebView,android.webkit.WebResourceRequest,android.webkit.WebResourceResponse):305:310 -> onReceivedHttpError + 7:7:void onReceivedHttpError(android.webkit.WebView,android.webkit.WebResourceRequest,android.webkit.WebResourceResponse):307:307 -> onReceivedHttpError + 1:3:void onReceivedSslError(android.webkit.WebView,android.webkit.SslErrorHandler,android.net.http.SslError):292:294 -> onReceivedSslError +com.batch.android.messaging.view.helper.ImageHelper -> com.batch.android.h0.a: + 1:1:void ():11:11 -> + 1:11:void setDownloadResultInImage(android.widget.ImageView,com.batch.android.messaging.AsyncImageDownloadTask$Result):24:34 -> a +com.batch.android.messaging.view.helper.ImageHelper$Cache -> com.batch.android.h0.a$a: + void put(com.batch.android.messaging.AsyncImageDownloadTask$Result) -> a + com.batch.android.messaging.AsyncImageDownloadTask$Result get(java.lang.String) -> b +com.batch.android.messaging.view.helper.StyleHelper -> com.batch.android.h0.b: + java.lang.String TAG -> a + int RIPPLE_COLOR -> b + 1:1:void ():50:50 -> + 1:1:void ():55:55 -> + 1:43:void applyCommonRules(android.view.View,java.util.Map):94:136 -> a + 44:202:void applyCommonRules(android.view.View,java.util.Map):133:291 -> a + 203:268:void applyCommonRules(android.view.View,java.util.Map):245:310 -> a + 269:269:void applyCommonRules(android.view.View,java.util.Map):306:306 -> a + 270:352:com.batch.android.messaging.view.FlexboxLayout$LayoutParams getFlexLayoutParams(android.content.Context,com.batch.android.messaging.view.FlexboxLayout$LayoutParams,java.util.Map):329:411 -> a + 353:353:com.batch.android.messaging.view.FlexboxLayout$LayoutParams getFlexLayoutParams(android.content.Context,com.batch.android.messaging.view.FlexboxLayout$LayoutParams,java.util.Map):407:407 -> a + 354:441:com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams getRelativeLayoutParams(android.content.Context,com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams,java.util.Map,int,android.view.View):436:523 -> a + 442:517:com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams getRelativeLayoutParams(android.content.Context,com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams,java.util.Map,int,android.view.View):461:536 -> a + 518:518:com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams getRelativeLayoutParams(android.content.Context,com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams,java.util.Map,int,android.view.View):532:532 -> a + 519:576:android.widget.FrameLayout$LayoutParams getFrameLayoutParams(android.content.Context,android.widget.FrameLayout$LayoutParams,java.util.Map):559:616 -> a + 577:621:android.widget.FrameLayout$LayoutParams getFrameLayoutParams(android.content.Context,android.widget.FrameLayout$LayoutParams,java.util.Map):581:625 -> a + 622:622:android.widget.FrameLayout$LayoutParams getFrameLayoutParams(android.content.Context,android.widget.FrameLayout$LayoutParams,java.util.Map):621:621 -> a + 623:623:int dpToPixels(android.content.res.Resources,java.lang.Float):642:642 -> a + 624:624:java.lang.Float optFloat(java.lang.String):691:691 -> a + 625:628:int darkenColor(int):722:725 -> a + 629:652:android.graphics.drawable.Drawable getPressableGradientDrawable(com.batch.android.messaging.view.PositionableGradientDrawable):736:759 -> a + 1:1:float pixelsToDp(android.content.res.Resources,java.lang.Float):656:656 -> b + 2:2:java.lang.Integer optInt(java.lang.String):672:672 -> b + 1:5:int parseColor(java.lang.String):705:709 -> c + 1:3:com.batch.android.messaging.css.Document parseStyle(java.lang.String):67:69 -> d + 4:12:com.batch.android.messaging.css.Document parseStyle(java.lang.String):65:73 -> d +com.batch.android.messaging.view.helper.ThemeHelper -> com.batch.android.h0.c: + 1:1:void ():12:12 -> + 1:9:int getDefaultLightTheme(android.content.Context):53:61 -> a + 10:10:int getThemeByName(java.lang.String,android.content.res.Resources,java.lang.String):75:75 -> a + 1:18:int getDefaultTheme(android.content.Context):22:39 -> b +com.batch.android.messaging.view.helper.ViewCompat -> com.batch.android.h0.d: + java.util.concurrent.atomic.AtomicInteger sNextGeneratedId -> a + 1:2:void ():38:39 -> + 1:1:void ():33:33 -> + 1:11:int generateViewId():50:60 -> a + 12:28:android.graphics.Point getScreenSize(android.content.Context):68:84 -> a + 1:5:boolean isTouchExplorationEnabled(android.content.Context):98:102 -> b +com.batch.android.messaging.view.percent.PercentFrameLayout -> com.batch.android.i0.a: + com.batch.android.messaging.view.percent.PercentLayoutHelper mHelper -> a + 1:1:void (android.content.Context):70:70 -> + 2:2:void (android.content.Context):67:67 -> + 3:3:void (android.content.Context,android.util.AttributeSet):74:74 -> + 4:4:void (android.content.Context,android.util.AttributeSet):67:67 -> + 5:5:void (android.content.Context,android.util.AttributeSet,int):78:78 -> + 6:6:void (android.content.Context,android.util.AttributeSet,int):67:67 -> + 1:2:void onLayout(boolean,int,int,int,int):92:93 -> onLayout + 1:4:void onMeasure(int,int):83:86 -> onMeasure +com.batch.android.messaging.view.percent.PercentFrameLayout$LayoutParams -> com.batch.android.i0.a$a: + com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo mPercentLayoutInfo -> a + 1:1:void (int,int):103:103 -> + 2:2:void (int,int,int):107:107 -> + 3:3:void (android.view.ViewGroup$LayoutParams):111:111 -> + 4:4:void (android.view.ViewGroup$MarginLayoutParams):115:115 -> + 5:6:void (android.widget.FrameLayout$LayoutParams):119:120 -> + 7:8:void (com.batch.android.messaging.view.percent.PercentFrameLayout$LayoutParams):124:125 -> + 1:5:com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo getPercentLayoutInfo():130:134 -> a + 1:1:void setBaseAttributes(android.content.res.TypedArray,int,int):139:139 -> setBaseAttributes +com.batch.android.messaging.view.percent.PercentLayoutHelper -> com.batch.android.i0.b: + android.view.ViewGroup mHost -> a + java.lang.String TAG -> b + 1:2:void (android.view.ViewGroup):75:76 -> + 1:2:void fetchWidthAndHeight(android.view.ViewGroup$LayoutParams,android.content.res.TypedArray,int,int):90:91 -> a + 3:11:void adjustChildren(int,int):102:110 -> a + 12:39:void adjustChildren(int,int):103:130 -> a + 40:61:boolean handleMeasuredStateTooSmall():181:202 -> a + 62:63:boolean shouldHandleMeasuredHeightTooSmall(android.view.View,com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo):217:218 -> a + 1:16:void restoreOriginalParams():143:158 -> b + 17:18:boolean shouldHandleMeasuredWidthTooSmall(android.view.View,com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo):208:209 -> b +com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo -> com.batch.android.i0.b$a: + float endMarginPercent -> h + float startMarginPercent -> g + float bottomMarginPercent -> f + float rightMarginPercent -> e + float topMarginPercent -> d + float leftMarginPercent -> c + float heightPercent -> b + float widthPercent -> a + android.view.ViewGroup$MarginLayoutParams mPreservedParams -> i + 1:10:void ():249:258 -> + 1:11:void fillLayoutParams(android.view.ViewGroup$LayoutParams,int,int):266:276 -> a + 12:41:void fillMarginLayoutParams(android.view.ViewGroup$MarginLayoutParams,int,int):285:314 -> a + 42:48:void restoreMarginLayoutParams(android.view.ViewGroup$MarginLayoutParams):340:346 -> a + 49:50:void restoreLayoutParams(android.view.ViewGroup$LayoutParams):355:356 -> a + 1:12:java.lang.String toString():320:320 -> toString +com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutParams -> com.batch.android.i0.b$b: + com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo getPercentLayoutInfo() -> a +com.batch.android.messaging.view.percent.PercentRelativeLayout -> com.batch.android.i0.c: + com.batch.android.messaging.view.percent.PercentLayoutHelper mHelper -> a + 1:1:void (android.content.Context):70:70 -> + 2:2:void (android.content.Context):67:67 -> + 3:3:void (android.content.Context,android.util.AttributeSet):74:74 -> + 4:4:void (android.content.Context,android.util.AttributeSet):67:67 -> + 5:5:void (android.content.Context,android.util.AttributeSet,int):78:78 -> + 6:6:void (android.content.Context,android.util.AttributeSet,int):67:67 -> + 1:2:void onLayout(boolean,int,int,int,int):92:93 -> onLayout + 1:4:void onMeasure(int,int):83:86 -> onMeasure +com.batch.android.messaging.view.percent.PercentRelativeLayout$LayoutParams -> com.batch.android.i0.c$a: + com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo mPercentLayoutInfo -> a + 1:1:void (int,int):103:103 -> + 2:2:void (android.view.ViewGroup$LayoutParams):107:107 -> + 3:3:void (android.view.ViewGroup$MarginLayoutParams):111:111 -> + 1:5:com.batch.android.messaging.view.percent.PercentLayoutHelper$PercentLayoutInfo getPercentLayoutInfo():116:120 -> a + 1:1:void setBaseAttributes(android.content.res.TypedArray,int,int):125:125 -> setBaseAttributes +com.batch.android.messaging.view.roundimage.Corner -> com.batch.android.j0.a: + int BOTTOM_LEFT -> d + int TOP_RIGHT -> b + int BOTTOM_RIGHT -> c + int TOP_LEFT -> a +com.batch.android.messaging.view.roundimage.RoundedDrawable -> com.batch.android.j0.b: + boolean mRebuildShader -> n + android.graphics.RectF mDrawableRect -> b + android.graphics.Matrix mShaderMatrix -> j + android.graphics.RectF mBounds -> a + android.graphics.RectF mBitmapRect -> c + android.content.res.ColorStateList mBorderColor -> s + int mBitmapWidth -> f + android.graphics.RectF mBorderRect -> h + int mBitmapHeight -> g + android.graphics.Bitmap mBitmap -> d + boolean[] mCornersRounded -> p + boolean mOval -> q + android.graphics.RectF mSquareCornersRect -> k + android.graphics.Shader$TileMode mTileModeX -> l + java.lang.String TAG -> u + android.graphics.Paint mBorderPaint -> i + android.graphics.Shader$TileMode mTileModeY -> m + android.widget.ImageView$ScaleType mScaleType -> t + android.graphics.Paint mBitmapPaint -> e + int DEFAULT_BORDER_COLOR -> v + float mBorderWidth -> r + float mCornerRadius -> o + 1:1:void (android.graphics.Bitmap):74:74 -> + 2:42:void (android.graphics.Bitmap):49:89 -> + 1:1:com.batch.android.messaging.view.roundimage.RoundedDrawable fromBitmap(android.graphics.Bitmap):94:94 -> a + 2:16:android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable):130:144 -> a + 17:49:void redrawBitmapForSquareCorners(android.graphics.Canvas):309:341 -> a + 50:50:float getCornerRadius(int):444:444 -> a + 51:64:com.batch.android.messaging.view.roundimage.RoundedDrawable setCornerRadius(int,float):466:479 -> a + 65:82:com.batch.android.messaging.view.roundimage.RoundedDrawable setCornerRadius(float,float,float,float):495:512 -> a + 83:93:com.batch.android.messaging.view.roundimage.RoundedDrawable setCornerRadius(float,float,float,float):510:520 -> a + 94:94:com.batch.android.messaging.view.roundimage.RoundedDrawable setCornerRadius(float,float,float,float):504:504 -> a + 95:96:com.batch.android.messaging.view.roundimage.RoundedDrawable setBorderWidth(float):529:530 -> a + 97:97:int getBorderColor():535:535 -> a + 98:99:com.batch.android.messaging.view.roundimage.RoundedDrawable setBorderColor(android.content.res.ColorStateList):547:548 -> a + 100:100:com.batch.android.messaging.view.roundimage.RoundedDrawable setOval(boolean):557:557 -> a + 101:105:com.batch.android.messaging.view.roundimage.RoundedDrawable setScaleType(android.widget.ImageView$ScaleType):567:571 -> a + 106:109:com.batch.android.messaging.view.roundimage.RoundedDrawable setTileModeX(android.graphics.Shader$TileMode):581:584 -> a + 110:111:boolean only(int,boolean[]):603:604 -> a + 112:112:boolean all(boolean[]):621:621 -> a + 1:22:android.graphics.drawable.Drawable fromDrawable(android.graphics.drawable.Drawable):102:123 -> b + 23:56:void redrawBorderForSquareCorners(android.graphics.Canvas):346:379 -> b + 57:57:com.batch.android.messaging.view.roundimage.RoundedDrawable setCornerRadius(float):454:454 -> b + 58:58:com.batch.android.messaging.view.roundimage.RoundedDrawable setBorderColor(int):539:539 -> b + 59:59:android.content.res.ColorStateList getBorderColors():543:543 -> b + 60:63:com.batch.android.messaging.view.roundimage.RoundedDrawable setTileModeY(android.graphics.Shader$TileMode):594:597 -> b + 64:64:boolean any(boolean[]):612:612 -> b + 1:1:float getBorderWidth():525:525 -> c + 1:1:float getCornerRadius():436:436 -> d + 1:32:void draw(android.graphics.Canvas):271:302 -> draw + 1:1:android.widget.ImageView$ScaleType getScaleType():562:562 -> e + 1:1:android.graphics.Bitmap getSourceBitmap():152:152 -> f + 1:1:android.graphics.Shader$TileMode getTileModeX():577:577 -> g + 1:1:int getAlpha():390:390 -> getAlpha + 1:1:android.graphics.ColorFilter getColorFilter():401:401 -> getColorFilter + 1:1:int getIntrinsicHeight():429:429 -> getIntrinsicHeight + 1:1:int getIntrinsicWidth():424:424 -> getIntrinsicWidth + 1:1:android.graphics.Shader$TileMode getTileModeY():590:590 -> h + 1:1:boolean isOval():553:553 -> i + 1:1:boolean isStateful():157:157 -> isStateful + 1:1:android.graphics.Bitmap toBitmap():630:630 -> j + 1:78:void updateShaderMatrix():176:253 -> k + 79:83:void updateShaderMatrix():243:247 -> k + 84:88:void updateShaderMatrix():236:240 -> k + 89:106:void updateShaderMatrix():208:225 -> k + 107:124:void updateShaderMatrix():188:205 -> k + 125:131:void updateShaderMatrix():178:184 -> k + 132:207:void updateShaderMatrix():182:257 -> k + 1:5:void onBoundsChange(android.graphics.Rect):262:266 -> onBoundsChange + 1:6:boolean onStateChange(int[]):162:167 -> onStateChange + 1:2:void setAlpha(int):395:396 -> setAlpha + 1:2:void setColorFilter(android.graphics.ColorFilter):406:407 -> setColorFilter + 1:2:void setDither(boolean):412:413 -> setDither + 1:2:void setFilterBitmap(boolean):418:419 -> setFilterBitmap +com.batch.android.messaging.view.roundimage.RoundedDrawable$1 -> com.batch.android.j0.b$a: + int[] $SwitchMap$android$widget$ImageView$ScaleType -> a + 1:1:void ():176:176 -> +com.batch.android.messaging.view.roundimage.RoundedImageView -> com.batch.android.j0.c: + int mBackgroundResource -> l + android.graphics.drawable.Drawable mDrawable -> g + boolean mIsOval -> i + boolean[] roundedCorners -> q + java.lang.String TAG -> v + android.graphics.Shader$TileMode mTileModeX -> n + android.content.res.ColorStateList mBorderColor -> c + float DEFAULT_RADIUS -> w + boolean mColorMod -> f + boolean mHasColorFilter -> h + int TILE_MODE_MIRROR -> u + boolean $assertionsDisabled -> A + int TILE_MODE_CLAMP -> s + android.graphics.ColorFilter mColorFilter -> e + boolean mMutateBackground -> j + int mResource -> k + float mBorderWidth -> d + float[] mCornerRadii -> a + android.widget.ImageView$ScaleType[] SCALE_TYPES -> z + android.graphics.drawable.Drawable mBackgroundDrawable -> b + android.graphics.Shader$TileMode mTileModeY -> o + float DEFAULT_BORDER_WIDTH -> x + android.widget.ImageView$ScaleType mScaleType -> m + int TILE_MODE_REPEAT -> t + float cornerRadius -> p + int TILE_MODE_UNDEFINED -> r + android.graphics.Shader$TileMode DEFAULT_TILE_MODE -> y + 1:15:void ():48:62 -> + 1:1:void (android.content.Context):96:96 -> + 2:22:void (android.content.Context):73:93 -> + 23:23:void (android.content.Context,android.util.AttributeSet):100:100 -> + 24:24:void (android.content.Context,android.util.AttributeSet,int):104:104 -> + 25:45:void (android.content.Context,android.util.AttributeSet,int):73:93 -> + 1:4:void applyColorMod():266:269 -> a + 5:27:void updateAttrs(android.graphics.drawable.Drawable,android.widget.ImageView$ScaleType):281:303 -> a + 28:28:float getCornerRadius(int):342:342 -> a + 29:29:void setCornerRadiusDimen(int,int):362:362 -> a + 30:37:void setCornerRadius(int,float):387:394 -> a + 38:54:void setCornerRadius(float,float,float,float):407:423 -> a + 55:61:void mutateBackground(boolean):517:523 -> a + 62:143:void applyStyleRules(java.util.Map):535:616 -> a + 144:144:void applyStyleRules(java.util.Map):612:612 -> a + 1:1:android.graphics.Shader$TileMode parseTileMode(int):114:114 -> b + 2:2:android.graphics.Shader$TileMode parseTileMode(int):112:112 -> b + 3:3:android.graphics.Shader$TileMode parseTileMode(int):110:110 -> b + 4:8:void updateBackgroundDrawableAttrs(boolean):243:247 -> b + 9:9:boolean isOval():472:472 -> b + 1:1:boolean mutatesBackground():513:513 -> c + 1:17:android.graphics.drawable.Drawable resolveBackgroundResource():219:235 -> d + 1:2:void drawableStateChanged():122:123 -> drawableStateChanged + 1:17:android.graphics.drawable.Drawable resolveResource():179:195 -> e + 1:1:void updateDrawableAttrs():239:239 -> f + 1:1:int getBorderColor():447:447 -> getBorderColor + 1:1:android.content.res.ColorStateList getBorderColors():455:455 -> getBorderColors + 1:1:float getBorderWidth():427:427 -> getBorderWidth + 1:1:float getCornerRadius():321:321 -> getCornerRadius + 1:2:float getMaxCornerRadius():329:330 -> getMaxCornerRadius + 1:1:android.widget.ImageView$ScaleType getScaleType():128:128 -> getScaleType + 1:1:android.graphics.Shader$TileMode getTileModeX():483:483 -> getTileModeX + 1:1:android.graphics.Shader$TileMode getTileModeY():498:498 -> getTileModeY + 1:1:void setBackground(android.graphics.drawable.Drawable):200:200 -> setBackground + 1:2:void setBackgroundColor(int):214:215 -> setBackgroundColor + 1:4:void setBackgroundDrawable(android.graphics.drawable.Drawable):311:314 -> setBackgroundDrawable + 1:4:void setBackgroundResource(int):205:208 -> setBackgroundResource + 1:1:void setBorderColor(int):451:451 -> setBorderColor + 2:10:void setBorderColor(android.content.res.ColorStateList):459:467 -> setBorderColor + 1:1:void setBorderWidth(int):431:431 -> setBorderWidth + 2:9:void setBorderWidth(float):435:442 -> setBorderWidth + 1:6:void setColorFilter(android.graphics.ColorFilter):253:258 -> setColorFilter + 1:6:void setCornerRadius(float):371:376 -> setCornerRadius + 7:7:void setCornerRadius(float):372:372 -> setCornerRadius + 1:2:void setCornerRadiusDimen(int):351:352 -> setCornerRadiusDimen + 1:5:void setImageBitmap(android.graphics.Bitmap):155:159 -> setImageBitmap + 1:4:void setImageDrawable(android.graphics.drawable.Drawable):147:150 -> setImageDrawable + 1:5:void setImageResource(int):164:168 -> setImageResource + 1:2:void setImageURI(android.net.Uri):174:175 -> setImageURI + 1:4:void setOval(boolean):476:479 -> setOval + 1:9:void setScaleType(android.widget.ImageView$ScaleType):133:141 -> setScaleType + 1:8:void setTileModeX(android.graphics.Shader$TileMode):487:494 -> setTileModeX + 1:8:void setTileModeY(android.graphics.Shader$TileMode):502:509 -> setTileModeY +com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder -> com.batch.android.j0.d: + android.content.res.ColorStateList mBorderColor -> e + float mBorderWidth -> d + android.util.DisplayMetrics mDisplayMetrics -> a + float[] mCornerRadii -> b + android.widget.ImageView$ScaleType mScaleType -> f + boolean mOval -> c + 1:1:void ():37:37 -> + 2:10:void ():30:38 -> + 1:1:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder scaleType(android.widget.ImageView$ScaleType):42:42 -> a + 2:2:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder cornerRadius(int,float):68:68 -> a + 3:3:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder borderWidth(float):100:100 -> a + 4:4:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder borderColor(int):122:122 -> a + 5:5:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder borderColor(android.content.res.ColorStateList):133:133 -> a + 6:6:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder oval(boolean):144:144 -> a + 1:1:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder cornerRadiusDp(int,float):90:90 -> b + 2:2:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder borderWidthDp(float):111:111 -> b + 1:4:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder cornerRadius(float):53:56 -> c + 1:1:com.batch.android.messaging.view.roundimage.RoundedTransformationBuilder cornerRadiusDp(float):79:79 -> d +com.batch.android.messaging.view.styled.Button -> com.batch.android.messaging.view.styled.a: + 1:1:void (android.content.Context):17:17 -> + 2:2:void (android.content.Context,android.util.AttributeSet):21:21 -> + 3:3:void (android.content.Context,android.util.AttributeSet,int):25:25 -> + 1:13:void applyStyleRules(java.util.Map):30:42 -> a +com.batch.android.messaging.view.styled.SeparatedFlexboxLayout -> com.batch.android.k0.a: + com.batch.android.messaging.view.DelegatedTouchEventViewGroup$Delegate delegate -> G + java.lang.String separatorPrefix -> H + int separatorCount -> J + com.batch.android.messaging.view.styled.SeparatedFlexboxLayout$SeparatorStyleProvider styleProvider -> I + 1:1:void (android.content.Context,java.lang.String,com.batch.android.messaging.view.styled.SeparatedFlexboxLayout$SeparatorStyleProvider):29:29 -> + 2:14:void (android.content.Context,java.lang.String,com.batch.android.messaging.view.styled.SeparatedFlexboxLayout$SeparatorStyleProvider):26:38 -> + 15:15:void (android.content.Context,java.lang.String,com.batch.android.messaging.view.styled.SeparatedFlexboxLayout$SeparatorStyleProvider):34:34 -> + 1:50:void applyStyleRules(java.util.Map):92:141 -> a + 51:51:boolean superOnTouchEvent(android.view.MotionEvent):182:182 -> a + 1:5:void addView(android.view.View):45:49 -> addView + 1:1:void internalAddView(android.view.View):53:53 -> b + 2:2:boolean superOnInterceptTouchEvent(android.view.MotionEvent):177:177 -> b + 1:9:void addSeparator():72:80 -> c + 10:10:void addSeparator():78:78 -> c + 11:21:void addSeparator():77:87 -> c + 1:1:boolean isHorizontal():57:57 -> d + 1:1:java.lang.String getSeparatorPrefix():65:65 -> getSeparatorPrefix + 1:4:boolean onInterceptTouchEvent(android.view.MotionEvent):153:156 -> onInterceptTouchEvent + 1:4:boolean onTouchEvent(android.view.MotionEvent):163:166 -> onTouchEvent + 1:1:void setTouchEventDelegate(com.batch.android.messaging.view.DelegatedTouchEventViewGroup$Delegate):172:172 -> setTouchEventDelegate +com.batch.android.messaging.view.styled.SeparatedFlexboxLayout$SeparatorStyleProvider -> com.batch.android.k0.a$a: + java.util.Map getRulesForSeparator(com.batch.android.messaging.view.styled.SeparatedFlexboxLayout,java.lang.String) -> a +com.batch.android.messaging.view.styled.SeparatorView -> com.batch.android.k0.b: + 1:1:void (android.content.Context):14:14 -> + 1:1:void applyStyleRules(java.util.Map):19:19 -> a +com.batch.android.messaging.view.styled.Styleable -> com.batch.android.k0.c: + void applyStyleRules(java.util.Map) -> a +com.batch.android.messaging.view.styled.TextView -> com.batch.android.messaging.view.styled.TextView: + android.graphics.Typeface typefaceOverride -> b + android.graphics.Typeface boldTypefaceOverride -> c + java.lang.String TAG -> a + 1:1:void (android.content.Context):36:36 -> + 2:2:void (android.content.Context,android.util.AttributeSet):40:40 -> + 3:3:void (android.content.Context,android.util.AttributeSet,int):44:44 -> + 4:4:void (android.content.Context,android.util.AttributeSet,int,int):49:49 -> + 1:1:void applyStyleRules(java.util.Map):54:54 -> a + 2:50:void applyStyleRules(android.widget.TextView,java.util.Map):64:112 -> a + 51:78:void applyStyleRules(android.widget.TextView,java.util.Map):110:137 -> a + 79:125:void applyStyleRules(android.widget.TextView,java.util.Map):136:182 -> a + 126:131:void applyStyleRules(android.widget.TextView,java.util.Map):180:185 -> a + 132:138:void makeScrollable():192:198 -> a +com.batch.android.messaging.view.styled.TextView$1 -> com.batch.android.messaging.view.styled.TextView$a: + android.widget.Scroller val$scroller -> b + com.batch.android.messaging.view.styled.TextView this$0 -> c + android.view.GestureDetector gesture -> a + 1:3:void (com.batch.android.messaging.view.styled.TextView,android.widget.Scroller):199:201 -> + 1:5:boolean onTouch(android.view.View,android.view.MotionEvent):218:222 -> onTouch +com.batch.android.messaging.view.styled.TextView$1$1 -> com.batch.android.messaging.view.styled.TextView$a$a: + com.batch.android.messaging.view.styled.TextView$1 this$1 -> a + 1:1:void (com.batch.android.messaging.view.styled.TextView$1):202:202 -> + 1:5:boolean onFling(android.view.MotionEvent,android.view.MotionEvent,float,float):205:209 -> onFling +com.batch.android.messaging.view.styled.WebView -> com.batch.android.k0.d: + 1:1:void (android.content.Context):11:11 -> + 1:1:void applyStyleRules(java.util.Map):16:16 -> a +com.batch.android.metrics.MetricManager -> com.batch.android.l0.a: + com.batch.android.core.DateProvider dateProvider -> e + java.util.List metrics -> a + java.lang.String TAG -> f + int DELAY_BEFORE_SENDING -> h + java.util.concurrent.atomic.AtomicBoolean isSending -> b + int DEFAULT_RETRY_AFTER -> g + long nextMetricServiceAvailableTimestamp -> d + java.util.concurrent.ScheduledExecutorService sendExecutor -> c + 1:38:void ():28:65 -> + 1:1:java.util.concurrent.atomic.AtomicBoolean access$000(com.batch.android.metrics.MetricManager):28:28 -> a + 2:2:long access$102(com.batch.android.metrics.MetricManager,long):28:28 -> a + 3:5:void addMetric(com.batch.android.metrics.model.Metric):73:75 -> a + 6:37:java.util.List getMetricsToSend():84:115 -> a + 38:65:void lambda$sendMetrics$0(android.content.Context):146:173 -> a + 1:1:com.batch.android.core.DateProvider access$200(com.batch.android.metrics.MetricManager):28:28 -> b + 2:2:boolean isMetricServiceAvailable():124:124 -> b + 1:1:com.batch.android.metrics.MetricManager provide():69:69 -> c + 1:14:void sendMetrics():131:144 -> d +com.batch.android.metrics.MetricManager$1 -> com.batch.android.l0.a$a: + com.batch.android.metrics.MetricManager this$0 -> a + 1:1:void (com.batch.android.metrics.MetricManager):154:154 -> + 1:6:void onFailure(com.batch.android.core.Webservice$WebserviceError):163:168 -> a + 1:2:void onSuccess():157:158 -> onSuccess +com.batch.android.metrics.MetricRegistry -> com.batch.android.l0.b: + com.batch.android.metrics.model.Observation localCampaignsSyncResponseTime -> c + com.batch.android.metrics.model.Observation localCampaignsJITResponseTime -> a + com.batch.android.metrics.model.Counter localCampaignsJITCount -> b + 1:15:void ():12:26 -> + 1:1:void ():9:9 -> +com.batch.android.metrics.model.Counter -> com.batch.android.m0.a: + float value -> g + 1:7:void (com.batch.android.metrics.model.Counter):12:18 -> + 8:10:void (java.lang.String):22:24 -> + 1:1:java.lang.Object newChild(java.util.List):7:7 -> a + 1:2:com.batch.android.metrics.model.Counter newChild(java.util.List):29:30 -> b + 1:3:void reset():36:38 -> j + 1:4:void inc():42:45 -> l +com.batch.android.metrics.model.Metric -> com.batch.android.m0.b: + java.util.List labelValues -> e + java.util.List labelNames -> d + java.util.List values -> c + java.util.concurrent.ConcurrentMap children -> f + java.lang.String name -> a + java.lang.String type -> b + 1:1:void (java.lang.String):32:32 -> + 2:5:void (java.lang.String):30:33 -> + java.lang.Object newChild(java.util.List) -> a + 1:1:java.lang.Object labelNames(java.lang.String[]):42:42 -> a + 2:13:void pack(com.batch.android.msgpack.core.MessageBufferPacker):61:72 -> a + 14:14:java.util.concurrent.ConcurrentMap getChildren():108:108 -> a + 1:5:java.lang.Object labels(java.lang.String[]):47:51 -> b + 6:6:java.util.List getLabelNames():100:100 -> b + 1:1:java.util.List getLabelValues():104:104 -> c + 1:1:java.lang.String getName():88:88 -> d + 1:1:java.lang.String getType():92:92 -> e + 1:1:java.util.List getValues():96:96 -> f + 1:1:boolean hasChanged():80:80 -> g + 1:1:boolean hasChildren():84:84 -> h + 1:1:java.lang.Object register():37:37 -> i + void reset() -> j + 1:1:void update():76:76 -> k +com.batch.android.metrics.model.Metric$Type -> com.batch.android.m0.b$a: + java.lang.String COUNTER -> a + java.lang.String OBSERVATION -> b +com.batch.android.metrics.model.Observation -> com.batch.android.m0.c: + java.util.concurrent.atomic.AtomicBoolean observing -> h + long startTime -> g + 1:1:void (java.lang.String):17:17 -> + 2:7:void (java.lang.String):14:19 -> + 8:8:void (com.batch.android.metrics.model.Observation):23:23 -> + 9:26:void (com.batch.android.metrics.model.Observation):14:31 -> + 1:1:java.lang.Object newChild(java.util.List):10:10 -> a + 1:2:com.batch.android.metrics.model.Observation newChild(java.util.List):36:37 -> b + 1:2:void reset():43:44 -> j + 1:1:boolean isObserving():60:60 -> l + 1:4:void observeDuration():53:56 -> m + 1:2:void startTimer():48:49 -> n +com.batch.android.module.ActionModule -> com.batch.android.n0.a: + java.util.HashMap drawableAliases -> b + com.batch.android.BatchDeeplinkInterceptor deeplinkInterceptor -> c + java.util.HashMap registeredActions -> a + java.lang.String RESERVED_ACTION_IDENTIFIER_PREFIX -> e + java.lang.String TAG -> d + 1:1:void ():48:48 -> + 2:9:void ():46:53 -> + 1:13:void registerAction(com.batch.android.UserAction):65:77 -> a + 14:14:void registerAction(com.batch.android.UserAction):67:67 -> a + 15:15:void registerAction(com.batch.android.UserAction):62:62 -> a + 16:24:void addDrawableAlias(java.lang.String,int):116:124 -> a + 25:25:void addDrawableAlias(java.lang.String,int):121:121 -> a + 26:26:void addDrawableAlias(java.lang.String,int):117:117 -> a + 27:27:void addDrawableAlias(java.lang.String,int):113:113 -> a + 28:34:int getAliasedDrawableID(java.lang.String):134:140 -> a + 35:49:boolean performUserAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject):154:168 -> a + 50:50:boolean performUserAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject):157:157 -> a + 51:58:boolean performAction(android.content.Context,java.lang.String,com.batch.android.json.JSONObject,com.batch.android.UserActionSource):187:194 -> a + 59:59:void setDeeplinkInterceptor(com.batch.android.BatchDeeplinkInterceptor):208:208 -> a + 60:68:int getDrawableIdForNameOrAlias(android.content.Context,java.lang.String):262:270 -> a + 1:15:void unregisterAction(java.lang.String):90:104 -> b + 16:16:void unregisterAction(java.lang.String):95:95 -> b + 17:17:void unregisterAction(java.lang.String):91:91 -> b + 18:18:void unregisterAction(java.lang.String):87:87 -> b + 1:1:java.lang.String getId():280:280 -> g + int getState() -> h + 1:1:com.batch.android.BatchDeeplinkInterceptor getDeeplinkInterceptor():216:216 -> i + 1:36:void registerBuiltinActions():220:255 -> j +com.batch.android.module.BatchModule -> com.batch.android.n0.b: + 1:1:void ():11:11 -> + void batchContextBecameAvailable(android.content.Context) -> a + void batchDidStart() -> b + void batchDidStop() -> c + void batchIsFinishing() -> d + void batchWillStart() -> e + void batchWillStop() -> f + java.lang.String getId() -> g + int getState() -> h +com.batch.android.module.BatchModuleMaster -> com.batch.android.n0.c: + java.util.List modules -> a + 1:2:void (java.util.List):32:33 -> + 1:2:void batchContextBecameAvailable(android.content.Context):65:66 -> a + 1:2:void batchDidStart():79:80 -> b + 1:2:void batchDidStop():100:101 -> c + 1:2:void batchIsFinishing():86:87 -> d + 1:2:void batchWillStart():72:73 -> e + 1:2:void batchWillStop():93:94 -> f + 1:1:java.lang.String getId():55:55 -> g + int getState() -> h + 1:11:com.batch.android.module.BatchModuleMaster provide():38:48 -> i +com.batch.android.module.DisplayReceiptModule -> com.batch.android.n0.d: + com.batch.android.module.OptOutModule optOutModule -> a + java.lang.String TAG -> b + 1:2:void (com.batch.android.module.OptOutModule):37:38 -> + 1:7:java.io.File savePushReceipt(android.content.Context,com.batch.android.core.InternalPushData):80:86 -> a + 8:54:void sendReceipt(android.content.Context,boolean):160:206 -> a + 1:11:void batchDidStart():58:68 -> b + 12:62:void scheduleDisplayReceipt(android.content.Context,com.batch.android.core.InternalPushData):96:146 -> b + 63:63:void wipeData(android.content.Context):217:217 -> b + 1:1:java.lang.String getId():48:48 -> g + int getState() -> h + 1:1:com.batch.android.module.DisplayReceiptModule provide():43:43 -> i +com.batch.android.module.DisplayReceiptModule$1 -> com.batch.android.n0.d$a: + java.util.Map val$payloads -> a + 1:1:void (java.util.Map):189:189 -> + 1:1:void onFailure(com.batch.android.core.Webservice$WebserviceError):200:200 -> a + 1:2:void onSuccess():193:194 -> onSuccess +com.batch.android.module.EventDispatcherModule -> com.batch.android.n0.e: + java.lang.String COMPONENT_KEY_PREFIX -> f + java.util.Set eventDispatchers -> a + com.batch.android.module.OptOutModule optOutModule -> b + boolean isContextLoaded -> c + java.lang.String COMPONENT_SENTINEL_VALUE -> e + java.lang.String TAG -> d + 1:1:void (com.batch.android.module.OptOutModule):35:35 -> + 2:8:void (com.batch.android.module.OptOutModule):30:36 -> + 1:1:void printLoadedDispatcher(java.lang.String):55:55 -> a + 2:4:void addEventDispatcher(com.batch.android.BatchEventDispatcher):59:61 -> a + 5:14:void dispatchEvent(com.batch.android.Batch$EventDispatcher$Type,com.batch.android.Batch$EventDispatcher$Payload):71:80 -> a + 1:3:boolean removeEventDispatcher(com.batch.android.BatchEventDispatcher):65:67 -> b + 4:29:void loadDispatcherFromContext(android.content.Context):84:109 -> b + 30:57:void loadDispatcherFromContext(android.content.Context):107:134 -> b + 58:58:void loadDispatcherFromContext(android.content.Context):95:95 -> b + 1:1:java.lang.String getId():46:46 -> g + int getState() -> h + 1:4:com.batch.android.json.JSONObject getDispatchersAnalyticRepresentation():145:148 -> i + 1:1:com.batch.android.module.EventDispatcherModule provide():41:41 -> j +com.batch.android.module.LocalCampaignsModule -> com.batch.android.n0.f: + java.util.concurrent.ExecutorService triggerExecutor -> f + java.lang.String TAG -> i + java.util.concurrent.atomic.AtomicBoolean isWaitingJITSync -> e + java.util.concurrent.atomic.AtomicBoolean isReady -> d + android.content.BroadcastReceiver newSessionBroadcastReceiver -> h + com.batch.android.localcampaigns.CampaignManager campaignManager -> a + boolean isNewSessionBroadcastReceiverRegistered -> g + boolean triedToReadSavedCampaign -> b + java.util.LinkedList signalQueue -> c + 1:1:void (com.batch.android.localcampaigns.CampaignManager):85:85 -> + 2:273:void (com.batch.android.localcampaigns.CampaignManager):53:324 -> + 274:274:void (com.batch.android.localcampaigns.CampaignManager):86:86 -> + 1:1:java.util.concurrent.atomic.AtomicBoolean access$000(com.batch.android.module.LocalCampaignsModule):41:41 -> a + 2:65:void electCampaignForSignal(com.batch.android.localcampaigns.signal.Signal):200:263 -> a + 66:78:void lambda$electCampaignForSignal$1(com.batch.android.localcampaigns.model.LocalCampaign,com.batch.android.localcampaigns.model.LocalCampaign):229:241 -> a + 79:80:void displayMessage(com.batch.android.localcampaigns.model.LocalCampaign):272:273 -> a + 81:82:void batchContextBecameAvailable(android.content.Context):369:370 -> a + 1:8:void enqueueSignal(com.batch.android.localcampaigns.signal.Signal):126:133 -> b + 9:15:void enqueueSignal(com.batch.android.localcampaigns.signal.Signal):131:137 -> b + 16:17:void lambda$loadSavedCampaigns$2(android.content.Context):359:360 -> b + 1:5:void lambda$processSignal$0(com.batch.android.localcampaigns.signal.Signal):170:174 -> c + 6:15:void loadSavedCampaigns(android.content.Context):354:363 -> c + 16:16:void batchDidStop():375:375 -> c + 1:25:void processSignal(com.batch.android.localcampaigns.signal.Signal):145:169 -> d + 26:31:void registerBroadcastReceiverIfNeeded(android.content.Context):340:345 -> d + 1:4:void sendSignal(com.batch.android.localcampaigns.signal.Signal):114:117 -> e + 5:7:void wipeData(android.content.Context):315:317 -> e + 1:1:java.lang.String getId():98:98 -> g + int getState() -> h + 1:12:void dequeueSignals():288:299 -> i + 1:2:void makeReady():280:281 -> j + 1:1:void onLocalCampaignsWebserviceFinished():306:306 -> k + 1:1:com.batch.android.module.LocalCampaignsModule provide():91:91 -> l +com.batch.android.module.LocalCampaignsModule$1 -> com.batch.android.n0.f$a: + com.batch.android.module.LocalCampaignsModule this$0 -> a + 1:1:void (com.batch.android.module.LocalCampaignsModule):324:324 -> + 1:4:void onReceive(android.content.Context,android.content.Intent):327:330 -> onReceive +com.batch.android.module.MessagingModule -> com.batch.android.n0.g: + com.batch.android.module.ActionModule actionModule -> f + com.batch.android.module.TrackerModule trackerModule -> g + java.lang.String ACTION_DISMISS_INTERSTITIAL -> i + java.lang.String TAG -> h + java.lang.String ACTION_DISMISS_BANNER -> j + java.lang.String MESSAGING_EVENT_NAME_DISMISS -> m + java.lang.String MESSAGING_EVENT_NAME_SHOW -> l + java.lang.String MESSAGING_EVENT_NAME_CLOSE_ERROR -> o + java.lang.String MESSAGING_EVENT_NAME_CLOSE -> n + java.lang.String MESSAGING_EVENT_NAME_GLOBAL_TAP -> q + java.lang.String MESSAGING_EVENT_NAME_AUTO_CLOSE -> p + java.lang.String MESSAGING_EVENT_NAME_WEBVIEW_CLICK -> s + java.lang.String MESSAGING_EVENT_NAME_CTA -> r + double DEFAULT_IMAGE_DOWNLOAD_TIMEOUT -> k + com.batch.android.BatchMessage pendingMessage -> e + boolean showForegroundLandings -> a + boolean automaticMode -> b + com.batch.android.Batch$Messaging$LifecycleListener listener -> c + boolean doNotDisturbMode -> d + 1:1:void (com.batch.android.module.ActionModule,com.batch.android.module.TrackerModule):110:110 -> + 2:18:void (com.batch.android.module.ActionModule,com.batch.android.module.TrackerModule):96:112 -> + 1:2:void setTypefaceOverride(android.graphics.Typeface,android.graphics.Typeface):167:168 -> a + 3:3:void setLifecycleListener(com.batch.android.Batch$Messaging$LifecycleListener):172:172 -> a + 4:16:boolean doesAppHaveRequiredLibraries(boolean):194:206 -> a + 17:42:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):287:312 -> a + 43:49:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):309:315 -> a + 50:51:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):304:305 -> a + 52:52:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):288:288 -> a + 53:53:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):284:284 -> a + 54:54:com.batch.android.BatchBannerView loadBanner(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):279:279 -> a + 55:56:void performAction(android.content.Context,com.batch.android.BatchMessage,com.batch.android.messaging.model.Action):320:321 -> a + 57:80:void displayMessage(android.content.Context,com.batch.android.BatchMessage,boolean):326:349 -> a + 81:98:void displayInAppMessage(com.batch.android.BatchInAppMessage):353:370 -> a + 99:110:com.batch.android.json.JSONObject generateBaseEventParameters(com.batch.android.messaging.model.Message,java.lang.String):383:394 -> a + 111:111:com.batch.android.json.JSONObject generateBaseEventParameters(com.batch.android.messaging.model.Message,java.lang.String):391:391 -> a + 112:127:com.batch.android.json.JSONObject generateBaseEventParameters(com.batch.android.messaging.model.Message,java.lang.String):388:403 -> a + 128:139:void trackCTAClickEvent(com.batch.android.messaging.model.Message,int,java.lang.String):429:440 -> a + 140:147:void trackWebViewClickEvent(com.batch.android.messaging.model.Message,java.lang.String,java.lang.String):450:457 -> a + 148:150:void onMessageCTAClicked(com.batch.android.messaging.model.Message,int,com.batch.android.messaging.model.CTA):488:490 -> a + 151:154:void onWebViewMessageClickTracked(com.batch.android.messaging.model.Message,com.batch.android.messaging.model.Action,java.lang.String):500:503 -> a + 155:169:void onMessageGlobalTap(com.batch.android.messaging.model.Message,com.batch.android.messaging.model.Action):512:526 -> a + 170:172:void onMessageAutoClosed(com.batch.android.messaging.model.Message):535:537 -> a + 173:175:void onMessageClosedError(com.batch.android.messaging.model.Message,com.batch.android.messaging.model.MessagingError):543:545 -> a + 1:1:void setAutomaticMode(boolean):163:163 -> b + 2:38:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):232:268 -> b + 39:40:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):249:250 -> b + 41:41:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):233:233 -> b + 42:42:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):229:229 -> b + 43:43:androidx.fragment.app.DialogFragment loadFragment(android.content.Context,com.batch.android.BatchMessage,com.batch.android.json.JSONObject):224:224 -> b + 44:46:void trackGenericEvent(com.batch.android.messaging.model.Message,java.lang.String):410:412 -> b + 47:53:void trackCloseErrorEvent(com.batch.android.messaging.model.Message,com.batch.android.messaging.model.MessagingError):418:424 -> b + 54:56:void onMessageClosed(com.batch.android.messaging.model.Message):481:483 -> b + 1:1:void setDoNotDisturbEnabled(boolean):176:176 -> c + 2:4:void onMessageDismissed(com.batch.android.messaging.model.Message):473:475 -> c + 1:1:void setShowForegroundLandings(boolean):159:159 -> d + 2:4:void onMessageShown(com.batch.android.messaging.model.Message):466:468 -> d + 1:1:java.lang.String getId():126:126 -> g + int getState() -> h + 1:1:com.batch.android.Batch$Messaging$LifecycleListener getListener():147:147 -> i + 1:1:boolean hasPendingMessage():180:180 -> j + 1:1:boolean isDoNotDisturbEnabled():151:151 -> k + 1:1:boolean isInAutomaticMode():143:143 -> l + 1:2:com.batch.android.BatchMessage popPendingMessage():185:186 -> m + 1:1:com.batch.android.module.MessagingModule provide():117:117 -> n + 1:1:boolean shouldShowForegroundLandings():139:139 -> o +com.batch.android.module.MessagingModule$1 -> com.batch.android.n0.g$a: + int[] $SwitchMap$com$batch$android$messaging$model$Message$Source -> a + 1:1:void ():386:386 -> +com.batch.android.module.OptOutModule -> com.batch.android.n0.h: + java.lang.String OPT_OUT_PREFERENCES_NAME -> g + java.lang.String INTENT_OPTED_OUT_WIPE_DATA_EXTRA -> f + java.lang.String SHOULD_SEND_OPTIN_EVENT_KEY -> i + java.lang.String OPTED_OUT_FROM_BATCHSDK_KEY -> h + java.lang.String MANIFEST_OPT_OUT_BY_DEFAULT_KEY -> j + android.content.SharedPreferences preferences -> b + java.lang.String TAG -> c + java.lang.Boolean isOptedOut -> a + java.lang.String INTENT_OPTED_IN -> e + java.lang.String INTENT_OPTED_OUT -> d + 1:1:void ():56:56 -> + 2:2:void ():52:52 -> + 1:7:void trackOptinEventIfNeeded(android.content.Context,com.batch.android.AdvertisingID):90:96 -> a + 8:54:com.batch.android.core.Promise optOut(android.content.Context,com.batch.android.AdvertisingID,boolean,com.batch.android.BatchOptOutResultListener):124:170 -> a + 55:56:void lambda$optOut$1(android.content.Context,com.batch.android.BatchOptOutResultListener,boolean,com.batch.android.core.Promise,java.lang.Void):146:147 -> a + 57:60:void lambda$optOut$0(com.batch.android.BatchOptOutResultListener,android.content.Context,boolean,com.batch.android.core.Promise):149:152 -> a + 61:62:void lambda$optOut$3(android.content.Context,com.batch.android.BatchOptOutResultListener,com.batch.android.core.Promise,boolean,java.lang.Exception):157:158 -> a + 63:69:void lambda$optOut$2(com.batch.android.BatchOptOutResultListener,com.batch.android.core.Promise,android.content.Context,boolean):160:166 -> a + 70:77:void doOptOut(android.content.Context,boolean):178:185 -> a + 78:86:boolean getManifestBoolean(android.content.Context,java.lang.String,boolean):212:220 -> a + 1:5:android.content.SharedPreferences getPreferences(android.content.Context):59:63 -> b + 1:16:boolean isOptedOutSync(android.content.Context):71:86 -> c + 1:10:void optIn(android.content.Context):102:111 -> d + 1:17:void wipeData(android.content.Context):190:206 -> e + 1:1:java.lang.String getId():230:230 -> g + int getState() -> h + 1:1:java.lang.Boolean isOptedOut():67:67 -> i +com.batch.android.module.PushModule -> com.batch.android.n0.i: + int NO_COLOR -> o + android.net.Uri notificationSoundUri -> f + com.batch.android.BatchNotificationInterceptor notificationInterceptor -> j + java.util.EnumSet tempNotifType -> h + java.lang.Integer customOpenIntentFlags -> i + boolean didSetupRegistrationProvider -> l + java.lang.String TAG -> n + int notificationColor -> e + int smallIconResourceId -> b + com.batch.android.PushRegistrationProvider registrationProvider -> k + com.batch.android.module.DisplayReceiptModule displayReceiptModule -> m + android.graphics.Bitmap largeIcon -> c + boolean manualDisplay -> g + boolean shouldRefreshToken -> a + java.lang.String gcmSenderId -> d + 1:1:void (com.batch.android.module.DisplayReceiptModule):126:126 -> + 2:52:void (com.batch.android.module.DisplayReceiptModule):77:127 -> + 1:1:void access$000(com.batch.android.module.PushModule,android.content.Context,com.batch.android.push.Registration):63:63 -> a + 2:2:void setCustomSmallIconResourceId(int):152:152 -> a + 3:3:void setAdditionalIntentFlags(java.lang.Integer):170:170 -> a + 4:4:void setCustomLargeIcon(android.graphics.Bitmap):188:188 -> a + 5:7:void setGCMSenderId(java.lang.String):197:199 -> a + 8:8:void setNotificationInterceptor(com.batch.android.BatchNotificationInterceptor):206:206 -> a + 9:13:boolean isBatchPush(android.content.Intent):257:261 -> a + 14:20:boolean isBatchPush(com.google.firebase.messaging.RemoteMessage):272:278 -> a + 21:24:void lambda$getRegistrationID$1(java.lang.StringBuilder,com.batch.android.runtime.State):292:295 -> a + 25:50:void setNotificationsType(java.util.EnumSet):378:403 -> a + 51:55:void lambda$setNotificationsType$2(int,java.util.concurrent.atomic.AtomicBoolean,com.batch.android.runtime.State):390:394 -> a + 56:56:void setSound(android.net.Uri):433:433 -> a + 57:57:void setManualDisplay(boolean):452:452 -> a + 58:61:void appendBatchData(android.content.Intent,android.content.Intent):473:476 -> a + 62:74:void appendBatchData(android.os.Bundle,android.content.Intent):489:501 -> a + 75:80:void appendBatchData(com.google.firebase.messaging.RemoteMessage,android.content.Intent):509:514 -> a + 81:90:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,android.os.Bundle):534:543 -> a + 91:96:android.app.PendingIntent makePendingIntent(android.content.Context,android.content.Intent,com.google.firebase.messaging.RemoteMessage):555:560 -> a + 97:106:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,android.os.Bundle):578:587 -> a + 107:112:android.app.PendingIntent makePendingIntentForDeeplink(android.content.Context,java.lang.String,com.google.firebase.messaging.RemoteMessage):599:604 -> a + 113:124:void displayNotification(android.content.Context,android.content.Intent,com.batch.android.BatchNotificationInterceptor,boolean):648:659 -> a + 125:133:void displayNotification(android.content.Context,android.content.Intent,com.batch.android.BatchNotificationInterceptor,boolean):656:664 -> a + 134:150:void displayNotification(android.content.Context,com.google.firebase.messaging.RemoteMessage,com.batch.android.BatchNotificationInterceptor):673:689 -> a + 151:159:void displayNotification(android.content.Context,com.google.firebase.messaging.RemoteMessage,com.batch.android.BatchNotificationInterceptor):686:694 -> a + 160:168:void onNotificationDisplayed(android.content.Context,android.content.Intent):706:714 -> a + 169:177:void onNotificationDisplayed(android.content.Context,com.google.firebase.messaging.RemoteMessage):723:731 -> a + 178:181:void requestRegistration(com.batch.android.PushRegistrationProvider):786:789 -> a + 182:194:void emitRegistration(android.content.Context,com.batch.android.push.Registration):842:854 -> a + 195:228:void lambda$emitRegistration$3(com.batch.android.push.Registration,android.content.Context,com.batch.android.runtime.State):855:888 -> a + 229:229:void printRegistration(com.batch.android.push.Registration):935:935 -> a + 230:236:void lambda$batchWillStart$4(com.batch.android.runtime.State):960:966 -> a + 1:17:void lambda$dismissNotifications$0(com.batch.android.runtime.State):223:239 -> b + 18:33:java.util.EnumSet getNotificationsType(android.content.Context):350:365 -> b + 34:34:void setNotificationsColor(int):414:414 -> b + 35:37:boolean shouldDisplayPush(android.content.Context,android.content.Intent):616:618 -> b + 38:40:boolean shouldDisplayPush(android.content.Context,com.google.firebase.messaging.RemoteMessage):628:630 -> b + 1:21:com.batch.android.push.Registration getRegistration(android.content.Context):312:332 -> c + 1:4:boolean isBackgroundRestricted(android.content.Context):925:928 -> d + 1:22:void batchWillStart():955:976 -> e + 1:1:java.lang.String getId():942:942 -> g + 1:1:int getState():947:947 -> h + 1:2:void dismissNotifications():221:222 -> i + 1:1:java.lang.Integer getAdditionalIntentFlags():160:160 -> j + 1:3:com.batch.android.AdsIdentifierProvider getAdsIdentifierProvider():755:757 -> k + 1:8:java.lang.String getAppVersion():771:778 -> l + 1:1:android.graphics.Bitmap getCustomLargeIcon():179:179 -> m + 1:1:int getCustomSmallIconResourceId():143:143 -> n + 1:1:int getNotificationColor():423:423 -> o + 1:1:com.batch.android.BatchNotificationInterceptor getNotificationInterceptor():213:213 -> p + 1:15:java.lang.String getRegistrationID():287:301 -> q + 1:16:com.batch.android.PushRegistrationProvider getRegistrationProvider():982:997 -> r + 1:1:android.net.Uri getSound():442:442 -> s + 1:11:boolean isBatchPushServiceAvailable():902:912 -> t + 1:1:boolean isManualDisplayModeActivated():461:461 -> u + 1:1:com.batch.android.module.PushModule provide():132:132 -> v + 1:3:void refreshRegistration():743:745 -> w +com.batch.android.module.PushModule$1 -> com.batch.android.n0.i$a: + android.content.Context val$context -> b + com.batch.android.PushRegistrationProvider val$provider -> a + com.batch.android.module.PushModule this$0 -> c + 1:1:void (com.batch.android.module.PushModule,com.batch.android.PushRegistrationProvider,android.content.Context):790:790 -> + 1:1:java.lang.String getTaskIdentifier():832:832 -> a + 1:23:void run():794:816 -> run + 24:38:void run():813:827 -> run + 39:39:void run():808:808 -> run + 40:46:void run():796:796 -> run +com.batch.android.module.TrackerModule -> com.batch.android.n0.j: + com.batch.android.module.LocalCampaignsModule localCampaignsModule -> h + com.batch.android.module.PushModule pushModule -> j + com.batch.android.localcampaigns.CampaignManager campaignManager -> i + java.lang.String TAG -> k + java.util.Queue memoryStorage -> b + java.util.concurrent.atomic.AtomicBoolean isFlushing -> d + int batchSendQuantity -> f + com.batch.android.module.OptOutModule optOutModule -> g + com.batch.android.tracker.TrackerDatasource datasource -> a + java.util.concurrent.ExecutorService flushExecutor -> c + com.batch.android.event.EventSender sender -> e + 1:1:void (com.batch.android.module.OptOutModule,com.batch.android.module.LocalCampaignsModule,com.batch.android.localcampaigns.CampaignManager,com.batch.android.module.PushModule):103:103 -> + 2:43:void (com.batch.android.module.OptOutModule,com.batch.android.module.LocalCampaignsModule,com.batch.android.localcampaigns.CampaignManager,com.batch.android.module.PushModule):66:107 -> + 1:1:void track(java.lang.String):191:191 -> a + 2:2:void track(java.lang.String,com.batch.android.json.JSONObject):201:201 -> a + 3:16:void track(java.lang.String,long,com.batch.android.json.JSONObject):212:225 -> a + 17:17:void track(java.lang.String,long):256:256 -> a + 18:49:com.batch.android.core.Promise trackOptOutEvent(android.content.Context,com.batch.android.AdvertisingID,java.lang.String):313:344 -> a + 50:52:void lambda$trackOptOutEvent$0(android.content.Context,java.util.List,com.batch.android.core.Promise):319:321 -> a + 53:73:void lambda$trackOptOutEvent$0(android.content.Context,java.util.List,com.batch.android.core.Promise):320:340 -> a + 74:102:com.batch.android.json.JSONObject makeOptBaseEventData(android.content.Context,com.batch.android.AdvertisingID):349:377 -> a + 103:107:void lambda$flush$2(com.batch.android.runtime.State):418:422 -> a + 108:112:void onEventsSendFailure(java.util.List):502:506 -> a + 113:130:void lambda$onEventsSendFailure$4(java.util.List,com.batch.android.runtime.State):507:524 -> a + 131:133:java.util.List getEventsToSend():532:534 -> a + 1:2:void batchDidStart():169:170 -> b + 3:12:void trackCollapsible(java.lang.String,long,com.batch.android.json.JSONObject):237:246 -> b + 13:34:void trackCampaignView(java.lang.String,com.batch.android.json.JSONObject):266:287 -> b + 35:35:void trackCampaignView(java.lang.String,com.batch.android.json.JSONObject):274:274 -> b + 36:36:void trackOptInEvent(android.content.Context,com.batch.android.AdvertisingID):299:299 -> b + 37:41:void onEventsSendSuccess(java.util.List):479:483 -> b + 42:52:void lambda$onEventsSendSuccess$3(java.util.List,com.batch.android.runtime.State):484:494 -> b + 53:62:void lambda$wipeData$6(android.content.Context):546:555 -> b + 1:3:void batchDidStop():177:179 -> c + 4:4:void lambda$getEventsToSend$5(java.util.List):534:534 -> c + 5:7:void wipeData(android.content.Context):542:544 -> c + 1:9:void batchWillStart():132:140 -> e + 10:22:void batchWillStart():137:149 -> e + 23:23:void batchWillStart():146:146 -> e + 24:40:void batchWillStart():145:161 -> e + 1:1:java.lang.String getId():122:122 -> g + 1:1:int getState():127:127 -> h + 1:8:void closeDatasource():388:395 -> i + 1:13:void flush():405:417 -> j + 1:2:com.batch.android.tracker.TrackerMode getMode():464:465 -> k + 3:3:com.batch.android.tracker.TrackerMode getMode():462:462 -> k + 4:15:com.batch.android.tracker.TrackerMode getMode():461:472 -> k + 1:18:void lambda$flush$1():424:441 -> l + 19:32:void lambda$flush$1():428:441 -> l + 33:36:void lambda$flush$1():439:442 -> l + 1:5:com.batch.android.module.TrackerModule provide():112:116 -> m +com.batch.android.module.TrackerModule$1 -> com.batch.android.n0.j$a: + com.batch.android.core.Promise val$promise -> a + com.batch.android.module.TrackerModule this$0 -> b + 1:1:void (com.batch.android.module.TrackerModule,com.batch.android.core.Promise):324:324 -> + void onFinish() -> a + 1:1:void onSuccess(java.util.List):327:327 -> a + 2:2:void onFailure(com.batch.android.FailReason,java.util.List):332:332 -> a +com.batch.android.module.UserModule -> com.batch.android.n0.k: + java.lang.String PARAMETER_KEY_DATA -> g + long LOCATION_UPDATE_MINIMUM_TIME_MS -> j + java.lang.String PARAMETER_KEY_LABEL -> f + java.lang.String PARAMETER_KEY_AMOUNT -> h + long CIPHER_FALLBACK_RESET_TIME_MS -> k + com.batch.android.module.TrackerModule trackerModule -> d + android.content.BroadcastReceiver localBroadcastReceiver -> a + long lastLocationTrackTimestamp -> c + java.util.regex.Pattern EVENT_NAME_PATTERN -> i + java.util.concurrent.ScheduledExecutorService applyQueue -> l + java.util.concurrent.atomic.AtomicBoolean checkScheduled -> b + java.util.List pendingUserOperation -> m + java.lang.String TAG -> e + 1:12:void ():59:70 -> + 1:1:void (com.batch.android.module.TrackerModule):80:80 -> + 2:9:void (com.batch.android.module.TrackerModule):74:81 -> + 1:5:void storeTransactionID(java.lang.String,long):249:253 -> a + 6:23:void lambda$storeTransactionID$2(long,java.lang.String):260:277 -> a + 24:24:void lambda$storeTransactionID$2(long,java.lang.String):263:263 -> a + 25:25:void bumpVersion(long):284:284 -> a + 26:46:void trackPublicEvent(java.lang.String,java.lang.String,com.batch.android.json.JSONObject):334:354 -> a + 47:54:boolean _trackEvent(java.lang.String,com.batch.android.json.JSONObject):359:366 -> a + 55:87:void trackLocation(android.location.Location):377:409 -> a + 88:98:void trackTransaction(double,com.batch.android.json.JSONObject):415:425 -> a + 99:102:void submitOnApplyQueue(long,java.lang.Runnable):434:437 -> a + 1:37:void batchDidStart():103:139 -> b + 38:59:void lambda$bumpVersion$3(long):291:312 -> b + 60:60:void lambda$bumpVersion$3(long):294:294 -> b + 61:70:void lambda$wipeData$6(android.content.Context):635:644 -> b + 1:3:void startCheckWS(long):190:192 -> c + 4:6:void addUserPendingOperations(java.util.List):454:456 -> c + 7:8:void userOptedIn(android.content.Context):650:651 -> c + 1:1:void startSendWS(long):147:147 -> d + 2:91:void applyUserOperationsSync(java.util.List):483:572 -> d + 92:92:void applyUserOperationsSync(java.util.List):504:504 -> d + 93:93:void applyUserOperationsSync(java.util.List):495:495 -> d + 94:94:void applyUserOperationsSync(java.util.List):486:486 -> d + 95:97:void wipeData(android.content.Context):630:632 -> d + 1:3:void lambda$executeUserPendingOperations$4(java.util.List):470:472 -> e + 1:1:java.lang.String getId():93:93 -> g + int getState() -> h + 1:17:void executeUserPendingOperations():463:479 -> i + 1:5:void lambda$printDebugInfo$5():612:616 -> j + 1:44:void lambda$startCheckWS$1():197:240 -> k + 45:45:void lambda$startCheckWS$1():239:239 -> k + 46:46:void lambda$startCheckWS$1():213:213 -> k + 1:34:void lambda$startSendWS$0():150:183 -> l + 35:35:void lambda$startSendWS$0():179:179 -> l + 36:36:void lambda$startSendWS$0():162:162 -> l + 1:1:java.util.concurrent.ScheduledExecutorService makeApplyQueue():67:67 -> m + 1:1:void printDebugInfo():609:609 -> n + 1:1:com.batch.android.module.UserModule provide():86:86 -> o +com.batch.android.module.UserModule$1 -> com.batch.android.n0.k$a: + com.batch.android.module.UserModule this$0 -> a + 1:1:void (com.batch.android.module.UserModule):125:125 -> + 1:2:void onReceive(android.content.Context,android.content.Intent):128:129 -> onReceive +com.batch.android.module.UserModule$SaveException -> com.batch.android.n0.k$b: + java.lang.String internalErrorMessage -> a + 1:1:void (java.lang.String):585:585 -> + 2:3:void (java.lang.String,java.lang.String):589:590 -> + 4:5:void (java.lang.String,java.lang.String,java.lang.Throwable):594:595 -> + 1:2:void log():599:600 -> a +com.batch.android.msgpack.MessagePackHelper -> com.batch.android.o0.a: + 1:1:void ():10:10 -> + 1:29:void packObject(com.batch.android.msgpack.core.MessageBufferPacker,java.lang.Object):15:43 -> a + 30:33:void packMap(com.batch.android.msgpack.core.MessageBufferPacker,java.util.Map):48:51 -> a + 34:36:void packList(com.batch.android.msgpack.core.MessageBufferPacker,java.util.List):56:58 -> a +com.batch.android.msgpack.core.ExtensionTypeHeader -> com.batch.android.p0.a: + byte type -> a + int length -> b + 1:4:void (byte,int):46:49 -> + 1:1:byte checkedCastToByte(int):53:53 -> a + 2:2:int getLength():65:65 -> a + 1:1:byte getType():61:61 -> b + 1:3:boolean equals(java.lang.Object):75:77 -> equals + 1:1:int hashCode():70:70 -> hashCode + 1:1:java.lang.String toString():84:84 -> toString +com.batch.android.msgpack.core.MessageBufferPacker -> com.batch.android.p0.b: + 1:1:void (com.batch.android.msgpack.core.MessagePack$PackerConfig):34:34 -> + 2:2:void (com.batch.android.msgpack.core.buffer.ArrayBufferOutput,com.batch.android.msgpack.core.MessagePack$PackerConfig):38:38 -> + 1:4:com.batch.android.msgpack.core.buffer.MessageBufferOutput reset(com.batch.android.msgpack.core.buffer.MessageBufferOutput):42:45 -> a + 5:5:com.batch.android.msgpack.core.buffer.MessageBufferOutput reset(com.batch.android.msgpack.core.buffer.MessageBufferOutput):43:43 -> a + 6:7:void clear():54:55 -> a + 1:1:com.batch.android.msgpack.core.buffer.ArrayBufferOutput getArrayBufferOut():49:49 -> f + 1:1:int getBufferSize():116:116 -> g + 1:6:java.util.List toBufferList():104:109 -> h + 7:7:java.util.List toBufferList():107:107 -> h + 1:6:byte[] toByteArray():68:73 -> i + 7:7:byte[] toByteArray():71:71 -> i + 1:6:com.batch.android.msgpack.core.buffer.MessageBuffer toMessageBuffer():86:91 -> j + 7:7:com.batch.android.msgpack.core.buffer.MessageBuffer toMessageBuffer():89:89 -> j +com.batch.android.msgpack.core.MessageFormat -> com.batch.android.p0.c: + com.batch.android.msgpack.core.MessageFormat FIXARRAY -> d + com.batch.android.msgpack.core.MessageFormat STR16 -> E + com.batch.android.msgpack.core.MessageFormat NIL -> f + com.batch.android.msgpack.core.MessageFormat ARRAY16 -> G + com.batch.android.msgpack.core.MessageFormat[] formatTable -> L + com.batch.android.msgpack.core.MessageFormat BOOLEAN -> h + com.batch.android.msgpack.core.MessageFormat MAP16 -> I + com.batch.android.msgpack.core.MessageFormat BIN16 -> j + com.batch.android.msgpack.core.MessageFormat NEGFIXINT -> K + com.batch.android.msgpack.core.MessageFormat EXT8 -> l + com.batch.android.msgpack.core.MessageFormat EXT32 -> n + com.batch.android.msgpack.core.MessageFormat FLOAT64 -> p + com.batch.android.msgpack.core.MessageFormat UINT16 -> r + com.batch.android.msgpack.core.MessageFormat UINT64 -> t + com.batch.android.msgpack.core.MessageFormat INT16 -> v + com.batch.android.msgpack.core.MessageFormat INT64 -> x + com.batch.android.msgpack.core.MessageFormat FIXEXT2 -> z + com.batch.android.msgpack.value.ValueType valueType -> a + com.batch.android.msgpack.core.MessageFormat FIXEXT8 -> B + com.batch.android.msgpack.core.MessageFormat FIXMAP -> c + com.batch.android.msgpack.core.MessageFormat STR8 -> D + com.batch.android.msgpack.core.MessageFormat FIXSTR -> e + com.batch.android.msgpack.core.MessageFormat STR32 -> F + com.batch.android.msgpack.core.MessageFormat[] $VALUES -> M + com.batch.android.msgpack.core.MessageFormat NEVER_USED -> g + com.batch.android.msgpack.core.MessageFormat ARRAY32 -> H + com.batch.android.msgpack.core.MessageFormat BIN8 -> i + com.batch.android.msgpack.core.MessageFormat MAP32 -> J + com.batch.android.msgpack.core.MessageFormat BIN32 -> k + com.batch.android.msgpack.core.MessageFormat EXT16 -> m + com.batch.android.msgpack.core.MessageFormat FLOAT32 -> o + com.batch.android.msgpack.core.MessageFormat UINT8 -> q + com.batch.android.msgpack.core.MessageFormat UINT32 -> s + com.batch.android.msgpack.core.MessageFormat INT8 -> u + com.batch.android.msgpack.core.MessageFormat INT32 -> w + com.batch.android.msgpack.core.MessageFormat FIXEXT1 -> y + com.batch.android.msgpack.core.MessageFormat FIXEXT4 -> A + com.batch.android.msgpack.core.MessageFormat POSFIXINT -> b + com.batch.android.msgpack.core.MessageFormat FIXEXT16 -> C + 1:40:void ():27:66 -> + 41:108:void ():25:92 -> + 1:2:void (java.lang.String,int,com.batch.android.msgpack.value.ValueType):71:72 -> + 1:4:com.batch.android.msgpack.value.ValueType getValueType():82:85 -> a + 5:5:com.batch.android.msgpack.value.ValueType getValueType():83:83 -> a + 6:84:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):114:192 -> a + 85:85:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):190:190 -> a + 86:86:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):188:188 -> a + 87:87:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):186:186 -> a + 88:88:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):184:184 -> a + 89:89:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):182:182 -> a + 90:90:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):180:180 -> a + 91:91:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):178:178 -> a + 92:92:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):176:176 -> a + 93:93:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):174:174 -> a + 94:94:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):172:172 -> a + 95:95:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):170:170 -> a + 96:96:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):168:168 -> a + 97:97:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):166:166 -> a + 98:98:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):164:164 -> a + 99:99:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):162:162 -> a + 100:100:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):160:160 -> a + 101:101:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):158:158 -> a + 102:102:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):156:156 -> a + 103:103:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):154:154 -> a + 104:104:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):152:152 -> a + 105:105:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):150:150 -> a + 106:106:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):148:148 -> a + 107:107:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):146:146 -> a + 108:108:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):144:144 -> a + 109:109:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):142:142 -> a + 110:110:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):140:140 -> a + 111:111:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):138:138 -> a + 112:112:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):136:136 -> a + 113:113:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):134:134 -> a + 114:114:com.batch.android.msgpack.core.MessageFormat toMessageFormat(byte):131:131 -> a + 1:1:com.batch.android.msgpack.core.MessageFormat valueOf(byte):103:103 -> b + 1:1:com.batch.android.msgpack.core.MessageFormat valueOf(java.lang.String):25:25 -> valueOf + 1:1:com.batch.android.msgpack.core.MessageFormat[] values():25:25 -> values +com.batch.android.msgpack.core.MessageFormatException -> com.batch.android.p0.d: + 1:1:void (java.lang.Throwable):24:24 -> + 2:2:void (java.lang.String):28:28 -> + 3:3:void (java.lang.String,java.lang.Throwable):32:32 -> +com.batch.android.msgpack.core.MessageInsufficientBufferException -> com.batch.android.p0.e: + 1:1:void ():24:24 -> + 2:2:void (java.lang.String):28:28 -> + 3:3:void (java.lang.Throwable):32:32 -> + 4:4:void (java.lang.String,java.lang.Throwable):36:36 -> +com.batch.android.msgpack.core.MessageIntegerOverflowException -> com.batch.android.p0.f: + java.math.BigInteger bigInteger -> b + 1:2:void (java.math.BigInteger):30:31 -> + 3:3:void (long):35:35 -> + 4:5:void (java.lang.String,java.math.BigInteger):39:40 -> + 1:1:java.math.BigInteger getBigInteger():44:44 -> a + 1:1:java.lang.String getMessage():49:49 -> getMessage +com.batch.android.msgpack.core.MessageNeverUsedFormatException -> com.batch.android.p0.g: + 1:1:void (java.lang.Throwable):24:24 -> + 2:2:void (java.lang.String):28:28 -> + 3:3:void (java.lang.String,java.lang.Throwable):32:32 -> +com.batch.android.msgpack.core.MessagePack -> com.batch.android.p0.h: + com.batch.android.msgpack.core.MessagePack$UnpackerConfig DEFAULT_UNPACKER_CONFIG -> c + java.nio.charset.Charset UTF8 -> a + com.batch.android.msgpack.core.MessagePack$PackerConfig DEFAULT_PACKER_CONFIG -> b + 1:11:void ():67:77 -> + 1:1:void ():160:160 -> + 1:1:com.batch.android.msgpack.core.MessagePacker newDefaultPacker(com.batch.android.msgpack.core.buffer.MessageBufferOutput):177:177 -> a + 2:2:com.batch.android.msgpack.core.MessagePacker newDefaultPacker(java.io.OutputStream):192:192 -> a + 3:3:com.batch.android.msgpack.core.MessagePacker newDefaultPacker(java.nio.channels.WritableByteChannel):204:204 -> a + 4:4:com.batch.android.msgpack.core.MessageBufferPacker newDefaultBufferPacker():217:217 -> a + 5:5:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(com.batch.android.msgpack.core.buffer.MessageBufferInput):234:234 -> a + 6:6:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(java.io.InputStream):249:249 -> a + 7:7:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(java.nio.channels.ReadableByteChannel):261:261 -> a + 8:8:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(byte[]):275:275 -> a + 9:9:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(byte[],int,int):291:291 -> a + 10:10:com.batch.android.msgpack.core.MessageUnpacker newDefaultUnpacker(java.nio.ByteBuffer):307:307 -> a +com.batch.android.msgpack.core.MessagePack$Code -> com.batch.android.p0.h$a: + byte FIXEXT1 -> y + byte FIXMAP_PREFIX -> b + byte FIXEXT4 -> A + byte FIXSTR_PREFIX -> d + byte FIXEXT16 -> C + byte NEVER_USED -> f + byte STR16 -> E + byte TRUE -> h + byte ARRAY16 -> G + byte MAP32 -> J + byte BIN8 -> i + byte BIN32 -> k + byte EXT16 -> m + byte FLOAT32 -> o + byte UINT8 -> q + byte UINT32 -> s + byte INT8 -> u + byte INT32 -> w + byte FIXEXT2 -> z + byte FIXEXT8 -> B + byte POSFIXINT_MASK -> a + byte STR8 -> D + byte FIXARRAY_PREFIX -> c + byte STR32 -> F + byte NIL -> e + byte ARRAY32 -> H + byte FALSE -> g + byte BIN16 -> j + byte MAP16 -> I + byte EXT8 -> l + byte NEGFIXINT_PREFIX -> K + byte EXT32 -> n + byte FLOAT64 -> p + byte UINT16 -> r + byte UINT64 -> t + byte INT16 -> v + byte INT64 -> x + 1:1:void ():82:82 -> + boolean isFixInt(byte) -> a + boolean isFixStr(byte) -> b + boolean isFixedArray(byte) -> c + boolean isFixedMap(byte) -> d + boolean isFixedRaw(byte) -> e + boolean isNegFixInt(byte) -> f + boolean isPosFixInt(byte) -> g +com.batch.android.msgpack.core.MessagePack$PackerConfig -> com.batch.android.p0.h$b: + int bufferFlushThreshold -> b + int bufferSize -> c + int smallStringOptimizationThreshold -> a + boolean str8FormatSupport -> d + 1:1:void ():323:323 -> + 2:8:void ():315:321 -> + 9:9:void (com.batch.android.msgpack.core.MessagePack$PackerConfig):325:325 -> + 10:24:void (com.batch.android.msgpack.core.MessagePack$PackerConfig):315:329 -> + 1:1:com.batch.android.msgpack.core.MessagePack$PackerConfig clone():334:334 -> a + 2:2:com.batch.android.msgpack.core.MessagePacker newPacker(com.batch.android.msgpack.core.buffer.MessageBufferOutput):370:370 -> a + 3:3:com.batch.android.msgpack.core.MessagePacker newPacker(java.io.OutputStream):383:383 -> a + 4:4:com.batch.android.msgpack.core.MessagePacker newPacker(java.nio.channels.WritableByteChannel):393:393 -> a + 5:6:com.batch.android.msgpack.core.MessagePack$PackerConfig withBufferFlushThreshold(int):426:427 -> a + 7:8:com.batch.android.msgpack.core.MessagePack$PackerConfig withStr8FormatSupport(boolean):455:456 -> a + 1:1:int getBufferFlushThreshold():432:432 -> b + 2:3:com.batch.android.msgpack.core.MessagePack$PackerConfig withBufferSize(int):440:441 -> b + 1:2:com.batch.android.msgpack.core.MessagePack$PackerConfig withSmallStringOptimizationThreshold(int):412:413 -> c + 3:3:int getBufferSize():446:446 -> c + 1:1:java.lang.Object clone():313:313 -> clone + 1:1:int getSmallStringOptimizationThreshold():418:418 -> d + 1:1:boolean isStr8FormatSupport():461:461 -> e + 1:5:boolean equals(java.lang.Object):348:352 -> equals + 1:1:com.batch.android.msgpack.core.MessageBufferPacker newBufferPacker():404:404 -> f + 1:4:int hashCode():339:342 -> hashCode +com.batch.android.msgpack.core.MessagePack$UnpackerConfig -> com.batch.android.p0.h$c: + java.nio.charset.CodingErrorAction actionOnUnmappableString -> d + java.nio.charset.CodingErrorAction actionOnMalformedString -> c + int bufferSize -> f + int stringDecoderBufferSize -> g + int stringSizeLimit -> e + boolean allowReadingStringAsBinary -> a + boolean allowReadingBinaryAsString -> b + 1:1:void ():484:484 -> + 2:14:void ():470:482 -> + 15:15:void (com.batch.android.msgpack.core.MessagePack$UnpackerConfig):486:486 -> + 16:38:void (com.batch.android.msgpack.core.MessagePack$UnpackerConfig):470:492 -> + 1:1:com.batch.android.msgpack.core.MessagePack$UnpackerConfig clone():497:497 -> a + 2:2:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(com.batch.android.msgpack.core.buffer.MessageBufferInput):539:539 -> a + 3:3:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(java.io.InputStream):552:552 -> a + 4:4:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(java.nio.channels.ReadableByteChannel):562:562 -> a + 5:5:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(byte[]):574:574 -> a + 6:6:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(byte[],int,int):588:588 -> a + 7:7:com.batch.android.msgpack.core.MessageUnpacker newUnpacker(java.nio.ByteBuffer):602:602 -> a + 8:9:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withAllowReadingBinaryAsString(boolean):622:623 -> a + 10:11:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withActionOnMalformedString(java.nio.charset.CodingErrorAction):635:636 -> a + 12:13:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withBufferSize(int):688:689 -> a + 1:2:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withAllowReadingStringAsBinary(boolean):609:610 -> b + 3:3:java.nio.charset.CodingErrorAction getActionOnMalformedString():641:641 -> b + 4:5:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withActionOnUnmappableString(java.nio.charset.CodingErrorAction):648:649 -> b + 6:7:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withStringDecoderBufferSize(int):674:675 -> b + 1:1:java.nio.charset.CodingErrorAction getActionOnUnmappableString():654:654 -> c + 2:3:com.batch.android.msgpack.core.MessagePack$UnpackerConfig withStringSizeLimit(int):661:662 -> c + 1:1:java.lang.Object clone():468:468 -> clone + 1:1:boolean getAllowReadingBinaryAsString():628:628 -> d + 1:1:boolean getAllowReadingStringAsBinary():615:615 -> e + 1:5:boolean equals(java.lang.Object):514:518 -> equals + 1:1:int getBufferSize():694:694 -> f + 1:1:int getStringDecoderBufferSize():680:680 -> g + 1:1:int getStringSizeLimit():667:667 -> h + 1:7:int hashCode():502:508 -> hashCode +com.batch.android.msgpack.core.MessagePackException -> com.batch.android.p0.i: + java.lang.IllegalStateException UNREACHABLE -> a + 1:1:void ():43:43 -> + 1:1:void ():24:24 -> + 2:2:void (java.lang.String):28:28 -> + 3:3:void (java.lang.String,java.lang.Throwable):32:32 -> + 4:4:void (java.lang.Throwable):36:36 -> + 1:1:java.lang.UnsupportedOperationException UNSUPPORTED(java.lang.String):40:40 -> a +com.batch.android.msgpack.core.MessagePacker -> com.batch.android.p0.j: + com.batch.android.msgpack.core.buffer.MessageBufferOutput out -> d + boolean CORRUPTED_CHARSET_ENCODER -> i + int UTF_8_MAX_CHAR_SIZE -> j + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> e + long totalFlushBytes -> g + int position -> f + int bufferFlushThreshold -> b + java.nio.charset.CharsetEncoder encoder -> h + boolean str8FormatSupport -> c + int smallStringOptimizationThreshold -> a + 1:25:void ():139:163 -> + 26:26:void ():161:161 -> + 27:27:void ():159:159 -> + 28:28:void ():157:157 -> + 29:39:void ():155:165 -> + 1:7:void (com.batch.android.msgpack.core.buffer.MessageBufferOutput,com.batch.android.msgpack.core.MessagePack$PackerConfig):200:206 -> + 1:9:com.batch.android.msgpack.core.buffer.MessageBufferOutput reset(com.batch.android.msgpack.core.buffer.MessageBufferOutput):225:233 -> a + 10:10:void clear():255:255 -> a + 11:13:void writeByteAndByte(byte,byte):307:309 -> a + 14:17:void writeByteAndShort(byte,short):313:316 -> a + 18:21:void writeByteAndFloat(byte,float):327:330 -> a + 22:25:void writeByteAndDouble(byte,double):334:337 -> a + 26:29:void writeByteAndLong(byte,long):341:344 -> a + 30:30:com.batch.android.msgpack.core.MessagePacker packBoolean(boolean):387:387 -> a + 31:33:com.batch.android.msgpack.core.MessagePacker packByte(byte):403:405 -> a + 34:44:com.batch.android.msgpack.core.MessagePacker packShort(short):423:433 -> a + 45:70:com.batch.android.msgpack.core.MessagePacker packLong(long):487:512 -> a + 71:76:com.batch.android.msgpack.core.MessagePacker packBigInteger(java.math.BigInteger):530:535 -> a + 77:77:com.batch.android.msgpack.core.MessagePacker packFloat(float):551:551 -> a + 78:78:com.batch.android.msgpack.core.MessagePacker packDouble(double):566:566 -> a + 79:100:int encodeStringToBufferAt(int,java.lang.String):601:622 -> a + 101:130:com.batch.android.msgpack.core.MessagePacker packString(java.lang.String):638:667 -> a + 131:165:com.batch.android.msgpack.core.MessagePacker packString(java.lang.String):659:693 -> a + 166:186:com.batch.android.msgpack.core.MessagePacker packString(java.lang.String):685:705 -> a + 187:187:com.batch.android.msgpack.core.MessagePacker packString(java.lang.String):644:644 -> a + 188:188:com.batch.android.msgpack.core.MessagePacker packValue(com.batch.android.msgpack.value.Value):770:770 -> a + 189:211:com.batch.android.msgpack.core.MessagePacker packExtensionTypeHeader(byte,int):788:810 -> a + 212:212:com.batch.android.msgpack.core.MessagePacker addPayload(byte[]):914:914 -> a + 1:4:void flushBuffer():286:289 -> b + 5:6:void writeByte(byte):302:303 -> b + 7:10:void writeByteAndInt(byte,int):320:323 -> b + 11:13:void writeShort(short):348:350 -> b + 14:16:void writeLong(long):360:362 -> b + 17:20:void packStringWithGetBytes(java.lang.String):572:575 -> b + 21:21:com.batch.android.msgpack.core.MessagePacker writePayload(byte[]):871:871 -> b + 1:1:long getTotalWrittenBytes():248:248 -> c + 2:6:void ensureCapacity(int):293:297 -> c + 7:14:com.batch.android.msgpack.core.MessagePacker addPayload(byte[],int,int):935:942 -> c + 15:18:com.batch.android.msgpack.core.MessagePacker addPayload(byte[],int,int):936:939 -> c + 1:4:void close():279:282 -> close + 1:1:com.batch.android.msgpack.core.MessagePacker packNil():374:374 -> d + 2:6:com.batch.android.msgpack.core.MessagePacker packArrayHeader(int):726:730 -> d + 7:7:com.batch.android.msgpack.core.MessagePacker packArrayHeader(int):722:722 -> d + 8:15:com.batch.android.msgpack.core.MessagePacker writePayload(byte[],int,int):886:893 -> d + 16:19:com.batch.android.msgpack.core.MessagePacker writePayload(byte[],int,int):887:890 -> d + 1:19:void prepareEncoder():579:597 -> e + 20:24:com.batch.android.msgpack.core.MessagePacker packBinaryHeader(int):827:831 -> e + 1:16:com.batch.android.msgpack.core.MessagePacker packInt(int):452:467 -> f + 1:4:void flush():265:268 -> flush + 1:5:com.batch.android.msgpack.core.MessagePacker packMapHeader(int):753:757 -> g + 6:6:com.batch.android.msgpack.core.MessagePacker packMapHeader(int):749:749 -> g + 1:7:com.batch.android.msgpack.core.MessagePacker packRawStringHeader(int):850:856 -> h + 1:3:void writeInt(int):354:356 -> i +com.batch.android.msgpack.core.MessageSizeException -> com.batch.android.p0.k: + long size -> b + 1:2:void (long):26:27 -> + 3:4:void (java.lang.String,long):31:32 -> + 1:1:long getSize():36:36 -> a +com.batch.android.msgpack.core.MessageStringCodingException -> com.batch.android.p0.l: + 1:1:void (java.lang.String,java.nio.charset.CharacterCodingException):26:26 -> + 2:2:void (java.nio.charset.CharacterCodingException):30:30 -> + 1:1:java.nio.charset.CharacterCodingException getCause():35:35 -> a + 1:1:java.lang.Throwable getCause():23:23 -> getCause +com.batch.android.msgpack.core.MessageTypeCastException -> com.batch.android.p0.m: + 1:1:void ():21:21 -> + 2:2:void (java.lang.String):25:25 -> + 3:3:void (java.lang.String,java.lang.Throwable):29:29 -> + 4:4:void (java.lang.Throwable):33:33 -> +com.batch.android.msgpack.core.MessageTypeException -> com.batch.android.p0.n: + 1:1:void ():24:24 -> + 2:2:void (java.lang.String):28:28 -> + 3:3:void (java.lang.String,java.lang.Throwable):32:32 -> + 4:4:void (java.lang.Throwable):36:36 -> +com.batch.android.msgpack.core.MessageUnpacker -> com.batch.android.p0.o: + long totalReadBytes -> j + com.batch.android.msgpack.core.buffer.MessageBuffer numberBuffer -> k + int nextReadPosition -> l + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> h + java.lang.StringBuilder decodeStringBuffer -> m + int position -> i + int stringDecoderBufferSize -> f + com.batch.android.msgpack.core.buffer.MessageBufferInput in -> g + java.lang.String EMPTY_STRING -> q + int stringSizeLimit -> e + com.batch.android.msgpack.core.buffer.MessageBuffer EMPTY_BUFFER -> p + boolean $assertionsDisabled -> r + java.nio.charset.CodingErrorAction actionOnUnmappableString -> d + java.nio.charset.CodingErrorAction actionOnMalformedString -> c + java.nio.CharBuffer decodeBuffer -> o + java.nio.charset.CharsetDecoder decoder -> n + boolean allowReadingStringAsBinary -> a + boolean allowReadingBinaryAsString -> b + 1:3:void ():149:151 -> + 1:1:void (com.batch.android.msgpack.core.buffer.MessageBufferInput,com.batch.android.msgpack.core.MessagePack$UnpackerConfig):209:209 -> + 2:53:void (com.batch.android.msgpack.core.buffer.MessageBufferInput,com.batch.android.msgpack.core.MessagePack$UnpackerConfig):165:216 -> + 1:40:int unpackInt():879:918 -> A + 41:43:int unpackInt():912:914 -> A + 44:44:int unpackInt():909:909 -> A + 45:45:int unpackInt():906:906 -> A + 46:46:int unpackInt():903:903 -> A + 47:49:int unpackInt():897:899 -> A + 50:52:int unpackInt():891:893 -> A + 53:53:int unpackInt():888:888 -> A + 54:54:int unpackInt():885:885 -> A + 1:38:long unpackLong():932:969 -> B + 39:39:long unpackLong():966:966 -> B + 40:40:long unpackLong():963:963 -> B + 41:41:long unpackLong():960:960 -> B + 42:42:long unpackLong():957:957 -> B + 43:45:long unpackLong():951:953 -> B + 46:46:long unpackLong():944:944 -> B + 47:47:long unpackLong():941:941 -> B + 48:48:long unpackLong():938:938 -> B + 1:17:int unpackMapHeader():1251:1267 -> C + 18:18:int unpackMapHeader():1258:1258 -> C + 1:5:void unpackNil():697:701 -> D + 1:16:int unpackRawStringHeader():1357:1372 -> E + 1:46:short unpackShort():820:865 -> F + 47:49:short unpackShort():859:861 -> F + 50:52:short unpackShort():853:855 -> F + 53:53:short unpackShort():850:850 -> F + 54:54:short unpackShort():847:847 -> F + 55:57:short unpackShort():841:843 -> F + 58:60:short unpackShort():835:837 -> F + 61:63:short unpackShort():829:831 -> F + 64:64:short unpackShort():826:826 -> F + 1:80:java.lang.String unpackString():1085:1164 -> G + 81:84:java.lang.String unpackString():1157:1160 -> G + 85:114:java.lang.String unpackString():1141:1170 -> G + 115:116:java.lang.String unpackString():1090:1091 -> G + 1:53:com.batch.android.msgpack.value.ImmutableValue unpackValue():567:619 -> H + 54:55:com.batch.android.msgpack.value.ImmutableValue unpackValue():615:616 -> H + 56:64:com.batch.android.msgpack.value.ImmutableValue unpackValue():603:611 -> H + 65:70:com.batch.android.msgpack.value.ImmutableValue unpackValue():594:599 -> H + 71:72:com.batch.android.msgpack.value.ImmutableValue unpackValue():589:590 -> H + 73:74:com.batch.android.msgpack.value.ImmutableValue unpackValue():584:585 -> H + 75:75:com.batch.android.msgpack.value.ImmutableValue unpackValue():581:581 -> H + 76:79:com.batch.android.msgpack.value.ImmutableValue unpackValue():575:578 -> H + 80:80:com.batch.android.msgpack.value.ImmutableValue unpackValue():573:573 -> H + 81:82:com.batch.android.msgpack.value.ImmutableValue unpackValue():570:571 -> H + 1:8:com.batch.android.msgpack.core.buffer.MessageBufferInput reset(com.batch.android.msgpack.core.buffer.MessageBufferInput):234:241 -> a + 9:16:boolean ensureBuffer():343:350 -> a + 17:26:com.batch.android.msgpack.core.MessagePackException unexpected(java.lang.String,byte):552:561 -> a + 27:89:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):624:686 -> a + 90:91:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):681:682 -> a + 92:99:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):669:676 -> a + 100:105:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):659:664 -> a + 106:107:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):653:654 -> a + 108:109:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):647:648 -> a + 110:110:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):643:643 -> a + 111:116:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):634:639 -> a + 117:117:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):636:636 -> a + 118:118:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):631:631 -> a + 119:120:com.batch.android.msgpack.value.Variable unpackValue(com.batch.android.msgpack.value.Variable):627:628 -> a + 121:124:void handleCoderError(java.nio.charset.CoderResult):1176:1179 -> a + 125:135:void readPayload(java.nio.ByteBuffer):1443:1453 -> a + 136:147:void readPayload(com.batch.android.msgpack.core.buffer.MessageBuffer,int,int):1471:1482 -> a + 148:148:void readPayload(byte[]):1498:1498 -> a + 149:150:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowU8(byte):1600:1601 -> a + 151:152:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowI16(short):1620:1621 -> a + 153:154:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowI64(long):1630:1631 -> a + 1:6:com.batch.android.msgpack.core.buffer.MessageBuffer getNextBuffer():267:272 -> b + 7:7:com.batch.android.msgpack.core.buffer.MessageBuffer getNextBuffer():269:269 -> b + 8:8:int tryReadBinaryHeader(byte):1350:1350 -> b + 9:9:int tryReadBinaryHeader(byte):1348:1348 -> b + 10:10:int tryReadBinaryHeader(byte):1346:1346 -> b + 11:12:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowU16(short):1605:1606 -> b + 13:14:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowU64(long):1615:1616 -> b + 1:5:com.batch.android.msgpack.core.MessageFormat getNextFormat():372:376 -> c + 6:6:com.batch.android.msgpack.core.MessageFormat getNextFormat():373:373 -> c + 7:24:java.lang.String decodeStringFastPath(int):1184:1201 -> c + 25:25:java.lang.String decodeStringFastPath(int):1198:1198 -> c + 26:26:int tryReadStringHeader(byte):1337:1337 -> c + 27:27:int tryReadStringHeader(byte):1335:1335 -> c + 28:28:int tryReadStringHeader(byte):1333:1333 -> c + 29:40:void readPayload(byte[],int,int):1531:1542 -> c + 1:3:void close():1594:1596 -> close + 1:1:long getTotalReadBytes():257:257 -> d + 2:2:int utf8MultibyteCharacterSize(byte):328:328 -> d + 3:4:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowI32(int):1625:1626 -> d + 1:1:boolean hasNext():339:339 -> e + 2:3:com.batch.android.msgpack.core.MessageIntegerOverflowException overflowU32(int):1610:1611 -> e + 1:2:void nextBuffer():277:278 -> f + 3:3:com.batch.android.msgpack.core.MessageSizeException overflowU32Size(int):1636:1636 -> f + 1:34:com.batch.android.msgpack.core.buffer.MessageBuffer prepareNumberBuffer(int):290:323 -> g + 35:35:com.batch.android.msgpack.core.buffer.MessageBuffer prepareNumberBuffer(int):316:316 -> g + 36:47:byte readByte():386:397 -> g + 1:2:double readDouble():422:423 -> h + 3:4:byte[] readPayload(int):1514:1515 -> h + 1:2:float readFloat():417:418 -> i + 3:10:com.batch.android.msgpack.core.buffer.MessageBuffer readPayloadAsReference(int):1558:1565 -> i + 1:2:int readInt():407:408 -> j + 3:11:void skipPayload(int):1419:1427 -> j + 1:2:long readLong():412:413 -> k + 3:96:void skipValue(int):443:536 -> k + 97:97:void skipValue(int):533:533 -> k + 98:98:void skipValue(int):530:530 -> k + 99:99:void skipValue(int):527:527 -> k + 100:100:void skipValue(int):524:524 -> k + 101:101:void skipValue(int):521:521 -> k + 102:102:void skipValue(int):518:518 -> k + 103:103:void skipValue(int):515:515 -> k + 104:104:void skipValue(int):512:512 -> k + 105:105:void skipValue(int):509:509 -> k + 106:106:void skipValue(int):506:506 -> k + 107:107:void skipValue(int):503:503 -> k + 108:108:void skipValue(int):500:500 -> k + 109:109:void skipValue(int):497:497 -> k + 110:110:void skipValue(int):493:493 -> k + 111:111:void skipValue(int):489:489 -> k + 112:112:void skipValue(int):485:485 -> k + 113:113:void skipValue(int):480:480 -> k + 114:114:void skipValue(int):475:475 -> k + 115:115:void skipValue(int):471:471 -> k + 116:116:void skipValue(int):466:466 -> k + 1:1:int readNextLength16():1575:1575 -> l + 1:3:int readNextLength32():1580:1582 -> m + 1:1:int readNextLength8():1570:1570 -> n + 1:2:short readShort():402:403 -> o + 1:14:void resetDecoder():1067:1080 -> p + 1:1:void skipValue():432:432 -> q + 1:6:boolean tryUnpackNil():716:721 -> r + 7:7:boolean tryUnpackNil():717:717 -> r + 1:17:int unpackArrayHeader():1218:1234 -> s + 18:18:int unpackArrayHeader():1225:1225 -> s + 1:40:java.math.BigInteger unpackBigInteger():980:1019 -> t + 41:42:java.math.BigInteger unpackBigInteger():1016:1017 -> t + 43:44:java.math.BigInteger unpackBigInteger():1013:1014 -> t + 45:46:java.math.BigInteger unpackBigInteger():1010:1011 -> t + 47:48:java.math.BigInteger unpackBigInteger():1007:1008 -> t + 49:54:java.math.BigInteger unpackBigInteger():999:1004 -> t + 55:59:java.math.BigInteger unpackBigInteger():992:996 -> t + 60:61:java.math.BigInteger unpackBigInteger():989:990 -> t + 62:63:java.math.BigInteger unpackBigInteger():986:987 -> t + 1:16:int unpackBinaryHeader():1392:1407 -> u + 1:7:boolean unpackBoolean():735:741 -> v + 1:52:byte unpackByte():755:806 -> w + 53:55:byte unpackByte():800:802 -> w + 56:58:byte unpackByte():794:796 -> w + 59:61:byte unpackByte():788:790 -> w + 62:62:byte unpackByte():785:785 -> w + 63:65:byte unpackByte():779:781 -> w + 66:68:byte unpackByte():773:775 -> w + 69:71:byte unpackByte():767:769 -> w + 72:74:byte unpackByte():761:763 -> w + 1:10:double unpackDouble():1052:1061 -> x + 11:11:double unpackDouble():1055:1055 -> x + 1:57:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1271:1327 -> y + 58:59:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1295:1296 -> y + 60:61:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1290:1291 -> y + 62:63:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1285:1286 -> y + 64:65:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1280:1281 -> y + 66:114:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1275:1323 -> y + 115:115:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1319:1319 -> y + 116:120:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1308:1312 -> y + 121:125:com.batch.android.msgpack.core.ExtensionTypeHeader unpackExtensionTypeHeader():1300:1304 -> y + 1:10:float unpackFloat():1032:1041 -> z + 11:11:float unpackFloat():1035:1035 -> z +com.batch.android.msgpack.core.MessageUnpacker$1 -> com.batch.android.p0.o$a: + int[] $SwitchMap$com$batch$android$msgpack$value$ValueType -> b + int[] $SwitchMap$com$batch$android$msgpack$core$MessageFormat -> a + 1:1:void ():568:568 -> + 2:2:void ():445:445 -> +com.batch.android.msgpack.core.Preconditions -> com.batch.android.p0.p: + 1:1:void ():75:75 -> + 1:1:void checkArgument(boolean):86:86 -> a + 2:2:void checkArgument(boolean,java.lang.Object):101:101 -> a + 3:3:void checkArgument(boolean,java.lang.String,java.lang.Object[]):130:130 -> a + 4:4:java.lang.Object checkNotNull(java.lang.Object):201:201 -> a + 5:5:java.lang.Object checkNotNull(java.lang.Object,java.lang.Object):218:218 -> a + 6:6:java.lang.Object checkNotNull(java.lang.Object,java.lang.String,java.lang.Object[]):247:247 -> a + 7:7:int checkElementIndex(int,int):295:295 -> a + 8:12:java.lang.String badElementIndex(int,int,java.lang.String):322:326 -> a + 13:13:java.lang.String badElementIndex(int,int,java.lang.String):324:324 -> a + 14:14:java.lang.String badPositionIndexes(int,int,int):408:408 -> a + 15:15:java.lang.String badPositionIndexes(int,int,int):405:405 -> a + 16:16:java.lang.String badPositionIndexes(int,int,int):402:402 -> a + 17:45:java.lang.String format(java.lang.String,java.lang.Object[]):425:453 -> a + 1:1:void checkState(boolean):143:143 -> b + 2:2:void checkState(boolean,java.lang.Object):158:158 -> b + 3:3:void checkState(boolean,java.lang.String,java.lang.Object[]):187:187 -> b + 4:4:int checkPositionIndex(int,int):344:344 -> b + 5:9:java.lang.String badPositionIndex(int,int,java.lang.String):371:375 -> b + 10:10:java.lang.String badPositionIndex(int,int,java.lang.String):373:373 -> b + 11:11:void checkPositionIndexes(int,int,int):396:396 -> b + 1:1:int checkElementIndex(int,int,java.lang.String):315:315 -> c + 1:1:int checkPositionIndex(int,int,java.lang.String):364:364 -> d +com.batch.android.msgpack.core.buffer.ArrayBufferInput -> com.batch.android.q0.a: + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> a + boolean isEmpty -> b + 1:6:void (com.batch.android.msgpack.core.buffer.MessageBuffer):28:33 -> + 7:7:void (byte[]):38:38 -> + 8:8:void (byte[],int,int):42:42 -> + 1:6:com.batch.android.msgpack.core.buffer.MessageBuffer reset(com.batch.android.msgpack.core.buffer.MessageBuffer):52:57 -> a + 7:7:void reset(byte[]):63:63 -> a + 1:1:void reset(byte[],int,int):67:67 -> c + 1:2:void close():81:82 -> close + 1:5:com.batch.android.msgpack.core.buffer.MessageBuffer next():72:76 -> next +com.batch.android.msgpack.core.buffer.ArrayBufferOutput -> com.batch.android.q0.b: + java.util.List list -> a + com.batch.android.msgpack.core.buffer.MessageBuffer lastBuffer -> c + int bufferSize -> b + 1:1:void ():35:35 -> + 2:4:void (int):38:40 -> + 1:1:void clear():108:108 -> a + 2:6:void writeBuffer(int):125:129 -> a + 7:9:void write(byte[],int,int):135:137 -> a + 1:2:int getSize():50:51 -> b + 3:8:com.batch.android.msgpack.core.buffer.MessageBuffer next(int):113:118 -> b + 9:10:void add(byte[],int,int):142:143 -> b + 1:1:java.util.List toBufferList():101:101 -> c + 1:5:byte[] toByteArray():65:69 -> d + 1:6:com.batch.android.msgpack.core.buffer.MessageBuffer toMessageBuffer():83:88 -> e +com.batch.android.msgpack.core.buffer.ByteBufferInput -> com.batch.android.q0.c: + java.nio.ByteBuffer input -> a + boolean isRead -> b + 1:1:void (java.nio.ByteBuffer):30:30 -> + 2:5:void (java.nio.ByteBuffer):28:31 -> + 1:3:java.nio.ByteBuffer reset(java.nio.ByteBuffer):41:43 -> a + 1:6:com.batch.android.msgpack.core.buffer.MessageBuffer next():49:54 -> next +com.batch.android.msgpack.core.buffer.ChannelBufferInput -> com.batch.android.q0.d: + java.nio.channels.ReadableByteChannel channel -> a + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> b + 1:1:void (java.nio.channels.ReadableByteChannel):34:34 -> + 2:5:void (java.nio.channels.ReadableByteChannel,int):37:40 -> + 1:2:java.nio.channels.ReadableByteChannel reset(java.nio.channels.ReadableByteChannel):50:51 -> a + 1:1:void close():68:68 -> close + 1:7:com.batch.android.msgpack.core.buffer.MessageBuffer next():57:63 -> next +com.batch.android.msgpack.core.buffer.ChannelBufferOutput -> com.batch.android.q0.e: + java.nio.channels.WritableByteChannel channel -> a + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> b + 1:1:void (java.nio.channels.WritableByteChannel):33:33 -> + 2:4:void (java.nio.channels.WritableByteChannel,int):36:38 -> + 1:2:java.nio.channels.WritableByteChannel reset(java.nio.channels.WritableByteChannel):48:49 -> a + 3:5:void writeBuffer(int):63:65 -> a + 6:8:void write(byte[],int,int):71:73 -> a + 1:4:com.batch.android.msgpack.core.buffer.MessageBuffer next(int):55:58 -> b + 5:5:void add(byte[],int,int):79:79 -> b + 1:1:void close():84:84 -> close +com.batch.android.msgpack.core.buffer.DirectBufferAccess -> com.batch.android.msgpack.core.buffer.a: + java.lang.Class directByteBufferClass -> f + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType directBufferConstructorType -> g + java.lang.reflect.Method memoryBlockWrapFromJni -> h + java.lang.reflect.Method mClean -> c + java.lang.reflect.Constructor byteBufferConstructor -> e + java.lang.reflect.Method mInvokeCleaner -> d + java.lang.reflect.Method mGetAddress -> a + java.lang.reflect.Method mCleaner -> b + 1:49:void ():54:102 -> + 50:63:void ():92:105 -> + 1:1:void ():30:30 -> + 1:1:java.lang.Object access$000(java.nio.ByteBuffer):28:28 -> a + 2:2:java.lang.Object access$100(java.nio.ByteBuffer,java.lang.reflect.Method):28:28 -> a + 3:10:void clean(java.lang.Object):232:239 -> a + 11:25:java.nio.ByteBuffer newByteBuffer(long,int,int,java.nio.ByteBuffer):249:263 -> a + 26:30:java.nio.ByteBuffer newByteBuffer(long,int,int,java.nio.ByteBuffer):257:257 -> a + 31:31:java.nio.ByteBuffer newByteBuffer(long,int,int,java.nio.ByteBuffer):255:255 -> a + 32:32:java.nio.ByteBuffer newByteBuffer(long,int,int,java.nio.ByteBuffer):253:253 -> a + 33:49:java.nio.ByteBuffer newByteBuffer(long,int,int,java.nio.ByteBuffer):251:267 -> a + 1:1:java.lang.Object access$200(java.nio.ByteBuffer):28:28 -> b + 2:5:java.lang.Object getCleanMethod(java.nio.ByteBuffer,java.lang.reflect.Method):185:188 -> b + 6:10:long getAddress(java.lang.Object):222:226 -> b + 11:11:long getAddress(java.lang.Object):224:224 -> b + 1:3:java.lang.Object getCleanerMethod(java.nio.ByteBuffer):163:165 -> c + 4:4:boolean isDirectByteBufferInstance(java.lang.Object):244:244 -> c + 1:2:java.lang.Object getInvokeCleanerMethod(java.nio.ByteBuffer):208:209 -> d + 1:27:void setupCleanerJava6(java.nio.ByteBuffer):111:137 -> e + 28:28:void setupCleanerJava6(java.nio.ByteBuffer):135:135 -> e + 29:29:void setupCleanerJava6(java.nio.ByteBuffer):121:121 -> e + 1:12:void setupCleanerJava9(java.nio.ByteBuffer):141:152 -> f + 13:13:void setupCleanerJava9(java.nio.ByteBuffer):150:150 -> f +com.batch.android.msgpack.core.buffer.DirectBufferAccess$1 -> com.batch.android.msgpack.core.buffer.a$a: + java.nio.ByteBuffer val$direct -> a + 1:1:void (java.nio.ByteBuffer):113:113 -> + 1:1:java.lang.Object run():116:116 -> run +com.batch.android.msgpack.core.buffer.DirectBufferAccess$2 -> com.batch.android.msgpack.core.buffer.a$b: + java.nio.ByteBuffer val$direct -> a + 1:1:void (java.nio.ByteBuffer):127:127 -> + 1:1:java.lang.Object run():130:130 -> run +com.batch.android.msgpack.core.buffer.DirectBufferAccess$3 -> com.batch.android.msgpack.core.buffer.a$c: + java.nio.ByteBuffer val$direct -> a + 1:1:void (java.nio.ByteBuffer):142:142 -> + 1:1:java.lang.Object run():145:145 -> run +com.batch.android.msgpack.core.buffer.DirectBufferAccess$4 -> com.batch.android.msgpack.core.buffer.a$d: + int[] $SwitchMap$com$batch$android$msgpack$core$buffer$DirectBufferAccess$DirectBufferConstructorType -> a + 1:1:void ():249:249 -> +com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType -> com.batch.android.msgpack.core.buffer.a$e: + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType ARGS_MB_INT_INT -> d + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType ARGS_LONG_INT -> b + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType ARGS_INT_INT -> c + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType ARGS_LONG_INT_REF -> a + com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType[] $VALUES -> e + 1:4:void ():33:36 -> + 5:5:void ():32:32 -> + 1:1:void (java.lang.String,int):32:32 -> + 1:1:com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType valueOf(java.lang.String):32:32 -> valueOf + 1:1:com.batch.android.msgpack.core.buffer.DirectBufferAccess$DirectBufferConstructorType[] values():32:32 -> values +com.batch.android.msgpack.core.buffer.InputStreamBufferInput -> com.batch.android.q0.f: + byte[] buffer -> b + java.io.InputStream in -> a + 1:1:void (java.io.InputStream):45:45 -> + 2:4:void (java.io.InputStream,int):48:50 -> + 1:8:com.batch.android.msgpack.core.buffer.MessageBufferInput newBufferInput(java.io.InputStream):34:41 -> a + 1:2:java.io.InputStream reset(java.io.InputStream):60:61 -> b + 1:1:void close():76:76 -> close + 1:5:com.batch.android.msgpack.core.buffer.MessageBuffer next():67:71 -> next +com.batch.android.msgpack.core.buffer.MessageBuffer -> com.batch.android.msgpack.core.buffer.MessageBuffer: + 1:56:void ():50:105 -> + 57:110:void ():98:151 -> + 111:153:void ():109:151 -> + 154:194:void ():114:154 -> + 195:196:void ():150:151 -> + 1:5:void (byte[],int,int):334:338 -> + 6:27:void (java.nio.ByteBuffer):346:367 -> + 28:32:void (java.lang.Object,long,int):371:375 -> + 1:1:com.batch.android.msgpack.core.buffer.MessageBuffer allocate(int):210:210 -> allocate + 2:2:com.batch.android.msgpack.core.buffer.MessageBuffer allocate(int):208:208 -> allocate + 1:1:byte[] array():568:568 -> array + 1:1:int arrayOffset():572:572 -> arrayOffset + 1:1:void copyTo(int,com.batch.android.msgpack.core.buffer.MessageBuffer,int,int):584:584 -> copyTo + 1:1:boolean getBoolean(int):405:405 -> getBoolean + 1:1:byte getByte(int):401:401 -> getByte + 1:1:void getBytes(int,byte[],int,int):440:440 -> getBytes + 2:6:void getBytes(int,int,java.nio.ByteBuffer):444:448 -> getBytes + 7:7:void getBytes(int,int,java.nio.ByteBuffer):445:445 -> getBytes + 1:1:double getDouble(int):436:436 -> getDouble + 1:1:float getFloat(int):427:427 -> getFloat + 1:3:int getInt(int):421:423 -> getInt + 1:15:int getJavaVersion():158:172 -> getJavaVersion + 1:2:long getLong(int):431:432 -> getLong + 1:2:short getShort(int):409:410 -> getShort + 1:1:boolean hasArray():553:553 -> hasArray + 1:16:com.batch.android.msgpack.core.buffer.MessageBuffer newInstance(java.lang.reflect.Constructor,java.lang.Object[]):297:312 -> newInstance + 17:17:com.batch.android.msgpack.core.buffer.MessageBuffer newInstance(java.lang.reflect.Constructor,java.lang.Object[]):307:307 -> newInstance + 18:18:com.batch.android.msgpack.core.buffer.MessageBuffer newInstance(java.lang.reflect.Constructor,java.lang.Object[]):303:303 -> newInstance + 19:19:com.batch.android.msgpack.core.buffer.MessageBuffer newInstance(java.lang.reflect.Constructor,java.lang.Object[]):300:300 -> newInstance + 1:5:com.batch.android.msgpack.core.buffer.MessageBuffer newMessageBuffer(byte[],int,int):266:270 -> newMessageBuffer + 6:10:com.batch.android.msgpack.core.buffer.MessageBuffer newMessageBuffer(java.nio.ByteBuffer):280:284 -> newMessageBuffer + 1:1:void putBoolean(int,boolean):456:456 -> putBoolean + 1:1:void putByte(int,byte):452:452 -> putByte + 1:21:void putByteBuffer(int,java.nio.ByteBuffer,int):495:515 -> putByteBuffer + 22:22:void putByteBuffer(int,java.nio.ByteBuffer,int):500:500 -> putByteBuffer + 23:23:void putByteBuffer(int,java.nio.ByteBuffer,int):496:496 -> putByteBuffer + 1:1:void putBytes(int,byte[],int,int):491:491 -> putBytes + 1:1:void putDouble(int,double):487:487 -> putDouble + 1:1:void putFloat(int,float):477:477 -> putFloat + 1:2:void putInt(int,int):472:473 -> putInt + 1:2:void putLong(int,long):482:483 -> putLong + 1:1:void putMessageBuffer(int,com.batch.android.msgpack.core.buffer.MessageBuffer,int,int):522:522 -> putMessageBuffer + 1:2:void putShort(int,short):460:461 -> putShort + 1:7:void releaseBuffer(com.batch.android.msgpack.core.buffer.MessageBuffer):317:323 -> releaseBuffer + 1:1:int size():387:387 -> size + 1:5:com.batch.android.msgpack.core.buffer.MessageBuffer slice(int,int):392:396 -> slice + 1:7:java.nio.ByteBuffer sliceAsByteBuffer(int,int):533:539 -> sliceAsByteBuffer + 8:8:java.nio.ByteBuffer sliceAsByteBuffer(int,int):537:537 -> sliceAsByteBuffer + 9:9:java.nio.ByteBuffer sliceAsByteBuffer():549:549 -> sliceAsByteBuffer + 1:2:byte[] toByteArray():562:563 -> toByteArray + 1:8:java.lang.String toHexString(int,int):588:595 -> toHexString + 1:1:com.batch.android.msgpack.core.buffer.MessageBuffer wrap(byte[]):224:224 -> wrap + 2:2:com.batch.android.msgpack.core.buffer.MessageBuffer wrap(byte[],int,int):240:240 -> wrap + 3:3:com.batch.android.msgpack.core.buffer.MessageBuffer wrap(java.nio.ByteBuffer):256:256 -> wrap +com.batch.android.msgpack.core.buffer.MessageBufferBE -> com.batch.android.msgpack.core.buffer.MessageBufferBE: + 1:1:void (byte[],int,int):30:30 -> + 2:2:void (java.nio.ByteBuffer):34:34 -> + 3:3:void (java.lang.Object,long,int):38:38 -> + 1:5:com.batch.android.msgpack.core.buffer.MessageBufferBE slice(int,int):43:47 -> a + 1:1:double getDouble(int):73:73 -> getDouble + 1:1:float getFloat(int):68:68 -> getFloat + 1:1:int getInt(int):59:59 -> getInt + 1:1:long getLong(int):63:63 -> getLong + 1:1:short getShort(int):53:53 -> getShort + 1:1:void putDouble(int,double):93:93 -> putDouble + 1:1:void putInt(int,int):83:83 -> putInt + 1:1:void putLong(int,long):88:88 -> putLong + 1:1:void putShort(int,short):78:78 -> putShort + 1:1:com.batch.android.msgpack.core.buffer.MessageBuffer slice(int,int):27:27 -> slice +com.batch.android.msgpack.core.buffer.MessageBufferInput -> com.batch.android.q0.g: +com.batch.android.msgpack.core.buffer.MessageBufferOutput -> com.batch.android.q0.h: + void write(byte[],int,int) -> a + void writeBuffer(int) -> a + void add(byte[],int,int) -> b + com.batch.android.msgpack.core.buffer.MessageBuffer next(int) -> b +com.batch.android.msgpack.core.buffer.MessageBufferU -> com.batch.android.msgpack.core.buffer.MessageBufferU: + 1:2:void (byte[],int,int):31:32 -> + 3:4:void (java.nio.ByteBuffer):36:37 -> + 5:6:void (java.lang.Object,long,int,java.nio.ByteBuffer):41:42 -> + 1:1:byte[] array():233:233 -> array + 1:5:void copyTo(int,com.batch.android.msgpack.core.buffer.MessageBuffer,int,int):207:211 -> copyTo + 1:1:boolean getBoolean(int):73:73 -> getBoolean + 1:1:byte getByte(int):68:68 -> getByte + 1:6:void getBytes(int,int,java.nio.ByteBuffer):104:109 -> getBytes + 7:11:void getBytes(int,byte[],int,int):166:170 -> getBytes + 1:1:double getDouble(int):98:98 -> getDouble + 1:1:float getFloat(int):88:88 -> getFloat + 1:1:int getInt(int):83:83 -> getInt + 1:1:long getLong(int):93:93 -> getLong + 1:1:short getShort(int):78:78 -> getShort + 1:1:boolean hasArray():228:228 -> hasArray + 1:1:void putBoolean(int,boolean):119:119 -> putBoolean + 1:1:void putByte(int,byte):114:114 -> putByte + 1:16:void putByteBuffer(int,java.nio.ByteBuffer,int):175:190 -> putByteBuffer + 17:17:void putByteBuffer(int,java.nio.ByteBuffer,int):176:176 -> putByteBuffer + 1:5:void putBytes(int,byte[],int,int):197:201 -> putBytes + 1:1:void putDouble(int,double):144:144 -> putDouble + 1:1:void putFloat(int,float):134:134 -> putFloat + 1:1:void putInt(int,int):129:129 -> putInt + 1:1:void putLong(int,long):139:139 -> putLong + 1:1:void putMessageBuffer(int,com.batch.android.msgpack.core.buffer.MessageBuffer,int,int):216:216 -> putMessageBuffer + 1:1:void putShort(int,short):124:124 -> putShort + 1:2:void resetBufferPosition():62:63 -> resetBufferPosition + 1:1:com.batch.android.msgpack.core.buffer.MessageBuffer slice(int,int):26:26 -> slice + 2:12:com.batch.android.msgpack.core.buffer.MessageBufferU slice(int,int):47:57 -> slice + 1:6:java.nio.ByteBuffer sliceAsByteBuffer(int,int):150:155 -> sliceAsByteBuffer + 7:7:java.nio.ByteBuffer sliceAsByteBuffer():160:160 -> sliceAsByteBuffer + 1:2:byte[] toByteArray():221:222 -> toByteArray +com.batch.android.msgpack.core.buffer.OutputStreamBufferOutput -> com.batch.android.q0.i: + java.io.OutputStream out -> a + com.batch.android.msgpack.core.buffer.MessageBuffer buffer -> b + 1:1:void (java.io.OutputStream):32:32 -> + 2:4:void (java.io.OutputStream,int):35:37 -> + 1:2:java.io.OutputStream reset(java.io.OutputStream):47:48 -> a + 3:3:void writeBuffer(int):62:62 -> a + 4:4:void write(byte[],int,int):67:67 -> a + 1:4:com.batch.android.msgpack.core.buffer.MessageBuffer next(int):54:57 -> b + 5:5:void add(byte[],int,int):72:72 -> b + 1:1:void close():77:77 -> close + 1:1:void flush():82:82 -> flush +com.batch.android.msgpack.value.ArrayValue -> com.batch.android.r0.a: + com.batch.android.msgpack.value.Value getOrNilValue(int) -> a + java.util.List list() -> l +com.batch.android.msgpack.value.BinaryValue -> com.batch.android.r0.b: +com.batch.android.msgpack.value.BooleanValue -> com.batch.android.r0.c: + boolean getBoolean() -> M +com.batch.android.msgpack.value.ExtensionValue -> com.batch.android.r0.d: + byte[] getData() -> e + byte getType() -> k +com.batch.android.msgpack.value.FloatValue -> com.batch.android.r0.e: +com.batch.android.msgpack.value.ImmutableArrayValue -> com.batch.android.r0.f: + java.util.List list() -> l +com.batch.android.msgpack.value.ImmutableBinaryValue -> com.batch.android.r0.g: +com.batch.android.msgpack.value.ImmutableBooleanValue -> com.batch.android.r0.h: +com.batch.android.msgpack.value.ImmutableExtensionValue -> com.batch.android.r0.i: +com.batch.android.msgpack.value.ImmutableFloatValue -> com.batch.android.r0.j: +com.batch.android.msgpack.value.ImmutableIntegerValue -> com.batch.android.r0.k: +com.batch.android.msgpack.value.ImmutableMapValue -> com.batch.android.r0.l: +com.batch.android.msgpack.value.ImmutableNilValue -> com.batch.android.r0.m: +com.batch.android.msgpack.value.ImmutableNumberValue -> com.batch.android.r0.n: +com.batch.android.msgpack.value.ImmutableRawValue -> com.batch.android.r0.o: +com.batch.android.msgpack.value.ImmutableStringValue -> com.batch.android.r0.p: +com.batch.android.msgpack.value.ImmutableValue -> com.batch.android.r0.q: + com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue() -> a + 1:1:com.batch.android.msgpack.value.ArrayValue asArrayValue():21:21 -> a + com.batch.android.msgpack.value.ImmutableNilValue asNilValue() -> b + 1:1:com.batch.android.msgpack.value.NilValue asNilValue():21:21 -> b + com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue() -> c + 1:1:com.batch.android.msgpack.value.IntegerValue asIntegerValue():21:21 -> c + com.batch.android.msgpack.value.ImmutableMapValue asMapValue() -> d + 1:1:com.batch.android.msgpack.value.MapValue asMapValue():21:21 -> d + com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue() -> f + 1:1:com.batch.android.msgpack.value.BinaryValue asBinaryValue():21:21 -> f + com.batch.android.msgpack.value.ImmutableStringValue asStringValue() -> g + 1:1:com.batch.android.msgpack.value.StringValue asStringValue():21:21 -> g + com.batch.android.msgpack.value.ImmutableRawValue asRawValue() -> h + 1:1:com.batch.android.msgpack.value.RawValue asRawValue():21:21 -> h + com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue() -> i + 1:1:com.batch.android.msgpack.value.BooleanValue asBooleanValue():21:21 -> i + com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue() -> j + 1:1:com.batch.android.msgpack.value.FloatValue asFloatValue():21:21 -> j +com.batch.android.msgpack.value.IntegerValue -> com.batch.android.r0.r: + java.math.BigInteger asBigInteger() -> B + long asLong() -> I + byte asByte() -> J + boolean isInLongRange() -> K + boolean isInByteRange() -> U + int asInt() -> V + boolean isInIntRange() -> p + short asShort() -> t + com.batch.android.msgpack.core.MessageFormat mostSuccinctMessageFormat() -> u + boolean isInShortRange() -> y +com.batch.android.msgpack.value.MapValue -> com.batch.android.r0.s: + java.util.Map map() -> H + com.batch.android.msgpack.value.Value[] getKeyValueArray() -> x +com.batch.android.msgpack.value.NilValue -> com.batch.android.r0.t: +com.batch.android.msgpack.value.NumberValue -> com.batch.android.r0.u: + java.math.BigInteger toBigInteger() -> F + int toInt() -> G + long toLong() -> Y + float toFloat() -> n + double toDouble() -> o + byte toByte() -> r + short toShort() -> z +com.batch.android.msgpack.value.RawValue -> com.batch.android.r0.v: + java.lang.String asString() -> A + java.nio.ByteBuffer asByteBuffer() -> D + byte[] asByteArray() -> P +com.batch.android.msgpack.value.StringValue -> com.batch.android.r0.w: +com.batch.android.msgpack.value.Value -> com.batch.android.r0.x: + boolean isBinaryValue() -> C + boolean isNilValue() -> E + boolean isNumberValue() -> L + boolean isArrayValue() -> N + boolean isRawValue() -> O + boolean isExtensionValue() -> Q + com.batch.android.msgpack.value.NumberValue asNumberValue() -> R + boolean isMapValue() -> S + boolean isFloatValue() -> T + boolean isBooleanValue() -> W + java.lang.String toJson() -> X + com.batch.android.msgpack.value.ArrayValue asArrayValue() -> a + void writeTo(com.batch.android.msgpack.core.MessagePacker) -> a + com.batch.android.msgpack.value.NilValue asNilValue() -> b + com.batch.android.msgpack.value.IntegerValue asIntegerValue() -> c + com.batch.android.msgpack.value.MapValue asMapValue() -> d + com.batch.android.msgpack.value.BinaryValue asBinaryValue() -> f + com.batch.android.msgpack.value.StringValue asStringValue() -> g + com.batch.android.msgpack.value.RawValue asRawValue() -> h + com.batch.android.msgpack.value.BooleanValue asBooleanValue() -> i + com.batch.android.msgpack.value.FloatValue asFloatValue() -> j + com.batch.android.msgpack.value.ValueType getValueType() -> m + com.batch.android.msgpack.value.ExtensionValue asExtensionValue() -> q + com.batch.android.msgpack.value.ImmutableValue immutableValue() -> s + boolean isStringValue() -> v + boolean isIntegerValue() -> w +com.batch.android.msgpack.value.ValueFactory -> com.batch.android.r0.y: + 1:1:void ():37:37 -> + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue newBoolean(boolean):44:44 -> a + 2:2:com.batch.android.msgpack.value.ImmutableIntegerValue newInteger(byte):48:48 -> a + 3:3:com.batch.android.msgpack.value.ImmutableIntegerValue newInteger(short):52:52 -> a + 4:4:com.batch.android.msgpack.value.ImmutableIntegerValue newInteger(int):56:56 -> a + 5:5:com.batch.android.msgpack.value.ImmutableIntegerValue newInteger(long):60:60 -> a + 6:6:com.batch.android.msgpack.value.ImmutableIntegerValue newInteger(java.math.BigInteger):64:64 -> a + 7:7:com.batch.android.msgpack.value.ImmutableFloatValue newFloat(float):68:68 -> a + 8:8:com.batch.android.msgpack.value.ImmutableFloatValue newFloat(double):72:72 -> a + 9:9:com.batch.android.msgpack.value.ImmutableBinaryValue newBinary(byte[]):76:76 -> a + 10:12:com.batch.android.msgpack.value.ImmutableBinaryValue newBinary(byte[],boolean):81:83 -> a + 13:13:com.batch.android.msgpack.value.ImmutableBinaryValue newBinary(byte[],int,int):88:88 -> a + 14:17:com.batch.android.msgpack.value.ImmutableBinaryValue newBinary(byte[],int,int,boolean):92:95 -> a + 18:18:com.batch.android.msgpack.value.ImmutableStringValue newString(java.lang.String):100:100 -> a + 19:23:com.batch.android.msgpack.value.ImmutableArrayValue newArray(java.util.List):128:132 -> a + 24:27:com.batch.android.msgpack.value.ImmutableArrayValue newArray(com.batch.android.msgpack.value.Value[]):136:139 -> a + 28:33:com.batch.android.msgpack.value.ImmutableArrayValue newArray(com.batch.android.msgpack.value.Value[],boolean):144:149 -> a + 34:34:com.batch.android.msgpack.value.ImmutableArrayValue emptyArray():154:154 -> a + 35:43:com.batch.android.msgpack.value.ImmutableMapValue newMap(java.util.Map):158:166 -> a + 44:49:com.batch.android.msgpack.value.MapValue newMap(java.util.Map$Entry[]):193:198 -> a + 50:50:java.util.Map$Entry newMapEntry(com.batch.android.msgpack.value.Value,com.batch.android.msgpack.value.Value):206:206 -> a + 51:51:com.batch.android.msgpack.value.ImmutableExtensionValue newExtension(byte,byte[]):245:245 -> a + 1:1:com.batch.android.msgpack.value.ImmutableStringValue newString(byte[]):104:104 -> b + 2:4:com.batch.android.msgpack.value.ImmutableStringValue newString(byte[],boolean):109:111 -> b + 5:5:com.batch.android.msgpack.value.ImmutableStringValue newString(byte[],int,int):116:116 -> b + 6:9:com.batch.android.msgpack.value.ImmutableStringValue newString(byte[],int,int,boolean):120:123 -> b + 10:13:com.batch.android.msgpack.value.ImmutableMapValue newMap(com.batch.android.msgpack.value.Value[]):170:173 -> b + 14:19:com.batch.android.msgpack.value.ImmutableMapValue newMap(com.batch.android.msgpack.value.Value[],boolean):178:183 -> b + 20:20:com.batch.android.msgpack.value.ImmutableMapValue emptyMap():188:188 -> b + 1:1:com.batch.android.msgpack.value.ValueFactory$MapBuilder newMapBuilder():202:202 -> c + 1:1:com.batch.android.msgpack.value.ImmutableNilValue newNil():40:40 -> d +com.batch.android.msgpack.value.ValueFactory$MapBuilder -> com.batch.android.r0.y$a: + java.util.Map map -> a + 1:1:void ():213:213 -> + 2:2:void ():211:211 -> + 1:1:com.batch.android.msgpack.value.MapValue build():216:216 -> a + 2:2:com.batch.android.msgpack.value.ValueFactory$MapBuilder put(java.util.Map$Entry):220:220 -> a + 3:3:com.batch.android.msgpack.value.ValueFactory$MapBuilder put(com.batch.android.msgpack.value.Value,com.batch.android.msgpack.value.Value):225:225 -> a + 4:5:com.batch.android.msgpack.value.ValueFactory$MapBuilder putAll(java.lang.Iterable):230:231 -> a + 6:7:com.batch.android.msgpack.value.ValueFactory$MapBuilder putAll(java.util.Map):237:238 -> a +com.batch.android.msgpack.value.ValueType -> com.batch.android.r0.z: + com.batch.android.msgpack.value.ValueType NIL -> c + com.batch.android.msgpack.value.ValueType BOOLEAN -> d + com.batch.android.msgpack.value.ValueType INTEGER -> e + com.batch.android.msgpack.value.ValueType FLOAT -> f + com.batch.android.msgpack.value.ValueType STRING -> g + com.batch.android.msgpack.value.ValueType BINARY -> h + com.batch.android.msgpack.value.ValueType ARRAY -> i + com.batch.android.msgpack.value.ValueType MAP -> j + com.batch.android.msgpack.value.ValueType EXTENSION -> k + boolean numberType -> a + boolean rawType -> b + com.batch.android.msgpack.value.ValueType[] $VALUES -> l + 1:9:void ():28:36 -> + 10:10:void ():27:27 -> + 1:3:void (java.lang.String,int,boolean,boolean):41:43 -> + 1:1:boolean isArrayType():79:79 -> a + 1:1:boolean isBinaryType():75:75 -> b + 1:1:boolean isBooleanType():51:51 -> c + 1:1:boolean isExtensionType():87:87 -> d + 1:1:boolean isFloatType():63:63 -> e + 1:1:boolean isIntegerType():59:59 -> f + 1:1:boolean isMapType():83:83 -> g + 1:1:boolean isNilType():47:47 -> h + 1:1:boolean isNumberType():55:55 -> i + 1:1:boolean isRawType():67:67 -> j + 1:1:boolean isStringType():71:71 -> k + 1:1:com.batch.android.msgpack.value.ValueType valueOf(java.lang.String):27:27 -> valueOf + 1:1:com.batch.android.msgpack.value.ValueType[] values():27:27 -> values +com.batch.android.msgpack.value.Variable -> com.batch.android.r0.a0: + com.batch.android.msgpack.value.Variable$ArrayValueAccessor arrayAccessor -> g + long longValue -> k + com.batch.android.msgpack.value.Variable$BinaryValueAccessor binaryAccessor -> e + java.math.BigInteger LONG_MAX -> p + java.math.BigInteger LONG_MIN -> o + com.batch.android.msgpack.value.Variable$StringValueAccessor stringAccessor -> f + com.batch.android.msgpack.value.Variable$FloatValueAccessor floatAccessor -> d + java.lang.Object objectValue -> m + com.batch.android.msgpack.value.Variable$ExtensionValueAccessor extensionAccessor -> i + double doubleValue -> l + com.batch.android.msgpack.value.Variable$AbstractValueAccessor accessor -> n + com.batch.android.msgpack.value.Variable$NilValueAccessor nilAccessor -> a + com.batch.android.msgpack.value.Variable$MapValueAccessor mapAccessor -> h + long INT_MAX -> v + long INT_MIN -> u + com.batch.android.msgpack.value.Variable$IntegerValueAccessor integerAccessor -> c + long BYTE_MAX -> r + long BYTE_MIN -> q + long SHORT_MAX -> t + com.batch.android.msgpack.value.Variable$Type type -> j + long SHORT_MIN -> s + com.batch.android.msgpack.value.Variable$BooleanValueAccessor booleanAccessor -> b + 1:2:void ():296:297 -> + 1:1:void ():214:214 -> + 2:21:void ():196:215 -> + 1:1:boolean isBinaryValue():940:940 -> C + 1:1:boolean isNilValue():910:910 -> E + 1:1:boolean isNumberValue():920:920 -> L + 1:1:boolean isArrayValue():950:950 -> N + 1:1:boolean isRawValue():935:935 -> O + 1:1:boolean isExtensionValue():960:960 -> Q + 1:4:com.batch.android.msgpack.value.NumberValue asNumberValue():981:984 -> R + 5:5:com.batch.android.msgpack.value.NumberValue asNumberValue():982:982 -> R + 1:1:boolean isMapValue():955:955 -> S + 1:1:boolean isFloatValue():930:930 -> T + 1:1:boolean isBooleanValue():915:915 -> W + 1:1:java.lang.String toJson():895:895 -> X + 1:2:com.batch.android.msgpack.value.Variable setNilValue():223:224 -> Z + 1:1:long access$1000(com.batch.android.msgpack.value.Variable):38:38 -> a + 2:4:com.batch.android.msgpack.value.Variable setBooleanValue(boolean):256:258 -> a + 5:7:com.batch.android.msgpack.value.Variable setIntegerValue(long):380:382 -> a + 8:15:com.batch.android.msgpack.value.Variable setIntegerValue(java.math.BigInteger):387:394 -> a + 16:19:com.batch.android.msgpack.value.Variable setFloatValue(double):512:515 -> a + 20:22:com.batch.android.msgpack.value.Variable setFloatValue(float):520:522 -> a + 23:25:com.batch.android.msgpack.value.Variable setBinaryValue(byte[]):607:609 -> a + 26:26:com.batch.android.msgpack.value.Variable setStringValue(java.lang.String):643:643 -> a + 27:29:com.batch.android.msgpack.value.Variable setArrayValue(java.util.List):683:685 -> a + 30:32:com.batch.android.msgpack.value.Variable setMapValue(java.util.Map):751:753 -> a + 33:35:com.batch.android.msgpack.value.Variable setExtensionValue(byte,byte[]):830:832 -> a + 36:36:void writeTo(com.batch.android.msgpack.core.MessagePacker):880:880 -> a + 37:40:com.batch.android.msgpack.value.ArrayValue asArrayValue():1029:1032 -> a + 41:41:com.batch.android.msgpack.value.ArrayValue asArrayValue():1030:1030 -> a + 1:1:com.batch.android.msgpack.value.Variable$Type access$1100(com.batch.android.msgpack.value.Variable):38:38 -> b + 2:4:com.batch.android.msgpack.value.Variable setStringValue(byte[]):647:649 -> b + 5:8:com.batch.android.msgpack.value.NilValue asNilValue():965:968 -> b + 9:9:com.batch.android.msgpack.value.NilValue asNilValue():966:966 -> b + 1:1:java.lang.Object access$1200(com.batch.android.msgpack.value.Variable):38:38 -> c + 2:5:com.batch.android.msgpack.value.IntegerValue asIntegerValue():989:992 -> c + 6:6:com.batch.android.msgpack.value.IntegerValue asIntegerValue():990:990 -> c + 1:1:double access$1300(com.batch.android.msgpack.value.Variable):38:38 -> d + 2:5:com.batch.android.msgpack.value.MapValue asMapValue():1037:1040 -> d + 6:6:com.batch.android.msgpack.value.MapValue asMapValue():1038:1038 -> d + 1:1:boolean equals(java.lang.Object):890:890 -> equals + 1:4:com.batch.android.msgpack.value.BinaryValue asBinaryValue():1013:1016 -> f + 5:5:com.batch.android.msgpack.value.BinaryValue asBinaryValue():1014:1014 -> f + 1:4:com.batch.android.msgpack.value.StringValue asStringValue():1021:1024 -> g + 5:5:com.batch.android.msgpack.value.StringValue asStringValue():1022:1022 -> g + 1:4:com.batch.android.msgpack.value.RawValue asRawValue():1005:1008 -> h + 5:5:com.batch.android.msgpack.value.RawValue asRawValue():1006:1006 -> h + 1:1:int hashCode():885:885 -> hashCode + 1:4:com.batch.android.msgpack.value.BooleanValue asBooleanValue():973:976 -> i + 5:5:com.batch.android.msgpack.value.BooleanValue asBooleanValue():974:974 -> i + 1:4:com.batch.android.msgpack.value.FloatValue asFloatValue():997:1000 -> j + 5:5:com.batch.android.msgpack.value.FloatValue asFloatValue():998:998 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():905:905 -> m + 1:4:com.batch.android.msgpack.value.ExtensionValue asExtensionValue():1045:1048 -> q + 5:5:com.batch.android.msgpack.value.ExtensionValue asExtensionValue():1046:1046 -> q + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():875:875 -> s + 1:1:java.lang.String toString():900:900 -> toString + 1:1:boolean isStringValue():945:945 -> v + 1:1:boolean isIntegerValue():925:925 -> w +com.batch.android.msgpack.value.Variable$1 -> com.batch.android.r0.a0$a: +com.batch.android.msgpack.value.Variable$AbstractNumberValueAccessor -> com.batch.android.r0.a0$b: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):305:305 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):305:305 -> + 1:6:java.math.BigInteger toBigInteger():346:351 -> F + 1:4:int toInt():330:333 -> G + com.batch.android.msgpack.value.NumberValue asNumberValue() -> R + 1:4:long toLong():338:341 -> Y + 1:6:float toFloat():356:361 -> n + 1:6:double toDouble():366:371 -> o + 1:4:byte toByte():314:317 -> r + 1:4:short toShort():322:325 -> z +com.batch.android.msgpack.value.Variable$AbstractRawValueAccessor -> com.batch.android.r0.a0$c: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):555:555 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):555:555 -> + 1:9:java.lang.String asString():574:582 -> A + 1:1:java.nio.ByteBuffer asByteBuffer():569:569 -> D + 1:1:byte[] asByteArray():564:564 -> P + com.batch.android.msgpack.value.RawValue asRawValue() -> h + 1:9:java.lang.String toString():589:597 -> toString +com.batch.android.msgpack.value.Variable$AbstractValueAccessor -> com.batch.android.r0.a0$d: + com.batch.android.msgpack.value.Variable this$0 -> a + 1:1:void (com.batch.android.msgpack.value.Variable):40:40 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):40:40 -> + 1:1:boolean isBinaryValue():74:74 -> C + 1:1:boolean isNilValue():44:44 -> E + 1:1:boolean isNumberValue():54:54 -> L + 1:1:boolean isArrayValue():84:84 -> N + 1:1:boolean isRawValue():69:69 -> O + 1:1:boolean isExtensionValue():94:94 -> Q + 1:1:com.batch.android.msgpack.value.NumberValue asNumberValue():109:109 -> R + 1:1:boolean isMapValue():89:89 -> S + 1:1:boolean isFloatValue():64:64 -> T + 1:1:boolean isBooleanValue():49:49 -> W + 1:1:java.lang.String toJson():164:164 -> X + 1:1:com.batch.android.msgpack.value.ArrayValue asArrayValue():139:139 -> a + 1:1:com.batch.android.msgpack.value.NilValue asNilValue():99:99 -> b + 1:1:com.batch.android.msgpack.value.IntegerValue asIntegerValue():114:114 -> c + 1:1:com.batch.android.msgpack.value.MapValue asMapValue():144:144 -> d + 1:1:boolean equals(java.lang.Object):154:154 -> equals + 1:1:com.batch.android.msgpack.value.BinaryValue asBinaryValue():129:129 -> f + 1:1:com.batch.android.msgpack.value.StringValue asStringValue():134:134 -> g + 1:1:com.batch.android.msgpack.value.RawValue asRawValue():124:124 -> h + 1:1:int hashCode():159:159 -> hashCode + 1:1:com.batch.android.msgpack.value.BooleanValue asBooleanValue():104:104 -> i + 1:1:com.batch.android.msgpack.value.FloatValue asFloatValue():119:119 -> j + 1:1:com.batch.android.msgpack.value.ExtensionValue asExtensionValue():149:149 -> q + 1:1:java.lang.String toString():169:169 -> toString + 1:1:boolean isStringValue():79:79 -> v + 1:1:boolean isIntegerValue():59:59 -> w +com.batch.android.msgpack.value.Variable$ArrayValueAccessor -> com.batch.android.r0.a0$e: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):689:689 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):689:689 -> + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue immutableValue():703:703 -> Z + com.batch.android.msgpack.value.ArrayValue asArrayValue() -> a + 1:5:com.batch.android.msgpack.value.Value getOrNilValue(int):718:722 -> a + 6:9:void writeTo(com.batch.android.msgpack.core.MessagePacker):738:741 -> a + 1:1:com.batch.android.msgpack.value.Value get(int):713:713 -> get + 1:1:java.util.Iterator iterator():727:727 -> iterator + 1:1:java.util.List list():733:733 -> l + 1:1:com.batch.android.msgpack.value.ValueType getValueType():693:693 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():689:689 -> s + 1:1:int size():708:708 -> size +com.batch.android.msgpack.value.Variable$BinaryValueAccessor -> com.batch.android.r0.a0$f: + com.batch.android.msgpack.value.Variable this$0 -> c + 1:1:void (com.batch.android.msgpack.value.Variable):613:613 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):613:613 -> + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue immutableValue():627:627 -> Z + 1:3:void writeTo(com.batch.android.msgpack.core.MessagePacker):632:634 -> a + com.batch.android.msgpack.value.BinaryValue asBinaryValue() -> f + 1:1:com.batch.android.msgpack.value.ValueType getValueType():617:617 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():613:613 -> s +com.batch.android.msgpack.value.Variable$BooleanValueAccessor -> com.batch.android.r0.a0$g: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):262:262 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):262:262 -> + 1:1:boolean getBoolean():281:281 -> M + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue immutableValue():276:276 -> Z + 1:1:void writeTo(com.batch.android.msgpack.core.MessagePacker):286:286 -> a + com.batch.android.msgpack.value.BooleanValue asBooleanValue() -> i + 1:1:com.batch.android.msgpack.value.ValueType getValueType():266:266 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():262:262 -> s +com.batch.android.msgpack.value.Variable$ExtensionValueAccessor -> com.batch.android.r0.a0$h: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):836:836 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):836:836 -> + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue immutableValue():850:850 -> Z + 1:1:void writeTo(com.batch.android.msgpack.core.MessagePacker):865:865 -> a + 1:1:byte[] getData():860:860 -> e + 1:1:byte getType():855:855 -> k + 1:1:com.batch.android.msgpack.value.ValueType getValueType():840:840 -> m + com.batch.android.msgpack.value.ExtensionValue asExtensionValue() -> q + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():836:836 -> s +com.batch.android.msgpack.value.Variable$FloatValueAccessor -> com.batch.android.r0.a0$i: + com.batch.android.msgpack.value.Variable this$0 -> c + 1:1:void (com.batch.android.msgpack.value.Variable):526:526 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):526:526 -> + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue immutableValue():535:535 -> Z + 1:1:void writeTo(com.batch.android.msgpack.core.MessagePacker):545:545 -> a + com.batch.android.msgpack.value.FloatValue asFloatValue() -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():540:540 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():526:526 -> s +com.batch.android.msgpack.value.Variable$IntegerValueAccessor -> com.batch.android.r0.a0$j: + com.batch.android.msgpack.value.Variable this$0 -> c + 1:1:void (com.batch.android.msgpack.value.Variable):399:399 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):399:399 -> + 1:4:java.math.BigInteger asBigInteger():490:493 -> B + 1:4:long asLong():482:485 -> I + 5:5:long asLong():483:483 -> I + 1:4:byte asByte():458:461 -> J + 5:5:byte asByte():459:459 -> J + 1:1:boolean isInLongRange():445:445 -> K + 1:4:boolean isInByteRange():421:424 -> U + 1:4:int asInt():474:477 -> V + 5:5:int asInt():475:475 -> V + 1:4:com.batch.android.msgpack.value.ImmutableIntegerValue immutableValue():413:416 -> Z + 1:4:void writeTo(com.batch.android.msgpack.core.MessagePacker):499:502 -> a + com.batch.android.msgpack.value.IntegerValue asIntegerValue() -> c + 1:1:com.batch.android.msgpack.value.ValueType getValueType():403:403 -> m + 1:4:boolean isInIntRange():437:440 -> p + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():399:399 -> s + 1:4:short asShort():466:469 -> t + 5:5:short asShort():467:467 -> t + 1:1:com.batch.android.msgpack.core.MessageFormat mostSuccinctMessageFormat():453:453 -> u + 1:4:boolean isInShortRange():429:432 -> y +com.batch.android.msgpack.value.Variable$MapValueAccessor -> com.batch.android.r0.a0$k: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):757:757 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):757:757 -> + 1:1:java.util.Map map():812:812 -> H + 1:1:com.batch.android.msgpack.value.ImmutableMapValue immutableValue():771:771 -> Z + 1:5:void writeTo(com.batch.android.msgpack.core.MessagePacker):817:821 -> a + com.batch.android.msgpack.value.MapValue asMapValue() -> d + 1:1:java.util.Set entrySet():786:786 -> entrySet + 1:1:java.util.Set keySet():781:781 -> keySet + 1:1:com.batch.android.msgpack.value.ValueType getValueType():761:761 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():757:757 -> s + 1:1:int size():776:776 -> size + 1:1:java.util.Collection values():791:791 -> values + 1:9:com.batch.android.msgpack.value.Value[] getKeyValueArray():796:804 -> x +com.batch.android.msgpack.value.Variable$NilValueAccessor -> com.batch.android.r0.a0$l: + com.batch.android.msgpack.value.Variable this$0 -> b + 1:1:void (com.batch.android.msgpack.value.Variable):228:228 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):228:228 -> + 1:1:com.batch.android.msgpack.value.ImmutableNilValue immutableValue():242:242 -> Z + 1:1:void writeTo(com.batch.android.msgpack.core.MessagePacker):247:247 -> a + com.batch.android.msgpack.value.NilValue asNilValue() -> b + 1:1:com.batch.android.msgpack.value.ValueType getValueType():232:232 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():228:228 -> s +com.batch.android.msgpack.value.Variable$StringValueAccessor -> com.batch.android.r0.a0$m: + com.batch.android.msgpack.value.Variable this$0 -> c + 1:1:void (com.batch.android.msgpack.value.Variable):653:653 -> + 2:2:void (com.batch.android.msgpack.value.Variable,com.batch.android.msgpack.value.Variable$1):653:653 -> + 1:1:com.batch.android.msgpack.value.ImmutableStringValue immutableValue():667:667 -> Z + 1:3:void writeTo(com.batch.android.msgpack.core.MessagePacker):672:674 -> a + com.batch.android.msgpack.value.StringValue asStringValue() -> g + 1:1:com.batch.android.msgpack.value.ValueType getValueType():657:657 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():653:653 -> s +com.batch.android.msgpack.value.Variable$Type -> com.batch.android.r0.a0$n: + com.batch.android.msgpack.value.Variable$Type BIG_INTEGER -> e + com.batch.android.msgpack.value.Variable$Type LONG -> d + com.batch.android.msgpack.value.Variable$Type BOOLEAN -> c + com.batch.android.msgpack.value.Variable$Type NULL -> b + com.batch.android.msgpack.value.Variable$Type LIST -> i + com.batch.android.msgpack.value.Variable$Type RAW_STRING -> h + com.batch.android.msgpack.value.Variable$Type BYTE_ARRAY -> g + com.batch.android.msgpack.value.Variable$Type DOUBLE -> f + com.batch.android.msgpack.value.Variable$Type EXTENSION -> k + com.batch.android.msgpack.value.Variable$Type MAP -> j + com.batch.android.msgpack.value.Variable$Type[] $VALUES -> l + com.batch.android.msgpack.value.ValueType valueType -> a + 1:10:void ():174:183 -> + 11:11:void ():173:173 -> + 1:2:void (java.lang.String,int,com.batch.android.msgpack.value.ValueType):187:188 -> + 1:1:com.batch.android.msgpack.value.ValueType getValueType():192:192 -> a + 1:1:com.batch.android.msgpack.value.Variable$Type valueOf(java.lang.String):173:173 -> valueOf + 1:1:com.batch.android.msgpack.value.Variable$Type[] values():173:173 -> values +com.batch.android.msgpack.value.impl.AbstractImmutableRawValue -> com.batch.android.s0.a: + byte[] data -> a + char[] HEX_TABLE -> d + java.nio.charset.CharacterCodingException codingException -> c + java.lang.String decodedStringCache -> b + 1:1:void ():158:158 -> + 1:2:void (byte[]):33:34 -> + 3:5:void (java.lang.String):37:39 -> + 1:7:java.lang.String asString():59:65 -> A + 8:8:java.lang.String asString():63:63 -> A + 1:1:boolean isBinaryValue():27:27 -> C + 1:1:java.nio.ByteBuffer asByteBuffer():54:54 -> D + 1:1:boolean isNilValue():27:27 -> E + 1:1:boolean isNumberValue():27:27 -> L + 1:1:boolean isArrayValue():27:27 -> N + 1:1:boolean isRawValue():27:27 -> O + 1:1:byte[] asByteArray():49:49 -> P + 1:1:boolean isExtensionValue():27:27 -> Q + 1:1:boolean isMapValue():27:27 -> S + 1:1:boolean isFloatValue():27:27 -> T + 1:1:boolean isBooleanValue():27:27 -> W + 1:3:java.lang.String toJson():71:73 -> X + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():27:27 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():27:27 -> a + 2:24:void appendJsonString(java.lang.StringBuilder,java.lang.String):111:133 -> a + 25:31:void appendJsonString(java.lang.StringBuilder,java.lang.String):120:126 -> a + 32:60:void appendJsonString(java.lang.StringBuilder,java.lang.String):117:145 -> a + 61:77:void appendJsonString(java.lang.StringBuilder,java.lang.String):139:155 -> a + 78:82:void escapeChar(java.lang.StringBuilder,int):161:165 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():27:27 -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():27:27 -> b + 1:23:void decodeString():77:99 -> b0 + 24:28:void decodeString():95:99 -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():27:27 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():27:27 -> d + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():27:27 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():27:27 -> g + com.batch.android.msgpack.value.ImmutableRawValue asRawValue() -> h + 1:1:com.batch.android.msgpack.value.RawValue asRawValue():27:27 -> h + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():27:27 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():27:27 -> j + 1:4:java.lang.String toString():104:107 -> toString + 1:1:boolean isStringValue():27:27 -> v + 1:1:boolean isIntegerValue():27:27 -> w +com.batch.android.msgpack.value.impl.AbstractImmutableValue -> com.batch.android.s0.b: + 1:1:void ():32:32 -> + 1:1:boolean isBinaryValue():66:66 -> C + 1:1:boolean isNilValue():36:36 -> E + 1:1:boolean isNumberValue():46:46 -> L + 1:1:boolean isArrayValue():76:76 -> N + 1:1:boolean isRawValue():61:61 -> O + 1:1:boolean isExtensionValue():86:86 -> Q + 1:1:com.batch.android.msgpack.value.NumberValue asNumberValue():32:32 -> R + 1:1:boolean isMapValue():81:81 -> S + 1:1:boolean isFloatValue():56:56 -> T + 1:1:boolean isBooleanValue():41:41 -> W + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():141:141 -> Z + 1:1:com.batch.android.msgpack.value.ArrayValue asArrayValue():32:32 -> a + 2:2:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():131:131 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():101:101 -> a0 + 1:1:com.batch.android.msgpack.value.NilValue asNilValue():32:32 -> b + 2:2:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():91:91 -> b + 1:1:com.batch.android.msgpack.value.IntegerValue asIntegerValue():32:32 -> c + 2:2:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():106:106 -> c + 1:1:com.batch.android.msgpack.value.MapValue asMapValue():32:32 -> d + 2:2:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():136:136 -> d + 1:1:com.batch.android.msgpack.value.BinaryValue asBinaryValue():32:32 -> f + 2:2:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():121:121 -> f + 1:1:com.batch.android.msgpack.value.StringValue asStringValue():32:32 -> g + 2:2:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():126:126 -> g + 1:1:com.batch.android.msgpack.value.RawValue asRawValue():32:32 -> h + 2:2:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():116:116 -> h + 1:1:com.batch.android.msgpack.value.BooleanValue asBooleanValue():32:32 -> i + 2:2:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():96:96 -> i + 1:1:com.batch.android.msgpack.value.FloatValue asFloatValue():32:32 -> j + 2:2:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():111:111 -> j + 1:1:com.batch.android.msgpack.value.ExtensionValue asExtensionValue():32:32 -> q + 1:1:boolean isStringValue():71:71 -> v + 1:1:boolean isIntegerValue():51:51 -> w +com.batch.android.msgpack.value.impl.ImmutableArrayValueImpl -> com.batch.android.s0.c: + com.batch.android.msgpack.value.Value[] array -> a + com.batch.android.msgpack.value.impl.ImmutableArrayValueImpl EMPTY -> b + 1:1:void ():37:37 -> + 1:2:void (com.batch.android.msgpack.value.Value[]):45:46 -> + 1:1:boolean isBinaryValue():35:35 -> C + 1:1:boolean isNilValue():35:35 -> E + 1:1:boolean isNumberValue():35:35 -> L + 1:1:boolean isArrayValue():35:35 -> N + 1:1:boolean isRawValue():35:35 -> O + 1:1:boolean isExtensionValue():35:35 -> Q + 1:1:boolean isMapValue():35:35 -> S + 1:1:boolean isFloatValue():35:35 -> T + 1:1:boolean isBooleanValue():35:35 -> W + 1:12:java.lang.String toJson():145:156 -> X + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():35:35 -> Z + com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue() -> a + 1:1:com.batch.android.msgpack.value.ArrayValue asArrayValue():35:35 -> a + 2:5:com.batch.android.msgpack.value.Value getOrNilValue(int):76:79 -> a + 6:8:void writeTo(com.batch.android.msgpack.core.MessagePacker):94:96 -> a + 9:12:void appendString(java.lang.StringBuilder,com.batch.android.msgpack.value.Value):176:179 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():35:35 -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():35:35 -> b + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue empty():40:40 -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():35:35 -> c + com.batch.android.msgpack.value.ImmutableArrayValue immutableValue() -> c0 + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():35:35 -> d + 1:20:boolean equals(java.lang.Object):105:124 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():35:35 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():35:35 -> g + 1:1:com.batch.android.msgpack.value.Value get(int):71:71 -> get + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():35:35 -> h + 1:3:int hashCode():136:138 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():35:35 -> i + 1:1:java.util.Iterator iterator():84:84 -> iterator + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():35:35 -> j + 1:1:java.util.List list():89:89 -> l + 1:1:com.batch.android.msgpack.value.ValueType getValueType():51:51 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():35:35 -> s + 1:1:int size():66:66 -> size + 1:12:java.lang.String toString():161:172 -> toString + 1:1:boolean isStringValue():35:35 -> v + 1:1:boolean isIntegerValue():35:35 -> w +com.batch.android.msgpack.value.impl.ImmutableArrayValueImpl$ImmutableArrayValueList -> com.batch.android.s0.c$a: + com.batch.android.msgpack.value.Value[] array -> a + 1:2:void (com.batch.android.msgpack.value.Value[]):187:188 -> + 1:1:java.lang.Object get(int):183:183 -> get + 2:2:com.batch.android.msgpack.value.Value get(int):193:193 -> get + 1:1:int size():198:198 -> size +com.batch.android.msgpack.value.impl.ImmutableArrayValueImpl$Ite -> com.batch.android.s0.c$b: + com.batch.android.msgpack.value.Value[] array -> a + int index -> b + 1:3:void (com.batch.android.msgpack.value.Value[]):207:209 -> + 1:6:com.batch.android.msgpack.value.Value next():219:224 -> a + 7:7:com.batch.android.msgpack.value.Value next():221:221 -> a + 1:1:boolean hasNext():214:214 -> hasNext + 1:1:java.lang.Object next():202:202 -> next + 1:1:void remove():229:229 -> remove +com.batch.android.msgpack.value.impl.ImmutableBigIntegerValueImpl -> com.batch.android.s0.d: + java.math.BigInteger INT_MIN -> f + java.math.BigInteger SHORT_MAX -> e + java.math.BigInteger LONG_MIN -> h + java.math.BigInteger INT_MAX -> g + java.math.BigInteger BYTE_MIN -> b + java.math.BigInteger value -> a + java.math.BigInteger SHORT_MIN -> d + java.math.BigInteger BYTE_MAX -> c + java.math.BigInteger LONG_MAX -> i + 1:8:void ():56:63 -> + 1:2:void (java.math.BigInteger):52:53 -> + 1:1:java.math.BigInteger asBigInteger():179:179 -> B + 1:1:boolean isBinaryValue():34:34 -> C + 1:1:boolean isNilValue():34:34 -> E + 1:1:java.math.BigInteger toBigInteger():107:107 -> F + 1:1:int toInt():97:97 -> G + 1:4:long asLong():171:174 -> I + 5:5:long asLong():172:172 -> I + 1:4:byte asByte():147:150 -> J + 5:5:byte asByte():148:148 -> J + 1:1:boolean isInLongRange():137:137 -> K + 1:1:boolean isNumberValue():34:34 -> L + 1:1:boolean isArrayValue():34:34 -> N + 1:1:boolean isRawValue():34:34 -> O + 1:1:boolean isExtensionValue():34:34 -> Q + 1:1:com.batch.android.msgpack.value.NumberValue asNumberValue():34:34 -> R + 1:1:boolean isMapValue():34:34 -> S + 1:1:boolean isFloatValue():34:34 -> T + 1:1:boolean isInByteRange():122:122 -> U + 1:4:int asInt():163:166 -> V + 5:5:int asInt():164:164 -> V + 1:1:boolean isBooleanValue():34:34 -> W + 1:1:java.lang.String toJson():217:217 -> X + 1:1:long toLong():102:102 -> Y + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():34:34 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():34:34 -> a + 2:11:com.batch.android.msgpack.core.MessageFormat mostSuccinctMessageFormat(com.batch.android.msgpack.value.IntegerValue):37:46 -> a + 12:12:void writeTo(com.batch.android.msgpack.core.MessagePacker):184:184 -> a + com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue() -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():34:34 -> b + com.batch.android.msgpack.value.ImmutableIntegerValue immutableValue() -> b0 + com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue() -> c + 1:1:com.batch.android.msgpack.value.IntegerValue asIntegerValue():34:34 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():34:34 -> d + 1:10:boolean equals(java.lang.Object):192:201 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():34:34 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():34:34 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():34:34 -> h + 1:7:int hashCode():206:212 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():34:34 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():34:34 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():67:67 -> m + 1:1:float toFloat():112:112 -> n + 1:1:double toDouble():117:117 -> o + 1:1:boolean isInIntRange():132:132 -> p + 1:1:byte toByte():87:87 -> r + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():34:34 -> s + 1:4:short asShort():155:158 -> t + 5:5:short asShort():156:156 -> t + 1:1:java.lang.String toString():222:222 -> toString + 1:1:com.batch.android.msgpack.core.MessageFormat mostSuccinctMessageFormat():142:142 -> u + 1:1:boolean isStringValue():34:34 -> v + 1:1:boolean isIntegerValue():34:34 -> w + 1:1:boolean isInShortRange():127:127 -> y + 1:1:short toShort():92:92 -> z +com.batch.android.msgpack.value.impl.ImmutableBinaryValueImpl -> com.batch.android.s0.e: + 1:1:void (byte[]):34:34 -> + 1:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):54:55 -> a + com.batch.android.msgpack.value.ImmutableBinaryValue immutableValue() -> c0 + 1:13:boolean equals(java.lang.Object):63:75 -> equals + com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue() -> f + 1:1:com.batch.android.msgpack.value.BinaryValue asBinaryValue():31:31 -> f + 1:1:int hashCode():81:81 -> hashCode + 1:1:com.batch.android.msgpack.value.ValueType getValueType():39:39 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():31:31 -> s +com.batch.android.msgpack.value.impl.ImmutableBooleanValueImpl -> com.batch.android.s0.f: + com.batch.android.msgpack.value.ImmutableBooleanValue FALSE -> c + boolean value -> a + com.batch.android.msgpack.value.ImmutableBooleanValue TRUE -> b + 1:2:void ():33:34 -> + 1:2:void (boolean):38:39 -> + 1:1:boolean isBinaryValue():31:31 -> C + 1:1:boolean isNilValue():31:31 -> E + 1:1:boolean isNumberValue():31:31 -> L + 1:1:boolean getBoolean():59:59 -> M + 1:1:boolean isArrayValue():31:31 -> N + 1:1:boolean isRawValue():31:31 -> O + 1:1:boolean isExtensionValue():31:31 -> Q + 1:1:boolean isMapValue():31:31 -> S + 1:1:boolean isFloatValue():31:31 -> T + 1:1:boolean isBooleanValue():31:31 -> W + 1:1:java.lang.String toJson():94:94 -> X + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():31:31 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():31:31 -> a + 2:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):64:64 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():31:31 -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():31:31 -> b + com.batch.android.msgpack.value.ImmutableBooleanValue immutableValue() -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():31:31 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():31:31 -> d + 1:9:boolean equals(java.lang.Object):72:80 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():31:31 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():31:31 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():31:31 -> h + 1:1:int hashCode():85:85 -> hashCode + com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue() -> i + 1:1:com.batch.android.msgpack.value.BooleanValue asBooleanValue():31:31 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():31:31 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():44:44 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():31:31 -> s + 1:1:java.lang.String toString():99:99 -> toString + 1:1:boolean isStringValue():31:31 -> v + 1:1:boolean isIntegerValue():31:31 -> w +com.batch.android.msgpack.value.impl.ImmutableDoubleValueImpl -> com.batch.android.s0.g: + double value -> a + 1:2:void (double):36:37 -> + 1:1:boolean isBinaryValue():32:32 -> C + 1:1:boolean isNilValue():32:32 -> E + 1:1:java.math.BigInteger toBigInteger():82:82 -> F + 1:1:int toInt():72:72 -> G + 1:1:boolean isNumberValue():32:32 -> L + 1:1:boolean isArrayValue():32:32 -> N + 1:1:boolean isRawValue():32:32 -> O + 1:1:boolean isExtensionValue():32:32 -> Q + 1:1:com.batch.android.msgpack.value.NumberValue asNumberValue():32:32 -> R + 1:1:boolean isMapValue():32:32 -> S + 1:1:boolean isFloatValue():32:32 -> T + 1:1:boolean isBooleanValue():32:32 -> W + 1:4:java.lang.String toJson():124:127 -> X + 5:5:java.lang.String toJson():125:125 -> X + 1:1:long toLong():77:77 -> Y + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():32:32 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():32:32 -> a + 2:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):97:97 -> a + com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue() -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():32:32 -> b + com.batch.android.msgpack.value.impl.ImmutableDoubleValueImpl immutableValue() -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():32:32 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():32:32 -> d + 1:9:boolean equals(java.lang.Object):105:113 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():32:32 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():32:32 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():32:32 -> h + 1:1:int hashCode():118:118 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():32:32 -> i + com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue() -> j + 1:1:com.batch.android.msgpack.value.FloatValue asFloatValue():32:32 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():42:42 -> m + 1:1:float toFloat():87:87 -> n + 1:1:double toDouble():92:92 -> o + 1:1:byte toByte():62:62 -> r + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():32:32 -> s + 1:1:java.lang.String toString():133:133 -> toString + 1:1:boolean isStringValue():32:32 -> v + 1:1:boolean isIntegerValue():32:32 -> w + 1:1:short toShort():67:67 -> z +com.batch.android.msgpack.value.impl.ImmutableExtensionValueImpl -> com.batch.android.s0.h: + byte[] data -> b + byte type -> a + 1:3:void (byte,byte[]):36:38 -> + 1:1:boolean isBinaryValue():31:31 -> C + 1:1:boolean isNilValue():31:31 -> E + 1:1:boolean isNumberValue():31:31 -> L + 1:1:boolean isArrayValue():31:31 -> N + 1:1:boolean isRawValue():31:31 -> O + 1:1:boolean isExtensionValue():31:31 -> Q + 1:1:boolean isMapValue():31:31 -> S + 1:1:boolean isFloatValue():31:31 -> T + 1:1:boolean isBooleanValue():31:31 -> W + 1:9:java.lang.String toJson():100:108 -> X + com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue() -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():31:31 -> a + 2:3:void writeTo(com.batch.android.msgpack.core.MessagePacker):68:69 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():31:31 -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():31:31 -> b + com.batch.android.msgpack.value.ImmutableExtensionValue immutableValue() -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():31:31 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():31:31 -> d + 1:1:byte[] getData():63:63 -> e + 1:10:boolean equals(java.lang.Object):77:86 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():31:31 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():31:31 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():31:31 -> h + 1:2:int hashCode():91:92 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():31:31 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():31:31 -> j + 1:1:byte getType():58:58 -> k + 1:1:com.batch.android.msgpack.value.ValueType getValueType():43:43 -> m + 1:1:com.batch.android.msgpack.value.ExtensionValue asExtensionValue():31:31 -> q + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():31:31 -> s + 1:9:java.lang.String toString():113:121 -> toString + 1:1:boolean isStringValue():31:31 -> v + 1:1:boolean isIntegerValue():31:31 -> w +com.batch.android.msgpack.value.impl.ImmutableLongValueImpl -> com.batch.android.s0.i: + long INT_MIN -> f + long SHORT_MAX -> e + long INT_MAX -> g + long BYTE_MIN -> b + long value -> a + long SHORT_MIN -> d + long BYTE_MAX -> c + 1:2:void (long):38:39 -> + 1:1:java.math.BigInteger asBigInteger():160:160 -> B + 1:1:boolean isBinaryValue():34:34 -> C + 1:1:boolean isNilValue():34:34 -> E + 1:1:java.math.BigInteger toBigInteger():91:91 -> F + 1:1:int toInt():81:81 -> G + 1:1:long asLong():155:155 -> I + 1:4:byte asByte():131:134 -> J + 5:5:byte asByte():132:132 -> J + boolean isInLongRange() -> K + 1:1:boolean isNumberValue():34:34 -> L + 1:1:boolean isArrayValue():34:34 -> N + 1:1:boolean isRawValue():34:34 -> O + 1:1:boolean isExtensionValue():34:34 -> Q + 1:1:com.batch.android.msgpack.value.NumberValue asNumberValue():34:34 -> R + 1:1:boolean isMapValue():34:34 -> S + 1:1:boolean isFloatValue():34:34 -> T + 1:1:boolean isInByteRange():106:106 -> U + 1:4:int asInt():147:150 -> V + 5:5:int asInt():148:148 -> V + 1:1:boolean isBooleanValue():34:34 -> W + 1:1:java.lang.String toJson():199:199 -> X + 1:1:long toLong():86:86 -> Y + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():34:34 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():34:34 -> a + 2:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):165:165 -> a + com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue() -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():34:34 -> b + com.batch.android.msgpack.value.ImmutableIntegerValue immutableValue() -> b0 + com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue() -> c + 1:1:com.batch.android.msgpack.value.IntegerValue asIntegerValue():34:34 -> c + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():34:34 -> d + 1:13:boolean equals(java.lang.Object):173:185 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():34:34 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():34:34 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():34:34 -> h + 1:1:int hashCode():190:190 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():34:34 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():34:34 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():51:51 -> m + 1:1:float toFloat():96:96 -> n + 1:1:double toDouble():101:101 -> o + 1:1:boolean isInIntRange():116:116 -> p + 1:1:byte toByte():71:71 -> r + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():34:34 -> s + 1:4:short asShort():139:142 -> t + 5:5:short asShort():140:140 -> t + 1:1:java.lang.String toString():204:204 -> toString + 1:1:com.batch.android.msgpack.core.MessageFormat mostSuccinctMessageFormat():126:126 -> u + 1:1:boolean isStringValue():34:34 -> v + 1:1:boolean isIntegerValue():34:34 -> w + 1:1:boolean isInShortRange():111:111 -> y + 1:1:short toShort():76:76 -> z +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl -> com.batch.android.s0.j: + com.batch.android.msgpack.value.Value[] kvs -> a + com.batch.android.msgpack.value.impl.ImmutableMapValueImpl EMPTY -> b + 1:1:void ():41:41 -> + 1:2:void (com.batch.android.msgpack.value.Value[]):49:50 -> + 1:1:boolean isBinaryValue():39:39 -> C + 1:1:boolean isNilValue():39:39 -> E + 1:1:java.util.Map map():95:95 -> H + 1:1:boolean isNumberValue():39:39 -> L + 1:1:boolean isArrayValue():39:39 -> N + 1:1:boolean isRawValue():39:39 -> O + 1:1:boolean isExtensionValue():39:39 -> Q + 1:1:boolean isMapValue():39:39 -> S + 1:1:boolean isFloatValue():39:39 -> T + 1:1:boolean isBooleanValue():39:39 -> W + 1:16:java.lang.String toJson():134:149 -> X + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():39:39 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():39:39 -> a + 2:4:void writeTo(com.batch.android.msgpack.core.MessagePacker):100:102 -> a + 5:8:void appendJsonKey(java.lang.StringBuilder,com.batch.android.msgpack.value.Value):153:156 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():39:39 -> a0 + 1:1:com.batch.android.msgpack.value.ImmutableNilValue asNilValue():39:39 -> b + 2:5:void appendString(java.lang.StringBuilder,com.batch.android.msgpack.value.Value):181:184 -> b + 1:1:com.batch.android.msgpack.value.ImmutableMapValue empty():44:44 -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():39:39 -> c + com.batch.android.msgpack.value.ImmutableMapValue immutableValue() -> c0 + com.batch.android.msgpack.value.ImmutableMapValue asMapValue() -> d + 1:1:com.batch.android.msgpack.value.MapValue asMapValue():39:39 -> d + 1:1:java.util.Set entrySet():85:85 -> entrySet + 1:10:boolean equals(java.lang.Object):111:120 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():39:39 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():39:39 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():39:39 -> h + 1:2:int hashCode():126:127 -> hashCode + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():39:39 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():39:39 -> j + 1:1:java.util.Set keySet():80:80 -> keySet + 1:1:com.batch.android.msgpack.value.ValueType getValueType():55:55 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():39:39 -> s + 1:1:int size():75:75 -> size + 1:16:java.lang.String toString():162:177 -> toString + 1:1:boolean isStringValue():39:39 -> v + 1:1:java.util.Collection values():90:90 -> values + 1:1:boolean isIntegerValue():39:39 -> w + 1:1:com.batch.android.msgpack.value.Value[] getKeyValueArray():70:70 -> x +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$EntryIterator -> com.batch.android.s0.j$a: + com.batch.android.msgpack.value.Value[] kvs -> a + int index -> b + 1:3:void (com.batch.android.msgpack.value.Value[],int):299:301 -> + 1:6:com.batch.android.msgpack.value.Value next():311:316 -> a + 7:7:com.batch.android.msgpack.value.Value next():313:313 -> a + 1:1:boolean hasNext():306:306 -> hasNext + 1:1:java.lang.Object next():294:294 -> next + 1:1:void remove():321:321 -> remove +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$EntrySet -> com.batch.android.s0.j$b: + com.batch.android.msgpack.value.Value[] kvs -> a + 1:2:void (com.batch.android.msgpack.value.Value[]):206:207 -> + 1:1:java.util.Iterator iterator():217:217 -> iterator + 1:1:int size():212:212 -> size +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$EntrySetIterator -> com.batch.android.s0.j$c: + com.batch.android.msgpack.value.Value[] kvs -> a + int index -> b + 1:3:void (com.batch.android.msgpack.value.Value[]):226:228 -> + 1:9:java.util.Map$Entry next():238:246 -> a + 10:10:java.util.Map$Entry next():239:239 -> a + 1:1:boolean hasNext():233:233 -> hasNext + 1:1:java.lang.Object next():221:221 -> next + 1:1:void remove():252:252 -> remove +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$ImmutableMapValueMap -> com.batch.android.s0.j$d: + com.batch.android.msgpack.value.Value[] kvs -> a + 1:2:void (com.batch.android.msgpack.value.Value[]):192:193 -> + 1:1:java.util.Set entrySet():198:198 -> entrySet +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$KeySet -> com.batch.android.s0.j$e: + com.batch.android.msgpack.value.Value[] kvs -> a + 1:2:void (com.batch.android.msgpack.value.Value[]):260:261 -> + 1:1:java.util.Iterator iterator():271:271 -> iterator + 1:1:int size():266:266 -> size +com.batch.android.msgpack.value.impl.ImmutableMapValueImpl$ValueCollection -> com.batch.android.s0.j$f: + com.batch.android.msgpack.value.Value[] kvs -> a + 1:2:void (com.batch.android.msgpack.value.Value[]):279:280 -> + 1:1:java.util.Iterator iterator():290:290 -> iterator + 1:1:int size():285:285 -> size +com.batch.android.msgpack.value.impl.ImmutableNilValueImpl -> com.batch.android.s0.k: + com.batch.android.msgpack.value.ImmutableNilValue instance -> a + 1:1:void ():33:33 -> + 1:1:void ():39:39 -> + 1:1:boolean isBinaryValue():31:31 -> C + 1:1:boolean isNilValue():31:31 -> E + 1:1:boolean isNumberValue():31:31 -> L + 1:1:boolean isArrayValue():31:31 -> N + 1:1:boolean isRawValue():31:31 -> O + 1:1:boolean isExtensionValue():31:31 -> Q + 1:1:boolean isMapValue():31:31 -> S + 1:1:boolean isFloatValue():31:31 -> T + 1:1:boolean isBooleanValue():31:31 -> W + 1:1:java.lang.String toJson():84:84 -> X + 1:1:com.batch.android.msgpack.value.ImmutableExtensionValue asExtensionValue():31:31 -> Z + 1:1:com.batch.android.msgpack.value.ImmutableArrayValue asArrayValue():31:31 -> a + 2:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):58:58 -> a + 1:1:com.batch.android.msgpack.value.ImmutableNumberValue asNumberValue():31:31 -> a0 + com.batch.android.msgpack.value.ImmutableNilValue asNilValue() -> b + 1:1:com.batch.android.msgpack.value.NilValue asNilValue():31:31 -> b + 1:1:com.batch.android.msgpack.value.ImmutableNilValue get():36:36 -> b0 + 1:1:com.batch.android.msgpack.value.ImmutableIntegerValue asIntegerValue():31:31 -> c + com.batch.android.msgpack.value.ImmutableNilValue immutableValue() -> c0 + 1:1:com.batch.android.msgpack.value.ImmutableMapValue asMapValue():31:31 -> d + 1:4:boolean equals(java.lang.Object):66:69 -> equals + 1:1:com.batch.android.msgpack.value.ImmutableBinaryValue asBinaryValue():31:31 -> f + 1:1:com.batch.android.msgpack.value.ImmutableStringValue asStringValue():31:31 -> g + 1:1:com.batch.android.msgpack.value.ImmutableRawValue asRawValue():31:31 -> h + 1:1:com.batch.android.msgpack.value.ImmutableBooleanValue asBooleanValue():31:31 -> i + 1:1:com.batch.android.msgpack.value.ImmutableFloatValue asFloatValue():31:31 -> j + 1:1:com.batch.android.msgpack.value.ValueType getValueType():43:43 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():31:31 -> s + 1:1:java.lang.String toString():79:79 -> toString + 1:1:boolean isStringValue():31:31 -> v + 1:1:boolean isIntegerValue():31:31 -> w +com.batch.android.msgpack.value.impl.ImmutableStringValueImpl -> com.batch.android.s0.l: + 1:1:void (byte[]):34:34 -> + 2:2:void (java.lang.String):38:38 -> + 1:2:void writeTo(com.batch.android.msgpack.core.MessagePacker):58:59 -> a + com.batch.android.msgpack.value.ImmutableStringValue immutableValue() -> c0 + 1:13:boolean equals(java.lang.Object):67:79 -> equals + com.batch.android.msgpack.value.ImmutableStringValue asStringValue() -> g + 1:1:com.batch.android.msgpack.value.StringValue asStringValue():31:31 -> g + 1:1:int hashCode():85:85 -> hashCode + 1:1:com.batch.android.msgpack.value.ValueType getValueType():43:43 -> m + 1:1:com.batch.android.msgpack.value.ImmutableValue immutableValue():31:31 -> s +com.batch.android.post.DisplayReceiptPostDataProvider -> com.batch.android.t0.a: + java.util.Collection receipts -> b + java.lang.String TAG -> c + 1:2:void (java.util.Collection):14:15 -> + 1:1:java.lang.Object getRawData():8:8 -> b + 1:8:byte[] pack():25:32 -> c + 1:1:java.util.Collection getRawData():20:20 -> d + 1:1:boolean isEmpty():37:37 -> isEmpty +com.batch.android.post.InboxSyncPostDataProvider -> com.batch.android.t0.b: + com.batch.android.json.JSONObject body -> a + java.lang.String TAG -> b + 1:15:void (java.util.Collection):16:30 -> + 1:1:java.lang.String getContentType():50:50 -> a + 1:1:java.lang.Object getRawData():11:11 -> b + 1:1:com.batch.android.json.JSONObject getRawData():36:36 -> c + 1:1:byte[] getData():41:41 -> e + 1:1:boolean isEmpty():45:45 -> isEmpty +com.batch.android.post.JSONPostDataProvider -> com.batch.android.t0.c: + com.batch.android.json.JSONObject data -> a + 1:1:void ():23:23 -> + 2:7:void (com.batch.android.json.JSONObject):31:36 -> + 8:8:void (com.batch.android.json.JSONObject):33:33 -> + 1:1:java.lang.String getContentType():48:48 -> a + 1:1:java.lang.Object getRawData():10:10 -> b + 1:1:com.batch.android.json.JSONObject getRawData():58:58 -> c + 1:1:byte[] getData():43:43 -> e + 1:1:boolean isEmpty():53:53 -> isEmpty +com.batch.android.post.LocalCampaignsJITPostDataProvider -> com.batch.android.t0.d: + java.lang.String VIEWS_KEY -> g + java.lang.String ATTRIBUTES_KEY -> f + java.lang.String ELIGIBLE_CAMPAIGNS_KEY -> i + java.lang.String COUNT_KEY -> h + java.util.Collection campaigns -> b + java.lang.String TAG -> c + java.lang.String CAMPAIGNS_KEY -> e + java.lang.String IDS_KEY -> d + 1:2:void (java.util.Collection):38:39 -> + 1:19:java.util.List unpack(byte[]):92:110 -> a + 1:1:java.lang.Object getRawData():25:25 -> b + 1:39:byte[] pack():49:87 -> c + 1:1:java.util.Collection getRawData():44:44 -> d + 1:1:boolean isEmpty():117:117 -> isEmpty +com.batch.android.post.MessagePackPostDataProvider -> com.batch.android.t0.e: + java.lang.String TAG -> a + 1:1:void ():5:5 -> + 1:1:java.lang.String getContentType():23:23 -> a + byte[] pack() -> c + 1:4:byte[] getData():14:17 -> e +com.batch.android.post.MetricPostDataProvider -> com.batch.android.t0.f: + java.util.Collection metrics -> b + java.lang.String TAG -> c + 1:2:void (java.util.Collection):14:15 -> + 1:1:java.lang.Object getRawData():8:8 -> b + 1:7:byte[] pack():25:31 -> c + 1:1:java.util.Collection getRawData():20:20 -> d + 1:1:boolean isEmpty():36:36 -> isEmpty +com.batch.android.post.ParametersPostDataProvider -> com.batch.android.t0.g: + java.util.Map params -> a + 1:1:void ():25:25 -> + 2:2:void (java.util.Map):33:33 -> + 3:24:void (java.util.Map):17:38 -> + 25:25:void (java.util.Map):35:35 -> + 1:1:java.lang.String getContentType():76:76 -> a + 1:1:java.lang.Object getRawData():12:12 -> b + 1:1:java.util.Map getRawData():45:45 -> c + 1:19:byte[] getData():53:71 -> e + 1:1:boolean isEmpty():81:81 -> isEmpty +com.batch.android.post.PostDataProvider -> com.batch.android.t0.h: + java.lang.String getContentType() -> a + java.lang.Object getRawData() -> b + byte[] getData() -> e +com.batch.android.push.FCMAbstractRegistrationProvider -> com.batch.android.u0.a: + com.batch.android.adsidentifier.GCMAdsIdentifierProvider adsIdentifierProvider -> a + java.lang.String senderID -> b + 1:3:void (android.content.Context):18:20 -> + 1:24:java.lang.String fetchSenderID(android.content.Context):25:48 -> a + 25:25:boolean isFirebaseCorePresent():91:91 -> a + 1:1:boolean isFirebaseMessagingPresent():100:100 -> b + 1:16:void checkLibraryAvailability():63:78 -> checkLibraryAvailability + 17:17:void checkLibraryAvailability():72:72 -> checkLibraryAvailability + 18:18:void checkLibraryAvailability():66:66 -> checkLibraryAvailability + 1:1:com.batch.android.AdsIdentifierProvider getAdsIdentifierProvider():86:86 -> getAdsIdentifierProvider + 1:1:java.lang.String getSenderID():53:53 -> getSenderID +com.batch.android.push.FCMInstanceIdRegistrationProvider -> com.batch.android.u0.b: + 1:1:void (android.content.Context):16:16 -> + 1:10:java.lang.String fetchSenderID(android.content.Context):26:35 -> a + 1:15:java.lang.String getRegistration():43:57 -> getRegistration + 1:1:java.lang.String getShortname():21:21 -> getShortname +com.batch.android.push.FCMTokenRegistrationProvider -> com.batch.android.u0.c: + 1:1:void (android.content.Context):16:16 -> + 1:22:java.lang.String getRegistration():29:50 -> getRegistration + 1:1:java.lang.String getShortname():21:21 -> getShortname +com.batch.android.push.GCMAbstractRegistrationProvider -> com.batch.android.u0.d: + com.batch.android.adsidentifier.GCMAdsIdentifierProvider adsIdentifierProvider -> a + android.content.Context context -> b + java.lang.String senderID -> c + java.lang.String TAG -> d + 1:4:void (android.content.Context,java.lang.String):23:26 -> + java.lang.Integer getGMSAvailability() -> a + 1:3:boolean isC2DMessagePermissionAvailable():97:99 -> b + 1:3:boolean isReceivePermissionAvailable():88:90 -> c + 1:35:void checkLibraryAvailability():41:75 -> checkLibraryAvailability + 36:36:void checkLibraryAvailability():71:71 -> checkLibraryAvailability + 37:37:void checkLibraryAvailability():65:65 -> checkLibraryAvailability + 38:40:void checkLibraryAvailability():56:58 -> checkLibraryAvailability + 41:41:void checkLibraryAvailability():50:50 -> checkLibraryAvailability + 42:42:void checkLibraryAvailability() -> checkLibraryAvailability + 1:1:com.batch.android.AdsIdentifierProvider getAdsIdentifierProvider():81:81 -> getAdsIdentifierProvider + 1:1:java.lang.String getSenderID():31:31 -> getSenderID +com.batch.android.push.GCMIidRegistrationProvider -> com.batch.android.u0.e: + 1:1:void (android.content.Context,java.lang.String):15:15 -> + 1:1:java.lang.Integer getGMSAvailability():25:25 -> a + 1:11:void checkLibraryAvailability():32:42 -> checkLibraryAvailability + 12:13:void checkLibraryAvailability():35:36 -> checkLibraryAvailability + 1:1:java.lang.String getRegistration():48:48 -> getRegistration + 1:1:java.lang.String getShortname():20:20 -> getShortname +com.batch.android.push.GCMLegacyRegistrationProvider -> com.batch.android.u0.f: + 1:1:void (android.content.Context,java.lang.String):14:14 -> + 1:1:java.lang.Integer getGMSAvailability():23:23 -> a + 1:6:java.lang.String getRegistration():29:34 -> getRegistration + 1:1:java.lang.String getShortname():19:19 -> getShortname +com.batch.android.push.PushRegistrationDiscoveryService -> com.batch.android.push.PushRegistrationDiscoveryService: + 1:1:void ():11:11 -> +com.batch.android.push.PushRegistrationProviderFactory -> com.batch.android.u0.g: + android.content.Context context -> a + java.lang.String COMPONENT_KEY_PREFIX -> f + java.lang.String gcmSenderID -> c + boolean shouldUseGoogleInstanceID -> b + java.lang.String COMPONENT_SENTINEL_VALUE -> e + java.lang.String TAG -> d + 1:4:void (android.content.Context,boolean,java.lang.String):43:46 -> + 1:13:com.batch.android.PushRegistrationProvider getExternalPushRegistrationProvider():308:320 -> a + 14:34:com.batch.android.PushRegistrationProvider getExternalPushRegistrationProvider():318:338 -> a + 35:51:com.batch.android.PushRegistrationProvider getExternalPushRegistrationProvider():333:349 -> a + 52:63:com.batch.android.PushRegistrationProvider getExternalPushRegistrationProvider():346:357 -> a + 64:72:com.batch.android.PushRegistrationProvider getExternalPushRegistrationProvider():354:362 -> a + 73:73:boolean isExternalProviderAllowed(java.lang.String):370:370 -> a + 1:113:com.batch.android.PushRegistrationProvider getRegistrationProvider():85:197 -> b + 1:14:boolean isBatchGCMIidServiceAvailable():267:280 -> c + 1:1:boolean isFCMFirebaseInstanceIdAvailable():244:244 -> d + 1:1:boolean isFCMTokenApiAvailable():230:230 -> e + 1:1:boolean isGCMInstanceIdAvailable():258:258 -> f + 1:16:boolean isLegacyPushReceiverInManifest():202:217 -> g + 1:1:boolean isSenderIdOverridden():304:304 -> h + 1:1:boolean shouldForceFirebaseIIDProvider():295:295 -> i +com.batch.android.push.Registration -> com.batch.android.u0.h: + java.lang.String provider -> a + java.lang.String senderID -> c + java.lang.String registrationID -> b + 1:4:void (java.lang.String,java.lang.String,java.lang.String):17:20 -> +com.batch.android.push.formats.APENFormat -> com.batch.android.v0.a: + android.widget.ImageView$ScaleType imageScaleType -> e + 1:2:void (java.lang.String,java.lang.String,android.graphics.Bitmap,android.graphics.Bitmap):33:34 -> + void applyExtraBuilderConfiguration(androidx.core.app.NotificationCompat$Builder) -> a + 1:10:android.widget.RemoteViews generateCollapsedView(java.lang.String):38:47 -> a + 11:11:androidx.core.app.NotificationCompat$Style getSupportNotificationStyle():82:82 -> a + 12:18:void applyArguments(com.batch.android.json.JSONObject):88:94 -> a + 1:22:android.widget.RemoteViews generateExpandedView(java.lang.String):54:75 -> b + 23:23:android.widget.ImageView$ScaleType getImageScaleType():104:104 -> b + 1:1:boolean isSupported():109:109 -> c +com.batch.android.push.formats.APENFormat$1 -> com.batch.android.v0.a$a: + int[] $SwitchMap$android$widget$ImageView$ScaleType -> a + 1:1:void ():63:63 -> +com.batch.android.push.formats.BaseFormat -> com.batch.android.v0.b: + android.graphics.Bitmap icon -> c + java.lang.String title -> a + android.graphics.Bitmap picture -> d + java.lang.String body -> b + 1:5:void (java.lang.String,java.lang.String,android.graphics.Bitmap,android.graphics.Bitmap):23:27 -> +com.batch.android.push.formats.NotificationFormat -> com.batch.android.v0.c: + void applyArguments(com.batch.android.json.JSONObject) -> a + void applyExtraBuilderConfiguration(androidx.core.app.NotificationCompat$Builder) -> a + android.widget.RemoteViews generateCollapsedView(java.lang.String) -> a + androidx.core.app.NotificationCompat$Style getSupportNotificationStyle() -> a + android.widget.RemoteViews generateExpandedView(java.lang.String) -> b +com.batch.android.push.formats.SystemFormat -> com.batch.android.v0.d: + boolean useLegacyBigPictureIconBehaviour -> e + 1:2:void (java.lang.String,java.lang.String,android.graphics.Bitmap,android.graphics.Bitmap,boolean):24:25 -> + void applyArguments(com.batch.android.json.JSONObject) -> a + android.widget.RemoteViews generateCollapsedView(java.lang.String) -> a + 1:15:androidx.core.app.NotificationCompat$Style getSupportNotificationStyle():45:59 -> a + 16:21:void applyExtraBuilderConfiguration(androidx.core.app.NotificationCompat$Builder):72:77 -> a + android.widget.RemoteViews generateExpandedView(java.lang.String) -> b +com.batch.android.query.AttributesCheckQuery -> com.batch.android.w0.a: + long version -> d + java.lang.String transactionID -> e + 1:11:void (android.content.Context,long,java.lang.String):26:36 -> + 12:12:void (android.content.Context,long,java.lang.String):32:32 -> + 13:13:void (android.content.Context,long,java.lang.String):28:28 -> + 1:4:com.batch.android.json.JSONObject toJSON():43:46 -> e +com.batch.android.query.AttributesSendQuery -> com.batch.android.w0.b: + long version -> d + java.util.Map attributes -> e + java.util.Map tags -> f + 1:16:void (android.content.Context,long,java.util.Map,java.util.Map):38:53 -> + 17:17:void (android.content.Context,long,java.util.Map,java.util.Map):48:48 -> + 18:18:void (android.content.Context,long,java.util.Map,java.util.Map):44:44 -> + 19:19:void (android.content.Context,long,java.util.Map,java.util.Map):40:40 -> + 1:5:com.batch.android.json.JSONObject toJSON():60:64 -> e +com.batch.android.query.LocalCampaignsQuery -> com.batch.android.w0.c: + java.util.Map capping -> d + java.lang.String TAG -> e + 1:1:void (com.batch.android.localcampaigns.CampaignManager,android.content.Context):30:30 -> + 2:18:void (com.batch.android.localcampaigns.CampaignManager,android.content.Context):27:43 -> + 1:8:com.batch.android.json.JSONObject toJSON():49:56 -> e +com.batch.android.query.PushQuery -> com.batch.android.w0.d: + com.batch.android.push.Registration registration -> d + 1:6:void (android.content.Context,com.batch.android.push.Registration):24:29 -> + 7:7:void (android.content.Context,com.batch.android.push.Registration):26:26 -> + 1:6:com.batch.android.json.JSONObject toJSON():36:41 -> e + 1:2:int getNotificationType():54:55 -> f + 3:3:int getNotificationType():53:53 -> f +com.batch.android.query.Query -> com.batch.android.w0.e: + android.content.Context context -> a + com.batch.android.query.QueryType type -> c + java.lang.String id -> b + 1:12:void (android.content.Context,com.batch.android.query.QueryType):33:44 -> + 13:13:void (android.content.Context,com.batch.android.query.QueryType):39:39 -> + 14:14:void (android.content.Context,com.batch.android.query.QueryType):35:35 -> + 1:1:java.lang.String generateID():102:102 -> a + 1:1:android.content.Context getContext():73:73 -> b + 1:1:java.lang.String getID():55:55 -> c + 1:1:com.batch.android.query.QueryType getType():64:64 -> d + 1:4:com.batch.android.json.JSONObject toJSON():86:89 -> e +com.batch.android.query.QueryType -> com.batch.android.w0.f: + com.batch.android.query.QueryType ATTRIBUTES -> d + com.batch.android.query.QueryType PUSH -> c + com.batch.android.query.QueryType TRACKING -> b + com.batch.android.query.QueryType START -> a + com.batch.android.query.QueryType LOCAL_CAMPAIGNS -> f + com.batch.android.query.QueryType ATTRIBUTES_CHECK -> e + com.batch.android.query.QueryType[] $VALUES -> g + 1:21:void ():11:31 -> + 22:22:void ():7:7 -> + 1:1:void (java.lang.String,int):7:7 -> + 1:1:com.batch.android.query.QueryType valueOf(java.lang.String):7:7 -> valueOf + 1:1:com.batch.android.query.QueryType[] values():7:7 -> values +com.batch.android.query.StartQuery -> com.batch.android.w0.g: + java.lang.String pushId -> f + boolean fromPush -> e + boolean userActivity -> d + 1:4:void (android.content.Context,boolean,java.lang.String,boolean):33:36 -> + 1:7:com.batch.android.json.JSONObject toJSON():43:49 -> e +com.batch.android.query.TrackingQuery -> com.batch.android.w0.h: + java.util.List events -> d + 1:6:void (android.content.Context,java.util.List):31:36 -> + 7:7:void (android.content.Context,java.util.List):33:33 -> + 1:46:com.batch.android.json.JSONObject toJSON():43:88 -> e +com.batch.android.query.response.AttributesCheckResponse -> com.batch.android.x0.a: + long version -> d + java.lang.String actionString -> c + java.lang.Long time -> e + 1:1:void (java.lang.String):18:18 -> + 2:4:void (java.lang.String):13:15 -> + 1:1:void setActionString(java.lang.String):48:48 -> a + 2:2:void setVersion(long):56:56 -> a + 3:3:void setTime(java.lang.Long):64:64 -> a + 1:15:com.batch.android.query.response.AttributesCheckResponse$Action getAction():22:36 -> c + 1:1:java.lang.Long getTime():60:60 -> d + 1:1:long getVersion():52:52 -> e +com.batch.android.query.response.AttributesCheckResponse$Action -> com.batch.android.x0.a$a: + com.batch.android.query.response.AttributesCheckResponse$Action RESEND -> d + com.batch.android.query.response.AttributesCheckResponse$Action UNKNOWN -> e + com.batch.android.query.response.AttributesCheckResponse$Action OK -> a + com.batch.android.query.response.AttributesCheckResponse$Action BUMP -> b + com.batch.android.query.response.AttributesCheckResponse$Action RECHECK -> c + com.batch.android.query.response.AttributesCheckResponse$Action[] $VALUES -> f + 1:5:void ():40:44 -> + 6:6:void ():39:39 -> + 1:1:void (java.lang.String,int):39:39 -> + 1:1:com.batch.android.query.response.AttributesCheckResponse$Action valueOf(java.lang.String):39:39 -> valueOf + 1:1:com.batch.android.query.response.AttributesCheckResponse$Action[] values():39:39 -> values +com.batch.android.query.response.AttributesSendResponse -> com.batch.android.x0.b: + long version -> d + java.lang.String transactionID -> c + 1:1:void (java.lang.String):16:16 -> + 2:2:void (java.lang.String):13:13 -> + 1:1:void setTransactionID(java.lang.String):20:20 -> a + 2:2:void setVersion(long):24:24 -> a +com.batch.android.query.response.LocalCampaignsResponse -> com.batch.android.x0.c: + java.lang.String TAG -> g + com.batch.android.query.response.LocalCampaignsResponse$Error error -> c + java.util.List campaigns -> d + com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings cappings -> f + java.lang.Long minDisplayInterval -> e + 1:1:void (java.lang.String):41:41 -> + 1:1:void setCampaigns(java.util.List):73:73 -> a + 2:2:void setMinDisplayInterval(java.lang.Long):77:77 -> a + 3:3:void setError(com.batch.android.query.response.LocalCampaignsResponse$Error):85:85 -> a + 4:4:void setCappings(com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings):98:98 -> a + 1:1:java.util.List getCampaigns():50:50 -> c + 1:7:java.util.List getCampaignsToSave():55:61 -> d + 1:1:com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings getCappings():94:94 -> e + 1:1:com.batch.android.query.response.LocalCampaignsResponse$Error getError():81:81 -> f + 1:1:java.lang.Long getMinDisplayInterval():69:69 -> g + 1:1:boolean hasCampaigns():45:45 -> h + 1:1:boolean hasCappings():102:102 -> i + 1:1:boolean hasError():89:89 -> j +com.batch.android.query.response.LocalCampaignsResponse$Error -> com.batch.android.x0.c$a: + java.lang.String message -> b + int code -> a + 1:1:void ():168:168 -> + 1:1:int getCode():181:181 -> a + 2:2:void setCode(int):185:185 -> a + 3:3:void setMessage(java.lang.String):193:193 -> a + 1:1:java.lang.String getMessage():189:189 -> b + 1:1:java.lang.String toString():199:199 -> toString +com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings -> com.batch.android.x0.c$b: + java.util.List timeBasedCappings -> b + java.lang.Integer session -> a + 1:3:void (java.lang.Integer,java.util.List):152:154 -> + 1:1:java.lang.Integer getSession():159:159 -> a + 1:1:java.util.List getTimeBasedCappings():164:164 -> b +com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings$TimeBasedCapping -> com.batch.android.x0.c$b$a: + java.lang.Integer views -> a + java.lang.Integer duration -> b + 1:3:void (java.lang.Integer,java.lang.Integer):126:128 -> + 1:1:java.lang.Integer getDuration():138:138 -> a + 1:1:java.lang.Integer getViews():133:133 -> b +com.batch.android.query.response.PushResponse -> com.batch.android.x0.d: + 1:1:void (java.lang.String):15:15 -> +com.batch.android.query.response.Response -> com.batch.android.x0.e: + com.batch.android.query.QueryType queryType -> b + java.lang.String queryID -> a + 1:11:void (com.batch.android.query.QueryType,java.lang.String):23:33 -> + 12:12:void (com.batch.android.query.QueryType,java.lang.String):29:29 -> + 13:13:void (com.batch.android.query.QueryType,java.lang.String):25:25 -> + 1:1:java.lang.String getQueryID():42:42 -> a + 1:1:com.batch.android.query.QueryType getQueryType():51:51 -> b +com.batch.android.query.response.StartResponse -> com.batch.android.x0.f: + 1:1:void (java.lang.String):15:15 -> +com.batch.android.query.response.TrackingResponse -> com.batch.android.x0.g: + 1:1:void (java.lang.String):15:15 -> +com.batch.android.query.serialization.deserializers.AttributesCheckResponseDeserializer -> com.batch.android.y0.a: + 1:1:void (com.batch.android.json.JSONObject):18:18 -> + 1:1:com.batch.android.query.response.Response deserialize():10:10 -> a + 1:9:com.batch.android.query.response.AttributesCheckResponse deserialize():29:37 -> c +com.batch.android.query.serialization.deserializers.AttributesSendResponseDeserializer -> com.batch.android.y0.b: + 1:1:void (com.batch.android.json.JSONObject):18:18 -> + 1:1:com.batch.android.query.response.Response deserialize():10:10 -> a + 1:6:com.batch.android.query.response.AttributesSendResponse deserialize():29:34 -> c +com.batch.android.query.serialization.deserializers.LocalCampaignsResponseDeserializer -> com.batch.android.y0.c: + com.batch.android.localcampaigns.serialization.LocalCampaignDeserializer localCampaignDeserializer -> b + java.lang.String TAG -> c + 1:1:void (com.batch.android.json.JSONObject):33:33 -> + 2:2:void (com.batch.android.json.JSONObject):25:25 -> + 1:1:com.batch.android.query.response.Response deserialize():18:18 -> a + 2:19:java.util.List parseTimeBasedCappings(com.batch.android.json.JSONArray):109:126 -> a + 1:19:com.batch.android.query.response.LocalCampaignsResponse deserialize():44:62 -> c + 20:20:com.batch.android.query.response.LocalCampaignsResponse deserialize():45:45 -> c + 1:2:java.util.List deserializeCampaigns():73:74 -> d + 1:11:com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings deserializeCappings():86:96 -> e + 1:8:com.batch.android.query.response.LocalCampaignsResponse$Error parseError():138:145 -> f +com.batch.android.query.serialization.deserializers.PushResponseDeserializer -> com.batch.android.y0.d: + 1:1:void (com.batch.android.json.JSONObject):18:18 -> + 1:1:com.batch.android.query.response.Response deserialize():10:10 -> a + 1:1:com.batch.android.query.response.PushResponse deserialize():29:29 -> c +com.batch.android.query.serialization.deserializers.ResponseDeserializer -> com.batch.android.y0.e: + com.batch.android.json.JSONObject json -> a + 1:2:void (com.batch.android.json.JSONObject):22:23 -> + com.batch.android.query.response.Response deserialize() -> a + 1:1:java.lang.String getId():33:33 -> b +com.batch.android.query.serialization.deserializers.StartResponseDeserializer -> com.batch.android.y0.f: + 1:1:void (com.batch.android.json.JSONObject):18:18 -> + 1:1:com.batch.android.query.response.Response deserialize():10:10 -> a + 1:1:com.batch.android.query.response.StartResponse deserialize():29:29 -> c +com.batch.android.query.serialization.deserializers.TrackingResponseDeserializer -> com.batch.android.y0.g: + 1:1:void (com.batch.android.json.JSONObject):18:18 -> + 1:1:com.batch.android.query.response.Response deserialize():10:10 -> a + 1:1:com.batch.android.query.response.TrackingResponse deserialize():29:29 -> c +com.batch.android.query.serialization.serializers.LocalCampaignsResponseSerializer -> com.batch.android.z0.a: + com.batch.android.localcampaigns.serialization.LocalCampaignSerializer localCampaignSerializer -> a + 1:6:void ():16:21 -> + 1:11:com.batch.android.json.JSONObject serialize(com.batch.android.query.response.LocalCampaignsResponse):34:44 -> a + 12:12:com.batch.android.json.JSONObject serialize(com.batch.android.query.response.LocalCampaignsResponse):38:38 -> a + 13:13:com.batch.android.json.JSONObject serialize(com.batch.android.query.response.LocalCampaignsResponse):32:32 -> a + 14:14:com.batch.android.json.JSONArray serializeCampaigns(java.util.List):56:56 -> a + 15:25:com.batch.android.json.JSONObject serializeCappings(com.batch.android.query.response.LocalCampaignsResponse$GlobalCappings):68:78 -> a +com.batch.android.runtime.ChangeStateAction -> com.batch.android.a1.a: + com.batch.android.runtime.State run(com.batch.android.runtime.State) -> a +com.batch.android.runtime.ForegroundActivityLifecycleListener -> com.batch.android.a1.b: + java.lang.Runnable delayedPauseRunnable -> e + java.lang.String TAG -> f + java.util.concurrent.atomic.AtomicInteger resumeCount -> a + android.os.Handler handler -> c + java.util.concurrent.atomic.AtomicBoolean isPaused -> b + int TIMEOUT_MS -> g + com.batch.android.runtime.ForegroundActivityLifecycleListener$AppLifecycleListener listener -> d + 1:42:void ():16:57 -> + 1:2:void registerAppLifecycleListener(com.batch.android.runtime.ForegroundActivityLifecycleListener$AppLifecycleListener):71:72 -> a + 3:17:boolean isApplicationInForeground():113:127 -> a + 1:4:void lambda$new$0():58:61 -> b + 1:2:void onActivityPaused(android.app.Activity):94:95 -> onActivityPaused + 1:5:void onActivityResumed(android.app.Activity):83:87 -> onActivityResumed +com.batch.android.runtime.ForegroundActivityLifecycleListener$AppLifecycleListener -> com.batch.android.a1.b$a: + void onEnterBackground() -> a + void onEnterForeground() -> b +com.batch.android.runtime.RuntimeManager -> com.batch.android.a1.c: + android.content.Context context -> a + java.util.Date lastUserStartDate -> d + java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock r -> k + com.batch.android.runtime.SessionManager sessionManager -> g + com.batch.android.runtime.ForegroundActivityLifecycleListener foregroundActivityLifecycleListener -> f + com.batch.android.runtime.State state -> i + java.lang.String TAG -> n + com.batch.android.debug.FindMyInstallationHelper installationIdHelper -> m + java.util.Date stopDate -> h + android.app.Activity activity -> e + android.os.Handler handler -> b + java.util.concurrent.locks.ReentrantReadWriteLock lock -> j + java.util.concurrent.atomic.AtomicInteger serviceRefCount -> c + java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock w -> l + 1:1:void ():100:100 -> + 2:61:void ():37:96 -> + 1:1:com.batch.android.debug.FindMyInstallationHelper access$000(com.batch.android.runtime.RuntimeManager):26:26 -> a + 2:13:boolean changeState(com.batch.android.runtime.ChangeStateAction):111:122 -> a + 14:28:boolean changeStateIf(com.batch.android.runtime.State,com.batch.android.runtime.ChangeStateAction):133:147 -> a + 29:38:boolean changeStateIf(com.batch.android.runtime.State,com.batch.android.runtime.ChangeStateAction):139:148 -> a + 39:44:void run(com.batch.android.runtime.StateAction):159:164 -> a + 45:54:boolean runIf(com.batch.android.runtime.State,com.batch.android.runtime.StateAction):175:184 -> a + 55:59:boolean runIf(com.batch.android.runtime.State,com.batch.android.runtime.StateAction):181:185 -> a + 60:60:boolean runIfReady(java.lang.Runnable):197:197 -> a + 61:71:boolean runIf(com.batch.android.runtime.State,java.lang.Runnable):208:218 -> a + 72:77:boolean runIf(com.batch.android.runtime.State,java.lang.Runnable):214:219 -> a + 78:78:void setActivity(android.app.Activity):260:260 -> a + 79:82:void setContext(android.content.Context):358:361 -> a + 83:96:void registerActivityListenerIfNeeded(android.app.Application):377:390 -> a + 97:110:void registerSessionManagerIfNeeded(android.app.Application,boolean):405:418 -> a + 111:111:void clearSessionManager():442:442 -> a + 1:1:void decrementServiceRefCount():283:283 -> b + 1:1:android.app.Activity getActivity():269:269 -> c + 1:1:android.content.Context getContext():371:371 -> d + 1:1:java.util.Date getLastUserStartDate():347:347 -> e + 1:5:java.lang.String getSessionIdentifier():429:433 -> f + 1:1:com.batch.android.runtime.SessionManager getSessionManager():437:437 -> g + 1:1:void incrementServiceRefCount():276:276 -> h + 1:5:boolean isApplicationInForeground():395:399 -> i + 1:1:boolean isReady():298:298 -> j + 1:15:boolean isRetainedByService():305:319 -> k + 1:4:java.lang.Long onStart():232:235 -> l + 1:5:void onStopWithoutFinishing():244:248 -> m + 1:1:void resetServiceRefCount():291:291 -> n + 1:1:void updateLastUserStartDate():338:338 -> o +com.batch.android.runtime.RuntimeManager$1 -> com.batch.android.a1.c$a: + com.batch.android.runtime.RuntimeManager this$0 -> a + 1:1:void (com.batch.android.runtime.RuntimeManager):380:380 -> + void onEnterBackground() -> a + 1:1:void onEnterForeground():383:383 -> b +com.batch.android.runtime.SessionManager -> com.batch.android.a1.d: + java.lang.String TAG -> f + java.util.concurrent.atomic.AtomicInteger createCount -> a + int BACKGROUNDED_SESSION_EXPIRATION_SEC -> g + java.lang.Long backgroundSessionExpirationUptime -> b + boolean sessionActive -> c + java.lang.String INTENT_NEW_SESSION -> e + java.lang.String sessionIdentifier -> d + 1:22:void ():32:53 -> + 1:12:void startNewSessionIfNeeded(android.content.Context):76:87 -> a + 13:27:boolean areAllActivitiesDestroyed():96:110 -> a + 1:1:java.lang.String getSessionIdentifier():61:61 -> b + 1:1:long getUptime():125:125 -> c + 1:7:void invalidateSessionIfNeeded():65:71 -> d + 1:4:void onActivityCreated(android.app.Activity,android.os.Bundle):145:148 -> onActivityCreated + 1:8:void onActivityDestroyed(android.app.Activity):174:181 -> onActivityDestroyed + 1:5:void onActivityResumed(android.app.Activity):156:160 -> onActivityResumed + 1:1:void onLowMemory():140:140 -> onLowMemory + 1:1:void onTrimMemory(int):131:131 -> onTrimMemory +com.batch.android.runtime.State -> com.batch.android.a1.e: + com.batch.android.runtime.State[] $VALUES -> d + com.batch.android.runtime.State READY -> b + com.batch.android.runtime.State FINISHING -> c + com.batch.android.runtime.State OFF -> a + 1:11:void ():11:21 -> + 12:12:void ():7:7 -> + 1:1:void (java.lang.String,int):7:7 -> + 1:1:com.batch.android.runtime.State valueOf(java.lang.String):7:7 -> valueOf + 1:1:com.batch.android.runtime.State[] values():7:7 -> values +com.batch.android.runtime.StateAction -> com.batch.android.a1.f: + void run(com.batch.android.runtime.State) -> a +com.batch.android.tracker.TrackerDatabaseHelper -> com.batch.android.b1.a: + java.lang.String COLUMN_PARAMETERS -> g + java.lang.String COLUMN_TIMEZONE -> f + java.lang.String COLUMN_SERVER_TIME -> i + java.lang.String COLUMN_STATE -> h + int DATABASE_VERSION -> m + java.lang.String COLUMN_SESSION_ID -> k + java.lang.String COLUMN_SECURE_DATE -> j + java.lang.String DATABASE_NAME -> l + java.lang.String TABLE_EVENTS -> a + java.lang.String COLUMN_ID -> c + java.lang.String COLUMN_DB_ID -> b + java.lang.String COLUMN_DATE -> e + java.lang.String COLUMN_NAME -> d + 1:1:void (android.content.Context):33:33 -> + 1:1:void onCreate(android.database.sqlite.SQLiteDatabase):38:38 -> onCreate + 1:4:void onUpgrade(android.database.sqlite.SQLiteDatabase,int,int):68:71 -> onUpgrade +com.batch.android.tracker.TrackerDatasource -> com.batch.android.b1.b: + android.content.Context context -> a + android.database.sqlite.SQLiteDatabase database -> b + com.batch.android.tracker.TrackerDatabaseHelper databaseHelper -> c + java.lang.String TAG -> d + 1:8:void (android.content.Context):42:49 -> + 9:9:void (android.content.Context):44:44 -> + 1:1:void clearDB():81:81 -> a + 2:3:boolean addEvent(com.batch.android.event.Event):93:94 -> a + 4:35:com.batch.android.event.Event parseEvent(android.database.Cursor):176:207 -> a + 36:51:int updateEventsToNewState(java.lang.String[],com.batch.android.event.Event$State):242:257 -> a + 52:69:int deleteEvents(java.lang.String[]):269:286 -> a + 70:70:int deleteOverflowEvents(int):298:298 -> a + 1:23:java.util.List extractEventsToSend(int):104:126 -> b + 24:67:java.util.List extractEventsToSend(int):119:162 -> b + 68:68:boolean updateEventsToNew(java.lang.String[]):220:220 -> b + 69:71:void close():318:320 -> b + 72:87:boolean insert(com.batch.android.event.Event):331:346 -> b + 88:133:boolean insert(com.batch.android.event.Event):343:388 -> b + 134:134:boolean insert(com.batch.android.event.Event):337:337 -> b + 1:13:java.util.List getAllEvents():60:72 -> c + 14:14:java.util.List getAllEvents():62:62 -> c + 15:15:boolean updateEventsToOld(java.lang.String[]):230:230 -> c + 1:11:boolean resetEventStatus():401:411 -> d + 12:25:boolean resetEventStatus():404:417 -> d +com.batch.android.tracker.TrackerMode -> com.batch.android.b1.c: + com.batch.android.tracker.TrackerMode[] $VALUES -> e + com.batch.android.tracker.TrackerMode OFF -> b + com.batch.android.tracker.TrackerMode DB_ONLY -> c + com.batch.android.tracker.TrackerMode ON -> d + int value -> a + 1:11:void ():11:21 -> + 12:12:void ():7:7 -> + 1:2:void (java.lang.String,int,int):27:28 -> + 1:1:int getValue():32:32 -> a + 2:3:com.batch.android.tracker.TrackerMode fromValue(int):44:45 -> a + 1:1:com.batch.android.tracker.TrackerMode valueOf(java.lang.String):7:7 -> valueOf + 1:1:com.batch.android.tracker.TrackerMode[] values():7:7 -> values +com.batch.android.user.AttributeType -> com.batch.android.c1.a: + com.batch.android.user.AttributeType[] $VALUES -> j + com.batch.android.user.AttributeType DELETED -> c + com.batch.android.user.AttributeType BOOL -> g + com.batch.android.user.AttributeType DOUBLE -> f + char typeChar -> b + com.batch.android.user.AttributeType LONG -> e + com.batch.android.user.AttributeType STRING -> d + com.batch.android.user.AttributeType URL -> i + int value -> a + com.batch.android.user.AttributeType DATE -> h + 1:13:void ():7:19 -> + 14:14:void ():6:6 -> + 1:3:void (java.lang.String,int,int,char):27:29 -> + 1:1:char getTypeChar():37:37 -> a + 2:3:com.batch.android.user.AttributeType fromValue(int):49:50 -> a + 1:1:int getValue():33:33 -> b + 1:1:com.batch.android.user.AttributeType valueOf(java.lang.String):6:6 -> valueOf + 1:1:com.batch.android.user.AttributeType[] values():6:6 -> values +com.batch.android.user.SQLUserDatasource -> com.batch.android.c1.b: + android.content.Context context -> a + java.lang.String TAG -> f + long currentChangeset -> e + com.batch.android.user.UserDatabaseHelper databaseHelper -> c + android.database.sqlite.SQLiteDatabase database -> b + boolean transactionOccurring -> d + 1:1:void (android.content.Context):59:59 -> + 2:16:void (android.content.Context):52:66 -> + 17:17:void (android.content.Context):61:61 -> + 1:10:void acquireTransactionLock(long):97:106 -> a + 11:13:void setAttribute(java.lang.String,long):151:153 -> a + 14:16:void setAttribute(java.lang.String,double):158:160 -> a + 17:19:void setAttribute(java.lang.String,boolean):165:167 -> a + 20:22:void setAttribute(java.lang.String,java.lang.String):172:174 -> a + 23:25:void setAttribute(java.lang.String,java.util.Date):179:181 -> a + 26:28:void setAttribute(java.lang.String,java.net.URI):186:188 -> a + 29:33:void clearTags(java.lang.String):238:242 -> a + 34:50:void setAttribute(java.lang.String,android.content.ContentValues,com.batch.android.user.AttributeType,boolean):266:282 -> a + 51:51:void setAttribute(java.lang.String,android.content.ContentValues,com.batch.android.user.AttributeType,boolean):267:267 -> a + 52:77:java.lang.String printDebugDump():506:531 -> a + 78:79:void logAndThrow(java.lang.String,java.lang.Throwable):540:541 -> a + 1:10:void commitTransaction():117:126 -> b + 11:11:void removeAttribute(java.lang.String):193:193 -> b + 12:12:void addTag(java.lang.String,java.lang.String):202:202 -> b + 13:22:void deleteAttribute(java.lang.String,boolean):287:296 -> b + 23:29:void deleteAttribute(java.lang.String,boolean):293:299 -> b + 30:30:void deleteAttribute(java.lang.String,boolean):288:288 -> b + 1:1:void removeTag(java.lang.String,java.lang.String):207:207 -> c + 2:6:void clearTags():229:233 -> c + 1:6:void clear():219:224 -> clear + 1:9:void close():73:81 -> close + 1:5:void clearAttributes():251:255 -> d + 6:18:void deleteTag(java.lang.String,java.lang.String):329:341 -> d + 19:19:void deleteTag(java.lang.String,java.lang.String):330:330 -> d + 1:17:void writeTag(java.lang.String,java.lang.String):308:324 -> e + 18:18:void writeTag(java.lang.String,java.lang.String):309:309 -> e + 19:41:java.util.HashMap getAttributes():417:439 -> e + 42:77:java.util.HashMap getAttributes():438:473 -> e + 78:78:java.util.HashMap getAttributes():470:470 -> e + 79:79:java.util.HashMap getAttributes():467:467 -> e + 80:81:java.util.HashMap getAttributes():462:463 -> e + 82:82:java.util.HashMap getAttributes():458:458 -> e + 83:112:java.util.HashMap getAttributes():455:484 -> e + 113:119:java.util.HashMap getAttributes():483:489 -> e + 120:195:java.util.HashMap getAttributes():419:494 -> e + 1:58:java.util.Map getTagCollections():351:408 -> f + 59:62:java.util.Map getTagCollections():374:377 -> f + 63:95:java.util.Map getTagCollections():376:408 -> f + 96:150:java.util.Map getTagCollections():355:409 -> f + 1:10:void rollbackTransaction():132:141 -> g + 1:1:void throwInvalidStateException():545:545 -> h +com.batch.android.user.SQLUserDatasource$1 -> com.batch.android.c1.b$a: + int[] $SwitchMap$com$batch$android$user$AttributeType -> a + 1:1:void ():453:453 -> +com.batch.android.user.UserAttribute -> com.batch.android.c1.c: + com.batch.android.user.AttributeType type -> b + java.lang.Object value -> a + 1:3:void (java.lang.Object,com.batch.android.user.AttributeType):14:16 -> + 1:13:java.util.Map getServerMapRepresentation(java.util.Map):20:32 -> a + 1:7:boolean equals(java.lang.Object):44:50 -> equals + 1:1:java.lang.String toString():55:55 -> toString +com.batch.android.user.UserDataDiff -> com.batch.android.c1.d: + com.batch.android.user.UserDataDiff$Result result -> a + 1:14:void (java.util.Map,java.util.Map,java.util.Map,java.util.Map):26:39 -> + 1:15:void computeAttributes(java.util.Map,java.util.Map):52:66 -> a + 16:48:void computeTagSetDiff(java.util.Set,java.util.Set,java.util.Set[]):104:136 -> a + 49:49:void computeTagSetDiff(java.util.Set,java.util.Set,java.util.Set[]):116:116 -> a + 50:53:void computeTagSetDiff(java.util.Set,java.util.Set,java.util.Set[]):109:112 -> a + 1:24:void computeTags(java.util.Map,java.util.Map):73:96 -> b +com.batch.android.user.UserDataDiff$1 -> com.batch.android.c1.d$a: +com.batch.android.user.UserDataDiff$Result -> com.batch.android.c1.d$b: + java.util.Map addedAttributes -> a + java.util.Map removedAttributes -> b + java.util.Map addedTags -> c + java.util.Map removedTags -> d + 1:1:void (com.batch.android.user.UserDataDiff$1):143:143 -> + 2:2:void ():151:151 -> + 1:5:boolean hasChanges():154:158 -> a + 6:10:com.batch.android.json.JSONObject toEventParameters(long):166:170 -> a + 11:23:com.batch.android.json.JSONObject convertToJson(java.util.Map,java.util.Map):179:191 -> a +com.batch.android.user.UserDatabaseException -> com.batch.android.c1.e: + 1:1:void (java.lang.String):6:6 -> +com.batch.android.user.UserDatabaseHelper -> com.batch.android.c1.f: + java.lang.String COLUMN_TAG_COLLECTION -> g + java.lang.String TABLE_TAGS -> f + java.lang.String COLUMN_TAG_CHANGESET -> i + java.lang.String COLUMN_TAG_VALUE -> h + java.lang.String DATABASE_NAME -> j + int DATABASE_VERSION -> k + java.lang.String TABLE_ATTRIBUTES -> a + java.lang.String COLUMN_ATTR_TYPE -> c + java.lang.String COLUMN_ATTR_NAME -> b + java.lang.String COLUMN_ATTR_CHANGESET -> e + java.lang.String COLUMN_ATTR_VALUE -> d + 1:1:void (android.content.Context):34:34 -> + 1:25:void onCreate(android.database.sqlite.SQLiteDatabase):39:63 -> onCreate +com.batch.android.user.UserDatasource -> com.batch.android.c1.g: + void acquireTransactionLock(long) -> a + void clearTags(java.lang.String) -> a + java.lang.String printDebugDump() -> a + void setAttribute(java.lang.String,double) -> a + void setAttribute(java.lang.String,long) -> a + void setAttribute(java.lang.String,java.lang.String) -> a + void setAttribute(java.lang.String,java.net.URI) -> a + void setAttribute(java.lang.String,java.util.Date) -> a + void setAttribute(java.lang.String,boolean) -> a + void addTag(java.lang.String,java.lang.String) -> b + void commitTransaction() -> b + void removeAttribute(java.lang.String) -> b + void clearTags() -> c + void removeTag(java.lang.String,java.lang.String) -> c + void clearAttributes() -> d + java.util.HashMap getAttributes() -> e + java.util.Map getTagCollections() -> f + void rollbackTransaction() -> g +com.batch.android.user.UserOperation -> com.batch.android.c1.h: + void execute(com.batch.android.user.SQLUserDatasource) -> a +com.batch.android.util.MetaDataUtils -> com.batch.android.d1.a: + java.lang.String MANIFEST_SENDER_ID_KEY -> a + java.lang.String MANIFEST_FORCE_FCM_IID_KEY -> b + 1:1:void ():10:10 -> + 1:2:android.os.Bundle getAppMetaData(android.content.Context):25:26 -> a + 3:8:boolean getBooleanMetaData(android.content.Context,java.lang.String):39:44 -> a + 1:6:int getIntMetaData(android.content.Context,java.lang.String):58:63 -> b +com.batch.android.webservice.listener.AttributesCheckWebserviceListener -> com.batch.android.e1.a: + void onError(com.batch.android.FailReason) -> a + void onSuccess(com.batch.android.query.response.AttributesCheckResponse) -> a +com.batch.android.webservice.listener.AttributesSendWebserviceListener -> com.batch.android.e1.b: + void onError(com.batch.android.FailReason) -> a + void onSuccess(com.batch.android.query.response.AttributesSendResponse) -> a +com.batch.android.webservice.listener.DisplayReceiptWebserviceListener -> com.batch.android.e1.c: + void onFailure(com.batch.android.core.Webservice$WebserviceError) -> a +com.batch.android.webservice.listener.InboxWebserviceListener -> com.batch.android.e1.d: + void onFailure(java.lang.String) -> a + void onSuccess(com.batch.android.inbox.InboxWebserviceResponse) -> a +com.batch.android.webservice.listener.LocalCampaignsJITWebserviceListener -> com.batch.android.e1.e: + void onFailure(com.batch.android.core.Webservice$WebserviceError) -> a + void onSuccess(java.util.List) -> a +com.batch.android.webservice.listener.LocalCampaignsWebserviceListener -> com.batch.android.e1.f: + void onError(com.batch.android.FailReason) -> a + void onSuccess(java.util.List) -> a +com.batch.android.webservice.listener.MetricWebserviceListener -> com.batch.android.e1.g: + void onFailure(com.batch.android.core.Webservice$WebserviceError) -> a +com.batch.android.webservice.listener.PushWebserviceListener -> com.batch.android.e1.h: + void onError(com.batch.android.FailReason) -> a +com.batch.android.webservice.listener.StartWebserviceListener -> com.batch.android.e1.i: + void onError(com.batch.android.FailReason) -> a +com.batch.android.webservice.listener.TrackerWebserviceListener -> com.batch.android.e1.j: + void onFailure(com.batch.android.FailReason,java.util.List) -> a + void onFinish() -> a + void onSuccess(java.util.List) -> a +com.batch.android.webservice.listener.impl.AttributesCheckWebserviceListenerImpl -> com.batch.android.f1.a: + long DEFAULT_RECHECK_TIME -> a + 1:1:void ():12:12 -> + 1:38:void onSuccess(com.batch.android.query.response.AttributesCheckResponse):20:57 -> a + 39:48:void onSuccess(com.batch.android.query.response.AttributesCheckResponse):38:47 -> a + 49:87:void onSuccess(com.batch.android.query.response.AttributesCheckResponse):27:65 -> a + 88:88:void onError(com.batch.android.FailReason):71:71 -> a +com.batch.android.webservice.listener.impl.AttributesCheckWebserviceListenerImpl$1 -> com.batch.android.f1.a$a: + int[] $SwitchMap$com$batch$android$query$response$AttributesCheckResponse$Action -> a + 1:1:void ():20:20 -> +com.batch.android.webservice.listener.impl.AttributesSendWebserviceListenerImpl -> com.batch.android.f1.b: + 1:1:void ():12:12 -> + 1:1:void onSuccess(com.batch.android.query.response.AttributesSendResponse):16:16 -> a + 2:2:void onError(com.batch.android.FailReason):21:21 -> a +com.batch.android.webservice.listener.impl.LocalCampaignsWebserviceListenerImpl -> com.batch.android.f1.c: + com.batch.android.localcampaigns.CampaignManager campaignManager -> b + com.batch.android.module.LocalCampaignsModule localCampaignsModule -> a + 1:3:void (com.batch.android.module.LocalCampaignsModule,com.batch.android.localcampaigns.CampaignManager):28:30 -> + 1:3:com.batch.android.webservice.listener.impl.LocalCampaignsWebserviceListenerImpl provide():35:37 -> a + 4:5:void onSuccess(java.util.List):43:44 -> a + 6:7:void onError(com.batch.android.FailReason):50:51 -> a + 8:10:void handleInAppResponse(com.batch.android.query.response.LocalCampaignsResponse):55:57 -> a +com.batch.android.webservice.listener.impl.PushWebserviceListenerImpl -> com.batch.android.f1.d: + 1:1:void ():10:10 -> + void onError(com.batch.android.FailReason) -> a +com.batch.android.webservice.listener.impl.StartWebserviceListenerImpl -> com.batch.android.f1.e: + 1:1:void ():10:10 -> + void onError(com.batch.android.FailReason) -> a