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( ...@@ -546,6 +546,11 @@ std::vector<IntentLaunchInfo> AppServiceProxy::GetAppsForIntent(
const apps::mojom::IntentPtr& intent, const apps::mojom::IntentPtr& intent,
bool exclude_browsers) { bool exclude_browsers) {
std::vector<IntentLaunchInfo> intent_launch_info; std::vector<IntentLaunchInfo> intent_launch_info;
if (apps_util::OnlyShareToDrive(intent) ||
!apps_util::IsIntentValid(intent)) {
return intent_launch_info;
}
if (app_service_.is_bound()) { if (app_service_.is_bound()) {
cache_.ForEachApp([&intent_launch_info, &intent, cache_.ForEachApp([&intent_launch_info, &intent,
&exclude_browsers](const apps::AppUpdate& update) { &exclude_browsers](const apps::AppUpdate& update) {
......
...@@ -117,15 +117,31 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction:: ...@@ -117,15 +117,31 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction::
base::File::Error error) { base::File::Error error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
bool result = false;
if (error != base::File::FILE_OK) { if (error != base::File::FILE_OK) {
LOG(ERROR) << "Error reading file properties in Drive: " << error; LOG(ERROR) << "Error reading file properties in Drive: " << error;
Respond(ArgumentList(extensions::api::file_manager_private_internal:: Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result))); SharesheetHasTargets::Results::Create(false)));
return; 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::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile( sharesheet::SharesheetServiceFactory::GetForProfile(
chrome_details_.GetProfile()); chrome_details_.GetProfile());
...@@ -133,9 +149,9 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction:: ...@@ -133,9 +149,9 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction::
(properties->can_share && *properties->can_share && properties->share_url) (properties->can_share && *properties->can_share && properties->share_url)
? GURL(*properties->share_url) ? GURL(*properties->share_url)
: GURL(); : GURL();
result = sharesheet_service->HasShareTargets( bool result = sharesheet_service->HasShareTargets(
apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0], apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0],
share_url), share_url, is_directory),
contains_hosted_document_); contains_hosted_document_);
Respond(ArgumentList(extensions::api::file_manager_private_internal:: Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result))); SharesheetHasTargets::Results::Create(result)));
...@@ -233,6 +249,23 @@ void FileManagerPrivateInternalInvokeSharesheetFunction:: ...@@ -233,6 +249,23 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::
return; 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(); auto* profile = chrome_details_.GetProfile();
sharesheet::SharesheetService* sharesheet_service = sharesheet::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile(profile); sharesheet::SharesheetServiceFactory::GetForProfile(profile);
...@@ -245,10 +278,11 @@ void FileManagerPrivateInternalInvokeSharesheetFunction:: ...@@ -245,10 +278,11 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::
(properties->can_share && *properties->can_share && properties->share_url) (properties->can_share && *properties->can_share && properties->share_url)
? GURL(*properties->share_url) ? GURL(*properties->share_url)
: GURL(); : GURL();
sharesheet_service->ShowBubble(GetSenderWebContents(), sharesheet_service->ShowBubble(
apps_util::CreateShareIntentFromDriveFile( GetSenderWebContents(),
urls_[0], (*mime_types)[0], share_url), apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0],
contains_hosted_document_); share_url, is_directory),
contains_hosted_document_);
Respond(NoArguments()); Respond(NoArguments());
} }
......
...@@ -29,6 +29,7 @@ struct EntryProperties; ...@@ -29,6 +29,7 @@ struct EntryProperties;
} // namespace api } // namespace api
namespace app_file_handler_util { namespace app_file_handler_util {
class IsDirectoryCollector;
class MimeTypeCollector; class MimeTypeCollector;
} // namespace app_file_handler_util } // namespace app_file_handler_util
...@@ -57,8 +58,15 @@ class FileManagerPrivateInternalSharesheetHasTargetsFunction ...@@ -57,8 +58,15 @@ class FileManagerPrivateInternalSharesheetHasTargetsFunction
std::unique_ptr<api::file_manager_private::EntryProperties> properties, std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error); 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> std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_; mime_type_collector_;
std::unique_ptr<app_file_handler_util::IsDirectoryCollector>
is_directory_collector_;
std::vector<GURL> urls_; std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_; const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_; std::vector<storage::FileSystemURL> file_system_urls_;
...@@ -89,8 +97,15 @@ class FileManagerPrivateInternalInvokeSharesheetFunction ...@@ -89,8 +97,15 @@ class FileManagerPrivateInternalInvokeSharesheetFunction
std::unique_ptr<api::file_manager_private::EntryProperties> properties, std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error); 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> std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_; mime_type_collector_;
std::unique_ptr<app_file_handler_util::IsDirectoryCollector>
is_directory_collector_;
std::vector<GURL> urls_; std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_; const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_; std::vector<storage::FileSystemURL> file_system_urls_;
......
...@@ -4,11 +4,20 @@ ...@@ -4,11 +4,20 @@
#include "chrome/browser/sharesheet/share_action.h" #include "chrome/browser/sharesheet/share_action.h"
#if defined(OS_CHROMEOS)
#include "components/services/app_service/public/cpp/intent_util.h"
#endif
namespace sharesheet { namespace sharesheet {
bool ShareAction::ShouldShowAction(const apps::mojom::IntentPtr& intent, bool ShareAction::ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document) { 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; return !contains_hosted_document;
#endif
} }
} // namespace sharesheet } // namespace sharesheet
...@@ -156,11 +156,14 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles( ...@@ -156,11 +156,14 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
apps::mojom::IntentPtr CreateShareIntentFromDriveFile( apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url, const GURL& filesystem_url,
const std::string& mime_type, const std::string& mime_type,
const GURL& drive_share_url) { const GURL& drive_share_url,
bool is_directory) {
auto intent = apps::mojom::Intent::New(); auto intent = apps::mojom::Intent::New();
intent->action = kIntentActionSend; intent->action = kIntentActionSend;
intent->mime_type = mime_type; if (!is_directory) {
intent->file_urls = std::vector<GURL>{filesystem_url}; intent->mime_type = mime_type;
intent->file_urls = std::vector<GURL>{filesystem_url};
}
if (!drive_share_url.is_empty()) { if (!drive_share_url.is_empty()) {
intent->drive_share_url = drive_share_url; intent->drive_share_url = drive_share_url;
} }
...@@ -306,4 +309,27 @@ bool MatchGlob(const std::string& value, const std::string& pattern) { ...@@ -306,4 +309,27 @@ bool MatchGlob(const std::string& value, const std::string& pattern) {
#undef GET_CHAR #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 } // namespace apps_util
...@@ -33,7 +33,8 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles( ...@@ -33,7 +33,8 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
apps::mojom::IntentPtr CreateShareIntentFromDriveFile( apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url, const GURL& filesystem_url,
const std::string& mime_type, const std::string& mime_type,
const GURL& drive_share_url); const GURL& drive_share_url,
bool is_directory);
// Create an intent struct from URL. // Create an intent struct from URL.
apps::mojom::IntentPtr CreateShareIntentFromText(const std::string& share_text); apps::mojom::IntentPtr CreateShareIntentFromText(const std::string& share_text);
...@@ -63,6 +64,12 @@ bool IntentMatchesFilter(const apps::mojom::IntentPtr& intent, ...@@ -63,6 +64,12 @@ bool IntentMatchesFilter(const apps::mojom::IntentPtr& intent,
// See // See
// https://android.googlesource.com/platform/frameworks/base.git/+/e93165456c3c28278f275566bd90bfbcf1a0e5f7/core/java/android/os/PatternMatcher.java#186 // 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); 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 } // namespace apps_util
#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_ #endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_
...@@ -1588,7 +1588,9 @@ CommandHandler.COMMANDS_['invoke-sharesheet'] = new class extends Command { ...@@ -1588,7 +1588,9 @@ CommandHandler.COMMANDS_['invoke-sharesheet'] = new class extends Command {
const entries = fileManager.selectionHandler.selection.entries; const entries = fileManager.selectionHandler.selection.entries;
if (!util.isSharesheetEnabled() || !entries || entries.length === 0 || 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.canExecute = false;
event.command.setHidden(true); event.command.setHidden(true);
event.command.disabled = 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