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

[Sharesheet] Add share to drive action in sharesheet.

This CL adds the share to drive action in sharesheet for files in Google
Drive.

Currently, for files in the Google Drive folder, there is an option to
"Share with others" to give permission to others to access the file
in the drive. Now we are migrating this functionality to sharesheet by
adding a drive_share_action. This action should show in sharesheet with
the same condition that the Share with others option available.

To get the required drive information, we need to get drive properties
from file system URL, therefore, I moved the private
SingleEntryPropertiesGetterForDriveFs class to util so that both
private_api_drive and private_api_sharesheet can use this getter
to get the drive properties.

BUG=1097623

Change-Id: I5701ddd6fdd17c21497061dd2755e92d7616369b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2400580Reviewed-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@{#806070}
parent 3e64bac9
...@@ -1514,6 +1514,7 @@ static_library("browser") { ...@@ -1514,6 +1514,7 @@ static_library("browser") {
"sessions/session_tab_helper_factory.h", "sessions/session_tab_helper_factory.h",
"sessions/tab_restore_service_factory.cc", "sessions/tab_restore_service_factory.cc",
"sessions/tab_restore_service_factory.h", "sessions/tab_restore_service_factory.h",
"sharesheet/share_action.cc",
"sharesheet/share_action.h", "sharesheet/share_action.h",
"sharesheet/sharesheet_action_cache.cc", "sharesheet/sharesheet_action_cache.cc",
"sharesheet/sharesheet_action_cache.h", "sharesheet/sharesheet_action_cache.h",
...@@ -4033,6 +4034,8 @@ static_library("browser") { ...@@ -4033,6 +4034,8 @@ static_library("browser") {
"renderer_context_menu/quick_answers_menu_observer.h", "renderer_context_menu/quick_answers_menu_observer.h",
"resource_coordinator/tab_manager_delegate_chromeos.cc", "resource_coordinator/tab_manager_delegate_chromeos.cc",
"resource_coordinator/tab_manager_delegate_chromeos.h", "resource_coordinator/tab_manager_delegate_chromeos.h",
"sharesheet/drive_share_action.cc",
"sharesheet/drive_share_action.h",
"shell_integration_chromeos.cc", "shell_integration_chromeos.cc",
"signin/signin_status_metrics_provider_chromeos.cc", "signin/signin_status_metrics_provider_chromeos.cc",
"signin/signin_status_metrics_provider_chromeos.h", "signin/signin_status_metrics_provider_chromeos.h",
......
...@@ -88,22 +88,6 @@ constexpr base::TimeDelta kDriveSlowOperationThreshold = ...@@ -88,22 +88,6 @@ constexpr base::TimeDelta kDriveSlowOperationThreshold =
constexpr base::TimeDelta kDriveVerySlowOperationThreshold = constexpr base::TimeDelta kDriveVerySlowOperationThreshold =
base::TimeDelta::FromMinutes(1); base::TimeDelta::FromMinutes(1);
std::unique_ptr<std::string> GetShareUrlFromAlternateUrl(
const GURL& alternate_url) {
// Set |share_url| to a modified version of |alternate_url| that opens the
// sharing dialog for files and folders (add ?userstoinvite="" to the URL).
// TODO(sashab): Add an endpoint to the Drive API that generates this URL,
// instead of manually modifying it here.
GURL::Replacements replacements;
std::string new_query =
(alternate_url.has_query() ? alternate_url.query() + "&" : "") +
"userstoinvite=%22%22";
replacements.SetQueryStr(new_query);
return std::make_unique<std::string>(
alternate_url.ReplaceComponents(replacements).spec());
}
class SingleEntryPropertiesGetterForFileSystemProvider { class SingleEntryPropertiesGetterForFileSystemProvider {
public: public:
typedef base::OnceCallback<void(std::unique_ptr<EntryProperties> properties, typedef base::OnceCallback<void(std::unique_ptr<EntryProperties> properties,
...@@ -241,184 +225,6 @@ class SingleEntryPropertiesGetterForFileSystemProvider { ...@@ -241,184 +225,6 @@ class SingleEntryPropertiesGetterForFileSystemProvider {
weak_ptr_factory_{this}; weak_ptr_factory_{this};
}; // class SingleEntryPropertiesGetterForFileSystemProvider }; // class SingleEntryPropertiesGetterForFileSystemProvider
class SingleEntryPropertiesGetterForDriveFs {
public:
using ResultCallback =
base::OnceCallback<void(std::unique_ptr<EntryProperties> properties,
base::File::Error error)>;
// Creates an instance and starts the process.
static void Start(const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
SingleEntryPropertiesGetterForDriveFs* instance =
new SingleEntryPropertiesGetterForDriveFs(file_system_url, profile,
std::move(callback));
instance->StartProcess();
// The instance will be destroyed by itself.
}
private:
SingleEntryPropertiesGetterForDriveFs(
const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback)
: callback_(std::move(callback)),
file_system_url_(file_system_url),
running_profile_(profile),
properties_(std::make_unique<EntryProperties>()) {
DCHECK(callback_);
DCHECK(profile);
}
void StartProcess() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
drive::DriveIntegrationService* integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(running_profile_);
if (!integration_service || !integration_service->IsMounted()) {
CompleteGetEntryProperties(drive::FILE_ERROR_SERVICE_UNAVAILABLE);
return;
}
base::FilePath path;
if (!integration_service->GetRelativeDrivePath(file_system_url_.path(),
&path)) {
CompleteGetEntryProperties(drive::FILE_ERROR_INVALID_OPERATION);
return;
}
auto* drivefs_interface = integration_service->GetDriveFsInterface();
if (!drivefs_interface) {
CompleteGetEntryProperties(drive::FILE_ERROR_SERVICE_UNAVAILABLE);
return;
}
drivefs_interface->GetMetadata(
path, mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(
&SingleEntryPropertiesGetterForDriveFs::OnGetFileInfo,
weak_ptr_factory_.GetWeakPtr()),
drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr));
}
void OnGetFileInfo(drive::FileError error,
drivefs::mojom::FileMetadataPtr metadata) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!metadata) {
CompleteGetEntryProperties(error);
return;
}
properties_->size = std::make_unique<double>(metadata->size);
properties_->present = std::make_unique<bool>(metadata->available_offline);
properties_->dirty = std::make_unique<bool>(metadata->dirty);
properties_->hosted =
std::make_unique<bool>(drivefs::IsHosted(metadata->type));
properties_->available_offline = std::make_unique<bool>(
metadata->available_offline || *properties_->hosted);
properties_->available_when_metered = std::make_unique<bool>(
metadata->available_offline || *properties_->hosted);
properties_->pinned = std::make_unique<bool>(metadata->pinned);
properties_->shared = std::make_unique<bool>(metadata->shared);
properties_->starred = std::make_unique<bool>(metadata->starred);
if (metadata->modification_time != base::Time()) {
properties_->modification_time =
std::make_unique<double>(metadata->modification_time.ToJsTime());
}
if (metadata->last_viewed_by_me_time != base::Time()) {
properties_->modification_by_me_time =
std::make_unique<double>(metadata->last_viewed_by_me_time.ToJsTime());
}
if (!metadata->content_mime_type.empty()) {
properties_->content_mime_type =
std::make_unique<std::string>(metadata->content_mime_type);
}
if (!metadata->custom_icon_url.empty()) {
properties_->custom_icon_url =
std::make_unique<std::string>(std::move(metadata->custom_icon_url));
}
if (!metadata->alternate_url.empty()) {
properties_->alternate_url =
std::make_unique<std::string>(std::move(metadata->alternate_url));
properties_->share_url =
GetShareUrlFromAlternateUrl(GURL(*properties_->alternate_url));
}
if (metadata->image_metadata) {
if (metadata->image_metadata->height) {
properties_->image_height =
std::make_unique<int32_t>(metadata->image_metadata->height);
}
if (metadata->image_metadata->width) {
properties_->image_width =
std::make_unique<int32_t>(metadata->image_metadata->width);
}
if (metadata->image_metadata->rotation) {
properties_->image_rotation =
std::make_unique<int32_t>(metadata->image_metadata->rotation);
}
}
properties_->can_delete =
std::make_unique<bool>(metadata->capabilities->can_delete);
properties_->can_rename =
std::make_unique<bool>(metadata->capabilities->can_rename);
properties_->can_add_children =
std::make_unique<bool>(metadata->capabilities->can_add_children);
// Only set the |can_copy| capability for hosted documents; for other files,
// we must have read access, so |can_copy| is implicitly true.
properties_->can_copy = std::make_unique<bool>(
!*properties_->hosted || metadata->capabilities->can_copy);
properties_->can_share =
std::make_unique<bool>(metadata->capabilities->can_share);
if (drivefs::IsAFile(metadata->type)) {
properties_->thumbnail_url = std::make_unique<std::string>(
base::StrCat({"drivefs:", file_system_url_.ToGURL().spec()}));
properties_->cropped_thumbnail_url =
std::make_unique<std::string>(*properties_->thumbnail_url);
}
if (metadata->folder_feature) {
properties_->is_machine_root =
std::make_unique<bool>(metadata->folder_feature->is_machine_root);
properties_->is_external_media =
std::make_unique<bool>(metadata->folder_feature->is_external_media);
properties_->is_arbitrary_sync_folder = std::make_unique<bool>(
metadata->folder_feature->is_arbitrary_sync_folder);
}
CompleteGetEntryProperties(drive::FILE_ERROR_OK);
}
void CompleteGetEntryProperties(drive::FileError error) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(callback_);
std::move(callback_).Run(std::move(properties_),
drive::FileErrorToBaseFileError(error));
content::GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, this);
}
// Given parameters.
ResultCallback callback_;
const storage::FileSystemURL file_system_url_;
Profile* const running_profile_;
// Values used in the process.
std::unique_ptr<EntryProperties> properties_;
base::WeakPtrFactory<SingleEntryPropertiesGetterForDriveFs> weak_ptr_factory_{
this};
DISALLOW_COPY_AND_ASSIGN(SingleEntryPropertiesGetterForDriveFs);
};
class SingleEntryPropertiesGetterForDocumentsProvider { class SingleEntryPropertiesGetterForDocumentsProvider {
public: public:
typedef base::OnceCallback<void(std::unique_ptr<EntryProperties> properties, typedef base::OnceCallback<void(std::unique_ptr<EntryProperties> properties,
...@@ -645,7 +451,7 @@ FileManagerPrivateInternalGetEntryPropertiesFunction::Run() { ...@@ -645,7 +451,7 @@ FileManagerPrivateInternalGetEntryPropertiesFunction::Run() {
this, i, file_system_url)); this, i, file_system_url));
break; break;
case storage::kFileSystemTypeDriveFs: case storage::kFileSystemTypeDriveFs:
SingleEntryPropertiesGetterForDriveFs::Start( file_manager::util::SingleEntryPropertiesGetterForDriveFs::Start(
file_system_url, chrome_details.GetProfile(), file_system_url, chrome_details.GetProfile(),
base::BindOnce( base::BindOnce(
&FileManagerPrivateInternalGetEntryPropertiesFunction:: &FileManagerPrivateInternalGetEntryPropertiesFunction::
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "chrome/browser/chromeos/extensions/file_manager/private_api_sharesheet.h" #include "chrome/browser/chromeos/extensions/file_manager/private_api_sharesheet.h"
#include "base/bind.h" #include "base/bind.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h" #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -12,6 +14,7 @@ ...@@ -12,6 +14,7 @@
#include "chrome/browser/sharesheet/sharesheet_service_factory.h" #include "chrome/browser/sharesheet/sharesheet_service_factory.h"
#include "chrome/common/extensions/api/file_manager_private.h" #include "chrome/common/extensions/api/file_manager_private.h"
#include "chrome/common/extensions/api/file_manager_private_internal.h" #include "chrome/common/extensions/api/file_manager_private_internal.h"
#include "components/drive/drive_api_util.h"
#include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/cpp/intent_util.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "extensions/browser/api/file_handlers/directory_util.h" #include "extensions/browser/api/file_handlers/directory_util.h"
...@@ -44,23 +47,25 @@ FileManagerPrivateInternalSharesheetHasTargetsFunction::Run() { ...@@ -44,23 +47,25 @@ FileManagerPrivateInternalSharesheetHasTargetsFunction::Run() {
file_manager::util::GetFileSystemContextForRenderFrameHost( file_manager::util::GetFileSystemContextForRenderFrameHost(
chrome_details_.GetProfile(), render_frame_host()); chrome_details_.GetProfile(), render_frame_host());
std::vector<storage::FileSystemURL> file_system_urls;
// Collect all the URLs, convert them to GURLs, and crack all the urls into // Collect all the URLs, convert them to GURLs, and crack all the urls into
// file paths. // file paths.
for (size_t i = 0; i < params->urls.size(); ++i) { for (size_t i = 0; i < params->urls.size(); ++i) {
const GURL url(params->urls[i]); const GURL url(params->urls[i]);
storage::FileSystemURL file_system_url(file_system_context->CrackURL(url)); storage::FileSystemURL file_system_url(file_system_context->CrackURL(url));
if (drive::util::HasHostedDocumentExtension(file_system_url.path())) {
contains_hosted_document_ = true;
}
if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url)) if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url))
continue; continue;
urls_.push_back(url); urls_.push_back(url);
file_system_urls.push_back(file_system_url); file_system_urls_.push_back(file_system_url);
} }
mime_type_collector_ = mime_type_collector_ =
std::make_unique<app_file_handler_util::MimeTypeCollector>( std::make_unique<app_file_handler_util::MimeTypeCollector>(
chrome_details_.GetProfile()); chrome_details_.GetProfile());
mime_type_collector_->CollectForURLs( mime_type_collector_->CollectForURLs(
file_system_urls, file_system_urls_,
base::BindOnce(&FileManagerPrivateInternalSharesheetHasTargetsFunction:: base::BindOnce(&FileManagerPrivateInternalSharesheetHasTargetsFunction::
OnMimeTypesCollected, OnMimeTypesCollected,
this)); this));
...@@ -79,11 +84,59 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction:: ...@@ -79,11 +84,59 @@ void FileManagerPrivateInternalSharesheetHasTargetsFunction::
LOG(ERROR) << "Couldn't get Sharesheet Service for profile"; LOG(ERROR) << "Couldn't get Sharesheet Service for profile";
Respond(ArgumentList(extensions::api::file_manager_private_internal:: Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result))); SharesheetHasTargets::Results::Create(result)));
return;
} }
if (file_system_urls_.size() == 1 &&
file_system_urls_[0].type() == storage::kFileSystemTypeDriveFs) {
auto connection_status = drive::util::GetDriveConnectionStatus(
Profile::FromBrowserContext(browser_context()));
if (connection_status == drive::util::DRIVE_CONNECTED_METERED ||
connection_status == drive::util::DRIVE_CONNECTED) {
file_manager::util::SingleEntryPropertiesGetterForDriveFs::Start(
file_system_urls_[0], chrome_details_.GetProfile(),
base::BindOnce(
&FileManagerPrivateInternalSharesheetHasTargetsFunction::
OnDrivePropertyCollected,
this, std::move(mime_types)));
return;
}
}
result = sharesheet_service->HasShareTargets( result = sharesheet_service->HasShareTargets(
apps_util::CreateShareIntentFromFiles(urls_, *mime_types)); apps_util::CreateShareIntentFromFiles(urls_, *mime_types),
contains_hosted_document_);
Respond(ArgumentList(extensions::api::file_manager_private_internal::
SharesheetHasTargets::Results::Create(result)));
}
void FileManagerPrivateInternalSharesheetHasTargetsFunction::
OnDrivePropertyCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
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)));
return;
}
sharesheet::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile(
chrome_details_.GetProfile());
GURL share_url =
(properties->can_share && *properties->can_share && properties->share_url)
? GURL(*properties->share_url)
: GURL();
result = sharesheet_service->HasShareTargets(
apps_util::CreateShareIntentFromDriveFile(urls_[0], (*mime_types)[0],
share_url),
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)));
} }
...@@ -109,23 +162,24 @@ FileManagerPrivateInternalInvokeSharesheetFunction::Run() { ...@@ -109,23 +162,24 @@ FileManagerPrivateInternalInvokeSharesheetFunction::Run() {
file_manager::util::GetFileSystemContextForRenderFrameHost( file_manager::util::GetFileSystemContextForRenderFrameHost(
chrome_details_.GetProfile(), render_frame_host()); chrome_details_.GetProfile(), render_frame_host());
std::vector<storage::FileSystemURL> file_system_urls;
// Collect all the URLs, convert them to GURLs, and crack all the urls into // Collect all the URLs, convert them to GURLs, and crack all the urls into
// file paths. // file paths.
for (size_t i = 0; i < params->urls.size(); ++i) { for (size_t i = 0; i < params->urls.size(); ++i) {
const GURL url(params->urls[i]); const GURL url(params->urls[i]);
storage::FileSystemURL file_system_url(file_system_context->CrackURL(url)); storage::FileSystemURL file_system_url(file_system_context->CrackURL(url));
if (drive::util::HasHostedDocumentExtension(file_system_url.path()))
contains_hosted_document_ = true;
if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url)) if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url))
continue; continue;
urls_.push_back(url); urls_.push_back(url);
file_system_urls.push_back(file_system_url); file_system_urls_.push_back(file_system_url);
} }
mime_type_collector_ = mime_type_collector_ =
std::make_unique<app_file_handler_util::MimeTypeCollector>( std::make_unique<app_file_handler_util::MimeTypeCollector>(
chrome_details_.GetProfile()); chrome_details_.GetProfile());
mime_type_collector_->CollectForURLs( mime_type_collector_->CollectForURLs(
file_system_urls, file_system_urls_,
base::BindOnce(&FileManagerPrivateInternalInvokeSharesheetFunction:: base::BindOnce(&FileManagerPrivateInternalInvokeSharesheetFunction::
OnMimeTypesCollected, OnMimeTypesCollected,
this)); this));
...@@ -143,10 +197,58 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::OnMimeTypesCollected( ...@@ -143,10 +197,58 @@ void FileManagerPrivateInternalInvokeSharesheetFunction::OnMimeTypesCollected(
Respond(Error("Cannot find sharesheet service")); Respond(Error("Cannot find sharesheet service"));
return; return;
} }
if (file_system_urls_.size() == 1 &&
file_system_urls_[0].type() == storage::kFileSystemTypeDriveFs) {
auto connection_status = drive::util::GetDriveConnectionStatus(
Profile::FromBrowserContext(browser_context()));
if (connection_status == drive::util::DRIVE_CONNECTED_METERED ||
connection_status == drive::util::DRIVE_CONNECTED) {
file_manager::util::SingleEntryPropertiesGetterForDriveFs::Start(
file_system_urls_[0], chrome_details_.GetProfile(),
base::BindOnce(&FileManagerPrivateInternalInvokeSharesheetFunction::
OnDrivePropertyCollected,
this, std::move(mime_types)));
return;
}
}
sharesheet_service->ShowBubble( sharesheet_service->ShowBubble(
GetSenderWebContents(), GetSenderWebContents(),
apps_util::CreateShareIntentFromFiles(urls_, *mime_types)); apps_util::CreateShareIntentFromFiles(urls_, *mime_types),
contains_hosted_document_);
Respond(NoArguments());
}
void FileManagerPrivateInternalInvokeSharesheetFunction::
OnDrivePropertyCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (error != base::File::FILE_OK) {
Respond(Error("Drive File Error"));
return;
}
auto* profile = chrome_details_.GetProfile();
sharesheet::SharesheetService* sharesheet_service =
sharesheet::SharesheetServiceFactory::GetForProfile(profile);
if (!sharesheet_service) {
Respond(Error("Cannot find sharesheet service"));
return;
}
GURL share_url =
(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),
contains_hosted_document_);
Respond(NoArguments()); Respond(NoArguments());
} }
......
...@@ -14,9 +14,20 @@ ...@@ -14,9 +14,20 @@
#include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h" #include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "storage/browser/file_system/file_system_url.h"
namespace base {
class File;
}
namespace extensions { namespace extensions {
namespace api {
namespace file_manager_private {
struct EntryProperties;
}
} // namespace api
namespace app_file_handler_util { namespace app_file_handler_util {
class MimeTypeCollector; class MimeTypeCollector;
} // namespace app_file_handler_util } // namespace app_file_handler_util
...@@ -41,10 +52,17 @@ class FileManagerPrivateInternalSharesheetHasTargetsFunction ...@@ -41,10 +52,17 @@ class FileManagerPrivateInternalSharesheetHasTargetsFunction
void OnMimeTypesCollected( void OnMimeTypesCollected(
std::unique_ptr<std::vector<std::string>> mime_types); std::unique_ptr<std::vector<std::string>> mime_types);
void OnDrivePropertyCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error);
std::unique_ptr<app_file_handler_util::MimeTypeCollector> std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_; mime_type_collector_;
std::vector<GURL> urls_; std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_; const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_;
bool contains_hosted_document_ = false;
}; };
// Implements the chrome.fileManagerPrivateInternal.invokeSharesheet method. // Implements the chrome.fileManagerPrivateInternal.invokeSharesheet method.
...@@ -66,10 +84,17 @@ class FileManagerPrivateInternalInvokeSharesheetFunction ...@@ -66,10 +84,17 @@ class FileManagerPrivateInternalInvokeSharesheetFunction
void OnMimeTypesCollected( void OnMimeTypesCollected(
std::unique_ptr<std::vector<std::string>> mime_types); std::unique_ptr<std::vector<std::string>> mime_types);
void OnDrivePropertyCollected(
std::unique_ptr<std::vector<std::string>> mime_types,
std::unique_ptr<api::file_manager_private::EntryProperties> properties,
base::File::Error error);
std::unique_ptr<app_file_handler_util::MimeTypeCollector> std::unique_ptr<app_file_handler_util::MimeTypeCollector>
mime_type_collector_; mime_type_collector_;
std::vector<GURL> urls_; std::vector<GURL> urls_;
const ChromeExtensionFunctionDetails chrome_details_; const ChromeExtensionFunctionDetails chrome_details_;
std::vector<storage::FileSystemURL> file_system_urls_;
bool contains_hosted_document_ = false;
}; };
} // namespace extensions } // namespace extensions
......
...@@ -30,7 +30,9 @@ ...@@ -30,7 +30,9 @@
#include "chromeos/components/drivefs/drivefs_util.h" #include "chromeos/components/drivefs/drivefs_util.h"
#include "components/drive/drive_api_util.h" #include "components/drive/drive_api_util.h"
#include "components/drive/file_errors.h" #include "components/drive/file_errors.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/child_process_security_policy.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_url.h" #include "storage/browser/file_system/file_system_url.h"
#include "ui/shell_dialogs/selected_file_info.h" #include "ui/shell_dialogs/selected_file_info.h"
...@@ -180,8 +182,186 @@ void ContinueGetSelectedFileInfoWithDriveFsMetadata( ...@@ -180,8 +182,186 @@ void ContinueGetSelectedFileInfoWithDriveFsMetadata(
GetSelectedFileInfoInternal(profile, std::move(params)); GetSelectedFileInfoInternal(profile, std::move(params));
} }
std::unique_ptr<std::string> GetShareUrlFromAlternateUrl(
const GURL& alternate_url) {
// Set |share_url| to a modified version of |alternate_url| that opens the
// sharing dialog for files and folders (add ?userstoinvite="" to the URL).
GURL::Replacements replacements;
std::string new_query =
(alternate_url.has_query() ? alternate_url.query() + "&" : "") +
"userstoinvite=%22%22";
replacements.SetQueryStr(new_query);
return std::make_unique<std::string>(
alternate_url.ReplaceComponents(replacements).spec());
}
} // namespace } // namespace
// Creates an instance and starts the process.
void SingleEntryPropertiesGetterForDriveFs::Start(
const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
SingleEntryPropertiesGetterForDriveFs* instance =
new SingleEntryPropertiesGetterForDriveFs(file_system_url, profile,
std::move(callback));
instance->StartProcess();
// The instance will be destroyed by itself.
}
SingleEntryPropertiesGetterForDriveFs::SingleEntryPropertiesGetterForDriveFs(
const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback)
: callback_(std::move(callback)),
file_system_url_(file_system_url),
running_profile_(profile),
properties_(std::make_unique<
extensions::api::file_manager_private::EntryProperties>()) {
DCHECK(callback_);
DCHECK(profile);
}
SingleEntryPropertiesGetterForDriveFs::
~SingleEntryPropertiesGetterForDriveFs() = default;
void SingleEntryPropertiesGetterForDriveFs::StartProcess() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
drive::DriveIntegrationService* integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(running_profile_);
if (!integration_service || !integration_service->IsMounted()) {
CompleteGetEntryProperties(drive::FILE_ERROR_SERVICE_UNAVAILABLE);
return;
}
base::FilePath path;
if (!integration_service->GetRelativeDrivePath(file_system_url_.path(),
&path)) {
CompleteGetEntryProperties(drive::FILE_ERROR_INVALID_OPERATION);
return;
}
auto* drivefs_interface = integration_service->GetDriveFsInterface();
if (!drivefs_interface) {
CompleteGetEntryProperties(drive::FILE_ERROR_SERVICE_UNAVAILABLE);
return;
}
drivefs_interface->GetMetadata(
path,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(&SingleEntryPropertiesGetterForDriveFs::OnGetFileInfo,
weak_ptr_factory_.GetWeakPtr()),
drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr));
}
void SingleEntryPropertiesGetterForDriveFs::OnGetFileInfo(
drive::FileError error,
drivefs::mojom::FileMetadataPtr metadata) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!metadata) {
CompleteGetEntryProperties(error);
return;
}
properties_->size = std::make_unique<double>(metadata->size);
properties_->present = std::make_unique<bool>(metadata->available_offline);
properties_->dirty = std::make_unique<bool>(metadata->dirty);
properties_->hosted =
std::make_unique<bool>(drivefs::IsHosted(metadata->type));
properties_->available_offline = std::make_unique<bool>(
metadata->available_offline || *properties_->hosted);
properties_->available_when_metered = std::make_unique<bool>(
metadata->available_offline || *properties_->hosted);
properties_->pinned = std::make_unique<bool>(metadata->pinned);
properties_->shared = std::make_unique<bool>(metadata->shared);
properties_->starred = std::make_unique<bool>(metadata->starred);
if (metadata->modification_time != base::Time()) {
properties_->modification_time =
std::make_unique<double>(metadata->modification_time.ToJsTime());
}
if (metadata->last_viewed_by_me_time != base::Time()) {
properties_->modification_by_me_time =
std::make_unique<double>(metadata->last_viewed_by_me_time.ToJsTime());
}
if (!metadata->content_mime_type.empty()) {
properties_->content_mime_type =
std::make_unique<std::string>(metadata->content_mime_type);
}
if (!metadata->custom_icon_url.empty()) {
properties_->custom_icon_url =
std::make_unique<std::string>(std::move(metadata->custom_icon_url));
}
if (!metadata->alternate_url.empty()) {
properties_->alternate_url =
std::make_unique<std::string>(std::move(metadata->alternate_url));
properties_->share_url =
GetShareUrlFromAlternateUrl(GURL(*properties_->alternate_url));
}
if (metadata->image_metadata) {
if (metadata->image_metadata->height) {
properties_->image_height =
std::make_unique<int32_t>(metadata->image_metadata->height);
}
if (metadata->image_metadata->width) {
properties_->image_width =
std::make_unique<int32_t>(metadata->image_metadata->width);
}
if (metadata->image_metadata->rotation) {
properties_->image_rotation =
std::make_unique<int32_t>(metadata->image_metadata->rotation);
}
}
properties_->can_delete =
std::make_unique<bool>(metadata->capabilities->can_delete);
properties_->can_rename =
std::make_unique<bool>(metadata->capabilities->can_rename);
properties_->can_add_children =
std::make_unique<bool>(metadata->capabilities->can_add_children);
// Only set the |can_copy| capability for hosted documents; for other files,
// we must have read access, so |can_copy| is implicitly true.
properties_->can_copy = std::make_unique<bool>(
!*properties_->hosted || metadata->capabilities->can_copy);
properties_->can_share =
std::make_unique<bool>(metadata->capabilities->can_share);
if (drivefs::IsAFile(metadata->type)) {
properties_->thumbnail_url = std::make_unique<std::string>(
base::StrCat({"drivefs:", file_system_url_.ToGURL().spec()}));
properties_->cropped_thumbnail_url =
std::make_unique<std::string>(*properties_->thumbnail_url);
}
if (metadata->folder_feature) {
properties_->is_machine_root =
std::make_unique<bool>(metadata->folder_feature->is_machine_root);
properties_->is_external_media =
std::make_unique<bool>(metadata->folder_feature->is_external_media);
properties_->is_arbitrary_sync_folder = std::make_unique<bool>(
metadata->folder_feature->is_arbitrary_sync_folder);
}
CompleteGetEntryProperties(drive::FILE_ERROR_OK);
}
void SingleEntryPropertiesGetterForDriveFs::CompleteGetEntryProperties(
drive::FileError error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(callback_);
std::move(callback_).Run(std::move(properties_),
drive::FileErrorToBaseFileError(error));
content::GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, this);
}
void FillIconSet(file_manager_private::IconSet* output, void FillIconSet(file_manager_private::IconSet* output,
const chromeos::file_system_provider::IconSet& input) { const chromeos::file_system_provider::IconSet& input) {
DCHECK(output); DCHECK(output);
......
...@@ -7,15 +7,23 @@ ...@@ -7,15 +7,23 @@
#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_UTIL_H_ #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_UTIL_H_
#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_UTIL_H_ #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_UTIL_H_
#include <memory>
#include <vector> #include <vector>
#include "base/callback.h"
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/strcat.h"
#include "chrome/browser/chromeos/file_system_provider/icon_set.h" #include "chrome/browser/chromeos/file_system_provider/icon_set.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom-forward.h"
#include "components/drive/file_errors.h"
#include "storage/browser/file_system/file_system_url.h"
class GURL; class GURL;
class Profile; class Profile;
namespace base { namespace base {
class File;
class FilePath; class FilePath;
} }
...@@ -30,6 +38,7 @@ class EventLogger; ...@@ -30,6 +38,7 @@ class EventLogger;
namespace extensions { namespace extensions {
namespace api { namespace api {
namespace file_manager_private { namespace file_manager_private {
struct EntryProperties;
struct IconSet; struct IconSet;
struct VolumeMetadata; struct VolumeMetadata;
} }
...@@ -46,6 +55,47 @@ class Volume; ...@@ -46,6 +55,47 @@ class Volume;
namespace util { namespace util {
class SingleEntryPropertiesGetterForDriveFs {
public:
using ResultCallback = base::OnceCallback<void(
std::unique_ptr<extensions::api::file_manager_private::EntryProperties>
properties,
base::File::Error error)>;
// Creates an instance and starts the process.
static void Start(const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback);
~SingleEntryPropertiesGetterForDriveFs();
SingleEntryPropertiesGetterForDriveFs(
const SingleEntryPropertiesGetterForDriveFs&) = delete;
SingleEntryPropertiesGetterForDriveFs& operator=(
const SingleEntryPropertiesGetterForDriveFs&) = delete;
private:
SingleEntryPropertiesGetterForDriveFs(
const storage::FileSystemURL& file_system_url,
Profile* const profile,
ResultCallback callback);
void StartProcess();
void OnGetFileInfo(drive::FileError error,
drivefs::mojom::FileMetadataPtr metadata);
void CompleteGetEntryProperties(drive::FileError error);
// Given parameters.
ResultCallback callback_;
const storage::FileSystemURL file_system_url_;
Profile* const running_profile_;
// Values used in the process.
std::unique_ptr<extensions::api::file_manager_private::EntryProperties>
properties_;
base::WeakPtrFactory<SingleEntryPropertiesGetterForDriveFs> weak_ptr_factory_{
this};
};
// Fills out IDL IconSet struct with the provided icon set. // Fills out IDL IconSet struct with the provided icon set.
void FillIconSet(extensions::api::file_manager_private::IconSet* output, void FillIconSet(extensions::api::file_manager_private::IconSet* output,
const chromeos::file_system_provider::IconSet& input); const chromeos::file_system_provider::IconSet& input);
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sharesheet/drive_share_action.h"
#include <memory>
#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/sharesheet/sharesheet_types.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "components/services/app_service/public/mojom/types.mojom.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
DriveShareAction::DriveShareAction() = default;
DriveShareAction::~DriveShareAction() = default;
const base::string16 DriveShareAction::GetActionName() {
// TODO(crbug.com/1097623): Get the Action name from files app strings.
return base::UTF8ToUTF16("ShareWithOthers");
}
const gfx::ImageSkia DriveShareAction::GetActionIcon() {
// TODO(crbug.com/1097623): Get the icon.
return gfx::ImageSkia();
}
void DriveShareAction::LaunchAction(
sharesheet::SharesheetController* controller,
views::View* root_view,
apps::mojom::IntentPtr intent) {
DCHECK(intent->drive_share_url.has_value());
NavigateParams params(controller->GetProfile(),
intent->drive_share_url.value(),
ui::PAGE_TRANSITION_LINK);
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
Navigate(&params);
}
void DriveShareAction::OnClosing(sharesheet::SharesheetController* controller) {
controller_ = nullptr;
}
bool DriveShareAction::ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document) {
return intent->drive_share_url.has_value() &&
!intent->drive_share_url->is_empty();
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SHARESHEET_DRIVE_SHARE_ACTION_H_
#define CHROME_BROWSER_SHARESHEET_DRIVE_SHARE_ACTION_H_
#include "chrome/browser/sharesheet/share_action.h"
class DriveShareAction : public sharesheet::ShareAction {
public:
DriveShareAction();
~DriveShareAction() override;
DriveShareAction(const DriveShareAction&) = delete;
DriveShareAction& operator=(const DriveShareAction&) = delete;
// sharesheet::ShareAction:
const base::string16 GetActionName() override;
const gfx::ImageSkia GetActionIcon() override;
void LaunchAction(sharesheet::SharesheetController* controller,
views::View* root_view,
apps::mojom::IntentPtr intent) override;
void OnClosing(sharesheet::SharesheetController* controller) override;
bool ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document) override;
private:
sharesheet::SharesheetController* controller_ = nullptr;
};
#endif // CHROME_BROWSER_SHARESHEET_DRIVE_SHARE_ACTION_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sharesheet/share_action.h"
namespace sharesheet {
bool ShareAction::ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document) {
return !contains_hosted_document;
}
} // namespace sharesheet
...@@ -45,6 +45,12 @@ class ShareAction { ...@@ -45,6 +45,12 @@ class ShareAction {
// shutdown when OnClosing is called, and not use |root_view| or |controller| // shutdown when OnClosing is called, and not use |root_view| or |controller|
// once the method completes as they will be destroyed. // once the method completes as they will be destroyed.
virtual void OnClosing(SharesheetController* controller) = 0; virtual void OnClosing(SharesheetController* controller) = 0;
// Return true if the action should be shown on the sharesheet. By default,
// the actions are only visible if the files don't contain a Google Drive
// hosted document.
virtual bool ShouldShowAction(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document);
}; };
} // namespace sharesheet } // namespace sharesheet
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/nearby_sharing/sharesheet/nearby_share_action.h" #include "chrome/browser/nearby_sharing/sharesheet/nearby_share_action.h"
#include "chrome/browser/sharesheet/drive_share_action.h"
#endif #endif
namespace sharesheet { namespace sharesheet {
...@@ -20,6 +21,7 @@ SharesheetActionCache::SharesheetActionCache() { ...@@ -20,6 +21,7 @@ SharesheetActionCache::SharesheetActionCache() {
if (base::FeatureList::IsEnabled(features::kNearbySharing)) { if (base::FeatureList::IsEnabled(features::kNearbySharing)) {
AddShareAction(std::make_unique<NearbyShareAction>()); AddShareAction(std::make_unique<NearbyShareAction>());
} }
AddShareAction(std::make_unique<DriveShareAction>());
#endif #endif
} }
...@@ -43,6 +45,17 @@ ShareAction* SharesheetActionCache::GetActionFromName( ...@@ -43,6 +45,17 @@ ShareAction* SharesheetActionCache::GetActionFromName(
return nullptr; return nullptr;
} }
bool SharesheetActionCache::HasVisibleActions(
const apps::mojom::IntentPtr& intent,
bool contains_google_document) {
for (auto& action : share_actions_) {
if (action->ShouldShowAction(intent, contains_google_document)) {
return true;
}
}
return false;
}
void SharesheetActionCache::AddShareAction( void SharesheetActionCache::AddShareAction(
std::unique_ptr<ShareAction> action) { std::unique_ptr<ShareAction> action) {
DCHECK_EQ(action->GetActionIcon().size(), gfx::Size(kIconSize, kIconSize)); DCHECK_EQ(action->GetActionIcon().size(), gfx::Size(kIconSize, kIconSize));
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/services/app_service/public/mojom/types.mojom.h"
namespace sharesheet { namespace sharesheet {
...@@ -28,6 +29,9 @@ class SharesheetActionCache { ...@@ -28,6 +29,9 @@ class SharesheetActionCache {
const std::vector<std::unique_ptr<ShareAction>>& GetShareActions(); const std::vector<std::unique_ptr<ShareAction>>& GetShareActions();
bool HasVisibleActions(const apps::mojom::IntentPtr& intent,
bool contains_google_document);
private: private:
void AddShareAction(std::unique_ptr<ShareAction> action); void AddShareAction(std::unique_ptr<ShareAction> action);
......
...@@ -40,18 +40,25 @@ void SharesheetService::ShowBubble(views::View* bubble_anchor_view, ...@@ -40,18 +40,25 @@ void SharesheetService::ShowBubble(views::View* bubble_anchor_view,
std::make_unique<SharesheetServiceDelegate>( std::make_unique<SharesheetServiceDelegate>(
delegate_counter_++, std::move(bubble_anchor_view), this); delegate_counter_++, std::move(bubble_anchor_view), this);
ShowBubbleWithDelegate(std::move(sharesheet_service_delegate), ShowBubbleWithDelegate(std::move(sharesheet_service_delegate),
std::move(intent)); std::move(intent), /*contains_hosted_document=*/false);
} }
void SharesheetService::ShowBubble(content::WebContents* web_contents, void SharesheetService::ShowBubble(content::WebContents* web_contents,
apps::mojom::IntentPtr intent) { apps::mojom::IntentPtr intent) {
ShowBubble(web_contents, std::move(intent),
/*contains_hosted_document=*/false);
}
void SharesheetService::ShowBubble(content::WebContents* web_contents,
apps::mojom::IntentPtr intent,
bool contains_hosted_document) {
DCHECK(intent->action == apps_util::kIntentActionSend || DCHECK(intent->action == apps_util::kIntentActionSend ||
intent->action == apps_util::kIntentActionSendMultiple); intent->action == apps_util::kIntentActionSendMultiple);
auto sharesheet_service_delegate = auto sharesheet_service_delegate =
std::make_unique<SharesheetServiceDelegate>(delegate_counter_++, std::make_unique<SharesheetServiceDelegate>(delegate_counter_++,
web_contents, this); web_contents, this);
ShowBubbleWithDelegate(std::move(sharesheet_service_delegate), ShowBubbleWithDelegate(std::move(sharesheet_service_delegate),
std::move(intent)); std::move(intent), contains_hosted_document);
} }
// Cleanup delegate when bubble closes. // Cleanup delegate when bubble closes.
...@@ -117,12 +124,14 @@ SharesheetServiceDelegate* SharesheetService::GetDelegate( ...@@ -117,12 +124,14 @@ SharesheetServiceDelegate* SharesheetService::GetDelegate(
return nullptr; return nullptr;
} }
bool SharesheetService::HasShareTargets(const apps::mojom::IntentPtr& intent) { bool SharesheetService::HasShareTargets(const apps::mojom::IntentPtr& intent,
auto& actions = sharesheet_action_cache_->GetShareActions(); bool contains_hosted_document) {
std::vector<apps::IntentLaunchInfo> intent_launch_info = std::vector<apps::IntentLaunchInfo> intent_launch_info =
app_service_proxy_->GetAppsForIntent(intent); app_service_proxy_->GetAppsForIntent(intent);
return !actions.empty() || !intent_launch_info.empty(); return sharesheet_action_cache_->HasVisibleActions(
intent, contains_hosted_document) ||
(!contains_hosted_document && !intent_launch_info.empty());
} }
Profile* SharesheetService::GetProfile() { Profile* SharesheetService::GetProfile() {
...@@ -185,19 +194,23 @@ void SharesheetService::OnAppIconsLoaded( ...@@ -185,19 +194,23 @@ void SharesheetService::OnAppIconsLoaded(
void SharesheetService::ShowBubbleWithDelegate( void SharesheetService::ShowBubbleWithDelegate(
std::unique_ptr<SharesheetServiceDelegate> delegate, std::unique_ptr<SharesheetServiceDelegate> delegate,
apps::mojom::IntentPtr intent) { apps::mojom::IntentPtr intent,
bool contains_hosted_document) {
std::vector<TargetInfo> targets; std::vector<TargetInfo> targets;
auto& actions = sharesheet_action_cache_->GetShareActions(); auto& actions = sharesheet_action_cache_->GetShareActions();
auto iter = actions.begin(); auto iter = actions.begin();
while (iter != actions.end()) { while (iter != actions.end()) {
targets.emplace_back(TargetType::kAction, (*iter)->GetActionIcon(), if ((*iter)->ShouldShowAction(intent, contains_hosted_document)) {
(*iter)->GetActionName(), (*iter)->GetActionName(), targets.emplace_back(TargetType::kAction, (*iter)->GetActionIcon(),
base::nullopt, base::nullopt); (*iter)->GetActionName(), (*iter)->GetActionName(),
base::nullopt, base::nullopt);
}
++iter; ++iter;
} }
std::vector<apps::IntentLaunchInfo> intent_launch_info = std::vector<apps::IntentLaunchInfo> intent_launch_info =
app_service_proxy_->GetAppsForIntent(intent); contains_hosted_document ? std::vector<apps::IntentLaunchInfo>()
: app_service_proxy_->GetAppsForIntent(intent);
sharesheet::SharesheetMetrics::RecordSharesheetAppCount( sharesheet::SharesheetMetrics::RecordSharesheetAppCount(
intent_launch_info.size()); intent_launch_info.size());
LoadAppIcons(std::move(intent_launch_info), std::move(targets), 0, LoadAppIcons(std::move(intent_launch_info), std::move(targets), 0,
......
...@@ -47,11 +47,15 @@ class SharesheetService : public KeyedService { ...@@ -47,11 +47,15 @@ class SharesheetService : public KeyedService {
// Displays the dialog (aka bubble) for sharing content (or files) with // Displays the dialog (aka bubble) for sharing content (or files) with
// other applications and targets. |intent| contains the list of the // other applications and targets. |intent| contains the list of the
// files/content to be shared. // files/content to be shared. If the files to share contains Google
// Drive hosted document, only drive share action will be shown.
void ShowBubble(views::View* bubble_anchor_view, void ShowBubble(views::View* bubble_anchor_view,
apps::mojom::IntentPtr intent); apps::mojom::IntentPtr intent);
void ShowBubble(content::WebContents* web_contents, void ShowBubble(content::WebContents* web_contents,
apps::mojom::IntentPtr intent); apps::mojom::IntentPtr intent);
void ShowBubble(content::WebContents* web_contents,
apps::mojom::IntentPtr intent,
bool contains_hosted_document);
void OnBubbleClosed(uint32_t id, const base::string16& active_action); void OnBubbleClosed(uint32_t id, const base::string16& active_action);
void OnTargetSelected(uint32_t delegate_id, void OnTargetSelected(uint32_t delegate_id,
const base::string16& target_name, const base::string16& target_name,
...@@ -59,7 +63,11 @@ class SharesheetService : public KeyedService { ...@@ -59,7 +63,11 @@ class SharesheetService : public KeyedService {
apps::mojom::IntentPtr intent, apps::mojom::IntentPtr intent,
views::View* share_action_view); views::View* share_action_view);
SharesheetServiceDelegate* GetDelegate(uint32_t delegate_id); SharesheetServiceDelegate* GetDelegate(uint32_t delegate_id);
bool HasShareTargets(const apps::mojom::IntentPtr& intent);
// If the files to share contains a Google Drive hosted document, only the
// drive share action will be shown.
bool HasShareTargets(const apps::mojom::IntentPtr& intent,
bool contains_hosted_document);
Profile* GetProfile(); Profile* GetProfile();
private: private:
...@@ -83,7 +91,8 @@ class SharesheetService : public KeyedService { ...@@ -83,7 +91,8 @@ class SharesheetService : public KeyedService {
void ShowBubbleWithDelegate( void ShowBubbleWithDelegate(
std::unique_ptr<SharesheetServiceDelegate> delegate, std::unique_ptr<SharesheetServiceDelegate> delegate,
apps::mojom::IntentPtr intent); apps::mojom::IntentPtr intent,
bool contains_hosted_document);
uint32_t delegate_counter_ = 0; uint32_t delegate_counter_ = 0;
Profile* profile_; Profile* profile_;
......
...@@ -153,6 +153,20 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles( ...@@ -153,6 +153,20 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
return intent; return intent;
} }
apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url,
const std::string& mime_type,
const GURL& drive_share_url) {
auto intent = apps::mojom::Intent::New();
intent->action = kIntentActionSend;
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;
}
return intent;
}
bool ConditionValueMatches( bool ConditionValueMatches(
const std::string& value, const std::string& value,
const apps::mojom::ConditionValuePtr& condition_value) { const apps::mojom::ConditionValuePtr& condition_value) {
......
...@@ -28,6 +28,13 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles( ...@@ -28,6 +28,13 @@ apps::mojom::IntentPtr CreateShareIntentFromFiles(
const std::vector<GURL>& filesystem_urls, const std::vector<GURL>& filesystem_urls,
const std::vector<std::string>& mime_types); const std::vector<std::string>& mime_types);
// Create an intent struct from the filesystem url, mime type
// and the drive share url for a Google Drive file.
apps::mojom::IntentPtr CreateShareIntentFromDriveFile(
const GURL& filesystem_url,
const std::string& mime_type,
const GURL& drive_share_url);
// Return true if |value| matches with the |condition_value|, based on the // Return true if |value| matches with the |condition_value|, based on the
// pattern match type in the |condition_value|. // pattern match type in the |condition_value|.
bool ConditionValueMatches( bool ConditionValueMatches(
......
...@@ -325,6 +325,10 @@ struct Intent { ...@@ -325,6 +325,10 @@ struct Intent {
string? mime_type; // MIME type. e.g. text/plain, image/*. string? mime_type; // MIME type. e.g. text/plain, image/*.
array<url.mojom.Url>? file_urls; // The URLs of the files to share. array<url.mojom.Url>? file_urls; // The URLs of the files to share.
string? activity_name; // The activity for the app to launch. string? activity_name; // The activity for the app to launch.
// The Drive share URL, this is only filled if the intent contains a file
// from Google Drive.
url.mojom.Url? drive_share_url;
}; };
// Represents a group of |app_ids| that is no longer preferred app of their // Represents a group of |app_ids| that is no longer preferred app of their
......
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