Home | History | Annotate | Download | only in fileapi
      1 // Copyright 2013 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.
      4 
      5 #include "chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/location.h"
     10 #include "base/logging.h"
     11 #include "base/process/process_handle.h"
     12 #include "chrome/common/chrome_utility_messages.h"
     13 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
     14 #include "content/public/browser/child_process_data.h"
     15 #include "content/public/browser/utility_process_host.h"
     16 #include "content/public/browser/browser_thread.h"
     17 #include "ipc/ipc_message_macros.h"
     18 #include "ipc/ipc_platform_file.h"
     19 
     20 SafeAudioVideoChecker::SafeAudioVideoChecker(
     21     base::File file,
     22     const storage::CopyOrMoveFileValidator::ResultCallback& callback)
     23     : state_(INITIAL_STATE), file_(file.Pass()), callback_(callback) {
     24   DCHECK(!callback.is_null());
     25 }
     26 
     27 void SafeAudioVideoChecker::Start() {
     28   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     29   if (state_ != INITIAL_STATE)
     30     return;
     31   state_ = PINGED_STATE;
     32 
     33   if (!file_.IsValid()) {
     34     callback_.Run(base::File::FILE_ERROR_SECURITY);
     35     state_ = FINISHED_STATE;
     36     return;
     37   }
     38 
     39   utility_process_host_ = content::UtilityProcessHost::Create(
     40       this, base::MessageLoopProxy::current())->AsWeakPtr();
     41   utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
     42 }
     43 
     44 SafeAudioVideoChecker::~SafeAudioVideoChecker() {}
     45 
     46 void SafeAudioVideoChecker::OnProcessStarted() {
     47   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     48   if (state_ != PINGED_STATE)
     49     return;
     50   state_ = STARTED_STATE;
     51 
     52   if (utility_process_host_->GetData().handle == base::kNullProcessHandle)
     53     DLOG(ERROR) << "Child process handle is null";
     54   IPC::PlatformFileForTransit file_for_transit =
     55       IPC::TakeFileHandleForProcess(file_.Pass(),
     56                                     utility_process_host_->GetData().handle);
     57   if (file_for_transit == IPC::InvalidPlatformFileForTransit()) {
     58     OnCheckingFinished(false /* valid? */);
     59     return;
     60   }
     61   const int64 kFileDecodeTimeInMS = 250;
     62   utility_process_host_->Send(new ChromeUtilityMsg_CheckMediaFile(
     63       kFileDecodeTimeInMS, file_for_transit));
     64 }
     65 
     66 void SafeAudioVideoChecker::OnCheckingFinished(bool valid) {
     67   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     68   if (state_ != STARTED_STATE)
     69     return;
     70   state_ = FINISHED_STATE;
     71 
     72   callback_.Run(valid ? base::File::FILE_OK :
     73                         base::File::FILE_ERROR_SECURITY);
     74 }
     75 
     76 void SafeAudioVideoChecker::OnProcessCrashed(int exit_code) {
     77   OnCheckingFinished(false);
     78 }
     79 
     80 bool SafeAudioVideoChecker::OnMessageReceived(const IPC::Message& message) {
     81   bool handled = true;
     82   IPC_BEGIN_MESSAGE_MAP(SafeAudioVideoChecker, message)
     83     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
     84         OnProcessStarted)
     85     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CheckMediaFile_Finished,
     86         OnCheckingFinished)
     87     IPC_MESSAGE_UNHANDLED(handled = false)
     88   IPC_END_MESSAGE_MAP()
     89   return handled;
     90 }
     91