Repository: 4ian/GDevelop
File: Extensions/AdMob/admobtools.ts (TypeScript)

Code before:
    let rewardedVideoLoading = false; // Becomes true when the video is loading.
    let rewardedVideoReady = false; // Becomes true when the video is loaded and ready to be shown.
    let rewardedVideoShowing = false; // Becomes true when the video is showing.
    let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.
    let rewardedVideoErrored = false; // Becomes true when the video fails to load.

    let npaValue = '0'; // 0 means that the user has consented to personalized ads, 1 means that the user has not consented to personalized ads.

    // Admob initialization listener
    document.addEventListener(
      'deviceready',
      async () => {
        logger.info('Starting AdMob.');
        isStarting = true;

        if (cordova.platformId === 'ios') {
          /*
            trackingStatus:
            0 = notDetermined
            1 = restricted
            2 = denied
            3 = authorized
          */
          let trackingStatus = await consent.trackingAuthorizationStatus();

          // If tracking is not determined, we ask the user for tracking authorization.
          if (trackingStatus === 0) {
            trackingStatus = await consent.requestTrackingAuthorization();
          }

          // If tracking is restricted or denied, we set npaValue to 1.
          if (trackingStatus === 1 || trackingStatus === 2) {
            npaValue = '1';
          }

          // otherwise, we set npaValue to 0.
          npaValue = '0';
        }

        const consentStatus = await consent.getConsentStatus();
        if (consentStatus === consent.ConsentStatus.Required) {
          await consent.requestInfoUpdate();
        }

        await consent.loadAndShowIfRequired();

        if (await consent.canRequestAds()) {
          await admob.start();

          logger.info('AdMob successfully started.');
          isStarting = false;

Review comment (security):
I wonder if it's a good idea to delay this by 2 seconds, and offer:
- an action to cancel automatic consent dialog/tracking authorization display.
- an action to do it manually.

So that if I want to postpone this (because it's better if my player plays a bit or click a button in the menu, so I have the opportunity to tell them "we'll ask for your consent, please say yes!"), I can do by:
-  using the first action at launch of my game
- using the second action whenever I want.

Code after:
    let rewardedVideoLoading = false; // Becomes true when the video is loading.
    let rewardedVideoReady = false; // Becomes true when the video is loaded and ready to be shown.
    let rewardedVideoShowing = false; // Becomes true when the video is showing.
    let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.
    let rewardedVideoErrored = false; // Becomes true when the video fails to load.

    let npaValue = '0'; // 0 means that the user has consented to personalized ads, 1 means that the user has not consented to personalized ads.

    let setupTimeoutId: NodeJS.Timeout | null = null;

    const askForConsentAndInitializeAdmob = async () => {
      if (admobStarted) {
        logger.warn('AdMob is already started.');
        return;
      }

      if (isStarting) {
        logger.warn('AdMob is already starting.');
        return;
      }

      try {
        logger.info('Starting AdMob.');
        isStarting = true;

        if (cordova.platformId === 'ios') {
          try {
            /*
            trackingStatus:
            0 = notDetermined
            1 = restricted
            2 = denied
            3 = authorized
          */
            let trackingStatus = await consent.trackingAuthorizationStatus();

            // If tracking is not determined, we ask the user for tracking authorization.
            if (trackingStatus === 0) {
              trackingStatus = await consent.requestTrackingAuthorization();
            }

            // If tracking is restricted or denied, we set npaValue to 1.
            if (trackingStatus === 1 || trackingStatus === 2) {
              npaValue = '1';
            }

            // otherwise, we set npaValue to 0.
            npaValue = '0';
          } catch (error) {
            logger.error(
              'Error while asking for tracking authorization, continuing:',