code: public Result tick() {
      if (System.currentTimeMillis() >= mLastEventHorizonMs) {
        return Result.EXPIRED;
      }
      if (System.currentTimeMillis() < mNextEventMs) {
        return Result.NOT_READY;
      }
      mNextEventMs = System.currentTimeMillis() + mIntervalMs;
      long next = Math.min(mIntervalMs * 2, mMaxIntervalMs);
      // Account for overflow.
      if (next < mIntervalMs) {
        next = Integer.MAX_VALUE;
      }
      mIntervalMs = next;
      mNumEvents++;
      return Result.READY;
    }
docs: Attempts to perform a timer tick. One of three scenarios can be encountered:
  
  1. the timer has expired
  2. the next event is not ready
  3. the next event is generated
  
  The last option has the side-effect of updating the internal state of the timer to reflect
  the generation of the event.
  
  @return the {@link Result} that indicates which scenario was encountered