dvRecordConsentChoice function

Future<bool> dvRecordConsentChoice(
  1. DVConsent consent,
  2. Map<DVConsentCategory, bool> answers, {
  3. required DVConsentPrompt prompt,
})

Records answers as a choice made through prompt, and returns whether everything that was answered was written.

Where DVAppTrackingTransparency.applies, a tracking category the person said yes to is granted only if the system prompt allows it, and recorded as answered through that prompt; if the prompt could not be shown nothing is recorded for it and it stays at its default. A tracking category the person said no to is recorded as no without asking the system anything.

Implementation

Future<bool> dvRecordConsentChoice(
  DVConsent consent,
  Map<DVConsentCategory, bool> answers, {
  required DVConsentPrompt prompt,
}) async {
  final bool throughSystem = DVAppTrackingTransparency.applies();
  final Map<DVConsentCategory, bool> direct = <DVConsentCategory, bool>{};
  final Set<DVConsentCategory> trackingWanted = <DVConsentCategory>{};
  for (final MapEntry<DVConsentCategory, bool> answer in answers.entries) {
    final DVConsentDeclaration? declared =
        consent.policy.declaration(answer.key);
    if (declared == null || declared.required) continue;
    if (declared.tracking && throughSystem && answer.value) {
      trackingWanted.add(answer.key);
    } else {
      direct[answer.key] = answer.value;
    }
  }

  bool saved = true;
  if (direct.isNotEmpty) {
    saved = await consent.record(direct,
        asked: direct.keys.toSet(), prompt: prompt);
    // A grant that was not written is not consent, and asking the system
    // for tracking on top of a choice that did not save would record half
    // of it.
    if (!saved) return false;
  }
  if (trackingWanted.isEmpty) return saved;

  final DVTrackingAuthorization status =
      await DVAppTrackingTransparency.request();
  final bool? allowed = switch (status) {
    DVTrackingAuthorization.authorized => true,
    DVTrackingAuthorization.denied || DVTrackingAuthorization.restricted =>
      false,
    DVTrackingAuthorization.notDetermined ||
    DVTrackingAuthorization.unavailable =>
      null,
  };
  if (allowed == null) return saved;
  return consent.record(
    <DVConsentCategory, bool>{
      for (final DVConsentCategory c in trackingWanted) c: allowed,
    },
    asked: trackingWanted,
    prompt: DVConsentPrompt.appTrackingTransparency,
  );
}