15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/utility/media_galleries/ipc_data_source.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/utility/utility_thread.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace metadata {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IPCDataSource::IPCDataSource(int64 total_size)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : total_size_(total_size),
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      utility_task_runner_(base::MessageLoopProxy::current()),
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      next_request_id_(0) {
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data_source_thread_checker_.DetachFromThread();
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IPCDataSource::~IPCDataSource() {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(utility_thread_checker_.CalledOnValidThread());
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void IPCDataSource::Stop() {
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(data_source_thread_checker_.CalledOnValidThread());
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IPCDataSource::Read(int64 position, int size, uint8* data,
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         const DataSource::ReadCB& read_cb) {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(data_source_thread_checker_.CalledOnValidThread());
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  utility_task_runner_->PostTask(
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&IPCDataSource::ReadOnUtilityThread, base::Unretained(this),
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 position, size, data, read_cb));
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IPCDataSource::GetSize(int64* size_out) {
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(data_source_thread_checker_.CalledOnValidThread());
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *size_out = total_size_;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IPCDataSource::IsStreaming() {
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(data_source_thread_checker_.CalledOnValidThread());
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IPCDataSource::SetBitrate(int bitrate) {
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(data_source_thread_checker_.CalledOnValidThread());
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IPCDataSource::OnMessageReceived(const IPC::Message& message) {
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(utility_thread_checker_.CalledOnValidThread());
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool handled = true;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(IPCDataSource, message)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RequestBlobBytes_Finished,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnRequestBlobBytesFinished)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return handled;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IPCDataSource::Request::Request()
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : destination(NULL) {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IPCDataSource::Request::~Request() {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void IPCDataSource::ReadOnUtilityThread(int64 position, int size, uint8* data,
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                        const DataSource::ReadCB& read_cb) {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(utility_thread_checker_.CalledOnValidThread());
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK_GE(total_size_, 0);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK_GE(position, 0);
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK_GE(size, 0);
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cap position and size within bounds.
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  position = std::min(position, total_size_);
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64 clamped_size =
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::min(static_cast<int64>(size), total_size_ - position);
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64 request_id = ++next_request_id_;
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Request request;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request.destination = data;
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request.callback = read_cb;
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pending_requests_[request_id] = request;
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::UtilityThread::Get()->Send(new ChromeUtilityHostMsg_RequestBlobBytes(
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      request_id, position, clamped_size));
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IPCDataSource::OnRequestBlobBytesFinished(int64 request_id,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               const std::string& bytes) {
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(utility_thread_checker_.CalledOnValidThread());
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int64, Request>::iterator it = pending_requests_.find(request_id);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (it == pending_requests_.end())
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::copy(bytes.begin(), bytes.end(), it->second.destination);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  it->second.callback.Run(bytes.size());
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pending_requests_.erase(it);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace metadata
108