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

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: 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 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/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/numerics/safe_conversions.h"
17 #include "base/platform_file.h" 18 #include "base/platform_file.h"
18 #include "base/stl_util.h" 19 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "base/values.h" 22 #include "base/values.h"
22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/extensions/api/file_system/file_system_api.h" 24 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
25 #include "chrome/browser/extensions/blob_holder.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/public/browser/browser_context.h"
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/fileapi/blob_context.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 "extensions/browser/event_router.h" 49 #include "extensions/browser/event_router.h"
46 #include "extensions/browser/extension_prefs.h" 50 #include "extensions/browser/extension_prefs.h"
47 #include "extensions/browser/extension_system.h" 51 #include "extensions/browser/extension_system.h"
48 #include "extensions/common/extension.h" 52 #include "extensions/common/extension.h"
49 #include "extensions/common/permissions/api_permission.h" 53 #include "extensions/common/permissions/api_permission.h"
50 #include "extensions/common/permissions/media_galleries_permission.h" 54 #include "extensions/common/permissions/media_galleries_permission.h"
51 #include "extensions/common/permissions/permissions_data.h" 55 #include "extensions/common/permissions/permissions_data.h"
52 #include "grit/generated_resources.h" 56 #include "grit/generated_resources.h"
53 #include "net/base/mime_sniffer.h" 57 #include "net/base/mime_sniffer.h"
54 #include "ui/base/l10n/l10n_util.h" 58 #include "ui/base/l10n/l10n_util.h"
59 #include "webkit/browser/blob/blob_data_handle.h"
55 60
56 using content::WebContents; 61 using content::WebContents;
57 using storage_monitor::MediaStorageUtil; 62 using storage_monitor::MediaStorageUtil;
58 using storage_monitor::StorageInfo; 63 using storage_monitor::StorageInfo;
59 using web_modal::WebContentsModalDialogManager; 64 using web_modal::WebContentsModalDialogManager;
60 65
61 namespace extensions { 66 namespace extensions {
62 67
63 namespace MediaGalleries = api::media_galleries; 68 namespace MediaGalleries = api::media_galleries;
64 namespace DropPermissionForMediaFileSystem = 69 namespace DropPermissionForMediaFileSystem =
(...skipping 11 matching lines...) Expand all
76 const char kNonExistentGalleryId[] = "Non-existent gallery id."; 81 const char kNonExistentGalleryId[] = "Non-existent gallery id.";
77 const char kNoScanPermission[] = "No permission to scan."; 82 const char kNoScanPermission[] = "No permission to scan.";
78 83
79 const char kDeviceIdKey[] = "deviceId"; 84 const char kDeviceIdKey[] = "deviceId";
80 const char kGalleryIdKey[] = "galleryId"; 85 const char kGalleryIdKey[] = "galleryId";
81 const char kIsAvailableKey[] = "isAvailable"; 86 const char kIsAvailableKey[] = "isAvailable";
82 const char kIsMediaDeviceKey[] = "isMediaDevice"; 87 const char kIsMediaDeviceKey[] = "isMediaDevice";
83 const char kIsRemovableKey[] = "isRemovable"; 88 const char kIsRemovableKey[] = "isRemovable";
84 const char kNameKey[] = "name"; 89 const char kNameKey[] = "name";
85 90
91 const char kMetadataKey[] = "metadata";
92 const char kAttachedImagesBlobInfoKey[] = "attachedImagesBlobInfo";
93 const char kBlobUUIDKey[] = "blobUUID";
94 const char kTypeKey[] = "type";
95 const char kSizeKey[] = "size";
96
86 MediaFileSystemRegistry* media_file_system_registry() { 97 MediaFileSystemRegistry* media_file_system_registry() {
87 return g_browser_process->media_file_system_registry(); 98 return g_browser_process->media_file_system_registry();
88 } 99 }
89 100
90 MediaScanManager* media_scan_manager() { 101 MediaScanManager* media_scan_manager() {
91 return media_file_system_registry()->media_scan_manager(); 102 return media_file_system_registry()->media_scan_manager();
92 } 103 }
93 104
94 // Checks whether the MediaGalleries API is currently accessible (it may be 105 // Checks whether the MediaGalleries API is currently accessible (it may be
95 // disallowed even if an extension has the requisite permission). Then 106 // disallowed even if an extension has the requisite permission). Then
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 if (!args_->Get(1, &options_value)) 829 if (!args_->Get(1, &options_value))
819 return false; 830 return false;
820 scoped_ptr<MediaGalleries::MediaMetadataOptions> options = 831 scoped_ptr<MediaGalleries::MediaMetadataOptions> options =
821 MediaGalleries::MediaMetadataOptions::FromValue(*options_value); 832 MediaGalleries::MediaMetadataOptions::FromValue(*options_value);
822 if (!options) 833 if (!options)
823 return false; 834 return false;
824 835
825 bool mime_type_only = options->metadata_type == 836 bool mime_type_only = options->metadata_type ==
826 MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY; 837 MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY;
827 838
839 // Get attached images by default.
840 bool get_attached_images =
841 options->metadata_type == MediaGalleries::GET_METADATA_TYPE_ALL ||
842 options->metadata_type == MediaGalleries::GET_METADATA_TYPE_NONE;
843
828 return Setup(GetProfile(), &error_, base::Bind( 844 return Setup(GetProfile(), &error_, base::Bind(
829 &MediaGalleriesGetMetadataFunction::OnPreferencesInit, this, 845 &MediaGalleriesGetMetadataFunction::OnPreferencesInit, this,
830 mime_type_only, blob_uuid)); 846 mime_type_only, get_attached_images, blob_uuid));
831 } 847 }
832 848
833 void MediaGalleriesGetMetadataFunction::OnPreferencesInit( 849 void MediaGalleriesGetMetadataFunction::OnPreferencesInit(
834 bool mime_type_only, const std::string& blob_uuid) { 850 bool mime_type_only, bool get_attached_images,
851 const std::string& blob_uuid) {
835 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 852 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
836 853
837 // BlobReader is self-deleting. 854 // BlobReader is self-deleting.
838 BlobReader* reader = new BlobReader( 855 BlobReader* reader = new BlobReader(
839 GetProfile(), 856 GetProfile(),
840 blob_uuid, 857 blob_uuid,
841 base::Bind(&MediaGalleriesGetMetadataFunction::SniffMimeType, this, 858 base::Bind(&MediaGalleriesGetMetadataFunction::GetMetadata, this,
842 mime_type_only, blob_uuid)); 859 mime_type_only, get_attached_images, blob_uuid));
843 reader->SetByteRange(0, net::kMaxBytesToSniff); 860 reader->SetByteRange(0, net::kMaxBytesToSniff);
844 reader->Start(); 861 reader->Start();
845 } 862 }
846 863
847 void MediaGalleriesGetMetadataFunction::SniffMimeType( 864 void MediaGalleriesGetMetadataFunction::GetMetadata(
848 bool mime_type_only, const std::string& blob_uuid, 865 bool mime_type_only, bool get_attached_images,
849 scoped_ptr<std::string> blob_header, int64 total_blob_length) { 866 const std::string& blob_uuid, scoped_ptr<std::string> blob_header,
867 int64 total_blob_length) {
850 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 868 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
851 869
852 std::string mime_type; 870 std::string mime_type;
853 bool mime_type_sniffed = net::SniffMimeTypeFromLocalData( 871 bool mime_type_sniffed = net::SniffMimeTypeFromLocalData(
854 blob_header->c_str(), blob_header->size(), &mime_type); 872 blob_header->c_str(), blob_header->size(), &mime_type);
855 873
856 if (!mime_type_sniffed) { 874 if (!mime_type_sniffed) {
857 SendResponse(false); 875 SendResponse(false);
858 return; 876 return;
859 } 877 }
860 878
861 if (mime_type_only) { 879 if (mime_type_only) {
862 MediaGalleries::MediaMetadata metadata; 880 MediaGalleries::MediaMetadata metadata;
863 metadata.mime_type = mime_type; 881 metadata.mime_type = mime_type;
864 SetResult(metadata.ToValue().release()); 882
883 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
884 result_dictionary->Set(kMetadataKey, metadata.ToValue().release());
885 SetResult(result_dictionary);
865 SendResponse(true); 886 SendResponse(true);
866 return; 887 return;
867 } 888 }
868 889
869 scoped_refptr<metadata::SafeMediaMetadataParser> parser( 890 scoped_refptr<metadata::SafeMediaMetadataParser> parser(
870 new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid, 891 new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid,
871 total_blob_length, mime_type)); 892 total_blob_length, mime_type,
893 get_attached_images));
872 parser->Start(base::Bind( 894 parser->Start(base::Bind(
873 &MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone, this)); 895 &MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone, this));
874 } 896 }
875 897
876 void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone( 898 void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone(
877 bool parse_success, base::DictionaryValue* metadata_dictionary) { 899 bool parse_success, scoped_ptr<base::DictionaryValue> metadata_dictionary,
900 scoped_ptr<std::vector<metadata::AttachedImage>> attached_images) {
901 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
902
878 if (!parse_success) { 903 if (!parse_success) {
879 SendResponse(false); 904 SendResponse(false);
880 return; 905 return;
881 } 906 }
882 907
883 SetResult(metadata_dictionary->DeepCopy()); 908 DCHECK(attached_images.get());
909 if (attached_images->empty()) {
910 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
911 result_dictionary->Set(kMetadataKey, metadata_dictionary.release());
912 SetResult(result_dictionary);
913 SendResponse(true);
914 return;
915 }
916
917 metadata::AttachedImage* first_image = &attached_images->front();
918 content::BrowserContext::GetBlobContext(GetProfile())->CreateMemoryBackedBlob(
919 first_image->data.c_str(),
920 first_image->data.size(),
921 base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob,
922 this, base::Passed(&metadata_dictionary),
923 base::Passed(&attached_images),
924 base::Passed(make_scoped_ptr(new std::vector<std::string>))));
925 }
926
927 void MediaGalleriesGetMetadataFunction::ConstructNextBlob(
928 scoped_ptr<base::DictionaryValue> metadata_dictionary,
929 scoped_ptr<std::vector<metadata::AttachedImage>> attached_images,
930 scoped_ptr<std::vector<std::string>> blob_uuids,
931 scoped_ptr<webkit_blob::BlobDataHandle> next_blob) {
932 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
933
934 DCHECK(metadata_dictionary.get());
935 DCHECK(attached_images.get());
936 DCHECK(blob_uuids.get());
937 DCHECK(next_blob.get());
938
939 DCHECK(!attached_images->empty());
940 DCHECK_LT(blob_uuids->size(), attached_images->size());
941
942 // For the newly constructed blob, add its UUID to list and store reference.
943 blob_uuids->push_back(next_blob->uuid());
944 WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
945 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.
946 extensions::BlobHolder* holder =
947 extensions::BlobHolder::FromWebContents(contents);
948 holder->HoldBlobReference(next_blob.Pass());
949
950 if (blob_uuids->size() == attached_images->size()) {
951 FinishRequest(metadata_dictionary.Pass(), attached_images.Pass(),
952 blob_uuids.Pass());
953 return;
954 }
955
956 // Construct the next Blob.
957 content::BlobContext* blob_context =
958 content::BrowserContext::GetBlobContext(GetProfile());
959 metadata::AttachedImage* next_image = &(*attached_images)[blob_uuids->size()];
960 blob_context->CreateMemoryBackedBlob(
961 next_image->data.c_str(), next_image->data.size(),
962 base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob,
963 this, base::Passed(&metadata_dictionary),
964 base::Passed(&attached_images), base::Passed(&blob_uuids)));
965 }
966
967 void MediaGalleriesGetMetadataFunction::FinishRequest(
968 scoped_ptr<base::DictionaryValue> metadata_dictionary,
969 scoped_ptr<std::vector<metadata::AttachedImage>> attached_images,
970 scoped_ptr<std::vector<std::string>> blob_uuids) {
971 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
972 DCHECK(metadata_dictionary.get());
973 DCHECK(attached_images->size() == blob_uuids->size());
974
975 base::DictionaryValue* result_dictionary = new base::DictionaryValue;
976 result_dictionary->Set(kMetadataKey, metadata_dictionary->DeepCopy());
977
978 // The custom JS binding takes ownership of the Blobs in the renderer.
979 base::ListValue* attached_images_list = new base::ListValue;
980 for (size_t i = 0; i < attached_images->size(); ++i) {
981 base::DictionaryValue* attached_image = new base::DictionaryValue;
982 attached_image->Set(kBlobUUIDKey, new base::StringValue((*blob_uuids)[i]));
983 attached_image->Set(kTypeKey, new base::StringValue(
984 (*attached_images)[i].type));
985 attached_image->Set(kSizeKey, new base::FundamentalValue(
986 base::checked_cast<int>((*attached_images)[i].data.size())));
987 attached_images_list->Append(attached_image);
988 }
989 result_dictionary->Set(kAttachedImagesBlobInfoKey, attached_images_list);
990
991 SetResult(result_dictionary);
884 SendResponse(true); 992 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
885 } 993 }
886 994
887 } // namespace extensions 995 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698