1 // Copyright (c) 2012 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.
5 #include "content/browser/android/child_process_launcher_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "content/browser/media/android/browser_media_player_manager.h"
12 #include "content/browser/renderer_host/compositor_impl_android.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/common/content_switches.h"
17 #include "jni/ChildProcessLauncher_jni.h"
18 #include "media/base/android/media_player_android.h"
19 #include "ui/gl/android/scoped_java_surface.h"
21 using base::android::AttachCurrentThread
;
22 using base::android::ToJavaArrayOfStrings
;
23 using base::android::ScopedJavaGlobalRef
;
24 using base::android::ScopedJavaLocalRef
;
25 using content::StartChildProcessCallback
;
31 // Pass a java surface object to the MediaPlayerAndroid object
32 // identified by render process handle, render view ID and player ID.
33 static void SetSurfacePeer(
34 const base::android::JavaRef
<jobject
>& surface
,
35 base::ProcessHandle render_process_handle
,
39 RenderProcessHost::iterator it
= RenderProcessHost::AllHostsIterator();
40 while (!it
.IsAtEnd()) {
41 if (it
.GetCurrentValue()->GetHandle() == render_process_handle
) {
42 renderer_id
= it
.GetCurrentValue()->GetID();
49 RenderViewHostImpl
* host
= RenderViewHostImpl::FromID(
50 renderer_id
, render_view_id
);
52 media::MediaPlayerAndroid
* player
=
53 host
->media_player_manager()->GetPlayer(player_id
);
55 player
!= host
->media_player_manager()->GetFullscreenPlayer()) {
56 gfx::ScopedJavaSurface
scoped_surface(surface
);
57 player
->SetVideoSurface(scoped_surface
.Pass());
63 } // anonymous namespace
65 // Called from ChildProcessLauncher.java when the ChildProcess was
67 // |client_context| is the pointer to StartChildProcessCallback which was
68 // passed in from StartChildProcess.
69 // |handle| is the processID of the child process as originated in Java, 0 if
70 // the ChildProcess could not be created.
71 static void OnChildProcessStarted(JNIEnv
*,
75 StartChildProcessCallback
* callback
=
76 reinterpret_cast<StartChildProcessCallback
*>(client_context
);
78 callback
->Run(static_cast<base::ProcessHandle
>(handle
));
82 void StartChildProcess(
83 const CommandLine::StringVector
& argv
,
85 const std::vector
<content::FileDescriptorInfo
>& files_to_register
,
86 const StartChildProcessCallback
& callback
) {
87 JNIEnv
* env
= AttachCurrentThread();
90 // Create the Command line String[]
91 ScopedJavaLocalRef
<jobjectArray
> j_argv
= ToJavaArrayOfStrings(env
, argv
);
93 size_t file_count
= files_to_register
.size();
94 DCHECK(file_count
> 0);
96 ScopedJavaLocalRef
<jintArray
> j_file_ids(env
, env
->NewIntArray(file_count
));
97 base::android::CheckException(env
);
98 jint
* file_ids
= env
->GetIntArrayElements(j_file_ids
.obj(), NULL
);
99 base::android::CheckException(env
);
100 ScopedJavaLocalRef
<jintArray
> j_file_fds(env
, env
->NewIntArray(file_count
));
101 base::android::CheckException(env
);
102 jint
* file_fds
= env
->GetIntArrayElements(j_file_fds
.obj(), NULL
);
103 base::android::CheckException(env
);
104 ScopedJavaLocalRef
<jbooleanArray
> j_file_auto_close(
105 env
, env
->NewBooleanArray(file_count
));
106 base::android::CheckException(env
);
107 jboolean
* file_auto_close
=
108 env
->GetBooleanArrayElements(j_file_auto_close
.obj(), NULL
);
109 base::android::CheckException(env
);
110 for (size_t i
= 0; i
< file_count
; ++i
) {
111 const content::FileDescriptorInfo
& fd_info
= files_to_register
[i
];
112 file_ids
[i
] = fd_info
.id
;
113 file_fds
[i
] = fd_info
.fd
.fd
;
114 file_auto_close
[i
] = fd_info
.fd
.auto_close
;
116 env
->ReleaseIntArrayElements(j_file_ids
.obj(), file_ids
, 0);
117 env
->ReleaseIntArrayElements(j_file_fds
.obj(), file_fds
, 0);
118 env
->ReleaseBooleanArrayElements(j_file_auto_close
.obj(), file_auto_close
, 0);
120 Java_ChildProcessLauncher_start(env
,
121 base::android::GetApplicationContext(),
126 j_file_auto_close
.obj(),
127 reinterpret_cast<intptr_t>(new StartChildProcessCallback(callback
)));
130 void StopChildProcess(base::ProcessHandle handle
) {
131 JNIEnv
* env
= AttachCurrentThread();
133 Java_ChildProcessLauncher_stop(env
, static_cast<jint
>(handle
));
136 bool IsChildProcessOomProtected(base::ProcessHandle handle
) {
137 JNIEnv
* env
= AttachCurrentThread();
139 return Java_ChildProcessLauncher_isOomProtected(env
,
140 static_cast<jint
>(handle
));
143 void SetChildProcessInForeground(base::ProcessHandle handle
,
144 bool in_foreground
) {
145 JNIEnv
* env
= AttachCurrentThread();
147 return Java_ChildProcessLauncher_setInForeground(env
,
148 static_cast<jint
>(handle
), static_cast<jboolean
>(in_foreground
));
151 void EstablishSurfacePeer(
152 JNIEnv
* env
, jclass clazz
,
153 jint pid
, jobject surface
, jint primary_id
, jint secondary_id
) {
154 ScopedJavaGlobalRef
<jobject
> jsurface
;
155 jsurface
.Reset(env
, surface
);
156 if (jsurface
.is_null())
159 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI
));
160 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, base::Bind(
161 &SetSurfacePeer
, jsurface
, pid
, primary_id
, secondary_id
));
164 void RegisterViewSurface(int surface_id
, jobject j_surface
) {
165 JNIEnv
* env
= AttachCurrentThread();
167 Java_ChildProcessLauncher_registerViewSurface(env
, surface_id
, j_surface
);
170 void UnregisterViewSurface(int surface_id
) {
171 JNIEnv
* env
= AttachCurrentThread();
173 Java_ChildProcessLauncher_unregisterViewSurface(env
, surface_id
);
176 void RegisterChildProcessSurfaceTexture(int surface_texture_id
,
177 int child_process_id
,
178 jobject j_surface_texture
) {
179 JNIEnv
* env
= AttachCurrentThread();
181 Java_ChildProcessLauncher_registerSurfaceTexture(
182 env
, surface_texture_id
, child_process_id
, j_surface_texture
);
185 void UnregisterChildProcessSurfaceTexture(int surface_texture_id
,
186 int child_process_id
) {
187 JNIEnv
* env
= AttachCurrentThread();
189 Java_ChildProcessLauncher_unregisterSurfaceTexture(
190 env
, surface_texture_id
, child_process_id
);
193 jboolean
IsSingleProcess(JNIEnv
* env
, jclass clazz
) {
194 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
);
197 bool RegisterChildProcessLauncher(JNIEnv
* env
) {
198 return RegisterNativesImpl(env
);
201 } // namespace content