1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found in the LICENSE file. 4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h" 6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/bind.h" 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/callback.h" 9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/location.h" 10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/logging.h" 11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/process/process_handle.h" 12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/common/chrome_utility_messages.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h" 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/public/browser/child_process_data.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/public/browser/utility_process_host.h" 16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/public/browser/browser_thread.h" 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ipc/ipc_message_macros.h" 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ipc/ipc_platform_file.h" 19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochSafeAudioVideoChecker::SafeAudioVideoChecker( 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File file, 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::CopyOrMoveFileValidator::ResultCallback& callback) 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : state_(INITIAL_STATE), file_(file.Pass()), callback_(callback) { 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(!callback.is_null()); 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid SafeAudioVideoChecker::Start() { 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ != INITIAL_STATE) 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = PINGED_STATE; 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!file_.IsValid()) { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_SECURITY); 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = FINISHED_STATE; 36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch utility_process_host_ = content::UtilityProcessHost::Create( 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch this, base::MessageLoopProxy::current())->AsWeakPtr(); 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch utility_process_host_->Send(new ChromeUtilityMsg_StartupPing); 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochSafeAudioVideoChecker::~SafeAudioVideoChecker() {} 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid SafeAudioVideoChecker::OnProcessStarted() { 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ != PINGED_STATE) 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = STARTED_STATE; 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (utility_process_host_->GetData().handle == base::kNullProcessHandle) 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DLOG(ERROR) << "Child process handle is null"; 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC::PlatformFileForTransit file_for_transit = 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::TakeFileHandleForProcess(file_.Pass(), 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch utility_process_host_->GetData().handle); 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (file_for_transit == IPC::InvalidPlatformFileForTransit()) { 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OnCheckingFinished(false /* valid? */); 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const int64 kFileDecodeTimeInMS = 250; 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch utility_process_host_->Send(new ChromeUtilityMsg_CheckMediaFile( 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kFileDecodeTimeInMS, file_for_transit)); 64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid SafeAudioVideoChecker::OnCheckingFinished(bool valid) { 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ != STARTED_STATE) 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = FINISHED_STATE; 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(valid ? base::File::FILE_OK : 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FILE_ERROR_SECURITY); 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid SafeAudioVideoChecker::OnProcessCrashed(int exit_code) { 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch OnCheckingFinished(false); 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool SafeAudioVideoChecker::OnMessageReceived(const IPC::Message& message) { 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool handled = true; 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC_BEGIN_MESSAGE_MAP(SafeAudioVideoChecker, message) 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch OnProcessStarted) 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CheckMediaFile_Finished, 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch OnCheckingFinished) 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC_MESSAGE_UNHANDLED(handled = false) 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC_END_MESSAGE_MAP() 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return handled; 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 91