示例#1
0
  /**
   * Saves a OC File after a successful upload.
   *
   * <p>A PROPFIND is necessary to keep the props in the local database synchronized with the
   * server, specially the modification time and Etag (where available)
   *
   * <p>TODO refactor this ugly thing
   */
  private void saveUploadedFile() {
    OCFile file = mCurrentUpload.getFile();
    if (file.fileExists()) {
      file = mStorageManager.getFileById(file.getFileId());
    }
    long syncDate = System.currentTimeMillis();
    file.setLastSyncDateForData(syncDate);

    // new PROPFIND to keep data consistent with server
    // in theory, should return the same we already have
    ReadRemoteFileOperation operation = new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
    RemoteOperationResult result = operation.execute(mUploadClient);
    if (result.isSuccess()) {
      updateOCFile(file, (RemoteFile) result.getData().get(0));
      file.setLastSyncDateForProperties(syncDate);
    }

    // / maybe this would be better as part of UploadFileOperation... or
    // maybe all this method
    if (mCurrentUpload.wasRenamed()) {
      OCFile oldFile = mCurrentUpload.getOldFile();
      if (oldFile.fileExists()) {
        oldFile.setStoragePath(null);
        mStorageManager.saveFile(oldFile);
      } // else: it was just an automatic renaming due to a name
      // coincidence; nothing else is needed, the storagePath is right
      // in the instance returned by mCurrentUpload.getFile()
    }

    mStorageManager.saveFile(file);
  }
示例#2
0
  /**
   * Creates a status notification to show the upload progress
   *
   * @param upload Upload operation starting.
   */
  @SuppressWarnings("deprecation")
  private void notifyUploadStart(UploadFileOperation upload) {
    // / create status notification with a progress bar
    mLastPercent = 0;
    mNotification =
        new Notification(
            DisplayUtils.getSeasonalIconId(),
            getString(R.string.uploader_upload_in_progress_ticker),
            System.currentTimeMillis());
    mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
    mDefaultNotificationContentView = mNotification.contentView;
    mNotification.contentView =
        new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
    mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
    mNotification.contentView.setTextViewText(
        R.id.status_text,
        String.format(
            getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
    mNotification.contentView.setImageViewResource(
        R.id.status_icon, DisplayUtils.getSeasonalIconId());

    /// includes a pending intent in the notification showing the details view of the file
    Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
    showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
    showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
    showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    mNotification.contentIntent =
        PendingIntent.getActivity(
            getApplicationContext(), (int) System.currentTimeMillis(), showDetailsIntent, 0);

    mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
  }
示例#3
0
  /**
   * Updates the status notification with the result of an upload operation.
   *
   * @param uploadResult Result of the upload operation.
   * @param upload Finished upload operation
   */
  private void notifyUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
    Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
    if (uploadResult.isCancelled()) {
      // / cancelled operation -> silent removal of progress notification
      mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);

    } else if (uploadResult.isSuccess()) {
      // / success -> silent update of progress notification to success
      // message
      mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove
      // the
      // ongoing
      // flag
      mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
      mNotification.contentView = mDefaultNotificationContentView;

      /// includes a pending intent in the notification showing the details view of the file
      Intent showDetailsIntent = null;
      if (PreviewImageFragment.canBePreviewed(upload.getFile())) {
        showDetailsIntent = new Intent(this, PreviewImageActivity.class);
      } else {
        showDetailsIntent = new Intent(this, FileDisplayActivity.class);
      }
      showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
      showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
      showDetailsIntent.putExtra(FileActivity.EXTRA_FROM_NOTIFICATION, true);
      showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      mNotification.contentIntent =
          PendingIntent.getActivity(
              getApplicationContext(), (int) System.currentTimeMillis(), showDetailsIntent, 0);

      mNotification.setLatestEventInfo(
          getApplicationContext(),
          getString(R.string.uploader_upload_succeeded_ticker),
          String.format(
              getString(R.string.uploader_upload_succeeded_content_single), upload.getFileName()),
          mNotification.contentIntent);

      mNotificationManager.notify(
          R.string.uploader_upload_in_progress_ticker, mNotification); // NOT
      // AN
      DbHandler db = new DbHandler(this.getBaseContext());
      db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
      db.close();

    } else {

      // / fail -> explicit failure notification
      mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
      Notification finalNotification =
          new Notification(
              DisplayUtils.getSeasonalIconId(),
              getString(R.string.uploader_upload_failed_ticker),
              System.currentTimeMillis());
      finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
      String content = null;

      boolean needsToUpdateCredentials =
          (uploadResult.getCode() == ResultCode.UNAUTHORIZED
              ||
              // (uploadResult.isTemporalRedirection() && uploadResult.isIdPRedirection() &&
              (uploadResult.isIdPRedirection() && mUploadClient.getCredentials() == null));
      // MainApp.getAuthTokenTypeSamlSessionCookie().equals(mUploadClient.getAuthTokenType())));
      if (needsToUpdateCredentials) {
        // let the user update credentials with one click
        Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount());
        updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ENFORCED_UPDATE, true);
        updateAccountCredentials.putExtra(
            AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
        updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
        finalNotification.contentIntent =
            PendingIntent.getActivity(
                this,
                (int) System.currentTimeMillis(),
                updateAccountCredentials,
                PendingIntent.FLAG_ONE_SHOT);
        content =
            String.format(
                getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
        finalNotification.setLatestEventInfo(
            getApplicationContext(),
            getString(R.string.uploader_upload_failed_ticker),
            content,
            finalNotification.contentIntent);
        mUploadClient =
            null; // grant that future retries on the same account will get the fresh credentials
      } else {
        // TODO put something smart in the contentIntent below
        //    finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
        // (int)System.currentTimeMillis(), new Intent(), 0);
        // }

        if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL
            || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
          // TODO we need a class to provide error messages for the users
          // from a RemoteOperationResult and a RemoteOperation
          content =
              String.format(
                  getString(R.string.error__upload__local_file_not_copied),
                  upload.getFileName(),
                  getString(R.string.app_name));
        } else if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
          content = getString(R.string.failed_upload_quota_exceeded_text);
        } else {
          content =
              String.format(
                  getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
        }

        // we add only for instant-uploads the InstantUploadActivity and the
        // db entry
        Intent detailUploadIntent = null;
        if (upload.isInstant() && InstantUploadActivity.IS_ENABLED) {
          detailUploadIntent = new Intent(this, InstantUploadActivity.class);
          detailUploadIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount());
        } else {
          detailUploadIntent = new Intent(this, FailedUploadActivity.class);
          detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content);
        }
        finalNotification.contentIntent =
            PendingIntent.getActivity(
                getApplicationContext(),
                (int) System.currentTimeMillis(),
                detailUploadIntent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);

        if (upload.isInstant()) {
          DbHandler db = null;
          try {
            db = new DbHandler(this.getBaseContext());
            String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
            Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
            if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
              message = getString(R.string.failed_upload_quota_exceeded_text);
              if (db.updateFileState(
                      upload.getOriginalStoragePath(),
                      DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
                      message)
                  == 0) {
                db.putFileForLater(
                    upload.getOriginalStoragePath(), upload.getAccount().name, message);
              }
            }
          } finally {
            if (db != null) {
              db.close();
            }
          }
        }
      }
      finalNotification.setLatestEventInfo(
          getApplicationContext(),
          getString(R.string.uploader_upload_failed_ticker),
          content,
          finalNotification.contentIntent);

      mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
    }
  }
示例#4
0
  /**
   * Core upload method: sends the file(s) to upload
   *
   * @param uploadKey Key to access the upload to perform, contained in mPendingUploads
   */
  public void uploadFile(String uploadKey) {

    synchronized (mPendingUploads) {
      mCurrentUpload = mPendingUploads.get(uploadKey);
    }

    if (mCurrentUpload != null) {

      notifyUploadStart(mCurrentUpload);

      RemoteOperationResult uploadResult = null, grantResult = null;

      try {
        /// prepare client object to send requests to the ownCloud server
        if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
          mLastAccount = mCurrentUpload.getAccount();
          mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
          mUploadClient =
              OwnCloudClientFactory.createOwnCloudClient(mLastAccount, getApplicationContext());
        }

        /// check the existence of the parent folder for the file to upload
        String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
        remoteParentPath =
            remoteParentPath.endsWith(OCFile.PATH_SEPARATOR)
                ? remoteParentPath
                : remoteParentPath + OCFile.PATH_SEPARATOR;
        grantResult = grantFolderExistence(remoteParentPath);

        /// perform the upload
        if (grantResult.isSuccess()) {
          OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
          mCurrentUpload.getFile().setParentId(parent.getFileId());
          uploadResult = mCurrentUpload.execute(mUploadClient);
          if (uploadResult.isSuccess()) {
            saveUploadedFile();
          }
        } else {
          uploadResult = grantResult;
        }

      } catch (AccountsException e) {
        Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
        uploadResult = new RemoteOperationResult(e);

      } catch (IOException e) {
        Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
        uploadResult = new RemoteOperationResult(e);

      } finally {
        synchronized (mPendingUploads) {
          mPendingUploads.remove(uploadKey);
          Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
        }
        if (uploadResult.isException()) {
          // enforce the creation of a new client object for next uploads; this grant that a new
          // socket will
          // be created in the future if the current exception is due to an abrupt lose of network
          // connection
          mUploadClient = null;
        }
      }

      /// notify result

      notifyUploadResult(uploadResult, mCurrentUpload);
      sendFinalBroadcast(mCurrentUpload, uploadResult);
    }
  }