1 // Copyright 2017 The Chromium Authors
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 "base/android/jni_array.h"
6 #include "base/android/jni_string.h"
7 #include "base/android/library_loader/library_loader_hooks.h"
8 #include "base/base_jni_headers/ChildProcessService_jni.h"
9 #include "base/debug/dump_without_crashing.h"
10 #include "base/file_descriptor_store.h"
11 #include "base/logging.h"
12 #include "base/posix/global_descriptors.h"
13 #include "third_party/abseil-cpp/absl/types/optional.h"
14
15 using base::android::JavaIntArrayToIntVector;
16 using base::android::JavaParamRef;
17
18 namespace base {
19 namespace android {
20
JNI_ChildProcessService_RegisterFileDescriptors(JNIEnv * env,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)21 void JNI_ChildProcessService_RegisterFileDescriptors(
22 JNIEnv* env,
23 const JavaParamRef<jobjectArray>& j_keys,
24 const JavaParamRef<jintArray>& j_ids,
25 const JavaParamRef<jintArray>& j_fds,
26 const JavaParamRef<jlongArray>& j_offsets,
27 const JavaParamRef<jlongArray>& j_sizes) {
28 std::vector<absl::optional<std::string>> keys;
29 JavaObjectArrayReader<jstring> keys_array(j_keys);
30 keys.reserve(checked_cast<size_t>(keys_array.size()));
31 for (auto str : keys_array) {
32 absl::optional<std::string> key;
33 if (str) {
34 key = base::android::ConvertJavaStringToUTF8(env, str);
35 }
36 keys.push_back(std::move(key));
37 }
38
39 std::vector<int> ids;
40 base::android::JavaIntArrayToIntVector(env, j_ids, &ids);
41 std::vector<int> fds;
42 base::android::JavaIntArrayToIntVector(env, j_fds, &fds);
43 std::vector<int64_t> offsets;
44 base::android::JavaLongArrayToInt64Vector(env, j_offsets, &offsets);
45 std::vector<int64_t> sizes;
46 base::android::JavaLongArrayToInt64Vector(env, j_sizes, &sizes);
47
48 DCHECK_EQ(keys.size(), ids.size());
49 DCHECK_EQ(ids.size(), fds.size());
50 DCHECK_EQ(fds.size(), offsets.size());
51 DCHECK_EQ(offsets.size(), sizes.size());
52
53 for (size_t i = 0; i < ids.size(); i++) {
54 base::MemoryMappedFile::Region region = {offsets.at(i),
55 static_cast<size_t>(sizes.at(i))};
56 const absl::optional<std::string>& key = keys.at(i);
57 const auto id = static_cast<GlobalDescriptors::Key>(ids.at(i));
58 int fd = fds.at(i);
59 if (key) {
60 base::FileDescriptorStore::GetInstance().Set(*key, base::ScopedFD(fd),
61 region);
62 } else {
63 base::GlobalDescriptors::GetInstance()->Set(id, fd, region);
64 }
65 }
66 }
67
JNI_ChildProcessService_ExitChildProcess(JNIEnv * env)68 void JNI_ChildProcessService_ExitChildProcess(JNIEnv* env) {
69 VLOG(0) << "ChildProcessService: Exiting child process.";
70 base::android::LibraryLoaderExitHook();
71 _exit(0);
72 }
73
74 // Make sure this isn't inlined so it shows up in stack traces.
75 // the function body unique by adding a log line, so it doesn't get merged
76 // with other functions by link time optimizations (ICF).
JNI_ChildProcessService_DumpProcessStack(JNIEnv * env)77 NOINLINE void JNI_ChildProcessService_DumpProcessStack(JNIEnv* env) {
78 LOG(ERROR) << "Dumping as requested.";
79 base::debug::DumpWithoutCrashing();
80 }
81
82 } // namespace android
83 } // namespace base
84