コード例 #1
0
  @Override
  // @FIXME: This run method needs to be refactored as the current logic of polling is bit too
  // complex and can be made much more simpler.
  public void run() {
    try {
      if (sLogger.isActivated()) {
        sLogger.debug("Start polling of the IMS connection");
      }

      long servicePollingPeriod = mRcsSettings.getImsServicePollingPeriod();
      long regBaseTime = mRcsSettings.getRegisterRetryBaseTime();
      long regMaxTime = mRcsSettings.getRegisterRetryMaxTime();
      Random random = new Random();
      int nbFailures = 0;

      while (mImsPollingThreadId == Thread.currentThread().getId()) {
        if (sLogger.isActivated()) {
          sLogger.debug("Polling: check IMS connection");
        }

        // Connection management
        try {
          // Test IMS registration
          if (!mCurrentNetworkInterface.isRegistered()) {
            if (sLogger.isActivated()) {
              sLogger.debug("Not yet registered to IMS: try registration");
            }

            // Try to register to IMS
            mCurrentNetworkInterface.register(mDnsResolvedFields);

            // InterruptedException thrown by stopImsConnection() may be caught by one
            // of the methods used in currentNetworkInterface.register() above
            if (mImsPollingThreadId != Thread.currentThread().getId()) {
              if (sLogger.isActivated()) {
                sLogger.debug("IMS connection polling thread race condition");
              }
              break;
            }

            if (mImsModule.isInitializationFinished() && !mImsServicesStarted) {
              if (sLogger.isActivated()) {
                sLogger.debug("Registered to the IMS with success: start IMS services");
              }
              mImsModule.startImsServices();
              mImsServicesStarted = true;
            }

            // Reset number of failures
            nbFailures = 0;
          } else {
            if (mImsModule.isInitializationFinished()) {
              if (!mImsServicesStarted) {
                if (sLogger.isActivated()) {
                  sLogger.debug("Already registered to IMS: start IMS services");
                }
                mImsModule.startImsServices();
                mImsServicesStarted = true;
              } else {
                if (sLogger.isActivated()) {
                  sLogger.debug("Already registered to IMS: check IMS services");
                }
                mImsModule.checkImsServices();
              }
            } else {
              if (sLogger.isActivated()) {
                sLogger.debug("Already registered to IMS: IMS services not yet started");
              }
            }
          }
        } catch (ContactManagerException e) {
          sLogger.error("Can't register to the IMS!", e);
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        } catch (PayloadException e) {
          sLogger.error("Can't register to the IMS!", e);
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        } catch (NetworkException e) {
          if (sLogger.isActivated()) {
            sLogger.debug(e.getMessage());
          }
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        }

        // InterruptedException thrown by stopImsConnection() may be caught by one
        // of the methods used in currentNetworkInterface.register() above
        if (mImsPollingThreadId != Thread.currentThread().getId()) {
          sLogger.debug("IMS connection polling thread race condition");
          break;
        }

        // Make a pause before the next polling
        try {
          if (!mCurrentNetworkInterface.isRegistered()) {
            final long retryAfterHeaderDuration =
                mCurrentNetworkInterface.getRetryAfterHeaderDuration();
            if (retryAfterHeaderDuration > 0) {
              Thread.sleep(retryAfterHeaderDuration);
            } else {
              // Pause before the next register attempt
              double w = Math.min(regMaxTime, (regBaseTime * Math.pow(2, nbFailures)));
              double coeff = (random.nextInt(51) + 50) / 100.0; // Coeff between 50%
              // and
              // 100%
              long retryPeriod = (long) (coeff * w);
              if (sLogger.isActivated()) {
                sLogger.debug(
                    new StringBuilder("Wait ")
                        .append(retryPeriod)
                        .append("ms before retry registration (failures=")
                        .append(nbFailures)
                        .append(", coeff=")
                        .append(coeff)
                        .append(')')
                        .toString());
              }
              Thread.sleep(retryPeriod);
            }
          } else if (!mImsServicesStarted) {
            if (sLogger.isActivated()) {
              sLogger.debug(
                  new StringBuilder("Wait ")
                      .append(DEFAULT_RETRY_PERIOD)
                      .append("ms before retry to start services")
                      .toString());
            }
            Thread.sleep(DEFAULT_RETRY_PERIOD);
          } else {
            // Pause before the next service check
            Thread.sleep(servicePollingPeriod);
          }
        } catch (InterruptedException e) {
          if (sLogger.isActivated()) {
            sLogger.warn("IMS connection polling is interrupted", e);
          }
          break;
        }
      }
      if (sLogger.isActivated()) {
        sLogger.debug("IMS connection polling is terminated");
      }
    } catch (RuntimeException e) {
      /*
       * Normally we are not allowed to catch runtime exceptions as these are genuine bugs
       * which should be handled/fixed within the code. However the cases when we are
       * executing operations on a thread unhandling such exceptions will eventually lead to
       * exit the system and thus can bring the whole system down, which is not intended.
       */
      sLogger.error("Failed to poll for ims connection!", e);
    }
  }