Skip to content

Commit

Permalink
Merge pull request #218 from bugsnag/session-tracking-amends
Browse files Browse the repository at this point in the history
Session tracking amends
  • Loading branch information
fractalwrench authored Jan 9, 2018
2 parents a4e8316 + acf41b0 commit 74bf0d6
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 31 deletions.
47 changes: 23 additions & 24 deletions sdk/src/main/java/com/bugsnag/android/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class Client extends Observable implements Observer {
private final long launchTimeMs;

private final EventReceiver eventReceiver = new EventReceiver();
private final SessionTracker sessionTracker;
final SessionTracker sessionTracker;
private ErrorReportApiClient errorReportApiClient;
private SessionTrackingApiClient sessionTrackingApiClient;
private final Handler handler;
Expand Down Expand Up @@ -141,10 +141,30 @@ public Client(@NonNull Context androidContext, @NonNull Configuration configurat

sessionTracker = new SessionTracker(configuration, this, sessionStore, sessionTrackingApiClient, appContext);

if (configuration.shouldAutoCaptureSessions()) { // create initial session
sessionTracker.startNewSession(new Date(), null, true);
// Set up and collect constant app and device diagnostics
SharedPreferences sharedPref = appContext.getSharedPreferences(SHARED_PREF_KEY, Context.MODE_PRIVATE);

appData = new AppData(appContext, config, sessionTracker);
deviceData = new DeviceData(appContext, sharedPref);

// Set up breadcrumbs
breadcrumbs = new Breadcrumbs();

// Set sensible defaults
setProjectPackages(appContext.getPackageName());

if (config.getPersistUserBetweenSessions()) {
// Check to see if a user was stored in the SharedPreferences
user.setId(sharedPref.getString(USER_ID_KEY, deviceData.getUserId()));
user.setName(sharedPref.getString(USER_NAME_KEY, null));
user.setEmail(sharedPref.getString(USER_EMAIL_KEY, null));
} else {
user.setId(deviceData.getUserId());
}

// create initial session
sessionTracker.startNewSession(new Date(), user, true);

if (appContext instanceof Application) {
Application application = (Application) appContext;
application.registerActivityLifecycleCallbacks(sessionTracker);
Expand All @@ -169,27 +189,6 @@ public Client(@NonNull Context androidContext, @NonNull Configuration configurat
}
}

// Set up and collect constant app and device diagnostics
SharedPreferences sharedPref = appContext.getSharedPreferences(SHARED_PREF_KEY, Context.MODE_PRIVATE);

appData = new AppData(appContext, config, sessionTracker);
deviceData = new DeviceData(appContext, sharedPref);

// Set up breadcrumbs
breadcrumbs = new Breadcrumbs();

// Set sensible defaults
setProjectPackages(appContext.getPackageName());

if (config.getPersistUserBetweenSessions()) {
// Check to see if a user was stored in the SharedPreferences
user.setId(sharedPref.getString(USER_ID_KEY, deviceData.getUserId()));
user.setName(sharedPref.getString(USER_NAME_KEY, null));
user.setEmail(sharedPref.getString(USER_EMAIL_KEY, null));
} else {
user.setId(deviceData.getUserId());
}

// Create the error store that is used in the exception handler
errorStore = new ErrorStore(config, appContext);

Expand Down
9 changes: 9 additions & 0 deletions sdk/src/main/java/com/bugsnag/android/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,15 @@ public boolean shouldAutoCaptureSessions() {
*/
public void setAutoCaptureSessions(boolean autoCapture) {
this.autoCaptureSessions = autoCapture;

if (autoCapture) { // track any existing sessions
Client client = Bugsnag.getClient();

//noinspection ConstantConditions
if (client != null && client.sessionTracker != null) {
client.sessionTracker.onAutoCaptureEnabled();
}
}
}

/**
Expand Down
54 changes: 47 additions & 7 deletions sdk/src/main/java/com/bugsnag/android/SessionTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class SessionTracker implements Application.ActivityLifecycleCallbacks {
private long lastForegroundMs;
private Long sessionStartMs;
private Session currentSession;
private boolean trackedFirstSession = false;

SessionTracker(Configuration configuration, Client client, SessionStore sessionStore,
SessionTrackingApiClient apiClient, Context context) {
Expand Down Expand Up @@ -68,18 +69,57 @@ class SessionTracker implements Application.ActivityLifecycleCallbacks {
*/
void startNewSession(@NonNull Date date, @Nullable User user, boolean autoCaptured) {
synchronized (sessionStore) {
sessionStartMs = date.getTime();
currentSession = generateSession(date, user, autoCaptured);
trackSessionIfNeeded(autoCaptured, currentSession);
}
}

@NonNull
private Session generateSession(@NonNull Date date, @Nullable User user, boolean autoCaptured) {
sessionStartMs = date.getTime();
Session session = new Session(UUID.randomUUID().toString(), date, user);
session.setAutoCaptured(autoCaptured);
return session;
}

Session session = new Session(UUID.randomUUID().toString(), date, user);
session.setAutoCaptured(autoCaptured);
/**
* Determines whether or not a session should be tracked. If this is true, the session will be
* stored and sent to the Bugsnag API, otherwise no action will occur in this method.
*
* @param autoCaptured whether the session was automatically captured by the SDK or not
* @param session the session
*/
private void trackSessionIfNeeded(boolean autoCaptured, Session session) {
String releaseStage = getReleaseStage();
boolean notifyForRelease = configuration.shouldNotifyForReleaseStage(releaseStage);

if ((configuration.shouldAutoCaptureSessions() || !autoCaptured) && notifyForRelease) {
sessionQueue.add(session);
sessionStore.write(session); // store session for sending
trackedFirstSession = true;
}
}

if (configuration.shouldAutoCaptureSessions() || !autoCaptured) {
sessionQueue.add(session);
sessionStore.write(session); // store session for sending
/**
* Track a new session when auto capture is enabled via config after initialisation.
*/
void onAutoCaptureEnabled() {
synchronized (sessionStore) {
if (!trackedFirstSession) {
if (currentSession == null) { // unlikely case, will be initialised later
return;
}
trackSessionIfNeeded(currentSession.isAutoCaptured(), currentSession);
}
currentSession = session;
}
}

private String getReleaseStage() {
if (configuration.getReleaseStage() != null) {
return configuration.getReleaseStage();
} else {
return AppDataSummary.guessReleaseStage(context);
}
}

@Nullable
Expand Down

0 comments on commit 74bf0d6

Please sign in to comment.