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/chrome_utility_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(Profile* profile,
18 const std::string& blob_uuid,
20 const std::string& mime_type)
22 blob_uuid_(blob_uuid),
23 blob_size_(blob_size),
24 mime_type_(mime_type),
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_));
56 parser_state_ = STARTED_PARSING_STATE;
59 void SafeMediaMetadataParser::OnParseMediaMetadataFinished(
60 bool parse_success, const base::DictionaryValue& metadata_dictionary) {
61 DCHECK_CURRENTLY_ON(BrowserThread::IO);
62 DCHECK(!callback_.is_null());
64 if (parser_state_ != STARTED_PARSING_STATE)
67 BrowserThread::PostTask(
70 base::Bind(callback_, parse_success,
71 base::Owned(metadata_dictionary.DeepCopy())));
72 parser_state_ = FINISHED_PARSING_STATE;
75 void SafeMediaMetadataParser::OnUtilityProcessRequestBlobBytes(
76 int64 request_id, int64 byte_start, int64 length) {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO);
78 BrowserThread::PostTask(
81 base::Bind(&SafeMediaMetadataParser::StartBlobReaderOnUIThread, this,
82 request_id, byte_start, length));
85 void SafeMediaMetadataParser::StartBlobReaderOnUIThread(
86 int64 request_id, int64 byte_start, int64 length) {
87 DCHECK_CURRENTLY_ON(BrowserThread::UI);
89 // BlobReader is self-deleting.
90 BlobReader* reader = new BlobReader(profile_, blob_uuid_, base::Bind(
91 &SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread, this, request_id));
92 reader->SetByteRange(byte_start, length);
96 void SafeMediaMetadataParser::OnBlobReaderDoneOnUIThread(
97 int64 request_id, scoped_ptr<std::string> data,
98 int64 /* blob_total_size */) {
99 DCHECK_CURRENTLY_ON(BrowserThread::UI);
100 BrowserThread::PostTask(
103 base::Bind(&SafeMediaMetadataParser::FinishRequestBlobBytes, this,
104 request_id, base::Passed(data.Pass())));
107 void SafeMediaMetadataParser::FinishRequestBlobBytes(
108 int64 request_id, scoped_ptr<std::string> data) {
109 DCHECK_CURRENTLY_ON(BrowserThread::IO);
110 if (!utility_process_host_.get())
112 utility_process_host_->Send(new ChromeUtilityMsg_RequestBlobBytes_Finished(
116 void SafeMediaMetadataParser::OnProcessCrashed(int exit_code) {
117 DCHECK_CURRENTLY_ON(BrowserThread::IO);
118 DCHECK(!callback_.is_null());
120 BrowserThread::PostTask(
123 base::Bind(callback_, false, base::Owned(new base::DictionaryValue)));
124 parser_state_ = FINISHED_PARSING_STATE;
127 bool SafeMediaMetadataParser::OnMessageReceived(const IPC::Message& message) {
129 IPC_BEGIN_MESSAGE_MAP(SafeMediaMetadataParser, message)
131 ChromeUtilityHostMsg_ParseMediaMetadata_Finished,
132 OnParseMediaMetadataFinished)
134 ChromeUtilityHostMsg_RequestBlobBytes,
135 OnUtilityProcessRequestBlobBytes)
136 IPC_MESSAGE_UNHANDLED(handled = false)
137 IPC_END_MESSAGE_MAP()
141 } // namespace metadata