idleFromTicks static method

  1. @visibleForTesting
int idleFromTicks({
  1. required bool succeeded,
  2. required int tickCount64,
  3. required int lastInputTick,
})

The Idle duration implied by one reading of the two clocks, including what to report when the OS call did not succeed.

Everything that can be decided without touching the OS lives here, so it can be tested on any host — the same split as InactivityPolicy and the shell. What is left in idleMilliseconds is plumbing with no decisions in it.

When succeeded is false the answer is zero — the user is treated as active. The retired C++ made that choice and it must be preserved: the shell catches exceptions from a read as transient faults and retries, so throwing on a persistently failing API would stall monitoring instead of degrading it, and reporting a large idle span would log the user out for an API failure.

Otherwise this is the wraparound-safe subtraction. GetLastInputInfo reports the last input as a 32-bit tick that wraps roughly every 49.7 days, while GetTickCount64 does not wrap in any practical timeframe. Subtracting them as they come would, after a wrap, report an idle span of about 49.7 days and fire the timeout on an actively used machine. Truncating the current tick to the same 32 bits and subtracting modulo 2^32 is correct for any real span, because a real span is far shorter than one lap. Dart has no 32-bit unsigned type, so the mask states that wrapping explicitly; on a two's-complement 64-bit int it also turns the negative difference a wrap produces back into the intended positive one. See ADR-0001 — this is the arithmetic that motivated computing the idle duration on the side of the boundary where it is naturally correct.

Implementation

@visibleForTesting
static int idleFromTicks({
  required bool succeeded,
  required int tickCount64,
  required int lastInputTick,
}) =>
    succeeded ? (tickCount64 - lastInputTick) & _tick32Mask : 0;