12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/app/android/child_process_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <android/native_window_jni.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cpu-features.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/android/jni_array.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/android/library_loader/library_loader_hooks.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/android/memory_pressure_listener_android.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/global_descriptors.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h" 164ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "content/common/android/surface_texture_lookup.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/android/surface_texture_peer.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_surface_lookup.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/app/android_library_loader_hooks.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_descriptors.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_descriptors.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "jni/ChildProcessService_jni.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gl/android/scoped_java_surface.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::android::AttachCurrentThread; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::android::CheckException; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::android::JavaIntArrayToIntVector; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 334ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochclass SurfaceTexturePeerChildImpl : public SurfaceTexturePeer, 344ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch public GpuSurfaceLookup, 354ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch public SurfaceTextureLookup { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |service| is the instance of 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // org.chromium.content.app.ChildProcessService. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit SurfaceTexturePeerChildImpl( 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::android::ScopedJavaLocalRef<jobject>& service) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : service_(service) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuSurfaceLookup::InitInstance(this); 434ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch SurfaceTextureLookup::InitInstance(this); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SurfaceTexturePeerChildImpl() { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuSurfaceLookup::InitInstance(NULL); 484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch SurfaceTextureLookup::InitInstance(NULL); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 514ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Overridden from SurfaceTexturePeer: 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void EstablishSurfaceTexturePeer( 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ProcessHandle pid, 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<gfx::SurfaceTexture> surface_texture, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int primary_id, 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int secondary_id) OVERRIDE { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env = base::android::AttachCurrentThread(); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Java_ChildProcessService_establishSurfaceTexturePeer( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env, service_.obj(), pid, 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) surface_texture->j_surface_texture().obj(), primary_id, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) secondary_id); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckException(env); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 654ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Overridden from GpuSurfaceLookup: 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) OVERRIDE { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env = base::android::AttachCurrentThread(); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::ScopedJavaSurface surface( 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Java_ChildProcessService_getViewSurface( 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env, service_.obj(), surface_id)); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (surface.j_surface().is_null()) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Note: This ensures that any local references used by 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // ANativeWindow_fromSurface are released immediately. This is needed as a 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // workaround for https://code.google.com/p/android/issues/detail?id=68174 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ANativeWindow* native_window = 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ANativeWindow_fromSurface(env, surface.j_surface().obj()); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return native_window; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 854ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Overridden from SurfaceTextureLookup: 864ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch virtual gfx::AcceleratedWidget AcquireNativeWidget(int primary_id, 874ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch int secondary_id) 884ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch OVERRIDE { 894ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch JNIEnv* env = base::android::AttachCurrentThread(); 904ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch gfx::ScopedJavaSurface surface( 914ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch content::Java_ChildProcessService_getSurfaceTextureSurface( 924ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch env, service_.obj(), primary_id, secondary_id)); 934ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 944ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch if (surface.j_surface().is_null()) 954ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return NULL; 964ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Note: This ensures that any local references used by 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // ANativeWindow_fromSurface are released immediately. This is needed as a 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // workaround for https://code.google.com/p/android/issues/detail?id=68174 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); 1014ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch ANativeWindow* native_window = 1024ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch ANativeWindow_fromSurface(env, surface.j_surface().obj()); 1034ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 1044ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return native_window; 1054ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch } 1064ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The instance of org.chromium.content.app.ChildProcessService. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::android::ScopedJavaGlobalRef<jobject> service_; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SurfaceTexturePeerChildImpl); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Chrome actually uses the renderer code path for all of its child 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// processes such as renderers, plugins, etc. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InternalInitChildProcess(const std::vector<int>& file_ids, 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::vector<int>& file_fds, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jclass clazz, 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jobject context, 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jobject service_in, 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jint cpu_count, 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jlong cpu_features) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::android::ScopedJavaLocalRef<jobject> service(env, service_in); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the CPU properties. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) android_setCpu(cpu_count, cpu_features); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Register the file descriptors. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This includes the IPC channel, the crash dump signals and resource related 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // files. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(file_fds.size() == file_ids.size()); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < file_ids.size(); ++i) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::GlobalDescriptors::GetInstance()->Set(file_ids[i], file_fds[i]); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1354ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // SurfaceTexturePeerChildImpl implements the SurfaceTextureLookup interface, 1364ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // which need to be set before we create a compositor thread that could be 1374ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // using it to initialize resources. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::SurfaceTexturePeer::InitInstance( 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SurfaceTexturePeerChildImpl(service)); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(env); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace <anonymous> 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InitChildProcess(JNIEnv* env, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jclass clazz, 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jobject context, 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jobject service, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jintArray j_file_ids, 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jintArray j_file_fds, 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jint cpu_count, 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jlong cpu_features) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<int> file_ids; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<int> file_fds; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JavaIntArrayToIntVector(env, j_file_ids, &file_ids); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JavaIntArrayToIntVector(env, j_file_fds, &file_fds); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InternalInitChildProcess( 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_ids, file_fds, env, clazz, context, service, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cpu_count, cpu_features); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExitChildProcess(JNIEnv* env, jclass clazz) { 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(0) << "ChildProcessService: Exiting child process."; 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::android::LibraryLoaderExitHook(); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _exit(0); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RegisterChildProcessService(JNIEnv* env) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RegisterNativesImpl(env); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShutdownMainThread(JNIEnv* env, jobject obj) { 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ChildThread::ShutdownThread(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 179