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

Side by Side 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: Create Blobs on browser-process, eliminating two IPC copies. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implements the Chrome Extensions Media Galleries API. 5 // Implements the Chrome Extensions Media Galleries API.
6 6
7 #include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h" 7 #include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h"
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "apps/app_window.h" 13 #include "apps/app_window.h"
14 #include "apps/app_window_registry.h" 14 #include "apps/app_window_registry.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/guid.h"
16 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/numerics/safe_conversions.h"
17 #include "base/platform_file.h" 19 #include "base/platform_file.h"
18 #include "base/stl_util.h" 20 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
21 #include "base/values.h" 23 #include "base/values.h"
22 #include "chrome/browser/browser_process.h" 24 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/extensions/api/file_system/file_system_api.h" 25 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
24 #include "chrome/browser/extensions/blob_reader.h" 26 #include "chrome/browser/extensions/blob_reader.h"
25 #include "chrome/browser/extensions/extension_tab_util.h" 27 #include "chrome/browser/extensions/extension_tab_util.h"
26 #include "chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h" 28 #include "chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h"
27 #include "chrome/browser/media_galleries/media_file_system_registry.h" 29 #include "chrome/browser/media_galleries/media_file_system_registry.h"
28 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h" 30 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h"
29 #include "chrome/browser/media_galleries/media_galleries_histograms.h" 31 #include "chrome/browser/media_galleries/media_galleries_histograms.h"
30 #include "chrome/browser/media_galleries/media_galleries_preferences.h" 32 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
31 #include "chrome/browser/media_galleries/media_galleries_scan_result_dialog_cont roller.h" 33 #include "chrome/browser/media_galleries/media_galleries_scan_result_dialog_cont roller.h"
32 #include "chrome/browser/media_galleries/media_scan_manager.h" 34 #include "chrome/browser/media_galleries/media_scan_manager.h"
33 #include "chrome/browser/platform_util.h" 35 #include "chrome/browser/platform_util.h"
34 #include "chrome/browser/profiles/profile.h" 36 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/ui/chrome_select_file_policy.h" 37 #include "chrome/browser/ui/chrome_select_file_policy.h"
36 #include "chrome/common/extensions/api/media_galleries.h" 38 #include "chrome/common/extensions/api/media_galleries.h"
37 #include "chrome/common/pref_names.h" 39 #include "chrome/common/pref_names.h"
38 #include "components/storage_monitor/storage_info.h" 40 #include "components/storage_monitor/storage_info.h"
39 #include "components/web_modal/web_contents_modal_dialog_manager.h" 41 #include "components/web_modal/web_contents_modal_dialog_manager.h"
42 #include "content/browser/fileapi/blob_storage_host.h"
tommycli 2014/04/29 23:29:26 This violates the include rules right now. I imagi
michaeln 2014/05/01 21:27:35 We need to expose an interface in the content api
40 #include "content/public/browser/browser_thread.h" 43 #include "content/public/browser/browser_thread.h"
41 #include "content/public/browser/child_process_security_policy.h" 44 #include "content/public/browser/child_process_security_policy.h"
45 #include "content/public/browser/render_frame_host.h"
42 #include "content/public/browser/render_process_host.h" 46 #include "content/public/browser/render_process_host.h"
43 #include "content/public/browser/render_view_host.h" 47 #include "content/public/browser/render_view_host.h"
44 #include "content/public/browser/web_contents.h" 48 #include "content/public/browser/web_contents.h"
45 #include "content/public/browser/web_contents_view.h" 49 #include "content/public/browser/web_contents_view.h"
46 #include "extensions/browser/event_router.h" 50 #include "extensions/browser/event_router.h"
47 #include "extensions/browser/extension_prefs.h" 51 #include "extensions/browser/extension_prefs.h"
48 #include "extensions/browser/extension_system.h" 52 #include "extensions/browser/extension_system.h"
49 #include "extensions/common/extension.h" 53 #include "extensions/common/extension.h"
50 #include "extensions/common/permissions/api_permission.h" 54 #include "extensions/common/permissions/api_permission.h"
51 #include "extensions/common/permissions/media_galleries_permission.h" 55 #include "extensions/common/permissions/media_galleries_permission.h"
52 #include "extensions/common/permissions/permissions_data.h" 56 #include "extensions/common/permissions/permissions_data.h"
53 #include "grit/generated_resources.h" 57 #include "grit/generated_resources.h"
54 #include "net/base/mime_sniffer.h" 58 #include "net/base/mime_sniffer.h"
55 #include "ui/base/l10n/l10n_util.h" 59 #include "ui/base/l10n/l10n_util.h"
60 #include "webkit/common/blob/blob_data.h"
56 61
57 using content::WebContents; 62 using content::WebContents;
58 using storage_monitor::MediaStorageUtil; 63 using storage_monitor::MediaStorageUtil;
59 using storage_monitor::StorageInfo; 64 using storage_monitor::StorageInfo;
60 using web_modal::WebContentsModalDialogManager; 65 using web_modal::WebContentsModalDialogManager;
61 66
62 namespace extensions { 67 namespace extensions {
63 68
64 namespace MediaGalleries = api::media_galleries; 69 namespace MediaGalleries = api::media_galleries;
65 namespace DropPermissionForMediaFileSystem = 70 namespace DropPermissionForMediaFileSystem =
(...skipping 11 matching lines...) Expand all
77 const char kNonExistentGalleryId[] = "Non-existent gallery id."; 82 const char kNonExistentGalleryId[] = "Non-existent gallery id.";
78 const char kNoScanPermission[] = "No permission to scan."; 83 const char kNoScanPermission[] = "No permission to scan.";
79 84
80 const char kDeviceIdKey[] = "deviceId"; 85 const char kDeviceIdKey[] = "deviceId";
81 const char kGalleryIdKey[] = "galleryId"; 86 const char kGalleryIdKey[] = "galleryId";
82 const char kIsAvailableKey[] = "isAvailable"; 87 const char kIsAvailableKey[] = "isAvailable";
83 const char kIsMediaDeviceKey[] = "isMediaDevice"; 88 const char kIsMediaDeviceKey[] = "isMediaDevice";
84 const char kIsRemovableKey[] = "isRemovable"; 89 const char kIsRemovableKey[] = "isRemovable";
85 const char kNameKey[] = "name"; 90 const char kNameKey[] = "name";
86 91
92 const char kMetadataKey[] = "metadata";
93 const char kAttachedImagesKey[] = "attachedImages";
94 const char kBlobUUIDKey[] = "blobUUID";
95 const char kTypeKey[] = "type";
96 const char kSizeKey[] = "size";
97
87 MediaFileSystemRegistry* media_file_system_registry() { 98 MediaFileSystemRegistry* media_file_system_registry() {
88 return g_browser_process->media_file_system_registry(); 99 return g_browser_process->media_file_system_registry();
89 } 100 }
90 101
91 MediaScanManager* media_scan_manager() { 102 MediaScanManager* media_scan_manager() {
92 return media_file_system_registry()->media_scan_manager(); 103 return media_file_system_registry()->media_scan_manager();
93 } 104 }
94 105
95 // Checks whether the MediaGalleries API is currently accessible (it may be 106 // Checks whether the MediaGalleries API is currently accessible (it may be
96 // disallowed even if an extension has the requisite permission). Then 107 // disallowed even if an extension has the requisite permission). Then
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 if (!args_->Get(1, &options_value)) 830 if (!args_->Get(1, &options_value))
820 return false; 831 return false;
821 scoped_ptr<MediaGalleries::MediaMetadataOptions> options = 832 scoped_ptr<MediaGalleries::MediaMetadataOptions> options =
822 MediaGalleries::MediaMetadataOptions::FromValue(*options_value); 833 MediaGalleries::MediaMetadataOptions::FromValue(*options_value);
823 if (!options) 834 if (!options)
824 return false; 835 return false;
825 836
826 bool mime_type_only = options->metadata_type == 837 bool mime_type_only = options->metadata_type ==
827 MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY; 838 MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY;
828 839
840 // Get attached images by default.
841 bool get_attached_images =
842 options->metadata_type == MediaGalleries::GET_METADATA_TYPE_ALL ||
843 options->metadata_type == MediaGalleries::GET_METADATA_TYPE_NONE;
844
829 return Setup(GetProfile(), &error_, base::Bind( 845 return Setup(GetProfile(), &error_, base::Bind(
830 &MediaGalleriesGetMetadataFunction::OnPreferencesInit, this, 846 &MediaGalleriesGetMetadataFunction::OnPreferencesInit, this,
831 mime_type_only, blob_uuid)); 847 mime_type_only, get_attached_images, blob_uuid));
832 } 848 }
833 849
834 void MediaGalleriesGetMetadataFunction::OnPreferencesInit( 850 void MediaGalleriesGetMetadataFunction::OnPreferencesInit(
835 bool mime_type_only, const std::string& blob_uuid) { 851 bool mime_type_only, bool get_attached_images,
852 const std::string& blob_uuid) {
836 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 853 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
837 854
838 // BlobReader is self-deleting. 855 // BlobReader is self-deleting.
839 BlobReader* reader = new BlobReader( 856 BlobReader* reader = new BlobReader(
840 GetProfile(), 857 GetProfile(),
841 blob_uuid, 858 blob_uuid,
842 base::Bind(&MediaGalleriesGetMetadataFunction::SniffMimeType, this, 859 base::Bind(&MediaGalleriesGetMetadataFunction::GetMetadata, this,
843 mime_type_only, blob_uuid)); 860 mime_type_only, get_attached_images, blob_uuid));
844 reader->SetByteRange(0, net::kMaxBytesToSniff); 861 reader->SetByteRange(0, net::kMaxBytesToSniff);
845 reader->Start(); 862 reader->Start();
846 } 863 }
847 864
848 void MediaGalleriesGetMetadataFunction::SniffMimeType( 865 void MediaGalleriesGetMetadataFunction::GetMetadata(
849 bool mime_type_only, const std::string& blob_uuid, 866 bool mime_type_only, bool get_attached_images,
850 scoped_ptr<std::string> blob_header, int64 total_blob_length) { 867 const std::string& blob_uuid, scoped_ptr<std::string> blob_header,
868 int64 total_blob_length) {
851 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 869 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
852 870
853 std::string mime_type; 871 std::string mime_type;
854 bool mime_type_sniffed = net::SniffMimeTypeFromLocalData( 872 bool mime_type_sniffed = net::SniffMimeTypeFromLocalData(
855 blob_header->c_str(), blob_header->size(), &mime_type); 873 blob_header->c_str(), blob_header->size(), &mime_type);
856 874
857 if (!mime_type_sniffed) { 875 if (!mime_type_sniffed) {
858 SendResponse(false); 876 SendResponse(false);
859 return; 877 return;
860 } 878 }
861 879
862 if (mime_type_only) { 880 if (mime_type_only) {
863 MediaGalleries::MediaMetadata metadata; 881 MediaGalleries::MediaMetadata metadata;
864 metadata.mime_type = mime_type; 882 metadata.mime_type = mime_type;
865 SetResult(metadata.ToValue().release()); 883
884 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
885 result_dictionary->Set(kMetadataKey, metadata.ToValue().release());
886 SetResult(result_dictionary);
866 SendResponse(true); 887 SendResponse(true);
867 return; 888 return;
868 } 889 }
869 890
870 scoped_refptr<metadata::SafeMediaMetadataParser> parser( 891 scoped_refptr<metadata::SafeMediaMetadataParser> parser(
871 new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid, 892 new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid,
872 total_blob_length, mime_type)); 893 total_blob_length, mime_type,
894 get_attached_images));
873 parser->Start(base::Bind( 895 parser->Start(base::Bind(
874 &MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone, this)); 896 &MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone, this));
875 } 897 }
876 898
877 void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone( 899 void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone(
878 bool parse_success, base::DictionaryValue* metadata_dictionary) { 900 bool parse_success, base::DictionaryValue* metadata_dictionary,
901 const std::vector<metadata::AttachedImage>& attached_images) {
902 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
903
879 if (!parse_success) { 904 if (!parse_success) {
880 SendResponse(false); 905 SendResponse(false);
881 return; 906 return;
882 } 907 }
883 908
884 SetResult(metadata_dictionary->DeepCopy()); 909 if (attached_images.empty()) {
910 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
911 result_dictionary->Set(kMetadataKey, metadata_dictionary->DeepCopy());
912 SetResult(result_dictionary);
913 SendResponse(true);
914 return;
915 }
916
917 content::BrowserThread::PostTaskAndReplyWithResult(
918 content::BrowserThread::IO,
919 FROM_HERE,
920 base::Bind(&MediaGalleriesGetMetadataFunction::CreateBlobsOnIOThread,
921 this, attached_images),
michaeln 2014/05/01 21:27:35 Kinda unrelated to the blob handling specifically,
tommycli 2014/05/07 21:39:04 Done.
922 base::Bind(&MediaGalleriesGetMetadataFunction::FinishWithBlobsOnUIThread,
923 this, base::Owned(metadata_dictionary->DeepCopy()),
924 attached_images));
925 }
926
927 std::vector<std::string>
928 MediaGalleriesGetMetadataFunction::CreateBlobsOnIOThread(
929 const std::vector<metadata::AttachedImage>& attached_images) {
930 content::BlobStorageHost* blob_storage =
931 render_view_host()->GetProcess()->GetBlobStorageHost();
932 std::vector<std::string> blob_uuids;
933
934 for (std::vector<metadata::AttachedImage>::const_iterator it =
935 attached_images.begin();
936 it != attached_images.end(); ++it) {
937 // Here we notably use a UUID generated in the browser process instead of
tommycli 2014/04/29 23:29:26 I generate a UUID on the browser process. Passes m
michaeln 2014/05/01 21:27:35 This is perfectly halal.
938 // in WebKit. It is upper case and doesn't conform to UUID 4 specifications,
939 // but this doesn't seem to cause any harm.
940 std::string uuid = base::GenerateGUID();
941 BlobData::Item item;
942 item.SetToBytes(it->data.c_str(), it->data.size());
943
944 // These should never return false.
945 CHECK(blob_storage->StartBuildingBlob(uuid));
michaeln 2014/05/01 21:27:35 The BlobStorageContext::AddFinishedBlob(...) metho
tommycli 2014/05/07 21:39:04 Done.
946 CHECK(blob_storage->AppendBlobDataItem(uuid, item));
947 CHECK(blob_storage->FinishBuildingBlob(uuid, it->type));
948
949 blob_uuids.push_back(uuid);
950 }
951
952 return blob_uuids;
953 }
954
955 void MediaGalleriesGetMetadataFunction::FinishWithBlobsOnUIThread(
956 base::DictionaryValue* metadata_dictionary,
957 const std::vector<metadata::AttachedImage>& attached_images,
958 const std::vector<std::string>& blob_uuids) {
959 DCHECK(attached_images.size() == blob_uuids.size());
960
961 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
962 result_dictionary->Set(kMetadataKey, metadata_dictionary->DeepCopy());
963
964 // The custom JS binding will reconstitute the blobs in the renderer.
965 base::ListValue* attached_images_list = new base::ListValue;
966 for (size_t i = 0; i < attached_images.size(); ++i) {
967 base::DictionaryValue* attached_image = new base::DictionaryValue;
968 attached_image->Set(kBlobUUIDKey, new base::StringValue(blob_uuids[i]));
969 attached_image->Set(kTypeKey, new base::StringValue(
970 attached_images[i].type));
971 attached_image->Set(kSizeKey, new base::FundamentalValue(
972 base::checked_cast<int>(attached_images[i].data.size())));
973 attached_images_list->Append(attached_image);
974 }
975 result_dictionary->Set(kAttachedImagesKey, attached_images_list);
976
977 SetResult(result_dictionary);
885 SendResponse(true); 978 SendResponse(true);
886 } 979 }
887 980
888 } // namespace extensions 981 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698