Two issues from review:
* The set of printed state sections was global, so a section printed for
one user decided the flags of another. A user with an installed list and
no enabled section was marked enabled=False and got a LOW "installed, not
enabled" alert. Sections are now tracked per user.
* A count-only record was added only when a user had no named component at
all. A dump stating installedServiceCount=2 and naming one service read
as complete. The count-only record is now added whenever the stated count
exceeds the distinct named components for that user, and carries the
difference in a new unnamed_service_count field. The module summary adds
up that remainder.
Most builds never print the `installed services: {...}` block. They state
installedServiceCount=N in the user's attributes line and list nothing, so the
parser recorded no service at all and MVT logged "Identified a total of 0
accessibility services" — an artifact that says "no accessibility services"
about a dump that said there are five. The dump pasted in #744 is itself an
example: it states installedServiceCount=6 and names none.
Parse the count per user and, for a user whose services the dump did not list,
keep one record carrying it, raised as LOW: a count is a coverage statement,
not a running service.
Name the service state in the alert and split its severity, as asked on #744:
a service the dump states is switched off is LOW, enabled or bound is MEDIUM,
and a dump that does not state the enabled state stays MEDIUM, because "not
stated" is not "not enabled". A state section the dump never printed now reads
None rather than False. IOC matching is unaffected by the state: a disabled
service still returns CRITICAL on a match.
Measured over 163 bug reports carrying an accessibility section: MEDIUM alerts
305 -> 4, LOW 0 -> 407. The four that stay MEDIUM are the only records in the
set with enabled=True.
Fixes#744