Commit bcec2acd authored by Maggie Cai's avatar Maggie Cai Committed by Commit Bot

[Sharesheet] Support share to drive for folders.

This CL adds the support to share a Google Drive folder in Sharesheet.

BUG=1097623, 1128829

Change-Id: I30dffaa3428cc82e0209ff52abfa97e757a273f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2434118Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarMelissa Zhang <melzhang@chromium.org>
Commit-Queue: Maggie Cai <mxcai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811583}
parent fdcd905f
......@@ -546,6 +546,11 @@ std::vector<IntentLaunchInfo> AppServiceProxy::GetAppsForIntent(
const apps::mojom::IntentPtr& intent,
bool exclude_browsers) {
std::vector<IntentLaunchInfo> intent_launch_info;
if (apps_util::OnlyShareToDrive(intent) ||
!apps_util::IsIntentValid(intent)) {
return intent_launch_info;
}
if (app_service_.is_bound()) {
cache_.ForEachApp([&intent_launch_info, &intent,
&exclude_browsers](const apps::AppUpdate& update) {
......
......@@ -117,15 +117,31 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction::
base::File::Error error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
bool result = false;
if (error != base::File::FILE_OK) {
LOG(ERROR) << "Error reading file properties in Drive: " << error;
Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result)));
SharesheetHasTargets::Results::Create(false)));
return;
}
is_directory_collector_ =
std::make_unique<app_file_handler_util::IsDirectoryCollector>(
chrome_details_.GetProfile());
is_directory_collector_->CollectForEntriesPaths(
std::vector<base::FilePath>{file_system_urls_[0].path()},
base::BindOnce(&FileManagerPrivateInternalSharesheetHasTargetsFunction::
OnIsDirectoryCollected,
this, std::move(mime_types), std::move(properties)));
}
void FileManagerPrivateInternalSharesheetHasTargetsFunction::
OnIsDirectoryCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
std::unique_ptr<std::set<base::FilePath>> path_directory_set) {
bool is_directory = path_directory_set->find(file_system_urls_[0].path()) !=
path_directory_set->end();
sharesheet::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile(
chrome_details_.GetProfile());
......@@ -133,9 +149,9 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction::
(properties->can_share && *properties->can_share && properties->share_url)
? GURL(*properties->share_url)
: GURL();
result = sharesheet_service->HasShareTargets(
bool result = sharesheet_service->HasShareTargets(
apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0],
share_url),
share_url, is_directory),
contains_hosted_document_);
Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result)));
......@@ -233,6 +249,23 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::
return;
}
is_directory_collector_ =
std::make_unique<app_file_handler_util::IsDirectoryCollector>(
chrome_details_.GetProfile());
is_directory_collector_->CollectForEntriesPaths(
std::vector<base::FilePath>{file_system_urls_[0].path()},
base::BindOnce(&FileManagerPrivateInternalInvokeSharesheetFunction::
OnIsDirectoryCollected,
this, std::move(mime_types), std::move(properties)));
}
void FileManagerPrivateInternalInvokeSharesheetFunction::OnIsDirectoryCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
std::unique_ptr<std::set<base::FilePath>> path_directory_set) {
bool is_directory = path_directory_set->find(file_system_urls_[0].path()) !=
path_directory_set->end();
auto* profile = chrome_details_.GetProfile();
sharesheet::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile(profile);
......@@ -245,9 +278,10 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::
(properties->can_share && *properties->can_share && properties->share_url)
? GURL(*properties->share_url)
: GURL();
sharesheet_service->ShowBubble(GetSenderWebContents(),
apps_util::CreateShareIntentFromDriveFile(
urls_[0], (*mime_types)[0], share_url),
sharesheet_service->ShowBubble(
GetSenderWebContents(),
apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0],
share_url, is_directory),
contains_hosted_document_);
Respond(NoArguments());
}
......
......@@ -29,6 +29,7 @@ struct EntryProperties;
} // namespace api
namespace app_file_handler_util {
class IsDirectoryCollector;
class MimeTypeCollector;
} // namespace app_file_handler_util
......@@ -57,8 +58,15 @@ class FileManagerPrivateInternalSharesheetHasTargetsFunction
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error);
void OnIsDirectoryCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
std::unique_ptr<std::set<base::FilePath>> path_directory_set);
std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_;
std::unique_ptr<app_file_handler_util::IsDirectoryCollector>
is_directory_collector_;
std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_;
......@@ -89,8 +97,15 @@ class FileManagerPrivateInternalInvokeSharesheetFunction
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error);
void OnIsDirectoryCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
std::unique_ptr<std::set<base::FilePath>> path_directory_set);
std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_;
std::unique_ptr<app_file_handler_util::IsDirectoryCollector>
is_directory_collector_;
std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_;
......
......@@ -4,11 +4,20 @@
#include "chrome/browser/sharesheet/share_action.h"
#if defined(OS_CHROMEOS)
#include "components/services/app_service/public/cpp/intent_util.h"
#endif
namespace sharesheet {
bool ShareAction::ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document) {
#if defined(OS_CHROMEOS)
return !contains_hosted_document && !apps_util::OnlyShareToDrive(intent) &&
apps_util::IsIntentValid(intent);
#else
return !contains_hosted_document;
#endif
}
} // namespace sharesheet
......@@ -156,11 +156,14 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url,
const std::string& mime_type,
const GURL& drive_share_url) {
const GURL& drive_share_url,
bool is_directory) {
auto intent = apps::mojom::Intent::New();
intent->action = kIntentActionSend;
if (!is_directory) {
intent->mime_type = mime_type;
intent->file_urls = std::vector<GURL>{filesystem_url};
}
if (!drive_share_url.is_empty()) {
intent->drive_share_url = drive_share_url;
}
......@@ -306,4 +309,27 @@ bool MatchGlob(const std::string& value, const std::string& pattern) {
#undef GET_CHAR
}
bool OnlyShareToDrive(const apps::mojom::IntentPtr& intent) {
if (intent->action == kIntentActionSend ||
intent->action == kIntentActionSendMultiple) {
if (intent->drive_share_url.has_value() &&
!intent->share_text.has_value() && !intent->file_urls.has_value()) {
return true;
}
}
return false;
}
bool IsIntentValid(const apps::mojom::IntentPtr& intent) {
// TODO(crbug.com/853604):Add more checks here to make this a general intent
// validity check. Check if this is a share intent with no file or text.
if (intent->action == kIntentActionSend ||
intent->action == kIntentActionSendMultiple) {
if (!intent->share_text.has_value() && !intent->file_urls.has_value()) {
return false;
}
}
return true;
}
} // namespace apps_util
......@@ -33,7 +33,8 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url,
const std::string& mime_type,
const GURL& drive_share_url);
const GURL& drive_share_url,
bool is_directory);
// Create an intent struct from URL.
apps::mojom::IntentPtr CreateShareIntentFromText(const std::string& share_text);
......@@ -63,6 +64,12 @@ bool IntentMatchesFilter(const apps::mojom::IntentPtr& intent,
// See
// https://android.googlesource.com/platform/frameworks/base.git/+/e93165456c3c28278f275566bd90bfbcf1a0e5f7/core/java/android/os/PatternMatcher.java#186
bool MatchGlob(const std::string& value, const std::string& pattern);
// Check if the intent only mean to share to Google Drive.
bool OnlyShareToDrive(const apps::mojom::IntentPtr& intent);
// Check the if the intent is valid, e.g. action matches content.
bool IsIntentValid(const apps::mojom::IntentPtr& intent);
} // namespace apps_util
#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_
......@@ -1588,7 +1588,9 @@ CommandHandler.COMMANDS_['invoke-sharesheet'] = new class extends Command {
const entries = fileManager.selectionHandler.selection.entries;
if (!util.isSharesheetEnabled() || !entries || entries.length === 0 ||
entries.some(entry => entry.isDirectory)) {
(entries.some(entry => entry.isDirectory) &&
(!CommandUtil.isDriveEntries(entries, fileManager.volumeManager) ||
entries.length > 1))) {
event.canExecute = false;
event.command.setHidden(true);
event.command.disabled = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment