| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/android/jni_array.h" |
| #include "base/android/jni_string.h" |
| #include "base/android/library_loader/library_loader_hooks.h" |
| #include "base/file_descriptor_store.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/optional.h" |
| #include "base/posix/global_descriptors.h" |
| #include "jni/ChildProcessService_jni.h" |
| |
| using base::android::JavaIntArrayToIntVector; |
| using base::android::JavaParamRef; |
| |
| namespace base { |
| namespace android { |
| |
| void JNI_ChildProcessService_RegisterFileDescriptors( |
| JNIEnv* env, |
| const JavaParamRef<jclass>& clazz, |
| const JavaParamRef<jobjectArray>& j_keys, |
| const JavaParamRef<jintArray>& j_ids, |
| const JavaParamRef<jintArray>& j_fds, |
| const JavaParamRef<jlongArray>& j_offsets, |
| const JavaParamRef<jlongArray>& j_sizes) { |
| std::vector<base::Optional<std::string>> keys; |
| jsize keys_size = env->GetArrayLength(j_keys); |
| keys.reserve(keys_size); |
| for (jsize i = 0; i < keys_size; i++) { |
| base::android::ScopedJavaLocalRef<jstring> str( |
| env, static_cast<jstring>(env->GetObjectArrayElement(j_keys, i))); |
| base::Optional<std::string> key; |
| if (!str.is_null()) { |
| key = base::android::ConvertJavaStringToUTF8(env, str); |
| } |
| keys.push_back(std::move(key)); |
| } |
| |
| std::vector<int> ids; |
| base::android::JavaIntArrayToIntVector(env, j_ids, &ids); |
| std::vector<int> fds; |
| base::android::JavaIntArrayToIntVector(env, j_fds, &fds); |
| std::vector<int64_t> offsets; |
| base::android::JavaLongArrayToInt64Vector(env, j_offsets, &offsets); |
| std::vector<int64_t> sizes; |
| base::android::JavaLongArrayToInt64Vector(env, j_sizes, &sizes); |
| |
| DCHECK_EQ(keys.size(), ids.size()); |
| DCHECK_EQ(ids.size(), fds.size()); |
| DCHECK_EQ(fds.size(), offsets.size()); |
| DCHECK_EQ(offsets.size(), sizes.size()); |
| |
| for (size_t i = 0; i < ids.size(); i++) { |
| base::MemoryMappedFile::Region region = {offsets.at(i), sizes.at(i)}; |
| const base::Optional<std::string>& key = keys.at(i); |
| int id = ids.at(i); |
| int fd = fds.at(i); |
| if (key) { |
| base::FileDescriptorStore::GetInstance().Set(*key, base::ScopedFD(fd), |
| region); |
| } else { |
| base::GlobalDescriptors::GetInstance()->Set(id, fd, region); |
| } |
| } |
| } |
| |
| void JNI_ChildProcessService_ExitChildProcess( |
| JNIEnv* env, |
| const JavaParamRef<jclass>& clazz) { |
| VLOG(0) << "ChildProcessService: Exiting child process."; |
| base::android::LibraryLoaderExitHook(); |
| _exit(0); |
| } |
| |
| } // namespace android |
| } // namespace base |