Ejemplo n.º 1
0
  /**
   * Execute the task.
   *
   * @return true if it works, false otherwise.
   */
  @Override
  public Boolean call() {
    final long start = System.nanoTime();
    CompletionStatus result = CompletionStatus.FAILED;
    try {
      Log.d(LOG_TAG, "Download Task started for download id = " + downloadId);
      failureMessage = MSG_OKAY;
      downloadErrorCode = DownloadError.NO_ERROR.getValue();

      if (!ensureFolderExists(destination)) {
        finish(
            CompletionStatus.FAILED,
            failureMessage,
            cumulativeBytesRead,
            totalBytes,
            autoRestart,
            downloadErrorCode);
        return false;
      }

      if (null != downloadTag && 0L < downloadOffset) {
        if (!ensurePartialFilePresent(destination, downloadOffset)) {
          // if we don't have the partial file any more, we have to start again
          downloadOffset = 0L;
        }
      }

      result = readFromUri(destination);
      finish(
          result, failureMessage, cumulativeBytesRead, totalBytes, autoRestart, downloadErrorCode);
      return CompletionStatus.SUCCEEDED == result;
    } finally {
      // Make sure we release wifi lock (if any)
      networkStatusProvider.releaseWifiLock(downloadId);

      final long duration = System.nanoTime() - start;

      Log.d(
          LOG_TAG,
          String.format(
              "Download result(%s) for download task with uri(%s) took %.3f seconds.",
              result.name(), uri, (double) duration / 1000000000));
    }
  }
    /** Poller main loop */
    @Override
    public void run() {
      for (; ; ) {
        CompletionStatus info;
        try {
          info = GetQueuedCompletionStatus(port);
        } catch (WindowsException x) {
          // this should not happen
          x.printStackTrace();
          return;
        }

        // wakeup
        if (info.completionKey() == WAKEUP_COMPLETION_KEY) {
          boolean shutdown = processRequests();
          if (shutdown) {
            return;
          }
          continue;
        }

        // map completionKey to get WatchKey
        WindowsWatchKey key = ck2key.get((int) info.completionKey());
        if (key == null) {
          // We get here when a registration is changed. In that case
          // the directory is closed which causes an event with the
          // old completion key.
          continue;
        }

        boolean criticalError = false;
        int errorCode = info.error();
        int messageSize = info.bytesTransferred();
        if (errorCode == ERROR_NOTIFY_ENUM_DIR) {
          // buffer overflow
          key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
        } else if (errorCode != 0 && errorCode != ERROR_MORE_DATA) {
          // ReadDirectoryChangesW failed
          criticalError = true;
        } else {
          // ERROR_MORE_DATA is a warning about incomplete
          // data transfer over TCP/UDP stack. For the case
          // [messageSize] is zero in the most of cases.

          if (messageSize > 0) {
            // process non-empty events.
            processEvents(key, messageSize);
          } else if (errorCode == 0) {
            // insufficient buffer size
            // not described, but can happen.
            key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
          }

          // start read for next batch of changes
          try {
            ReadDirectoryChangesW(
                key.handle(),
                key.buffer().address(),
                CHANGES_BUFFER_SIZE,
                key.watchSubtree(),
                ALL_FILE_NOTIFY_EVENTS,
                key.countAddress(),
                key.overlappedAddress());
          } catch (WindowsException x) {
            // no choice but to cancel key
            criticalError = true;
          }
        }
        if (criticalError) {
          implCancelKey(key);
          key.signal();
        }
      }
    }