Commit e790f0c8 authored by Hoch Hochkeppel's avatar Hoch Hochkeppel Committed by Commit Bot

WebShare: Share operation for Windows

Adding a class for performing a navigator.share() operation on Windows,
and corresponding tests.

Originally committed as part of https://crrev.com/c/2443757, but
reverted due to test issues. Patchset 1 is a cherry pick of this
original change (reduced to the files relevant to this portion) for
easy comparison.

Bug: 1035527
Change-Id: I82a61739c168b0a2c9aa9f9f9d20572d8a45a2f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2503819
Commit-Queue: Hoch Hochkeppel <mhochk@microsoft.com>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821806}
parent 8d7f9750
......@@ -4552,6 +4552,8 @@ static_library("browser") {
"upgrade_detector/get_installed_version_win.cc",
"upgrade_detector/registry_monitor.cc",
"upgrade_detector/registry_monitor.h",
"webshare/win/share_operation.cc",
"webshare/win/share_operation.h",
"webshare/win/show_share_ui_for_window_operation.cc",
"webshare/win/show_share_ui_for_window_operation.h",
"win/app_icon.cc",
......
......@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/test/bind_test_util.h"
#include "base/test/fake_iasync_operation_win.h"
#include "base/threading/thread_task_runner_handle.h"
......@@ -61,9 +62,8 @@ class FakeStorageFile final
// API, so we use a temporary ScopedHString to make a copy we can safely own
// and release ownership of the original 'back' to the caller.
base::win::ScopedHString holder(display_name_with_extension);
display_name_with_extension_ =
base::win::ScopedHString::Create(holder.Get());
(void)holder.release();
display_name_with_extension_ = holder.GetAsUTF8();
ignore_result(holder.release());
}
FakeStorageFile(const FakeStorageFile&) = delete;
FakeStorageFile& operator=(const FakeStorageFile&) = delete;
......@@ -198,8 +198,7 @@ class FakeStorageFile final
return E_NOTIMPL;
}
IFACEMETHODIMP get_Name(HSTRING* value) final {
auto copy =
base::win::ScopedHString::Create(display_name_with_extension_.Get());
auto copy = base::win::ScopedHString::Create(display_name_with_extension_);
*value = copy.release();
return S_OK;
}
......@@ -248,8 +247,7 @@ class FakeStorageFile final
streamed_file_data_requested_handler_->Invoke(output_stream.Get()));
}
base::win::ScopedHString display_name_with_extension_ =
base::win::ScopedHString::Create("");
std::string display_name_with_extension_;
bool open_async_in_progress_ = false;
ComPtr<IStreamedFileDataRequestedHandler>
streamed_file_data_requested_handler_;
......
// 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/webshare/win/scoped_share_operation_fake_components.h"
#include <windows.storage.streams.h>
#include <wrl/implements.h>
#include "base/strings/string_piece.h"
#include "base/win/com_init_util.h"
#include "base/win/core_winrt_util.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "chrome/browser/webshare/win/fake_data_writer_factory.h"
#include "chrome/browser/webshare/win/fake_storage_file_statics.h"
#include "chrome/browser/webshare/win/fake_uri_runtime_class_factory.h"
#include "chrome/browser/webshare/win/scoped_fake_data_transfer_manager_interop.h"
#include "chrome/browser/webshare/win/share_operation.h"
#include "testing/gtest/include/gtest/gtest-spi.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace webshare {
namespace {
static FakeDataWriterFactory* g_current_fake_data_writer_factory = nullptr;
static FakeStorageFileStatics* g_current_fake_storage_file_statics = nullptr;
static FakeUriRuntimeClassFactory* g_current_fake_uri_runtime_class_factory =
nullptr;
static HRESULT FakeRoGetActivationFactory(HSTRING class_id,
const IID& iid,
void** out_factory) {
void* instance = nullptr;
base::win::ScopedHString class_id_hstring(class_id);
if (class_id_hstring.Get() == RuntimeClass_Windows_Storage_StorageFile) {
instance = g_current_fake_storage_file_statics;
} else if (class_id_hstring.Get() ==
RuntimeClass_Windows_Storage_Streams_DataWriter) {
instance = g_current_fake_data_writer_factory;
} else if (class_id_hstring.Get() == RuntimeClass_Windows_Foundation_Uri) {
instance = g_current_fake_uri_runtime_class_factory;
}
if (!instance) {
NOTREACHED();
return E_NOTIMPL;
}
*out_factory = instance;
reinterpret_cast<IUnknown*>(instance)->AddRef();
return S_OK;
}
} // namespace
// static
bool ScopedShareOperationFakeComponents::IsSupportedEnvironment() {
return ScopedFakeDataTransferManagerInterop::IsSupportedEnvironment();
}
ScopedShareOperationFakeComponents::ScopedShareOperationFakeComponents() =
default;
ScopedShareOperationFakeComponents::~ScopedShareOperationFakeComponents() {
g_current_fake_data_writer_factory = nullptr;
g_current_fake_storage_file_statics = nullptr;
g_current_fake_uri_runtime_class_factory = nullptr;
ShareOperation::SetRoGetActivationFactoryFunctionForTesting(
&base::win::RoGetActivationFactory);
}
void ScopedShareOperationFakeComponents::SetUp() {
ASSERT_TRUE(IsSupportedEnvironment());
base::win::AssertComInitialized();
ASSERT_NO_FATAL_FAILURE(scoped_fake_data_transfer_manager_interop_.SetUp());
fake_data_writer_factory_ = Microsoft::WRL::Make<FakeDataWriterFactory>();
fake_storage_file_statics_ = Microsoft::WRL::Make<FakeStorageFileStatics>();
fake_uri_runtime_class_factory_ =
Microsoft::WRL::Make<FakeUriRuntimeClassFactory>();
// Confirm there are no competing instances and set these instances
// for use by the main factory function
ASSERT_EQ(g_current_fake_data_writer_factory, nullptr);
g_current_fake_data_writer_factory = fake_data_writer_factory_.Get();
ASSERT_EQ(g_current_fake_storage_file_statics, nullptr);
g_current_fake_storage_file_statics = fake_storage_file_statics_.Get();
ASSERT_EQ(g_current_fake_uri_runtime_class_factory, nullptr);
g_current_fake_uri_runtime_class_factory =
fake_uri_runtime_class_factory_.Get();
ShareOperation::SetRoGetActivationFactoryFunctionForTesting(
&FakeRoGetActivationFactory);
}
FakeDataTransferManagerInterop&
ScopedShareOperationFakeComponents::fake_data_transfer_manager_interop() {
return scoped_fake_data_transfer_manager_interop_.instance();
}
} // namespace webshare
// 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_WEBSHARE_WIN_SCOPED_SHARE_OPERATION_FAKE_COMPONENTS_H_
#define CHROME_BROWSER_WEBSHARE_WIN_SCOPED_SHARE_OPERATION_FAKE_COMPONENTS_H_
#include <wrl/client.h>
#include "chrome/browser/webshare/win/scoped_fake_data_transfer_manager_interop.h"
namespace webshare {
class FakeDataTransferManagerInterop;
class FakeDataWriterFactory;
class FakeStorageFileStatics;
class FakeUriRuntimeClassFactory;
// Creates, registers, and maintains the fake equivalents of various Windows
// APIS used by the ShareOperation, allowing GTests to easily use a
// ShareOperation.
class ScopedShareOperationFakeComponents final {
public:
static bool IsSupportedEnvironment();
ScopedShareOperationFakeComponents();
ScopedShareOperationFakeComponents(
const ScopedShareOperationFakeComponents&) = delete;
ScopedShareOperationFakeComponents& operator=(
const ScopedShareOperationFakeComponents&) = delete;
~ScopedShareOperationFakeComponents();
// Initializes this component, creating test failures if anything does not
// succeed. Intended to be called from a test's SetUp function, after having
// verified this is a supported environment.
void SetUp();
FakeDataTransferManagerInterop& fake_data_transfer_manager_interop();
private:
Microsoft::WRL::ComPtr<FakeDataWriterFactory> fake_data_writer_factory_;
Microsoft::WRL::ComPtr<FakeStorageFileStatics> fake_storage_file_statics_;
Microsoft::WRL::ComPtr<FakeUriRuntimeClassFactory>
fake_uri_runtime_class_factory_;
ScopedFakeDataTransferManagerInterop
scoped_fake_data_transfer_manager_interop_;
};
} // namespace webshare
#endif // CHROME_BROWSER_WEBSHARE_WIN_SCOPED_SHARE_OPERATION_FAKE_COMPONENTS_H_
This diff is collapsed.
// 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_WEBSHARE_WIN_SHARE_OPERATION_H_
#define CHROME_BROWSER_WEBSHARE_WIN_SHARE_OPERATION_H_
#include <memory>
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/win/core_winrt_util.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/mojom/webshare/webshare.mojom.h"
#include "url/gurl.h"
#include <wrl/client.h>
namespace ABI {
namespace Windows {
namespace ApplicationModel {
namespace DataTransfer {
struct IDataPackage;
class IDataRequest;
class IDataRequestDeferral;
class IDataRequestedEventArgs;
} // namespace DataTransfer
} // namespace ApplicationModel
namespace Storage {
class IStorageFile;
class IStorageItem;
} // namespace Storage
} // namespace Windows
} // namespace ABI
namespace base {
namespace win {
template <typename T>
class Vector;
} // namespace win
} // namespace base
namespace webshare {
class ShowShareUIForWindowOperation;
class ShareOperation : content::WebContentsObserver {
public:
static void SetMaxFileBytesForTesting(uint64_t max_file_bytes);
// Test hook for overriding the base RoGetActivationFactory function
static void SetRoGetActivationFactoryFunctionForTesting(
decltype(&base::win::RoGetActivationFactory) value);
ShareOperation(const std::string& title,
const std::string& text,
const GURL& url,
std::vector<blink::mojom::SharedFilePtr> files,
content::WebContents* web_contents);
ShareOperation(const ShareOperation&) = delete;
ShareOperation& operator=(const ShareOperation&) = delete;
~ShareOperation() override;
base::WeakPtr<ShareOperation> AsWeakPtr();
// Starts this Windows Share operation for the previously provided content.
// The |callback| will be invoked upon completion of the operation with a
// value indicating the success of the operation, or if the returned instance
// is destroyed before the operation is completed the |callback| will be
// invoked with a CANCELLED value and the underlying Windows operation will be
// aborted.
void Run(blink::mojom::ShareService::ShareCallback callback);
private:
void OnDataRequested(
ABI::Windows::ApplicationModel::DataTransfer::IDataRequestedEventArgs* e);
bool PutShareContentInDataPackage(
ABI::Windows::ApplicationModel::DataTransfer::IDataRequest* data_request);
bool PutShareContentInEventArgs(
ABI::Windows::ApplicationModel::DataTransfer::IDataRequestedEventArgs* e);
void OnStreamedFileCreated(
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFile> storage_file);
void Complete(const blink::mojom::ShareError share_error);
const std::string title_;
const std::string text_;
const GURL url_;
const std::vector<blink::mojom::SharedFilePtr> files_;
blink::mojom::ShareService::ShareCallback callback_;
Microsoft::WRL::ComPtr<
ABI::Windows::ApplicationModel::DataTransfer::IDataPackage>
data_package_;
Microsoft::WRL::ComPtr<
ABI::Windows::ApplicationModel::DataTransfer::IDataRequestDeferral>
data_request_deferral_;
std::unique_ptr<ShowShareUIForWindowOperation>
show_share_ui_for_window_operation_;
// Though this Vector is declared as using a raw IStorageItem*, because
// IStorageItem implements IUnknown it will be stored internally with
// ComPtrs, so does not need to be specially handled.
Microsoft::WRL::ComPtr<
base::win::Vector<ABI::Windows::Storage::IStorageItem*>>
storage_items_;
base::WeakPtrFactory<ShareOperation> weak_factory_{this};
};
} // namespace webshare
#endif // CHROME_BROWSER_WEBSHARE_WIN_SHARE_OPERATION_H_
This diff is collapsed.
......@@ -338,6 +338,8 @@ static_library("test_support") {
"../browser/webshare/win/fake_uri_runtime_class_factory.h",
"../browser/webshare/win/scoped_fake_data_transfer_manager_interop.cc",
"../browser/webshare/win/scoped_fake_data_transfer_manager_interop.h",
"../browser/webshare/win/scoped_share_operation_fake_components.cc",
"../browser/webshare/win/scoped_share_operation_fake_components.h",
"//chrome/app/chrome_crash_reporter_client_win.cc",
]
public_deps += [
......@@ -5835,6 +5837,7 @@ test("unit_tests") {
"../browser/webshare/win/fake_random_access_stream_unittest.cc",
"../browser/webshare/win/fake_storage_file_statics_unittest.cc",
"../browser/webshare/win/fake_uri_runtime_class_factory_unittest.cc",
"../browser/webshare/win/share_operation_unittest.cc",
"../browser/webshare/win/show_share_ui_for_window_operation_unittest.cc",
]
deps += [
......
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