chromium/chrome/browser/ash/file_manager/copy_or_move_encrypted_hook_delegate.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/file_manager/copy_or_move_encrypted_hook_delegate.h"

#include "chrome/browser/ash/drive/drive_integration_service.h"
#include "chrome/browser/ash/drive/file_system_util.h"
#include "components/drive/drive_api_util.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/common/task_util.h"

namespace file_manager::io_task {

namespace {

void CheckFileCompleted(
    storage::FileSystemURL source_url,
    base::RepeatingCallback<void(storage::FileSystemURL source_url)>
        skip_callback,
    CopyOrMoveEncryptedHookDelegate::ErrorCallback finish_callback,
    drive::FileError error,
    drivefs::mojom::FileMetadataPtr metadata) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (metadata &&
      drive::util::IsEncryptedMimeType(metadata->content_mime_type)) {
    skip_callback.Run(std::move(source_url));
    std::move(finish_callback)
        .Run(CopyOrMoveEncryptedHookDelegate::ErrorAction::kSkip);
  } else {
    std::move(finish_callback)
        .Run(CopyOrMoveEncryptedHookDelegate::ErrorAction::kDefault);
  }
}

void CheckFile(Profile* profile,
               storage::FileSystemURL source_url,
               base::RepeatingCallback<void(storage::FileSystemURL source_url)>
                   skip_callback,
               CopyOrMoveEncryptedHookDelegate::ErrorCallback finish_callback) {
  // We can only access drive integration service from the UI thread.
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  drive::DriveIntegrationService* drive_integration_service =
      drive::util::GetIntegrationServiceByProfile(profile);
  if (!drive_integration_service) {
    std::move(finish_callback)
        .Run(CopyOrMoveEncryptedHookDelegate::ErrorAction::kDefault);
    return;
  }

  base::FilePath source_path = source_url.path();
  drive_integration_service->GetMetadata(
      source_path,
      base::BindOnce(&CheckFileCompleted, std::move(source_url),
                     std::move(skip_callback), std::move(finish_callback)));
}

}  // anonymous namespace

CopyOrMoveEncryptedHookDelegate::CopyOrMoveEncryptedHookDelegate(
    Profile* profile,
    base::RepeatingCallback<void(storage::FileSystemURL source_url)>
        on_file_skipped)
    : on_file_skipped_(std::move(on_file_skipped)),
      check_file_(google_apis::CreateRelayCallback(
          base::BindRepeating(&CheckFile, profile))) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

CopyOrMoveEncryptedHookDelegate::~CopyOrMoveEncryptedHookDelegate() = default;

void CopyOrMoveEncryptedHookDelegate::OnError(
    const storage::FileSystemURL& source_url,
    const storage::FileSystemURL& destination_url __attribute__((unused)),
    base::File::Error error,
    ErrorCallback callback) {
  if (source_url.type() != storage::kFileSystemTypeDriveFs) {
    std::move(callback).Run(ErrorAction::kDefault);
    return;
  }

  if (error != base::File::FILE_ERROR_FAILED) {
    std::move(callback).Run(ErrorAction::kDefault);
    return;
  }

  check_file_.Run(source_url, on_file_skipped_,
                  google_apis::CreateRelayCallback(std::move(callback)));
}

}  // namespace file_manager::io_task