private boolean updatePopUpLocation()

in admob/src_java/com/google/firebase/admob/internal/cpp/NativeExpressAdViewHelper.java [410:539]


  private boolean updatePopUpLocation(final long callbackDataPtr) {
    if (mActivity == null) {
      return false;
    }
    final View view = mActivity.findViewById(android.R.id.content);
    if (view == null) {
      return false;
    }

    // If mActivity's content view doesn't have a window token, it will be
    // impossible to update or display the popup later in this method. This is
    // a rare case caused by mActivity spinning up or winding down, but it will
    // cause the WindowManager to crash.
    final View root = view.getRootView();
    if (root == null || root.getWindowToken() == null) {
      return false;
    }

    synchronized (mPopUpLock) {
      if (mPopUp != null) {
        mActivity.runOnUiThread(new Runnable() {
          @Override
          public void run() {
            synchronized (mPopUpLock) {
              // Any change in visibility or position results in the dismissal of the popup (if
              // one is being displayed) and creation of a fresh one.
              mPopUp.dismiss();
              mPopUp = null;
            }
          }
        });
      }

      mPopUpShowRetryCount = 0;
      mPopUpRunnable = new Runnable() {
        @Override
        public void run() {
          int errorCode = ConstantsHelper.CALLBACK_ERROR_NONE;
          String errorMessage = ConstantsHelper.CALLBACK_ERROR_MESSAGE_NONE;
          // If the Activity's window doesn't currently have focus it's not
          // possible to display the popup window. Poll the focus after a delay of 10ms and try
          // to show the popup again.
          if (!mActivity.hasWindowFocus()) {
            synchronized (mPopUpLock) {
              if (mPopUpRunnable == null) {
                errorCode = ConstantsHelper.CALLBACK_ERROR_UNINITIALIZED;
                errorMessage = ConstantsHelper.CALLBACK_ERROR_MESSAGE_UNINITIALIZED;
              } else {
                if (mPopUpShowRetryCount < POPUP_SHOW_RETRY_COUNT) {
                  mPopUpShowRetryCount++;
                  new Handler().postDelayed(mPopUpRunnable, 10);
                  return;
                } else {
                  errorCode = ConstantsHelper.CALLBACK_ERROR_NO_WINDOW_TOKEN;
                  errorMessage = ConstantsHelper.CALLBACK_ERROR_MESSAGE_NO_WINDOW_TOKEN;
                }
              }
            }
          }

          if (mNativeExpressAdView == null) {
            errorCode = ConstantsHelper.CALLBACK_ERROR_UNINITIALIZED;
            errorMessage = ConstantsHelper.CALLBACK_ERROR_MESSAGE_UNINITIALIZED;
          }

          if (errorCode != ConstantsHelper.CALLBACK_ERROR_NONE) {
            completeNativeExpressAdViewFutureCallback(callbackDataPtr, errorCode, errorMessage);
            return;
          }

          if (mPopUp == null) {
            mPopUp = new PopupWindow(
                mNativeExpressAdView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            mPopUp.setBackgroundDrawable(new ColorDrawable(0xFF000000)); // Black
            mNativeExpressAdView.getViewTreeObserver().addOnPreDrawListener(
                NativeExpressAdViewHelper.this);

            if (mShouldUseXYForPosition) {
              mPopUp.showAtLocation(root, Gravity.NO_GRAVITY, mDesiredX, mDesiredY);
            } else {
              switch (mDesiredPosition) {
                case ConstantsHelper.AD_VIEW_POSITION_TOP:
                  mPopUp.showAtLocation(root, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
                  break;
                case ConstantsHelper.AD_VIEW_POSITION_BOTTOM:
                  mPopUp.showAtLocation(root, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
                  break;
                case ConstantsHelper.AD_VIEW_POSITION_TOP_LEFT:
                  mPopUp.showAtLocation(root, Gravity.TOP | Gravity.LEFT, 0, 0);
                  break;
                case ConstantsHelper.AD_VIEW_POSITION_TOP_RIGHT:
                  mPopUp.showAtLocation(root, Gravity.TOP | Gravity.RIGHT, 0, 0);
                  break;
                case ConstantsHelper.AD_VIEW_POSITION_BOTTOM_LEFT:
                  mPopUp.showAtLocation(root, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
                  break;
                case ConstantsHelper.AD_VIEW_POSITION_BOTTOM_RIGHT:
                  mPopUp.showAtLocation(root, Gravity.BOTTOM | Gravity.RIGHT, 0, 0);
                  break;
                default:
                  mPopUp.showAtLocation(root, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
                  break;
              }
            }
          }

          if (errorCode == ConstantsHelper.CALLBACK_ERROR_NO_WINDOW_TOKEN) {
            mCurrentPresentationState = ConstantsHelper.AD_VIEW_PRESENTATION_STATE_HIDDEN;
          } else if (mNativeExpressAdViewContainsAd) {
            mCurrentPresentationState = ConstantsHelper.AD_VIEW_PRESENTATION_STATE_VISIBLE_WITH_AD;
          } else {
            mCurrentPresentationState =
                ConstantsHelper.AD_VIEW_PRESENTATION_STATE_VISIBLE_WITHOUT_AD;
          }

          completeNativeExpressAdViewFutureCallback(callbackDataPtr, errorCode, errorMessage);
          notifyStateChanged(
              mNativeExpressAdViewInternalPtr, ConstantsHelper.AD_VIEW_CHANGED_PRESENTATION_STATE);
          mNotifyListenerOnNextDraw.set(true);
        }
      };
    }

    // TODO(b/31391149): This delay is a workaround for b/31391149, and should be removed once
    // that bug is resolved.
    Handler mainHandler = new Handler(Looper.getMainLooper());
    mainHandler.postDelayed(mPopUpRunnable, WEBVIEW_DELAY_MILLISECONDS);

    return true;
  }