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/memory_pressure_listener_android.h" 12 #include "base/logging.h" 13 #include "base/posix/global_descriptors.h" 14 #include "content/child/child_thread.h" 15 #include "content/common/android/surface_texture_peer.h" 16 #include "content/common/gpu/gpu_surface_lookup.h" 17 #include "content/public/app/android_library_loader_hooks.h" 18 #include "content/public/common/content_descriptors.h" 19 #include "ipc/ipc_descriptors.h" 20 #include "jni/ChildProcessService_jni.h" 21 #include "ui/gl/android/scoped_java_surface.h" 22 23 using base::android::AttachCurrentThread; 24 using base::android::CheckException; 25 using base::android::JavaIntArrayToIntVector; 26 27 namespace content { 28 29 namespace { 30 31 class SurfaceTexturePeerChildImpl : public content::SurfaceTexturePeer, 32 public content::GpuSurfaceLookup { 33 public: 34 // |service| is the instance of 35 // org.chromium.content.app.ChildProcessService. 36 explicit SurfaceTexturePeerChildImpl( 37 const base::android::ScopedJavaLocalRef<jobject>& service) 38 : service_(service) { 39 GpuSurfaceLookup::InitInstance(this); 40 } 41 42 virtual ~SurfaceTexturePeerChildImpl() { 43 GpuSurfaceLookup::InitInstance(NULL); 44 } 45 46 virtual void EstablishSurfaceTexturePeer( 47 base::ProcessHandle pid, 48 scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge, 49 int primary_id, 50 int secondary_id) OVERRIDE { 51 JNIEnv* env = base::android::AttachCurrentThread(); 52 content::Java_ChildProcessService_establishSurfaceTexturePeer( 53 env, service_.obj(), pid, 54 surface_texture_bridge->j_surface_texture().obj(), primary_id, 55 secondary_id); 56 CheckException(env); 57 } 58 59 virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) OVERRIDE { 60 JNIEnv* env = base::android::AttachCurrentThread(); 61 gfx::ScopedJavaSurface surface( 62 content::Java_ChildProcessService_getViewSurface( 63 env, service_.obj(), surface_id)); 64 65 if (surface.j_surface().is_null()) 66 return NULL; 67 68 ANativeWindow* native_window = ANativeWindow_fromSurface( 69 env, surface.j_surface().obj()); 70 71 return native_window; 72 } 73 74 private: 75 // The instance of org.chromium.content.app.ChildProcessService. 76 base::android::ScopedJavaGlobalRef<jobject> service_; 77 78 DISALLOW_COPY_AND_ASSIGN(SurfaceTexturePeerChildImpl); 79 }; 80 81 // Chrome actually uses the renderer code path for all of its child 82 // processes such as renderers, plugins, etc. 83 void InternalInitChildProcess(const std::vector<int>& file_ids, 84 const std::vector<int>& file_fds, 85 JNIEnv* env, 86 jclass clazz, 87 jobject context, 88 jobject service_in, 89 jint cpu_count, 90 jlong cpu_features) { 91 base::android::ScopedJavaLocalRef<jobject> service(env, service_in); 92 93 // Set the CPU properties. 94 android_setCpu(cpu_count, cpu_features); 95 // Register the file descriptors. 96 // This includes the IPC channel, the crash dump signals and resource related 97 // files. 98 DCHECK(file_fds.size() == file_ids.size()); 99 for (size_t i = 0; i < file_ids.size(); ++i) 100 base::GlobalDescriptors::GetInstance()->Set(file_ids[i], file_fds[i]); 101 102 content::SurfaceTexturePeer::InitInstance( 103 new SurfaceTexturePeerChildImpl(service)); 104 105 base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(env); 106 } 107 108 } // namespace <anonymous> 109 110 void InitChildProcess(JNIEnv* env, 111 jclass clazz, 112 jobject context, 113 jobject service, 114 jintArray j_file_ids, 115 jintArray j_file_fds, 116 jint cpu_count, 117 jlong cpu_features) { 118 std::vector<int> file_ids; 119 std::vector<int> file_fds; 120 JavaIntArrayToIntVector(env, j_file_ids, &file_ids); 121 JavaIntArrayToIntVector(env, j_file_fds, &file_fds); 122 123 InternalInitChildProcess( 124 file_ids, file_fds, env, clazz, context, service, 125 cpu_count, cpu_features); 126 } 127 128 void ExitChildProcess(JNIEnv* env, jclass clazz) { 129 LOG(INFO) << "ChildProcessService: Exiting child process."; 130 LibraryLoaderExitHook(); 131 _exit(0); 132 } 133 134 bool RegisterChildProcessService(JNIEnv* env) { 135 return RegisterNativesImpl(env); 136 } 137 138 void ShutdownMainThread(JNIEnv* env, jobject obj) { 139 ChildThread::ShutdownThread(); 140 } 141 142 } // namespace content 143