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);
        }