internal Userflow(string name, int value) : this() { this.name = StringUtils.TruncateString(name, MAX_NAME_LENGTH); // timeout in milliseconds (Applying "userflow specific configuration" // can only be done after we know "name" of this userflow.) timeout = ClampTimeout(Int32.MaxValue); if (value == NULL_VALUE) { value = DefaultValue(); } this.value = value; UserflowReporter.Save(this); }
internal Userflow(string name, long beginTime, long endTime) : this(name, 0) { //////////////////////////////////////////////////////////////// // Input: // name = userflow name // beginTime = userflow begin time in ticks // endTime = userflow end time in ticks // NOTE: Automatic userflows ("App Load", "App Foreground", "App Background") //////////////////////////////////////////////////////////////// state = UserflowState.ENDED; SetBeginTime(beginTime); SetEndTime(endTime); eyeTime = endTime - beginTime; SetForegroundTime(beginTime); // This "Save" needs to occur after the "state" assigned above is known. Debug.WriteLine("Reporting '" + name + "' == " + (eyeTime / (double)TimeUtils.TICKS_PER_SEC) + " seconds"); UserflowReporter.Save(this); }
private void SetState(UserflowState newState, long nowTime) { // Establishes newState for userflow at nowTime . state = newState; isForegrounded = UserflowReporter.isForegrounded; switch (state) { case UserflowState.CANCELLED: SetEndTime(nowTime); RemoveTimer(); break; case UserflowState.BEGUN: SetBeginTime(nowTime); if (isForegrounded) { SetForegroundTime(nowTime); CreateTimer(); } break; default: // Final state SetEndTime(nowTime); RemoveTimer(); if (isForegrounded) { // Entering final state is effectively closing early ahead of // the time when app may be backgrounded later. The persisted // record gets the correct additional "eye time". eyeTime += nowTime - foregroundTime; isForegrounded = false; } if (newState == UserflowState.TIMEOUT) { Crittercism.OnUserflowTimeOut(new CRUserflowEventArgs(name)); } break; } UserflowReporter.Save(this); }