12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/messaging/native_process_launcher.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/strings/string_number_conversions.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/win/hwnd_util.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN) 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Name of the command line switch used to pass handle of the native view to 33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// the native messaging host. 34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char kParentWindowSwitchName[] = "parent-window"; 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif // defined(OS_WIN) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default implementation on NativeProcessLauncher interface. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NativeProcessLauncherImpl : public NativeProcessLauncher { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NativeProcessLauncherImpl(bool allow_user_level_hosts, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) intptr_t native_window); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~NativeProcessLauncherImpl(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Launch(const GURL& origin, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback) const OVERRIDE; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class Core : public base::RefCountedThreadSafe<Core> { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Core(bool allow_user_level_hosts, intptr_t native_window); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Launch(const GURL& origin, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Detach(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<Core>; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Core(); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DoLaunchOnThreadPool(const GURL& origin, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback); 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void PostErrorResult(const LaunchedCallback& callback, LaunchResult error); 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void PostResult(const LaunchedCallback& callback, 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle, 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File read_file, 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File write_file); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CallCallbackOnIOThread(LaunchedCallback callback, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchResult result, 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle, 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File read_file, 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File write_file); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool detached_; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allow_user_level_hosts_; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Handle of the native window corresponding to the extension. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) intptr_t window_handle_; 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<Core> core_; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NativeProcessLauncherImpl); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NativeProcessLauncherImpl::Core::Core(bool allow_user_level_hosts, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) intptr_t window_handle) 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : detached_(false), 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allow_user_level_hosts_(allow_user_level_hosts), 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_handle_(window_handle) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NativeProcessLauncherImpl::Core::~Core() { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(detached_); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeProcessLauncherImpl::Core::Detach() { 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) detached_ = true; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeProcessLauncherImpl::Core::Launch( 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origin, native_host_name, callback)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool( 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!NativeMessagingHostManifest::IsValidName(native_host_name)) { 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_INVALID_NAME); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error_message; 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::FilePath manifest_path = 128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FindManifest(native_host_name, allow_user_level_hosts_, &error_message); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (manifest_path.empty()) { 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(ERROR) << "Can't find manifest for native messaging host " 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << native_host_name; 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_NOT_FOUND); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<NativeMessagingHostManifest> manifest = 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NativeMessagingHostManifest::Load(manifest_path, &error_message); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to load manifest for native messaging host " 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << native_host_name << ": " << error_message; 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_NOT_FOUND); 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (manifest->name() != native_host_name) { 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(ERROR) << "Failed to load manifest for native messaging host " 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << native_host_name 150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << ": Invalid name specified in the manifest."; 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_NOT_FOUND); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest->allowed_origins().MatchesSecurityOrigin(origin)) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not an allowed origin. 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_FORBIDDEN); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::FilePath host_path = manifest->path(); 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!host_path.IsAbsolute()) { 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // On Windows host path is allowed to be relative to the location of the 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // manifest file. On all other platforms the path must be absolute. 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_WIN) 166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) host_path = manifest_path.DirName().Append(host_path); 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#else // defined(OS_WIN) 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(ERROR) << "Native messaging host path must be absolute for " 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << native_host_name; 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_NOT_FOUND); 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif // !defined(OS_WIN) 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // In case when the manifest file is there, but the host binary doesn't exist 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // report the NOT_FOUND error. 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!base::PathExists(host_path)) { 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << "Found manifest, but not the binary for native messaging host " 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << native_host_name << ". Host path specified in the manifest: " 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << host_path.AsUTF8Unsafe(); 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch PostErrorResult(callback, RESULT_NOT_FOUND); 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CommandLine command_line(host_path); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line.AppendArg(origin.spec()); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Pass handle of the native view window to the native messaging host. This 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // way the host will be able to create properly focused UI windows. 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if defined(OS_WIN) 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch command_line.AppendSwitchASCII(kParentWindowSwitchName, 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Int64ToString(window_handle_)); 194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif // !defined(OS_WIN) 195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle; 19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File read_file; 19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File write_file; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NativeProcessLauncher::LaunchNativeProcess( 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) command_line, &process_handle, &read_file, &write_file)) { 20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PostResult(callback, process_handle, read_file.Pass(), write_file.Pass()); 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostErrorResult(callback, RESULT_FAILED_TO_START); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeProcessLauncherImpl::Core::CallCallbackOnIOThread( 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchResult result, 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle, 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File read_file, 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File write_file) { 213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (detached_) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback.Run(result, process_handle, read_file.Pass(), write_file.Pass()); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void NativeProcessLauncherImpl::Core::PostErrorResult( 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const LaunchedCallback& callback, 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LaunchResult error) { 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::BrowserThread::PostTask( 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::BrowserThread::IO, FROM_HERE, 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread, this, 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback, error, base::kNullProcessHandle, 22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Passed(base::File()), Passed(base::File()))); 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void NativeProcessLauncherImpl::Core::PostResult( 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const LaunchedCallback& callback, 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle, 23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File read_file, 23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File write_file) { 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::BrowserThread::PostTask( 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::BrowserThread::IO, FROM_HERE, 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread, this, 23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback, RESULT_SUCCESS, process_handle, 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Passed(read_file.Pass()), Passed(write_file.Pass()))); 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochNativeProcessLauncherImpl::NativeProcessLauncherImpl( 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allow_user_level_hosts, 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) intptr_t window_handle) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : core_(new Core(allow_user_level_hosts, window_handle)) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NativeProcessLauncherImpl::~NativeProcessLauncherImpl() { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_->Detach(); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeProcessLauncherImpl::Launch(const GURL& origin, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& native_host_name, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LaunchedCallback callback) const { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_->Launch(origin, native_host_name, callback); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochscoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault( 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allow_user_level_hosts, 263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch gfx::NativeView native_view) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) intptr_t window_handle = 0; 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_handle = reinterpret_cast<intptr_t>( 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::HWNDForNativeView(native_view)); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return scoped_ptr<NativeProcessLauncher>( 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new NativeProcessLauncherImpl(allow_user_level_hosts, window_handle)); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 274