| Index: content/browser/child_process_launcher_helper_android.cc
|
| diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc
|
| index 175fe9018cc2705f377670c322a8f11b738b10d0..a452859f997892d9c292fe30acb7417ee44f41bb 100644
|
| --- a/content/browser/child_process_launcher_helper_android.cc
|
| +++ b/content/browser/child_process_launcher_helper_android.cc
|
| @@ -2,15 +2,19 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "content/browser/child_process_launcher_helper.h"
|
| +#include "content/browser/child_process_launcher_helper_android.h"
|
|
|
| #include <memory>
|
|
|
| #include "base/android/apk_assets.h"
|
| +#include "base/android/context_utils.h"
|
| +#include "base/android/jni_array.h"
|
| +#include "base/android/unguessable_token_android.h"
|
| #include "base/i18n/icu_util.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/field_trial.h"
|
| -#include "content/browser/android/child_process_launcher_android.h"
|
| +#include "content/browser/android/scoped_surface_request_manager.h"
|
| +#include "content/browser/child_process_launcher_helper.h"
|
| #include "content/browser/child_process_launcher_helper_posix.h"
|
| #include "content/browser/file_descriptor_info_impl.h"
|
| #include "content/browser/web_contents/web_contents_impl.h"
|
| @@ -19,12 +23,91 @@
|
| #include "content/public/common/content_descriptors.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "gin/v8_initializer.h"
|
| +#include "gpu/ipc/common/gpu_surface_tracker.h"
|
| +#include "jni/ChildProcessLauncher_jni.h"
|
| +
|
| +using base::android::AttachCurrentThread;
|
| +using base::android::JavaParamRef;
|
| +using base::android::ScopedJavaGlobalRef;
|
| +using base::android::ScopedJavaLocalRef;
|
| +using base::android::ToJavaArrayOfStrings;
|
|
|
| namespace content {
|
| +
|
| +typedef base::Callback<void(base::ProcessHandle, int /* launch result */)>
|
| + StartChildProcessCallback;
|
| +
|
| namespace internal {
|
|
|
| namespace {
|
|
|
| +// Starts a process as a child process spawned by the Android ActivityManager.
|
| +// The created process handle is returned to the |callback| on success, 0 is
|
| +// returned if the process could not be created.
|
| +void StartChildProcess(const base::CommandLine::StringVector& argv,
|
| + int child_process_id,
|
| + content::FileDescriptorInfo* files_to_register,
|
| + const StartChildProcessCallback& callback) {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + DCHECK(env);
|
| +
|
| + // Create the Command line String[]
|
| + ScopedJavaLocalRef<jobjectArray> j_argv = ToJavaArrayOfStrings(env, argv);
|
| +
|
| + size_t file_count = files_to_register->GetMappingSize();
|
| + DCHECK(file_count > 0);
|
| +
|
| + ScopedJavaLocalRef<jclass> j_file_info_class = base::android::GetClass(
|
| + env, "org/chromium/content/common/FileDescriptorInfo");
|
| + ScopedJavaLocalRef<jobjectArray> j_file_infos(
|
| + env, env->NewObjectArray(file_count, j_file_info_class.obj(), NULL));
|
| + base::android::CheckException(env);
|
| +
|
| + for (size_t i = 0; i < file_count; ++i) {
|
| + int fd = files_to_register->GetFDAt(i);
|
| + PCHECK(0 <= fd);
|
| + int id = files_to_register->GetIDAt(i);
|
| + const auto& region = files_to_register->GetRegionAt(i);
|
| + bool auto_close = files_to_register->OwnsFD(fd);
|
| + ScopedJavaLocalRef<jobject> j_file_info =
|
| + Java_ChildProcessLauncher_makeFdInfo(env, id, fd, auto_close,
|
| + region.offset, region.size);
|
| + PCHECK(j_file_info.obj());
|
| + env->SetObjectArrayElement(j_file_infos.obj(), i, j_file_info.obj());
|
| + if (auto_close) {
|
| + ignore_result(files_to_register->ReleaseFD(fd).release());
|
| + }
|
| + }
|
| +
|
| + constexpr int param_key = 0; // TODO(boliu): Use this.
|
| + Java_ChildProcessLauncher_start(
|
| + env, base::android::GetApplicationContext(), param_key, j_argv,
|
| + child_process_id, j_file_infos,
|
| + reinterpret_cast<intptr_t>(new StartChildProcessCallback(callback)));
|
| +}
|
| +
|
| +// Stops a child process based on the handle returned from StartChildProcess.
|
| +void StopChildProcess(base::ProcessHandle handle) {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + DCHECK(env);
|
| + Java_ChildProcessLauncher_stop(env, static_cast<jint>(handle));
|
| +}
|
| +
|
| +bool IsChildProcessOomProtected(base::ProcessHandle handle) {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + DCHECK(env);
|
| + return Java_ChildProcessLauncher_isOomProtected(env,
|
| + static_cast<jint>(handle));
|
| +}
|
| +
|
| +void SetChildProcessInForeground(base::ProcessHandle handle,
|
| + bool in_foreground) {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + DCHECK(env);
|
| + return Java_ChildProcessLauncher_setInForeground(
|
| + env, static_cast<jint>(handle), static_cast<jboolean>(in_foreground));
|
| +}
|
| +
|
| // Callback invoked from Java once the process has been started.
|
| void ChildProcessStartedCallback(
|
| ChildProcessLauncherHelper* helper,
|
| @@ -181,4 +264,62 @@ base::File OpenFileToShare(const base::FilePath& path,
|
| }
|
|
|
| } // namespace internal
|
| +
|
| +// Called from ChildProcessLauncher.java when the ChildProcess was
|
| +// started.
|
| +// |client_context| is the pointer to StartChildProcessCallback which was
|
| +// passed in from StartChildProcess.
|
| +// |handle| is the processID of the child process as originated in Java, 0 if
|
| +// the ChildProcess could not be created.
|
| +static void OnChildProcessStarted(JNIEnv*,
|
| + const JavaParamRef<jclass>&,
|
| + jlong client_context,
|
| + jint handle) {
|
| + StartChildProcessCallback* callback =
|
| + reinterpret_cast<StartChildProcessCallback*>(client_context);
|
| + int launch_result = (handle == base::kNullProcessHandle)
|
| + ? LAUNCH_RESULT_FAILURE
|
| + : LAUNCH_RESULT_SUCCESS;
|
| + callback->Run(static_cast<base::ProcessHandle>(handle), launch_result);
|
| + delete callback;
|
| +}
|
| +
|
| +void CompleteScopedSurfaceRequest(JNIEnv* env,
|
| + const JavaParamRef<jclass>& clazz,
|
| + const JavaParamRef<jobject>& token,
|
| + const JavaParamRef<jobject>& surface) {
|
| + base::UnguessableToken requestToken =
|
| + base::android::UnguessableTokenAndroid::FromJavaUnguessableToken(env,
|
| + token);
|
| + if (!requestToken) {
|
| + DLOG(ERROR) << "Received invalid surface request token.";
|
| + return;
|
| + }
|
| +
|
| + DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + ScopedJavaGlobalRef<jobject> jsurface;
|
| + jsurface.Reset(env, surface);
|
| + ScopedSurfaceRequestManager::GetInstance()->FulfillScopedSurfaceRequest(
|
| + requestToken, gl::ScopedJavaSurface(jsurface));
|
| +}
|
| +
|
| +jboolean IsSingleProcess(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
|
| + return base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kSingleProcess);
|
| +}
|
| +
|
| +base::android::ScopedJavaLocalRef<jobject> GetViewSurface(
|
| + JNIEnv* env,
|
| + const base::android::JavaParamRef<jclass>& jcaller,
|
| + jint surface_id) {
|
| + gl::ScopedJavaSurface surface_view =
|
| + gpu::GpuSurfaceTracker::GetInstance()->AcquireJavaSurface(surface_id);
|
| + return base::android::ScopedJavaLocalRef<jobject>(surface_view.j_surface());
|
| +}
|
| +
|
| +bool RegisterChildProcessLauncher(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| } // namespace content
|
|
|