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 "base/single_thread_task_runner.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "chrome/browser/extensions/blob_reader.h"
10 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/child_process_data.h"
14 #include "content/public/browser/utility_process_host.h"
15 #include "ui/base/l10n/l10n_util.h"
17 using content::BrowserThread
;
21 SafeMediaMetadataParser::SafeMediaMetadataParser(
22 Profile
* profile
, const std::string
& blob_uuid
, int64 blob_size
,
23 const std::string
& mime_type
, bool get_attached_images
)
25 blob_uuid_(blob_uuid
),
26 blob_size_(blob_size
),
27 mime_type_(mime_type
),
28 get_attached_images_(get_attached_images
),
29 parser_state_(INITIAL_STATE
) {
30 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
33 void SafeMediaMetadataParser::Start(const DoneCallback
& callback
) {
34 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
36 BrowserThread::PostTask(
39 base::Bind(&SafeMediaMetadataParser::StartWorkOnIOThread
, this,
43 SafeMediaMetadataParser::~SafeMediaMetadataParser() {
46 void SafeMediaMetadataParser::StartWorkOnIOThread(
47 const DoneCallback
& callback
) {
48 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
49 DCHECK_EQ(INITIAL_STATE
, parser_state_
);
50 DCHECK(!callback
.is_null());
54 utility_process_host_
= content::UtilityProcessHost::Create(
55 this, base::ThreadTaskRunnerHandle::Get())->AsWeakPtr();
56 utility_process_host_
->SetName(l10n_util::GetStringUTF16(
57 IDS_UTILITY_PROCESS_MEDIA_FILE_CHECKER_NAME
));
59 utility_process_host_
->Send(
60 new ChromeUtilityMsg_ParseMediaMetadata(mime_type_
, blob_size_
,
61 get_attached_images_
));
63 parser_state_
= STARTED_PARSING_STATE
;
66 void SafeMediaMetadataParser::OnParseMediaMetadataFinished(
67 bool parse_success
, const base::DictionaryValue
& metadata_dictionary
,
68 const std::vector
<AttachedImage
>& attached_images
) {
69 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
70 DCHECK(!callback_
.is_null());
72 if (parser_state_
!= STARTED_PARSING_STATE
)
75 // We need to make a scoped copy of this vector since it will be destroyed
76 // at the end of the IPC message handler.
77 scoped_ptr
<std::vector
<metadata::AttachedImage
> > attached_images_copy
=
78 make_scoped_ptr(new std::vector
<metadata::AttachedImage
>(
81 BrowserThread::PostTask(
84 base::Bind(callback_
, parse_success
,
85 base::Passed(make_scoped_ptr(metadata_dictionary
.DeepCopy())),
86 base::Passed(&attached_images_copy
)));
87 parser_state_
= FINISHED_PARSING_STATE
;
90 void SafeMediaMetadataParser::OnUtilityProcessRequestBlobBytes(
91 int64 request_id
, int64 byte_start
, int64 length
) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
93 BrowserThread::PostTask(
96 base::Bind(&SafeMediaMetadataParser::StartBlobReaderOnUIThread
, this,
97 request_id
, byte_start
, length
));
100 void SafeMediaMetadataParser::StartBlobReaderOnUIThread(
101 int64 request_id
, int64 byte_start
, int64 length
) {
102 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
104 // BlobReader is self-deleting.
105 BlobReader
* reader
= new BlobReader(profile_
, blob_uuid_
, base::Bind(
106 &SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread
, this, request_id
));
107 reader
->SetByteRange(byte_start
, length
);
111 void SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread(
112 int64 request_id
, scoped_ptr
<std::string
> data
,
113 int64
/* blob_total_size */) {
114 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
115 BrowserThread::PostTask(
118 base::Bind(&SafeMediaMetadataParser::FinishRequestBlobBytes
, this,
119 request_id
, base::Passed(data
.Pass())));
122 void SafeMediaMetadataParser::FinishRequestBlobBytes(
123 int64 request_id
, scoped_ptr
<std::string
> data
) {
124 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
125 if (!utility_process_host_
.get())
127 utility_process_host_
->Send(new ChromeUtilityMsg_RequestBlobBytes_Finished(
131 void SafeMediaMetadataParser::OnProcessCrashed(int exit_code
) {
132 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
133 DCHECK(!callback_
.is_null());
135 BrowserThread::PostTask(
138 base::Bind(callback_
, false,
139 base::Passed(scoped_ptr
<base::DictionaryValue
>()),
140 base::Passed(scoped_ptr
<std::vector
<AttachedImage
> >())));
141 parser_state_
= FINISHED_PARSING_STATE
;
144 bool SafeMediaMetadataParser::OnMessageReceived(const IPC::Message
& message
) {
146 IPC_BEGIN_MESSAGE_MAP(SafeMediaMetadataParser
, message
)
148 ChromeUtilityHostMsg_ParseMediaMetadata_Finished
,
149 OnParseMediaMetadataFinished
)
151 ChromeUtilityHostMsg_RequestBlobBytes
,
152 OnUtilityProcessRequestBlobBytes
)
153 IPC_MESSAGE_UNHANDLED(handled
= false)
154 IPC_END_MESSAGE_MAP()
158 } // namespace metadata