Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: chrome/browser/extensions/api/media_galleries/media_galleries_api.cc

Issue 250143002: Media Galleries API: Audio/Video attached pictures support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove stray changes. clarify some variable naming Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
index 024efde11debb09e40c1130d6abb8d6812858795..befb9f460ab23e92c4e8a13513c92265d9b31f1c 100644
--- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
@@ -14,6 +14,7 @@
#include "apps/app_window_registry.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
+#include "base/numerics/safe_conversions.h"
#include "base/platform_file.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -21,6 +22,7 @@
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
+#include "chrome/browser/extensions/blob_holder.h"
#include "chrome/browser/extensions/blob_reader.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h"
@@ -37,8 +39,10 @@
#include "chrome/common/pref_names.h"
#include "components/storage_monitor/storage_info.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/fileapi/blob_context.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -52,6 +56,7 @@
#include "grit/generated_resources.h"
#include "net/base/mime_sniffer.h"
#include "ui/base/l10n/l10n_util.h"
+#include "webkit/browser/blob/blob_data_handle.h"
using content::WebContents;
using storage_monitor::MediaStorageUtil;
@@ -83,6 +88,12 @@ const char kIsMediaDeviceKey[] = "isMediaDevice";
const char kIsRemovableKey[] = "isRemovable";
const char kNameKey[] = "name";
+const char kMetadataKey[] = "metadata";
+const char kAttachedImagesBlobInfoKey[] = "attachedImagesBlobInfo";
+const char kBlobUUIDKey[] = "blobUUID";
+const char kTypeKey[] = "type";
+const char kSizeKey[] = "size";
+
MediaFileSystemRegistry* media_file_system_registry() {
return g_browser_process->media_file_system_registry();
}
@@ -825,28 +836,35 @@ bool MediaGalleriesGetMetadataFunction::RunAsync() {
bool mime_type_only = options->metadata_type ==
MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY;
+ // Get attached images by default.
+ bool get_attached_images =
+ options->metadata_type == MediaGalleries::GET_METADATA_TYPE_ALL ||
+ options->metadata_type == MediaGalleries::GET_METADATA_TYPE_NONE;
+
return Setup(GetProfile(), &error_, base::Bind(
&MediaGalleriesGetMetadataFunction::OnPreferencesInit, this,
- mime_type_only, blob_uuid));
+ mime_type_only, get_attached_images, blob_uuid));
}
void MediaGalleriesGetMetadataFunction::OnPreferencesInit(
- bool mime_type_only, const std::string& blob_uuid) {
+ bool mime_type_only, bool get_attached_images,
+ const std::string& blob_uuid) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// BlobReader is self-deleting.
BlobReader* reader = new BlobReader(
GetProfile(),
blob_uuid,
- base::Bind(&MediaGalleriesGetMetadataFunction::SniffMimeType, this,
- mime_type_only, blob_uuid));
+ base::Bind(&MediaGalleriesGetMetadataFunction::GetMetadata, this,
+ mime_type_only, get_attached_images, blob_uuid));
reader->SetByteRange(0, net::kMaxBytesToSniff);
reader->Start();
}
-void MediaGalleriesGetMetadataFunction::SniffMimeType(
- bool mime_type_only, const std::string& blob_uuid,
- scoped_ptr<std::string> blob_header, int64 total_blob_length) {
+void MediaGalleriesGetMetadataFunction::GetMetadata(
+ bool mime_type_only, bool get_attached_images,
+ const std::string& blob_uuid, scoped_ptr<std::string> blob_header,
+ int64 total_blob_length) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
std::string mime_type;
@@ -861,26 +879,116 @@ void MediaGalleriesGetMetadataFunction::SniffMimeType(
if (mime_type_only) {
MediaGalleries::MediaMetadata metadata;
metadata.mime_type = mime_type;
- SetResult(metadata.ToValue().release());
+
+ base::DictionaryValue* result_dictionary = new base::DictionaryValue;
+ result_dictionary->Set(kMetadataKey, metadata.ToValue().release());
+ SetResult(result_dictionary);
SendResponse(true);
return;
}
scoped_refptr<metadata::SafeMediaMetadataParser> parser(
new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid,
- total_blob_length, mime_type));
+ total_blob_length, mime_type,
+ get_attached_images));
parser->Start(base::Bind(
&MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone, this));
}
void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone(
- bool parse_success, base::DictionaryValue* metadata_dictionary) {
+ bool parse_success, scoped_ptr<base::DictionaryValue> metadata_dictionary,
+ scoped_ptr<std::vector<metadata::AttachedImage>> attached_images) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
if (!parse_success) {
SendResponse(false);
return;
}
- SetResult(metadata_dictionary->DeepCopy());
+ DCHECK(attached_images.get());
+ if (attached_images->empty()) {
+ base::DictionaryValue* result_dictionary = new base::DictionaryValue;
+ result_dictionary->Set(kMetadataKey, metadata_dictionary.release());
+ SetResult(result_dictionary);
+ SendResponse(true);
+ return;
+ }
+
+ metadata::AttachedImage* first_image = &attached_images->front();
+ content::BrowserContext::GetBlobContext(GetProfile())->CreateMemoryBackedBlob(
+ first_image->data.c_str(),
+ first_image->data.size(),
+ base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob,
+ this, base::Passed(&metadata_dictionary),
+ base::Passed(&attached_images),
+ base::Passed(make_scoped_ptr(new std::vector<std::string>))));
+}
+
+void MediaGalleriesGetMetadataFunction::ConstructNextBlob(
+ scoped_ptr<base::DictionaryValue> metadata_dictionary,
+ scoped_ptr<std::vector<metadata::AttachedImage>> attached_images,
+ scoped_ptr<std::vector<std::string>> blob_uuids,
+ scoped_ptr<webkit_blob::BlobDataHandle> next_blob) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ DCHECK(metadata_dictionary.get());
+ DCHECK(attached_images.get());
+ DCHECK(blob_uuids.get());
+ DCHECK(next_blob.get());
+
+ DCHECK(!attached_images->empty());
+ DCHECK_LT(blob_uuids->size(), attached_images->size());
+
+ // For the newly constructed blob, add its UUID to list and store reference.
+ blob_uuids->push_back(next_blob->uuid());
+ WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
+ extensions::BlobHolder::CreateForWebContents(contents);
michaeln 2014/05/08 21:22:24 If the holder already exists, is CreateForWebConte
tommycli 2014/05/08 22:57:12 Correct. It does nothing if it already exists.
+ extensions::BlobHolder* holder =
+ extensions::BlobHolder::FromWebContents(contents);
+ holder->HoldBlobReference(next_blob.Pass());
+
+ if (blob_uuids->size() == attached_images->size()) {
+ FinishRequest(metadata_dictionary.Pass(), attached_images.Pass(),
+ blob_uuids.Pass());
+ return;
+ }
+
+ // Construct the next Blob.
+ content::BlobContext* blob_context =
+ content::BrowserContext::GetBlobContext(GetProfile());
+ metadata::AttachedImage* next_image = &(*attached_images)[blob_uuids->size()];
+ blob_context->CreateMemoryBackedBlob(
+ next_image->data.c_str(), next_image->data.size(),
+ base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob,
+ this, base::Passed(&metadata_dictionary),
+ base::Passed(&attached_images), base::Passed(&blob_uuids)));
+}
+
+void MediaGalleriesGetMetadataFunction::FinishRequest(
+ scoped_ptr<base::DictionaryValue> metadata_dictionary,
+ scoped_ptr<std::vector<metadata::AttachedImage>> attached_images,
+ scoped_ptr<std::vector<std::string>> blob_uuids) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(metadata_dictionary.get());
+ DCHECK(attached_images->size() == blob_uuids->size());
+
+ base::DictionaryValue* result_dictionary = new base::DictionaryValue;
+ result_dictionary->Set(kMetadataKey, metadata_dictionary->DeepCopy());
+
+ // The custom JS binding takes ownership of the Blobs in the renderer.
+ base::ListValue* attached_images_list = new base::ListValue;
+ for (size_t i = 0; i < attached_images->size(); ++i) {
+ base::DictionaryValue* attached_image = new base::DictionaryValue;
+ attached_image->Set(kBlobUUIDKey, new base::StringValue((*blob_uuids)[i]));
+ attached_image->Set(kTypeKey, new base::StringValue(
+ (*attached_images)[i].type));
+ attached_image->Set(kSizeKey, new base::FundamentalValue(
+ base::checked_cast<int>((*attached_images)[i].data.size())));
+ attached_images_list->Append(attached_image);
+ }
+ result_dictionary->Set(kAttachedImagesBlobInfoKey, attached_images_list);
+
+ SetResult(result_dictionary);
SendResponse(true);
michaeln 2014/05/08 21:22:24 What happens if the page which has invoked this me
tommycli 2014/05/08 22:57:12 That's a good question. The current design of Blob
}

Powered by Google App Engine
This is Rietveld 408576698