Search in sources :

Example 1 with UserMetadata

use of com.google.firebase.crashlytics.internal.metadata.UserMetadata in project firebase-android-sdk by firebase.

the class CrashlyticsCore method onPreExecute.

// endregion
// region Initialization
public boolean onPreExecute(AppData appData, SettingsDataProvider settingsProvider) {
    // before starting the crash detector make sure that this was built with our build
    // tools.
    // Throw an exception and halt the app if the build ID is required and not present.
    // TODO: This flag is no longer supported and should be removed, as part of a larger refactor
    // now that the buildId is now only used for mapping file association.
    final boolean requiresBuildId = CommonUtils.getBooleanResourceValue(context, CRASHLYTICS_REQUIRE_BUILD_ID, CRASHLYTICS_REQUIRE_BUILD_ID_DEFAULT);
    if (!isBuildIdValid(appData.buildId, requiresBuildId)) {
        throw new IllegalStateException(MISSING_BUILD_ID_MSG);
    }
    final String sessionIdentifier = new CLSUUID(idManager).toString();
    try {
        crashMarker = new CrashlyticsFileMarker(CRASH_MARKER_FILE_NAME, fileStore);
        initializationMarker = new CrashlyticsFileMarker(INITIALIZATION_MARKER_FILE_NAME, fileStore);
        final UserMetadata userMetadata = new UserMetadata(sessionIdentifier, fileStore, backgroundWorker);
        final LogFileManager logFileManager = new LogFileManager(fileStore);
        final StackTraceTrimmingStrategy stackTraceTrimmingStrategy = new MiddleOutFallbackStrategy(MAX_STACK_SIZE, new RemoveRepeatsStrategy(NUM_STACK_REPETITIONS_ALLOWED));
        final SessionReportingCoordinator sessionReportingCoordinator = SessionReportingCoordinator.create(context, idManager, fileStore, appData, logFileManager, userMetadata, stackTraceTrimmingStrategy, settingsProvider);
        controller = new CrashlyticsController(context, backgroundWorker, idManager, dataCollectionArbiter, fileStore, crashMarker, appData, userMetadata, logFileManager, sessionReportingCoordinator, nativeComponent, analyticsEventLogger);
        // If the file is present at this point, then the previous run's initialization
        // did not complete, and we want to perform initialization synchronously this time.
        // We make this check early here because we want to guarantee that the async
        // startup thread we're about to launch doesn't affect the value.
        final boolean initializeSynchronously = didPreviousInitializationFail();
        checkForPreviousCrash();
        controller.enableExceptionHandling(sessionIdentifier, Thread.getDefaultUncaughtExceptionHandler(), settingsProvider);
        if (initializeSynchronously && CommonUtils.canTryConnection(context)) {
            Logger.getLogger().d("Crashlytics did not finish previous background " + "initialization. Initializing synchronously.");
            // finishInitSynchronously blocks the UI thread while it finishes background init.
            finishInitSynchronously(settingsProvider);
            // Returning false here to stop the rest of init from being run in the background thread.
            return false;
        }
    } catch (Exception e) {
        Logger.getLogger().e("Crashlytics was not started due to an exception during initialization", e);
        controller = null;
        return false;
    }
    Logger.getLogger().d("Successfully configured exception handler.");
    return true;
}
Also used : RemoveRepeatsStrategy(com.google.firebase.crashlytics.internal.stacktrace.RemoveRepeatsStrategy) UserMetadata(com.google.firebase.crashlytics.internal.metadata.UserMetadata) LogFileManager(com.google.firebase.crashlytics.internal.metadata.LogFileManager) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException) StackTraceTrimmingStrategy(com.google.firebase.crashlytics.internal.stacktrace.StackTraceTrimmingStrategy) MiddleOutFallbackStrategy(com.google.firebase.crashlytics.internal.stacktrace.MiddleOutFallbackStrategy)

Example 2 with UserMetadata

use of com.google.firebase.crashlytics.internal.metadata.UserMetadata in project firebase-android-sdk by firebase.

the class CrashlyticsController method writeApplicationExitInfoEventIfRelevant.

// endregion
// region ApplicationExitInfo
/**
 * If an ApplicationExitInfo exists relevant to the session, writes that event.
 */
private void writeApplicationExitInfoEventIfRelevant(String sessionId) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        // Gets all the available app exit infos.
        List<ApplicationExitInfo> applicationExitInfoList = activityManager.getHistoricalProcessExitReasons(null, 0, 0);
        // happened during the session.
        if (applicationExitInfoList.size() != 0) {
            final LogFileManager relevantSessionLogManager = new LogFileManager(fileStore, sessionId);
            final UserMetadata relevantUserMetadata = UserMetadata.loadFromExistingSession(sessionId, fileStore, backgroundWorker);
            reportingCoordinator.persistRelevantAppExitInfoEvent(sessionId, applicationExitInfoList, relevantSessionLogManager, relevantUserMetadata);
        } else {
            Logger.getLogger().v("No ApplicationExitInfo available. Session: " + sessionId);
        }
    } else {
        Logger.getLogger().v("ANR feature enabled, but device is API " + android.os.Build.VERSION.SDK_INT);
    }
}
Also used : ApplicationExitInfo(android.app.ApplicationExitInfo) UserMetadata(com.google.firebase.crashlytics.internal.metadata.UserMetadata) ActivityManager(android.app.ActivityManager) LogFileManager(com.google.firebase.crashlytics.internal.metadata.LogFileManager)

Example 3 with UserMetadata

use of com.google.firebase.crashlytics.internal.metadata.UserMetadata in project firebase-android-sdk by firebase.

the class CrashlyticsCore method onPreExecute.

// endregion
// region Initialization
public boolean onPreExecute(AppData appData, SettingsProvider settingsProvider) {
    // before starting the crash detector make sure that this was built with our build
    // tools.
    // Throw an exception and halt the app if the build ID is required and not present.
    // TODO: This flag is no longer supported and should be removed, as part of a larger refactor
    // now that the buildId is now only used for mapping file association.
    final boolean requiresBuildId = CommonUtils.getBooleanResourceValue(context, CRASHLYTICS_REQUIRE_BUILD_ID, CRASHLYTICS_REQUIRE_BUILD_ID_DEFAULT);
    if (!isBuildIdValid(appData.buildId, requiresBuildId)) {
        throw new IllegalStateException(MISSING_BUILD_ID_MSG);
    }
    final String sessionIdentifier = new CLSUUID(idManager).toString();
    try {
        crashMarker = new CrashlyticsFileMarker(CRASH_MARKER_FILE_NAME, fileStore);
        initializationMarker = new CrashlyticsFileMarker(INITIALIZATION_MARKER_FILE_NAME, fileStore);
        final UserMetadata userMetadata = new UserMetadata(sessionIdentifier, fileStore, backgroundWorker);
        final LogFileManager logFileManager = new LogFileManager(fileStore);
        final StackTraceTrimmingStrategy stackTraceTrimmingStrategy = new MiddleOutFallbackStrategy(MAX_STACK_SIZE, new RemoveRepeatsStrategy(NUM_STACK_REPETITIONS_ALLOWED));
        final SessionReportingCoordinator sessionReportingCoordinator = SessionReportingCoordinator.create(context, idManager, fileStore, appData, logFileManager, userMetadata, stackTraceTrimmingStrategy, settingsProvider, onDemandCounter);
        controller = new CrashlyticsController(context, backgroundWorker, idManager, dataCollectionArbiter, fileStore, crashMarker, appData, userMetadata, logFileManager, sessionReportingCoordinator, nativeComponent, analyticsEventLogger);
        // If the file is present at this point, then the previous run's initialization
        // did not complete, and we want to perform initialization synchronously this time.
        // We make this check early here because we want to guarantee that the async
        // startup thread we're about to launch doesn't affect the value.
        final boolean initializeSynchronously = didPreviousInitializationFail();
        checkForPreviousCrash();
        controller.enableExceptionHandling(sessionIdentifier, Thread.getDefaultUncaughtExceptionHandler(), settingsProvider);
        if (initializeSynchronously && CommonUtils.canTryConnection(context)) {
            Logger.getLogger().d("Crashlytics did not finish previous background " + "initialization. Initializing synchronously.");
            // finishInitSynchronously blocks the UI thread while it finishes background init.
            finishInitSynchronously(settingsProvider);
            // Returning false here to stop the rest of init from being run in the background thread.
            return false;
        }
    } catch (Exception e) {
        Logger.getLogger().e("Crashlytics was not started due to an exception during initialization", e);
        controller = null;
        return false;
    }
    Logger.getLogger().d("Successfully configured exception handler.");
    return true;
}
Also used : RemoveRepeatsStrategy(com.google.firebase.crashlytics.internal.stacktrace.RemoveRepeatsStrategy) UserMetadata(com.google.firebase.crashlytics.internal.metadata.UserMetadata) LogFileManager(com.google.firebase.crashlytics.internal.metadata.LogFileManager) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException) StackTraceTrimmingStrategy(com.google.firebase.crashlytics.internal.stacktrace.StackTraceTrimmingStrategy) MiddleOutFallbackStrategy(com.google.firebase.crashlytics.internal.stacktrace.MiddleOutFallbackStrategy)

Example 4 with UserMetadata

use of com.google.firebase.crashlytics.internal.metadata.UserMetadata in project firebase-android-sdk by firebase.

the class CrashlyticsCoreTest method testBulkCustomKeys.

public void testBulkCustomKeys() throws Exception {
    final double DELTA = 1e-15;
    UserMetadata metadata = crashlyticsCore.getController().getUserMetadata();
    final String stringKey = "string key";
    final String stringValue = "value1";
    final String trimmedKey = "trimmed key";
    final String trimmedValue = "trimmed value";
    final StringBuffer idBuffer = new StringBuffer("id012345");
    while (idBuffer.length() < UserMetadata.MAX_ATTRIBUTE_SIZE) {
        idBuffer.append("0");
    }
    final String longId = idBuffer.toString();
    final String superLongId = longId + "more chars";
    final String longStringValue = longId.replaceAll("0", "x");
    final String superLongValue = longStringValue + "some more chars";
    final String booleanKey = "boolean key";
    final Boolean booleanValue = true;
    final String doubleKey = "double key";
    final double doubleValue = 1.000000000000001;
    final String floatKey = "float key";
    final float floatValue = 2.000002f;
    final String longKey = "long key";
    final long longValue = 3;
    final String intKey = "int key";
    final int intValue = 4;
    Map<String, String> keysAndValues = new HashMap<>();
    keysAndValues.put(stringKey, stringValue);
    keysAndValues.put(" " + trimmedKey + " ", " " + trimmedValue + " ");
    keysAndValues.put(longId, longStringValue);
    keysAndValues.put(superLongId, superLongValue);
    keysAndValues.put(booleanKey, booleanValue.toString());
    keysAndValues.put(doubleKey, String.valueOf(doubleValue));
    keysAndValues.put(floatKey, String.valueOf(floatValue));
    keysAndValues.put(longKey, String.valueOf(longValue));
    keysAndValues.put(intKey, String.valueOf(intValue));
    crashlyticsCore.setCustomKeys(keysAndValues);
    assertEquals(stringValue, metadata.getCustomKeys().get(stringKey));
    assertEquals(trimmedValue, metadata.getCustomKeys().get(trimmedKey));
    assertEquals(longStringValue, metadata.getCustomKeys().get(longId));
    // Test truncation of custom keys and attributes
    assertNull(metadata.getCustomKeys().get(superLongId));
    assertTrue(Boolean.parseBoolean(metadata.getCustomKeys().get(booleanKey)));
    assertEquals(doubleValue, Double.parseDouble(metadata.getCustomKeys().get(doubleKey)), DELTA);
    assertEquals(floatValue, Float.parseFloat(metadata.getCustomKeys().get(floatKey)), DELTA);
    assertEquals(longValue, Long.parseLong(metadata.getCustomKeys().get(longKey)), DELTA);
    assertEquals(intValue, Integer.parseInt(metadata.getCustomKeys().get(intKey)), DELTA);
    // Add the max number of attributes (already set 8)
    Map<String, String> addlKeysAndValues = new HashMap<>();
    for (int i = 8; i < UserMetadata.MAX_ATTRIBUTES; ++i) {
        final String key = "key" + i;
        final String value = "value" + i;
        addlKeysAndValues.put(key, value);
    }
    crashlyticsCore.setCustomKeys(addlKeysAndValues);
    // Ensure all keys have been set
    assertEquals(UserMetadata.MAX_ATTRIBUTES, metadata.getCustomKeys().size(), DELTA);
    // Make sure the first MAX_ATTRIBUTES - 8 keys were set
    for (int i = 8; i < UserMetadata.MAX_ATTRIBUTES + 1; ++i) {
        final String key = "key" + i;
        final String value = "value" + i;
    }
    Map<String, String> extraKeysAndValues = new HashMap<>();
    for (int i = UserMetadata.MAX_ATTRIBUTES; i < UserMetadata.MAX_ATTRIBUTES + 10; ++i) {
        final String key = "key" + i;
        final String value = "value" + i;
        extraKeysAndValues.put(key, value);
    }
    crashlyticsCore.setCustomKeys(extraKeysAndValues);
    // Make sure the extra keys were not added
    for (int i = UserMetadata.MAX_ATTRIBUTES; i < UserMetadata.MAX_ATTRIBUTES + 10; ++i) {
        final String key = "key" + i;
        assertFalse(metadata.getCustomKeys().containsKey(key));
    }
    // Check updating existing keys and setting to null
    final String updatedStringValue = "string value 1";
    final boolean updatedBooleanValue = false;
    final double updatedDoubleValue = -1.000000000000001;
    final float updatedFloatValue = -2.000002f;
    final long updatedLongValue = -3;
    final int updatedIntValue = -4;
    Map<String, String> updatedKeysAndValues = new HashMap<>();
    updatedKeysAndValues.put(stringKey, updatedStringValue);
    updatedKeysAndValues.put(longId, null);
    updatedKeysAndValues.put(booleanKey, String.valueOf(updatedBooleanValue));
    updatedKeysAndValues.put(doubleKey, String.valueOf(updatedDoubleValue));
    updatedKeysAndValues.put(floatKey, String.valueOf(updatedFloatValue));
    updatedKeysAndValues.put(longKey, String.valueOf(updatedLongValue));
    updatedKeysAndValues.put(intKey, String.valueOf(updatedIntValue));
    crashlyticsCore.setCustomKeys(updatedKeysAndValues);
    assertEquals(updatedStringValue, metadata.getCustomKeys().get(stringKey));
    assertFalse(Boolean.parseBoolean(metadata.getCustomKeys().get(booleanKey)));
    assertEquals(updatedDoubleValue, Double.parseDouble(metadata.getCustomKeys().get(doubleKey)), DELTA);
    assertEquals(updatedFloatValue, Float.parseFloat(metadata.getCustomKeys().get(floatKey)), DELTA);
    assertEquals(updatedLongValue, Long.parseLong(metadata.getCustomKeys().get(longKey)), DELTA);
    assertEquals(updatedIntValue, Integer.parseInt(metadata.getCustomKeys().get(intKey)), DELTA);
    assertEquals("", metadata.getCustomKeys().get(longId));
}
Also used : HashMap(java.util.HashMap) UserMetadata(com.google.firebase.crashlytics.internal.metadata.UserMetadata) Mockito.anyString(org.mockito.Mockito.anyString)

Example 5 with UserMetadata

use of com.google.firebase.crashlytics.internal.metadata.UserMetadata in project firebase-android-sdk by firebase.

the class CrashlyticsCoreTest method testCustomAttributes.

public void testCustomAttributes() throws Exception {
    UserMetadata metadata = crashlyticsCore.getController().getUserMetadata();
    assertNull(metadata.getUserId());
    assertTrue(metadata.getCustomKeys().isEmpty());
    final String id = "id012345";
    crashlyticsCore.setUserId(id);
    assertEquals(id, metadata.getUserId());
    final StringBuffer idBuffer = new StringBuffer(id);
    while (idBuffer.length() < UserMetadata.MAX_ATTRIBUTE_SIZE) {
        idBuffer.append("0");
    }
    final String longId = idBuffer.toString();
    final String superLongId = longId + "more chars";
    crashlyticsCore.setUserId(superLongId);
    assertEquals(longId, metadata.getUserId());
    final String key1 = "key1";
    final String value1 = "value1";
    crashlyticsCore.setCustomKey(key1, value1);
    assertEquals(value1, metadata.getCustomKeys().get(key1));
    // Adding an existing key with the same value should return false
    assertFalse(metadata.setCustomKey(key1, value1));
    assertTrue(metadata.setCustomKey(key1, "someOtherValue"));
    assertTrue(metadata.setCustomKey(key1, value1));
    assertFalse(metadata.setCustomKey(key1, value1));
    final String longValue = longId.replaceAll("0", "x");
    final String superLongValue = longValue + "some more chars";
    // test truncation of custom keys and attributes
    crashlyticsCore.setCustomKey(superLongId, superLongValue);
    assertNull(metadata.getCustomKeys().get(superLongId));
    assertEquals(longValue, metadata.getCustomKeys().get(longId));
    // test the max number of attributes. We've already set 2.
    for (int i = 2; i < UserMetadata.MAX_ATTRIBUTES; ++i) {
        final String key = "key" + i;
        final String value = "value" + i;
        crashlyticsCore.setCustomKey(key, value);
        assertEquals(value, metadata.getCustomKeys().get(key));
    }
    // should be full now, extra key, value pairs will be dropped.
    final String key = "new key";
    crashlyticsCore.setCustomKey(key, "some value");
    assertFalse(metadata.getCustomKeys().containsKey(key));
    // should be able to update existing keys
    crashlyticsCore.setCustomKey(key1, longValue);
    assertEquals(longValue, metadata.getCustomKeys().get(key1));
    // when we set a key to null, it should still exist with an empty value
    crashlyticsCore.setCustomKey(key1, null);
    assertEquals("", metadata.getCustomKeys().get(key1));
    // keys and values are trimmed.
    crashlyticsCore.setCustomKey(" " + key1 + " ", " " + longValue + " ");
    assertTrue(metadata.getCustomKeys().containsKey(key1));
    assertEquals(longValue, metadata.getCustomKeys().get(key1));
}
Also used : UserMetadata(com.google.firebase.crashlytics.internal.metadata.UserMetadata) Mockito.anyString(org.mockito.Mockito.anyString)

Aggregations

UserMetadata (com.google.firebase.crashlytics.internal.metadata.UserMetadata)5 LogFileManager (com.google.firebase.crashlytics.internal.metadata.LogFileManager)3 MiddleOutFallbackStrategy (com.google.firebase.crashlytics.internal.stacktrace.MiddleOutFallbackStrategy)2 RemoveRepeatsStrategy (com.google.firebase.crashlytics.internal.stacktrace.RemoveRepeatsStrategy)2 StackTraceTrimmingStrategy (com.google.firebase.crashlytics.internal.stacktrace.StackTraceTrimmingStrategy)2 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 Mockito.anyString (org.mockito.Mockito.anyString)2 ActivityManager (android.app.ActivityManager)1 ApplicationExitInfo (android.app.ApplicationExitInfo)1 HashMap (java.util.HashMap)1