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. 4 5 #include "content/app/android/child_process_service.h" 6 7 #include <android/native_window_jni.h> 8 #include <cpu-features.h> 9 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" 24 25 using base::android::AttachCurrentThread; 26 using base::android::CheckException; 27 using base::android::JavaIntArrayToIntVector; 28 29 namespace content { 30 31 namespace { 32 33 class SurfaceTexturePeerChildImpl : public SurfaceTexturePeer, 34 public GpuSurfaceLookup, 35 public SurfaceTextureLookup { 36 public: 37 // |service| is the instance of 38 // org.chromium.content.app.ChildProcessService. 39 explicit SurfaceTexturePeerChildImpl( 40 const base::android::ScopedJavaLocalRef<jobject>& service) 41 : service_(service) { 42 GpuSurfaceLookup::InitInstance(this); 43 SurfaceTextureLookup::InitInstance(this); 44 } 45 46 virtual ~SurfaceTexturePeerChildImpl() { 47 GpuSurfaceLookup::InitInstance(NULL); 48 SurfaceTextureLookup::InitInstance(NULL); 49 } 50 51 // Overridden from SurfaceTexturePeer: 52 virtual void EstablishSurfaceTexturePeer( 53 base::ProcessHandle pid, 54 scoped_refptr<gfx::SurfaceTexture> surface_texture, 55 int primary_id, 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, 61 secondary_id); 62 CheckException(env); 63 } 64 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)); 71 72 if (surface.j_surface().is_null()) 73 return NULL; 74 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()); 81 82 return native_window; 83 } 84 85 // Overridden from SurfaceTextureLookup: 86 virtual gfx::AcceleratedWidget AcquireNativeWidget(int primary_id, 87 int secondary_id) 88 OVERRIDE { 89 JNIEnv* env = base::android::AttachCurrentThread(); 90 gfx::ScopedJavaSurface surface( 91 content::Java_ChildProcessService_getSurfaceTextureSurface( 92 env, service_.obj(), primary_id, secondary_id)); 93 94 if (surface.j_surface().is_null()) 95 return NULL; 96 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()); 103 104 return native_window; 105 } 106 107 private: 108 // The instance of org.chromium.content.app.ChildProcessService. 109 base::android::ScopedJavaGlobalRef<jobject> service_; 110 111 DISALLOW_COPY_AND_ASSIGN(SurfaceTexturePeerChildImpl); 112 }; 113 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, 118 JNIEnv* env, 119 jclass clazz, 120 jobject context, 121 jobject service_in, 122 jint cpu_count, 123 jlong cpu_features) { 124 base::android::ScopedJavaLocalRef<jobject> service(env, service_in); 125 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 130 // files. 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]); 134 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)); 140 141 base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(env); 142 } 143 144 } // namespace <anonymous> 145 146 void InitChildProcess(JNIEnv* env, 147 jclass clazz, 148 jobject context, 149 jobject service, 150 jintArray j_file_ids, 151 jintArray j_file_fds, 152 jint cpu_count, 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); 158 159 InternalInitChildProcess( 160 file_ids, file_fds, env, clazz, context, service, 161 cpu_count, cpu_features); 162 } 163 164 void ExitChildProcess(JNIEnv* env, jclass clazz) { 165 VLOG(0) << "ChildProcessService: Exiting child process."; 166 base::android::LibraryLoaderExitHook(); 167 _exit(0); 168 } 169 170 bool RegisterChildProcessService(JNIEnv* env) { 171 return RegisterNativesImpl(env); 172 } 173 174 void ShutdownMainThread(JNIEnv* env, jobject obj) { 175 ChildThread::ShutdownThread(); 176 } 177 178 } // namespace content 179