Detection results
Every check returns a CheckResult with a status and the signals
that fired.
Status
Section titled “Status”CheckStatus |
Meaning |
|---|---|
detected |
Enough evidence fired. See the rule below |
clear |
The check ran and found too little. signals may still list weak ones |
notApplicable |
The check doesn’t exist here: root on iOS, jailbreak on Android or the iOS Simulator |
failed |
The check couldn’t run (timeout, platform error, unsupported platform). error says why |
The detection rule
Section titled “The detection rule”Each signal has a strength:
| Strength | Meaning | Counts towards detected |
|---|---|---|
| Strong | Rarely seen on unmodified devices | One is enough |
| Medium | Suggestive | Two are needed |
| Weak | Common on legitimate devices: custom ROMs, emulators, debug builds | Never, on its own or together |
So a check is detected when at least one strong signal fires, or at least two medium ones.
This avoids the most common false positives:
- A stock emulator isn’t reported as rooted. Emulator system properties fire only weak root signals.
- A debug build isn’t reported as being debugged.
debuggable_flagis weak. - An installed fake-GPS app alone isn’t a mocked location.
fake_gps_app_installedis weak.
The strength of every signal is on the Signals
page. If your threat model is stricter, look at signals yourself: every
fired signal is listed, including weak ones.
final root = await DeviceShield.checkRoot();final anyEvidence = root.signals.isNotEmpty; // stricter than root.detectedMock location
Section titled “Mock location”checkMockLocation() returns a MockLocationResult, which also says
whether the check could see a location:
final result = await DeviceShield.checkMockLocation();if (!result.locationPermissionGranted) { // Only the non-location signals could run.}