Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ public void testListSortedOpenSessionIds_noOpenSessions() {
assertTrue(openSessionIds.isEmpty());
}

@Test
public void testPersistReports_getStartTimestampMillis() {
final String sessionId = "testSession";
final CrashlyticsReport testReport = makeTestReport(sessionId);

reportPersistence.persistReport(testReport);
assertEquals(
testReport.getSession().getStartedAt() * 1000,
reportPersistence.getStartTimestampMillis(sessionId));
}

@Test
public void testHasFinalizedReports() {
final String sessionId = "testSession";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -168,14 +167,14 @@ synchronized void handleUncaughtException(

// Capture the time that the crash occurs and close over it so that the time doesn't
// reflect when we get around to executing the task later.
final Date time = new Date();
final long timestampMillis = System.currentTimeMillis();

final Task<Void> handleUncaughtExceptionTask =
backgroundWorker.submitTask(
new Callable<Task<Void>>() {
@Override
public Task<Void> call() throws Exception {
final long timestampSeconds = getTimestampSeconds(time);
final long timestampSeconds = getTimestampSeconds(timestampMillis);

final String currentSessionId = getCurrentSessionId();
if (currentSessionId == null) {
Expand All @@ -190,7 +189,7 @@ public Task<Void> call() throws Exception {
reportingCoordinator.persistFatalEvent(
ex, thread, currentSessionId, timestampSeconds);

doWriteAppExceptionMarker(time.getTime());
doWriteAppExceptionMarker(timestampMillis);

doCloseSessions();
doOpenSession();
Expand Down Expand Up @@ -397,14 +396,14 @@ public Void call() throws Exception {
void writeNonFatalException(@NonNull final Thread thread, @NonNull final Throwable ex) {
// Capture and close over the current time, so that we get the exact call time,
// rather than the time at which the task executes.
final Date time = new Date();
final long timestampMillis = System.currentTimeMillis();

backgroundWorker.submit(
new Runnable() {
@Override
public void run() {
if (!isHandlingException()) {
long timestampSeconds = getTimestampSeconds(time);
long timestampSeconds = getTimestampSeconds(timestampMillis);
final String currentSessionId = getCurrentSessionId();
if (currentSessionId == null) {
Logger.getLogger()
Expand Down Expand Up @@ -661,11 +660,11 @@ private void finalizePreviousNativeSession(String previousSessionId) {
}

private static long getCurrentTimestampSeconds() {
return getTimestampSeconds(new Date());
return getTimestampSeconds(System.currentTimeMillis());
}

private static long getTimestampSeconds(Date date) {
return date.getTime() / 1000;
private static long getTimestampSeconds(long timestampMillis) {
return timestampMillis / 1000;
}

// region Serialization to protobuf
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public CrashlyticsReportDataCapture(
this.stackTraceTrimmingStrategy = stackTraceTrimmingStrategy;
}

public CrashlyticsReport captureReportData(String identifier, long timestamp) {
return buildReportData().setSession(populateSessionData(identifier, timestamp)).build();
public CrashlyticsReport captureReportData(String identifier, long timestampSeconds) {
return buildReportData().setSession(populateSessionData(identifier, timestampSeconds)).build();
}

public Event captureEventData(
Expand Down Expand Up @@ -120,9 +120,9 @@ private CrashlyticsReport.Builder buildReportData() {
.setPlatform(REPORT_ANDROID_PLATFORM);
}

private CrashlyticsReport.Session populateSessionData(String identifier, long timestamp) {
private CrashlyticsReport.Session populateSessionData(String identifier, long timestampSeconds) {
return CrashlyticsReport.Session.builder()
.setStartedAt(timestamp)
.setStartedAt(timestampSeconds)
.setIdentifier(identifier)
.setGenerator(GENERATOR)
.setApp(populateSessionApplicationData())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ public static SessionReportingCoordinator create(
}

@Override
public void onBeginSession(@NonNull String sessionId, long timestamp) {
final CrashlyticsReport capturedReport = dataCapture.captureReportData(sessionId, timestamp);
public void onBeginSession(@NonNull String sessionId, long timestampSeconds) {
final CrashlyticsReport capturedReport =
dataCapture.captureReportData(sessionId, timestampSeconds);

reportPersistence.persistReport(capturedReport);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public class CrashlyticsReportPersistence {

private static final String REPORT_FILE_NAME = "report";
private static final String USER_FILE_NAME = "user";
// We use the lastModified timestamp of this file to quickly store and access the startTime in ms
// of a session.
private static final String SESSION_START_TIMESTAMP_FILE_NAME = "start-time";
private static final String EVENT_FILE_NAME_PREFIX = "event";
private static final int EVENT_COUNTER_WIDTH = 10; // String width of maximum positive int value
private static final String EVENT_COUNTER_FORMAT = "%0" + EVENT_COUNTER_WIDTH + "d";
Expand Down Expand Up @@ -110,6 +113,10 @@ public void persistReport(@NonNull CrashlyticsReport report) {
final File sessionDirectory = prepareDirectory(getSessionDirectoryById(sessionId));
final String json = TRANSFORM.reportToJson(report);
writeTextFile(new File(sessionDirectory, REPORT_FILE_NAME), json);
writeTextFile(
new File(sessionDirectory, SESSION_START_TIMESTAMP_FILE_NAME),
"",
session.getStartedAt());
} catch (IOException e) {
Logger.getLogger().d("Could not persist report for session " + sessionId, e);
}
Expand Down Expand Up @@ -177,6 +184,19 @@ public List<String> listSortedOpenSessionIds() {
return openSessionIds;
}

/**
* Gets the startTimestampMs of the given sessionId.
*
* @param sessionId
* @return startTimestampMs
*/
public long getStartTimestampMillis(String sessionId) {
final File sessionDirectory = getSessionDirectoryById(sessionId);
final File sessionStartTimestampFile =
new File(sessionDirectory, SESSION_START_TIMESTAMP_FILE_NAME);
return sessionStartTimestampFile.lastModified();
}

public boolean hasFinalizedReports() {
return !getAllFinalizedReportFiles().isEmpty();
}
Expand Down Expand Up @@ -489,6 +509,14 @@ private static void writeTextFile(File file, String text) throws IOException {
}
}

private static void writeTextFile(File file, String text, long lastModifiedTimestampSeconds)
throws IOException {
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF_8)) {
writer.write(text);
file.setLastModified(convertTimestampFromSecondsToMs(lastModifiedTimestampSeconds));
}
}

@NonNull
private static String readTextFile(@NonNull File file) throws IOException {
final byte[] readBuffer = new byte[8192];
Expand Down Expand Up @@ -532,4 +560,8 @@ private static void recursiveDelete(@Nullable File file) {
}
file.delete();
}

private static long convertTimestampFromSecondsToMs(long timestampSeconds) {
return timestampSeconds * 1000;
}
}