1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h"
7 #include "chrome/browser/extensions/blob_reader.h"
8 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/child_process_data.h"
11 #include "content/public/browser/utility_process_host.h"
13 using content::BrowserThread
;
17 SafeMediaMetadataParser::SafeMediaMetadataParser(
18 Profile
* profile
, const std::string
& blob_uuid
, int64 blob_size
,
19 const std::string
& mime_type
, bool get_attached_images
)
21 blob_uuid_(blob_uuid
),
22 blob_size_(blob_size
),
23 mime_type_(mime_type
),
24 get_attached_images_(get_attached_images
),
25 parser_state_(INITIAL_STATE
) {
26 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
29 void SafeMediaMetadataParser::Start(const DoneCallback
& callback
) {
30 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
32 BrowserThread::PostTask(
35 base::Bind(&SafeMediaMetadataParser::StartWorkOnIOThread
, this,
39 SafeMediaMetadataParser::~SafeMediaMetadataParser() {
42 void SafeMediaMetadataParser::StartWorkOnIOThread(
43 const DoneCallback
& callback
) {
44 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
45 DCHECK_EQ(INITIAL_STATE
, parser_state_
);
46 DCHECK(!callback
.is_null());
50 utility_process_host_
= content::UtilityProcessHost::Create(
51 this, base::MessageLoopProxy::current())->AsWeakPtr();
53 utility_process_host_
->Send(
54 new ChromeUtilityMsg_ParseMediaMetadata(mime_type_
, blob_size_
,
55 get_attached_images_
));
57 parser_state_
= STARTED_PARSING_STATE
;
60 void SafeMediaMetadataParser::OnParseMediaMetadataFinished(
61 bool parse_success
, const base::DictionaryValue
& metadata_dictionary
,
62 const std::vector
<AttachedImage
>& attached_images
) {
63 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
64 DCHECK(!callback_
.is_null());
66 if (parser_state_
!= STARTED_PARSING_STATE
)
69 // We need to make a scoped copy of this vector since it will be destroyed
70 // at the end of the IPC message handler.
71 scoped_ptr
<std::vector
<metadata::AttachedImage
> > attached_images_copy
=
72 make_scoped_ptr(new std::vector
<metadata::AttachedImage
>(
75 BrowserThread::PostTask(
78 base::Bind(callback_
, parse_success
,
79 base::Passed(make_scoped_ptr(metadata_dictionary
.DeepCopy())),
80 base::Passed(&attached_images_copy
)));
81 parser_state_
= FINISHED_PARSING_STATE
;
84 void SafeMediaMetadataParser::OnUtilityProcessRequestBlobBytes(
85 int64 request_id
, int64 byte_start
, int64 length
) {
86 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
87 BrowserThread::PostTask(
90 base::Bind(&SafeMediaMetadataParser::StartBlobReaderOnUIThread
, this,
91 request_id
, byte_start
, length
));
94 void SafeMediaMetadataParser::StartBlobReaderOnUIThread(
95 int64 request_id
, int64 byte_start
, int64 length
) {
96 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
98 // BlobReader is self-deleting.
99 BlobReader
* reader
= new BlobReader(profile_
, blob_uuid_
, base::Bind(
100 &SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread
, this, request_id
));
101 reader
->SetByteRange(byte_start
, length
);
105 void SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread(
106 int64 request_id
, scoped_ptr
<std::string
> data
,
107 int64
/* blob_total_size */) {
108 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
109 BrowserThread::PostTask(
112 base::Bind(&SafeMediaMetadataParser::FinishRequestBlobBytes
, this,
113 request_id
, base::Passed(data
.Pass())));
116 void SafeMediaMetadataParser::FinishRequestBlobBytes(
117 int64 request_id
, scoped_ptr
<std::string
> data
) {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
119 if (!utility_process_host_
.get())
121 utility_process_host_
->Send(new ChromeUtilityMsg_RequestBlobBytes_Finished(
125 void SafeMediaMetadataParser::OnProcessCrashed(int exit_code
) {
126 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
127 DCHECK(!callback_
.is_null());
129 BrowserThread::PostTask(
132 base::Bind(callback_
, false,
133 base::Passed(scoped_ptr
<base::DictionaryValue
>()),
134 base::Passed(scoped_ptr
<std::vector
<AttachedImage
> >())));
135 parser_state_
= FINISHED_PARSING_STATE
;
138 bool SafeMediaMetadataParser::OnMessageReceived(const IPC::Message
& message
) {
140 IPC_BEGIN_MESSAGE_MAP(SafeMediaMetadataParser
, message
)
142 ChromeUtilityHostMsg_ParseMediaMetadata_Finished
,
143 OnParseMediaMetadataFinished
)
145 ChromeUtilityHostMsg_RequestBlobBytes
,
146 OnUtilityProcessRequestBlobBytes
)
147 IPC_MESSAGE_UNHANDLED(handled
= false)
148 IPC_END_MESSAGE_MAP()
152 } // namespace metadata