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_impl.h"
16 #include "content/common/android/surface_texture_manager.h"
17 #include "content/common/android/surface_texture_peer.h"
18 #include "content/common/gpu/gpu_surface_lookup.h"
19 #include "content/public/common/content_descriptors.h"
20 #include "ipc/ipc_descriptors.h"
21 #include "jni/ChildProcessService_jni.h"
22 #include "ui/gl/android/scoped_java_surface.h"
24 using base::android::AttachCurrentThread
;
25 using base::android::CheckException
;
26 using base::android::JavaIntArrayToIntVector
;
32 // TODO(sievers): Use two different implementations of this depending on if
33 // we're in a renderer or gpu process.
34 class SurfaceTextureManagerImpl
: public SurfaceTextureManager
,
35 public SurfaceTexturePeer
,
36 public GpuSurfaceLookup
{
38 // |service| is the instance of
39 // org.chromium.content.app.ChildProcessService.
40 explicit SurfaceTextureManagerImpl(
41 const base::android::ScopedJavaLocalRef
<jobject
>& service
)
43 SurfaceTexturePeer::InitInstance(this);
44 GpuSurfaceLookup::InitInstance(this);
46 ~SurfaceTextureManagerImpl() override
{
47 SurfaceTexturePeer::InitInstance(NULL
);
48 GpuSurfaceLookup::InitInstance(NULL
);
51 // Overridden from SurfaceTextureManager:
52 void RegisterSurfaceTexture(int surface_texture_id
,
54 gfx::SurfaceTexture
* surface_texture
) override
{
55 JNIEnv
* env
= base::android::AttachCurrentThread();
56 Java_ChildProcessService_createSurfaceTextureSurface(
61 surface_texture
->j_surface_texture().obj());
63 void UnregisterSurfaceTexture(int surface_texture_id
,
64 int client_id
) override
{
65 JNIEnv
* env
= base::android::AttachCurrentThread();
66 Java_ChildProcessService_destroySurfaceTextureSurface(
67 env
, service_
.obj(), surface_texture_id
, client_id
);
69 gfx::AcceleratedWidget
AcquireNativeWidgetForSurfaceTexture(
70 int surface_texture_id
) override
{
71 JNIEnv
* env
= base::android::AttachCurrentThread();
72 gfx::ScopedJavaSurface
surface(
73 Java_ChildProcessService_getSurfaceTextureSurface(env
, service_
.obj(),
76 if (surface
.j_surface().is_null())
79 // Note: This ensures that any local references used by
80 // ANativeWindow_fromSurface are released immediately. This is needed as a
81 // workaround for https://code.google.com/p/android/issues/detail?id=68174
82 base::android::ScopedJavaLocalFrame
scoped_local_reference_frame(env
);
83 ANativeWindow
* native_window
=
84 ANativeWindow_fromSurface(env
, surface
.j_surface().obj());
89 // Overridden from SurfaceTexturePeer:
90 void EstablishSurfaceTexturePeer(
91 base::ProcessHandle pid
,
92 scoped_refptr
<gfx::SurfaceTexture
> surface_texture
,
94 int secondary_id
) override
{
95 JNIEnv
* env
= base::android::AttachCurrentThread();
96 content::Java_ChildProcessService_establishSurfaceTexturePeer(
100 surface_texture
->j_surface_texture().obj(),
105 // Overridden from GpuSurfaceLookup:
106 gfx::AcceleratedWidget
AcquireNativeWidget(int surface_id
) override
{
107 JNIEnv
* env
= base::android::AttachCurrentThread();
108 gfx::ScopedJavaSurface
surface(
109 content::Java_ChildProcessService_getViewSurface(
110 env
, service_
.obj(), surface_id
));
112 if (surface
.j_surface().is_null())
115 // Note: This ensures that any local references used by
116 // ANativeWindow_fromSurface are released immediately. This is needed as a
117 // workaround for https://code.google.com/p/android/issues/detail?id=68174
118 base::android::ScopedJavaLocalFrame
scoped_local_reference_frame(env
);
119 ANativeWindow
* native_window
=
120 ANativeWindow_fromSurface(env
, surface
.j_surface().obj());
122 return native_window
;
126 // The instance of org.chromium.content.app.ChildProcessService.
127 base::android::ScopedJavaGlobalRef
<jobject
> service_
;
129 DISALLOW_COPY_AND_ASSIGN(SurfaceTextureManagerImpl
);
132 // Chrome actually uses the renderer code path for all of its child
133 // processes such as renderers, plugins, etc.
134 void InternalInitChildProcess(JNIEnv
* env
,
139 jlong cpu_features
) {
140 base::android::ScopedJavaLocalRef
<jobject
> service(env
, service_in
);
142 // Set the CPU properties.
143 android_setCpu(cpu_count
, cpu_features
);
144 SurfaceTextureManager::SetInstance(new SurfaceTextureManagerImpl(service
));
146 base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(env
);
149 } // namespace <anonymous>
151 void RegisterGlobalFileDescriptor(JNIEnv
* env
,
157 base::MemoryMappedFile::Region region
= {offset
, size
};
158 base::GlobalDescriptors::GetInstance()->Set(id
, fd
, region
);
161 void InitChildProcess(JNIEnv
* env
,
166 jlong cpu_features
) {
167 InternalInitChildProcess(env
, clazz
, context
, service
, cpu_count
,
171 void ExitChildProcess(JNIEnv
* env
, jclass clazz
) {
172 VLOG(0) << "ChildProcessService: Exiting child process.";
173 base::android::LibraryLoaderExitHook();
177 bool RegisterChildProcessService(JNIEnv
* env
) {
178 return RegisterNativesImpl(env
);
181 void ShutdownMainThread(JNIEnv
* env
, jobject obj
) {
182 ChildThreadImpl::ShutdownThread();
185 } // namespace content