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/app/android/child_process_service.h"
7 #include <android/native_window_jni.h>
8 #include <cpu-features.h>
10 #include "base/android/jni_array.h"
11 #include "base/android/library_loader/library_loader_hooks.h"
12 #include "base/android/memory_pressure_listener_android.h"
13 #include "base/logging.h"
14 #include "base/posix/global_descriptors.h"
15 #include "content/child/child_thread.h"
16 #include "content/common/android/surface_texture_lookup.h"
17 #include "content/common/android/surface_texture_peer.h"
18 #include "content/common/gpu/gpu_surface_lookup.h"
19 #include "content/public/app/android_library_loader_hooks.h"
20 #include "content/public/common/content_descriptors.h"
21 #include "ipc/ipc_descriptors.h"
22 #include "jni/ChildProcessService_jni.h"
23 #include "ui/gl/android/scoped_java_surface.h"
25 using base::android::AttachCurrentThread
;
26 using base::android::CheckException
;
27 using base::android::JavaIntArrayToIntVector
;
33 class SurfaceTexturePeerChildImpl
: public SurfaceTexturePeer
,
34 public GpuSurfaceLookup
,
35 public SurfaceTextureLookup
{
37 // |service| is the instance of
38 // org.chromium.content.app.ChildProcessService.
39 explicit SurfaceTexturePeerChildImpl(
40 const base::android::ScopedJavaLocalRef
<jobject
>& service
)
42 GpuSurfaceLookup::InitInstance(this);
43 SurfaceTextureLookup::InitInstance(this);
46 virtual ~SurfaceTexturePeerChildImpl() {
47 GpuSurfaceLookup::InitInstance(NULL
);
48 SurfaceTextureLookup::InitInstance(NULL
);
51 // Overridden from SurfaceTexturePeer:
52 virtual void EstablishSurfaceTexturePeer(
53 base::ProcessHandle pid
,
54 scoped_refptr
<gfx::SurfaceTexture
> surface_texture
,
56 int secondary_id
) OVERRIDE
{
57 JNIEnv
* env
= base::android::AttachCurrentThread();
58 content::Java_ChildProcessService_establishSurfaceTexturePeer(
59 env
, service_
.obj(), pid
,
60 surface_texture
->j_surface_texture().obj(), primary_id
,
65 // Overridden from GpuSurfaceLookup:
66 virtual gfx::AcceleratedWidget
AcquireNativeWidget(int surface_id
) OVERRIDE
{
67 JNIEnv
* env
= base::android::AttachCurrentThread();
68 gfx::ScopedJavaSurface
surface(
69 content::Java_ChildProcessService_getViewSurface(
70 env
, service_
.obj(), surface_id
));
72 if (surface
.j_surface().is_null())
75 // Note: This ensures that any local references used by
76 // ANativeWindow_fromSurface are released immediately. This is needed as a
77 // workaround for https://code.google.com/p/android/issues/detail?id=68174
78 base::android::ScopedJavaLocalFrame
scoped_local_reference_frame(env
);
79 ANativeWindow
* native_window
=
80 ANativeWindow_fromSurface(env
, surface
.j_surface().obj());
85 // Overridden from SurfaceTextureLookup:
86 virtual gfx::AcceleratedWidget
AcquireNativeWidget(int primary_id
,
89 JNIEnv
* env
= base::android::AttachCurrentThread();
90 gfx::ScopedJavaSurface
surface(
91 content::Java_ChildProcessService_getSurfaceTextureSurface(
92 env
, service_
.obj(), primary_id
, secondary_id
));
94 if (surface
.j_surface().is_null())
97 // Note: This ensures that any local references used by
98 // ANativeWindow_fromSurface are released immediately. This is needed as a
99 // workaround for https://code.google.com/p/android/issues/detail?id=68174
100 base::android::ScopedJavaLocalFrame
scoped_local_reference_frame(env
);
101 ANativeWindow
* native_window
=
102 ANativeWindow_fromSurface(env
, surface
.j_surface().obj());
104 return native_window
;
108 // The instance of org.chromium.content.app.ChildProcessService.
109 base::android::ScopedJavaGlobalRef
<jobject
> service_
;
111 DISALLOW_COPY_AND_ASSIGN(SurfaceTexturePeerChildImpl
);
114 // Chrome actually uses the renderer code path for all of its child
115 // processes such as renderers, plugins, etc.
116 void InternalInitChildProcess(const std::vector
<int>& file_ids
,
117 const std::vector
<int>& file_fds
,
123 jlong cpu_features
) {
124 base::android::ScopedJavaLocalRef
<jobject
> service(env
, service_in
);
126 // Set the CPU properties.
127 android_setCpu(cpu_count
, cpu_features
);
128 // Register the file descriptors.
129 // This includes the IPC channel, the crash dump signals and resource related
131 DCHECK(file_fds
.size() == file_ids
.size());
132 for (size_t i
= 0; i
< file_ids
.size(); ++i
)
133 base::GlobalDescriptors::GetInstance()->Set(file_ids
[i
], file_fds
[i
]);
135 // SurfaceTexturePeerChildImpl implements the SurfaceTextureLookup interface,
136 // which need to be set before we create a compositor thread that could be
137 // using it to initialize resources.
138 content::SurfaceTexturePeer::InitInstance(
139 new SurfaceTexturePeerChildImpl(service
));
141 base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(env
);
144 } // namespace <anonymous>
146 void InitChildProcess(JNIEnv
* env
,
150 jintArray j_file_ids
,
151 jintArray j_file_fds
,
153 jlong cpu_features
) {
154 std::vector
<int> file_ids
;
155 std::vector
<int> file_fds
;
156 JavaIntArrayToIntVector(env
, j_file_ids
, &file_ids
);
157 JavaIntArrayToIntVector(env
, j_file_fds
, &file_fds
);
159 InternalInitChildProcess(
160 file_ids
, file_fds
, env
, clazz
, context
, service
,
161 cpu_count
, cpu_features
);
164 void ExitChildProcess(JNIEnv
* env
, jclass clazz
) {
165 VLOG(0) << "ChildProcessService: Exiting child process.";
166 base::android::LibraryLoaderExitHook();
170 bool RegisterChildProcessService(JNIEnv
* env
) {
171 return RegisterNativesImpl(env
);
174 void ShutdownMainThread(JNIEnv
* env
, jobject obj
) {
175 ChildThread::ShutdownThread();
178 } // namespace content