Commit b7a13e3e authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Media gallery: Decouple media gallery from extension blob reader.

Currently media gallery api reads media data from a blob in browser
process with extension's blob reader.

This CL abstracts a factory class to create MediaDataSource, so that
Android can implement a different source that read data from local file.

Eventually, media gallery api will not depend on extension, which is
not supported on Android, and can have different data source.

Bug: 826021,826975
Change-Id: I6d9d6c0ffc8cbae42cd036af34fb4944cf25e685
Reviewed-on: https://chromium-review.googlesource.com/997012
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarTommy Li <tommycli@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550653}
parent e55f61d6
...@@ -247,6 +247,8 @@ static_library("extensions") { ...@@ -247,6 +247,8 @@ static_library("extensions") {
"api/language_settings_private/language_settings_private_delegate_factory.h", "api/language_settings_private/language_settings_private_delegate_factory.h",
"api/management/chrome_management_api_delegate.cc", "api/management/chrome_management_api_delegate.cc",
"api/management/chrome_management_api_delegate.h", "api/management/chrome_management_api_delegate.h",
"api/media_galleries/blob_data_source_factory.cc",
"api/media_galleries/blob_data_source_factory.h",
"api/media_galleries/media_galleries_api.cc", "api/media_galleries/media_galleries_api.cc",
"api/media_galleries/media_galleries_api.h", "api/media_galleries/media_galleries_api.h",
"api/messaging/chrome_messaging_delegate.cc", "api/messaging/chrome_messaging_delegate.cc",
......
// Copyright 2018 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/extensions/api/media_galleries/blob_data_source_factory.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/blob_reader.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace extensions {
namespace {
// Media data source that reads data from a blob in browser process.
class BlobMediaDataSource : public chrome::mojom::MediaDataSource {
public:
BlobMediaDataSource(chrome::mojom::MediaDataSourcePtr* interface,
content::BrowserContext* browser_context,
const std::string& blob_uuid,
BlobDataSourceFactory::MediaDataCallback callback)
: binding_(this, mojo::MakeRequest(interface)),
browser_context_(browser_context),
blob_uuid_(blob_uuid),
callback_(callback),
weak_factory_(this) {}
~BlobMediaDataSource() override = default;
private:
// chrome::mojom::MediaDataSource implementation.
void Read(int64_t position,
int64_t length,
chrome::mojom::MediaDataSource::ReadCallback callback) override {
StartBlobRequest(std::move(callback), position, length);
}
void StartBlobRequest(chrome::mojom::MediaDataSource::ReadCallback callback,
int64_t position,
int64_t length) {
BlobReader* reader = new BlobReader( // BlobReader is self-deleting.
browser_context_, blob_uuid_,
base::BindRepeating(&BlobMediaDataSource::OnBlobReaderDone,
weak_factory_.GetWeakPtr(),
base::Passed(&callback)));
reader->SetByteRange(position, length);
reader->Start();
}
void OnBlobReaderDone(chrome::mojom::MediaDataSource::ReadCallback callback,
std::unique_ptr<std::string> data,
int64_t size) {
callback_.Run(std::move(callback), std::move(data));
}
mojo::Binding<chrome::mojom::MediaDataSource> binding_;
content::BrowserContext* const browser_context_;
std::string blob_uuid_;
BlobDataSourceFactory::MediaDataCallback callback_;
base::WeakPtrFactory<BlobMediaDataSource> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BlobMediaDataSource);
};
} // namespace
BlobDataSourceFactory::BlobDataSourceFactory(
content::BrowserContext* browser_context,
const std::string& blob_uuid)
: browser_context_(browser_context), blob_uuid_(blob_uuid) {}
BlobDataSourceFactory::~BlobDataSourceFactory() = default;
std::unique_ptr<chrome::mojom::MediaDataSource>
BlobDataSourceFactory::CreateMediaDataSource(
chrome::mojom::MediaDataSourcePtr* request,
MediaDataCallback media_data_callback) {
return std::make_unique<BlobMediaDataSource>(request, browser_context_,
blob_uuid_, media_data_callback);
}
} // namespace extensions
// Copyright 2018 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_EXTENSIONS_API_MEDIA_GALLERIES_BLOB_DATA_SOURCE_FACTORY_H_
#define CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_BLOB_DATA_SOURCE_FACTORY_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "chrome/services/media_gallery_util/public/cpp/safe_media_metadata_parser.h"
#include "chrome/services/media_gallery_util/public/mojom/media_parser.mojom.h"
namespace content {
class BrowserContext;
} // namespace content
namespace extensions {
// Factory to provide media data source for extension media gallery API.
// Internally it will read media data from a blob in browser process.
class BlobDataSourceFactory
: public SafeMediaMetadataParser::MediaDataSourceFactory {
public:
BlobDataSourceFactory(content::BrowserContext* browser_context,
const std::string& blob_uuid);
~BlobDataSourceFactory() override;
private:
// SafeMediaMetadataParser::MediaDataSourceFactory implementation.
std::unique_ptr<chrome::mojom::MediaDataSource> CreateMediaDataSource(
chrome::mojom::MediaDataSourcePtr* request,
MediaDataCallback media_data_callback) override;
content::BrowserContext* browser_context_;
std::string blob_uuid_;
MediaDataCallback callback_;
DISALLOW_COPY_AND_ASSIGN(BlobDataSourceFactory);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_BLOB_DATA_SOURCE_FACTORY_H_
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/media_galleries/blob_data_source_factory.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/media_galleries/gallery_watch_manager.h" #include "chrome/browser/media_galleries/gallery_watch_manager.h"
...@@ -674,9 +675,11 @@ void MediaGalleriesGetMetadataFunction::GetMetadata( ...@@ -674,9 +675,11 @@ void MediaGalleriesGetMetadataFunction::GetMetadata(
metadata_type == MediaGalleries::GET_METADATA_TYPE_ALL || metadata_type == MediaGalleries::GET_METADATA_TYPE_ALL ||
metadata_type == MediaGalleries::GET_METADATA_TYPE_NONE; metadata_type == MediaGalleries::GET_METADATA_TYPE_NONE;
auto media_data_source_factory =
std::make_unique<BlobDataSourceFactory>(GetProfile(), blob_uuid);
auto parser = std::make_unique<SafeMediaMetadataParser>( auto parser = std::make_unique<SafeMediaMetadataParser>(
GetProfile(), blob_uuid, total_blob_length, mime_type, total_blob_length, mime_type, get_attached_images,
get_attached_images); std::move(media_data_source_factory));
SafeMediaMetadataParser* parser_ptr = parser.get(); SafeMediaMetadataParser* parser_ptr = parser.get();
parser_ptr->Start( parser_ptr->Start(
content::ServiceManagerConnection::GetForProcess()->GetConnector(), content::ServiceManagerConnection::GetForProcess()->GetConnector(),
......
...@@ -36,7 +36,7 @@ void IPCDataSource::Read(int64_t position, ...@@ -36,7 +36,7 @@ void IPCDataSource::Read(int64_t position,
utility_task_runner_->PostTask( utility_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&IPCDataSource::ReadBlob, base::Unretained(this), base::BindOnce(&IPCDataSource::ReadMediaData, base::Unretained(this),
destination, callback, position, size)); destination, callback, position, size));
} }
...@@ -55,10 +55,10 @@ void IPCDataSource::SetBitrate(int bitrate) { ...@@ -55,10 +55,10 @@ void IPCDataSource::SetBitrate(int bitrate) {
DCHECK_CALLED_ON_VALID_THREAD(data_source_thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(data_source_thread_checker_);
} }
void IPCDataSource::ReadBlob(uint8_t* destination, void IPCDataSource::ReadMediaData(uint8_t* destination,
const DataSource::ReadCB& callback, const DataSource::ReadCB& callback,
int64_t position, int64_t position,
int size) { int size) {
DCHECK_CALLED_ON_VALID_THREAD(utility_thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(utility_thread_checker_);
CHECK_GE(total_size_, 0); CHECK_GE(total_size_, 0);
CHECK_GE(position, 0); CHECK_GE(position, 0);
...@@ -69,7 +69,7 @@ void IPCDataSource::ReadBlob(uint8_t* destination, ...@@ -69,7 +69,7 @@ void IPCDataSource::ReadBlob(uint8_t* destination,
int64_t clamped_size = int64_t clamped_size =
std::min(static_cast<int64_t>(size), total_size_ - position); std::min(static_cast<int64_t>(size), total_size_ - position);
media_data_source_->ReadBlob( media_data_source_->Read(
position, clamped_size, position, clamped_size,
base::BindOnce(&IPCDataSource::ReadDone, base::Unretained(this), base::BindOnce(&IPCDataSource::ReadDone, base::Unretained(this),
destination, callback)); destination, callback));
......
...@@ -42,11 +42,11 @@ class IPCDataSource : public media::DataSource { ...@@ -42,11 +42,11 @@ class IPCDataSource : public media::DataSource {
void SetBitrate(int bitrate) override; void SetBitrate(int bitrate) override;
private: private:
// Blob data read helpers: must be run on the utility thread. // Media data read helpers: must be run on the utility thread.
void ReadBlob(uint8_t* destination, void ReadMediaData(uint8_t* destination,
const ReadCB& callback, const ReadCB& callback,
int64_t position, int64_t position,
int size); int size);
void ReadDone(uint8_t* destination, void ReadDone(uint8_t* destination,
const ReadCB& callback, const ReadCB& callback,
const std::vector<uint8_t>& data); const std::vector<uint8_t>& data);
......
...@@ -8,47 +8,17 @@ ...@@ -8,47 +8,17 @@
#include "base/callback.h" #include "base/callback.h"
#include "chrome/services/media_gallery_util/public/mojom/constants.mojom.h" #include "chrome/services/media_gallery_util/public/mojom/constants.mojom.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/blob_reader.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
class SafeMediaMetadataParser::MediaDataSourceImpl
: public chrome::mojom::MediaDataSource {
public:
MediaDataSourceImpl(SafeMediaMetadataParser* owner,
chrome::mojom::MediaDataSourcePtr* interface)
: binding_(this, mojo::MakeRequest(interface)),
safe_media_metadata_parser_(owner) {}
~MediaDataSourceImpl() override = default;
private:
void ReadBlob(int64_t position,
int64_t length,
ReadBlobCallback callback) override {
safe_media_metadata_parser_->StartBlobRequest(std::move(callback), position,
length);
}
mojo::Binding<chrome::mojom::MediaDataSource> binding_;
// |safe_media_metadata_parser_| owns |this|.
SafeMediaMetadataParser* const safe_media_metadata_parser_;
DISALLOW_COPY_AND_ASSIGN(MediaDataSourceImpl);
};
SafeMediaMetadataParser::SafeMediaMetadataParser( SafeMediaMetadataParser::SafeMediaMetadataParser(
content::BrowserContext* browser_context, int64_t size,
const std::string& blob_uuid,
int64_t blob_size,
const std::string& mime_type, const std::string& mime_type,
bool get_attached_images) bool get_attached_images,
: browser_context_(browser_context), std::unique_ptr<MediaDataSourceFactory> media_source_factory)
blob_uuid_(blob_uuid), : size_(size),
blob_size_(blob_size),
mime_type_(mime_type), mime_type_(mime_type),
get_attached_images_(get_attached_images), get_attached_images_(get_attached_images),
media_source_factory_(std::move(media_source_factory)),
weak_factory_(this) {} weak_factory_(this) {}
SafeMediaMetadataParser::~SafeMediaMetadataParser() = default; SafeMediaMetadataParser::~SafeMediaMetadataParser() = default;
...@@ -65,9 +35,11 @@ void SafeMediaMetadataParser::Start(service_manager::Connector* connector, ...@@ -65,9 +35,11 @@ void SafeMediaMetadataParser::Start(service_manager::Connector* connector,
void SafeMediaMetadataParser::OnMediaParserCreated() { void SafeMediaMetadataParser::OnMediaParserCreated() {
chrome::mojom::MediaDataSourcePtr source; chrome::mojom::MediaDataSourcePtr source;
media_data_source_ = std::make_unique<MediaDataSourceImpl>(this, &source); media_data_source_ = media_source_factory_->CreateMediaDataSource(
&source, base::BindRepeating(&SafeMediaMetadataParser::OnMediaDataReady,
weak_factory_.GetWeakPtr()));
media_parser()->ParseMediaMetadata( media_parser()->ParseMediaMetadata(
mime_type_, blob_size_, get_attached_images_, std::move(source), mime_type_, size_, get_attached_images_, std::move(source),
base::BindOnce(&SafeMediaMetadataParser::ParseMediaMetadataDone, base::BindOnce(&SafeMediaMetadataParser::ParseMediaMetadataDone,
base::Unretained(this))); base::Unretained(this)));
} }
...@@ -96,22 +68,9 @@ void SafeMediaMetadataParser::ParseMediaMetadataDone( ...@@ -96,22 +68,9 @@ void SafeMediaMetadataParser::ParseMediaMetadataDone(
std::move(attached_images_copy)); std::move(attached_images_copy));
} }
void SafeMediaMetadataParser::StartBlobRequest( void SafeMediaMetadataParser::OnMediaDataReady(
chrome::mojom::MediaDataSource::ReadBlobCallback callback, chrome::mojom::MediaDataSource::ReadCallback callback,
int64_t position, std::unique_ptr<std::string> data) {
int64_t length) {
BlobReader* reader = new BlobReader( // BlobReader is self-deleting.
browser_context_, blob_uuid_,
base::Bind(&SafeMediaMetadataParser::BlobReaderDone,
weak_factory_.GetWeakPtr(), base::Passed(&callback)));
reader->SetByteRange(position, length);
reader->Start();
}
void SafeMediaMetadataParser::BlobReaderDone(
chrome::mojom::MediaDataSource::ReadBlobCallback callback,
std::unique_ptr<std::string> data,
int64_t /* blob_total_size */) {
if (media_parser()) if (media_parser())
std::move(callback).Run(std::vector<uint8_t>(data->begin(), data->end())); std::move(callback).Run(std::vector<uint8_t>(data->begin(), data->end()));
} }
...@@ -18,18 +18,14 @@ ...@@ -18,18 +18,14 @@
#include "chrome/services/media_gallery_util/public/cpp/media_parser_provider.h" #include "chrome/services/media_gallery_util/public/cpp/media_parser_provider.h"
#include "chrome/services/media_gallery_util/public/mojom/media_parser.mojom.h" #include "chrome/services/media_gallery_util/public/mojom/media_parser.mojom.h"
namespace content {
class BrowserContext;
}
namespace service_manager { namespace service_manager {
class Connector; class Connector;
} }
// Parses the media metadata of a Blob safely in a utility process. This class // Parses the media metadata safely in a utility process. This class expects the
// expects the MIME type of the Blob to be already known. It creates a utility // MIME type and the size of media data to be already known. It creates a
// process to do further MIME-type-specific metadata extraction from the Blob // utility process to do further MIME-type-specific metadata extraction from the
// data. // media data.
class SafeMediaMetadataParser : public MediaParserProvider { class SafeMediaMetadataParser : public MediaParserProvider {
public: public:
typedef base::OnceCallback<void( typedef base::OnceCallback<void(
...@@ -38,11 +34,26 @@ class SafeMediaMetadataParser : public MediaParserProvider { ...@@ -38,11 +34,26 @@ class SafeMediaMetadataParser : public MediaParserProvider {
std::unique_ptr<std::vector<metadata::AttachedImage>> attached_images)> std::unique_ptr<std::vector<metadata::AttachedImage>> attached_images)>
DoneCallback; DoneCallback;
SafeMediaMetadataParser(content::BrowserContext* browser_context, // Factory to create media data source instance. The underlying implementation
const std::string& blob_uuid, // may read from different kinds of storage.
int64_t blob_size, class MediaDataSourceFactory {
const std::string& mime_type, public:
bool get_attached_images); typedef base::RepeatingCallback<void(
chrome::mojom::MediaDataSource::ReadCallback callback,
std::unique_ptr<std::string> data)>
MediaDataCallback;
virtual std::unique_ptr<chrome::mojom::MediaDataSource>
CreateMediaDataSource(chrome::mojom::MediaDataSourcePtr* request,
MediaDataCallback media_data_callback) = 0;
virtual ~MediaDataSourceFactory() {}
};
SafeMediaMetadataParser(
int64_t size,
const std::string& mime_type,
bool get_attached_images,
std::unique_ptr<MediaDataSourceFactory> media_source_factory);
~SafeMediaMetadataParser() override; ~SafeMediaMetadataParser() override;
// Should be called on the thread |connector| is associated with. |callback| // Should be called on the thread |connector| is associated with. |callback|
...@@ -50,8 +61,6 @@ class SafeMediaMetadataParser : public MediaParserProvider { ...@@ -50,8 +61,6 @@ class SafeMediaMetadataParser : public MediaParserProvider {
void Start(service_manager::Connector* connector, DoneCallback callback); void Start(service_manager::Connector* connector, DoneCallback callback);
private: private:
class MediaDataSourceImpl;
// MediaParserProvider implementation: // MediaParserProvider implementation:
void OnMediaParserCreated() override; void OnMediaParserCreated() override;
void OnConnectionError() override; void OnConnectionError() override;
...@@ -62,27 +71,19 @@ class SafeMediaMetadataParser : public MediaParserProvider { ...@@ -62,27 +71,19 @@ class SafeMediaMetadataParser : public MediaParserProvider {
std::unique_ptr<base::DictionaryValue> metadata_dictionary, std::unique_ptr<base::DictionaryValue> metadata_dictionary,
const std::vector<metadata::AttachedImage>& attached_images); const std::vector<metadata::AttachedImage>& attached_images);
// Starts to read the blob data and sends the data back to the utility // Invoked when the media data has been read, which will be sent back to
// process. // utility process soon. |data| might be partial content of the media data.
void StartBlobRequest( void OnMediaDataReady(chrome::mojom::MediaDataSource::ReadCallback callback,
chrome::mojom::MediaDataSource::ReadBlobCallback callback, std::unique_ptr<std::string> data);
int64_t position,
int64_t length); const int64_t size_;
// Invoked when the full blob content has been read.
void BlobReaderDone(chrome::mojom::MediaDataSource::ReadBlobCallback callback,
std::unique_ptr<std::string> data,
int64_t /* blob_total_size */);
content::BrowserContext* const browser_context_;
const std::string blob_uuid_;
const int64_t blob_size_;
const std::string mime_type_; const std::string mime_type_;
bool get_attached_images_; bool get_attached_images_;
DoneCallback callback_; DoneCallback callback_;
std::unique_ptr<MediaDataSourceImpl> media_data_source_; std::unique_ptr<chrome::mojom::MediaDataSource> media_data_source_;
std::unique_ptr<MediaDataSourceFactory> media_source_factory_;
base::WeakPtrFactory<SafeMediaMetadataParser> weak_factory_; base::WeakPtrFactory<SafeMediaMetadataParser> weak_factory_;
......
...@@ -9,7 +9,7 @@ import "mojo/public/mojom/base/file.mojom"; ...@@ -9,7 +9,7 @@ import "mojo/public/mojom/base/file.mojom";
import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/time.mojom";
interface MediaParser { interface MediaParser {
// Extracts metadata from a |mime_type| blob of data of |total_size| and // Extracts metadata from media data with |mime_type|, |total_size| and
// available from |media_data_source|. If there are images referred to in the // available from |media_data_source|. If there are images referred to in the
// metadata, and |get_attached_images| is true, return the images in // metadata, and |get_attached_images| is true, return the images in
// |attached_images|. // |attached_images|.
...@@ -47,9 +47,9 @@ interface MediaParserFactory { ...@@ -47,9 +47,9 @@ interface MediaParserFactory {
}; };
interface MediaDataSource { interface MediaDataSource {
// ParseMediaMetadata interface used to read blob data for parsing from the // ParseMediaMetadata interface used to read data for parsing from the
// calling process. // calling process.
ReadBlob(int64 position, int64 length) => (array<uint8> data); Read(int64 position, int64 length) => (array<uint8> data);
}; };
struct AttachedImage { struct AttachedImage {
......
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