1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <dlfcn.h>
18 #include <pthread.h>
19
20 #include <chrono>
21 #include <thread>
22
23 #include <jni.h>
24 #include <nativehelper/JNIHelp.h>
25
26 #include <binder/IServiceManager.h>
27 #include <hidl/HidlTransportSupport.h>
28 #include <incremental_service.h>
29
30 #include <schedulerservice/SchedulingPolicyService.h>
31 #include <sensorservice/SensorService.h>
32 #include <sensorservicehidl/SensorManager.h>
33 #include <stats/StatsHal.h>
34
35 #include <bionic/malloc.h>
36 #include <bionic/reserved_signals.h>
37
38 #include <android-base/properties.h>
39 #include <cutils/properties.h>
40 #include <utils/Log.h>
41 #include <utils/misc.h>
42 #include <utils/AndroidThreads.h>
43
44 using android::base::GetIntProperty;
45 using namespace std::chrono_literals;
46
47 namespace android {
48
android_server_SystemServer_startSensorService(JNIEnv *,jobject)49 static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
50 char propBuf[PROPERTY_VALUE_MAX];
51 property_get("system_init.startsensorservice", propBuf, "1");
52 if (strcmp(propBuf, "1") == 0) {
53 SensorService::publish(false /* allowIsolated */,
54 IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
55 }
56
57 }
58
android_server_SystemServer_startHidlServices(JNIEnv * env,jobject)59 static void android_server_SystemServer_startHidlServices(JNIEnv* env, jobject /* clazz */) {
60 using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService;
61 using ::android::frameworks::schedulerservice::V1_0::implementation::SchedulingPolicyService;
62 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
63 using ::android::frameworks::sensorservice::V1_0::implementation::SensorManager;
64 using ::android::frameworks::stats::V1_0::IStats;
65 using ::android::frameworks::stats::V1_0::implementation::StatsHal;
66 using ::android::hardware::configureRpcThreadpool;
67
68 status_t err;
69
70 configureRpcThreadpool(5, false /* callerWillJoin */);
71
72 JavaVM *vm;
73 LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Cannot get Java VM");
74
75 sp<ISensorManager> sensorService = new SensorManager(vm);
76 err = sensorService->registerAsService();
77 ALOGE_IF(err != OK, "Cannot register %s: %d", ISensorManager::descriptor, err);
78
79 sp<ISchedulingPolicyService> schedulingService = new SchedulingPolicyService();
80 err = schedulingService->registerAsService();
81 ALOGE_IF(err != OK, "Cannot register %s: %d", ISchedulingPolicyService::descriptor, err);
82
83 sp<IStats> statsHal = new StatsHal();
84 err = statsHal->registerAsService();
85 ALOGE_IF(err != OK, "Cannot register %s: %d", IStats::descriptor, err);
86 }
87
android_server_SystemServer_initZygoteChildHeapProfiling(JNIEnv *,jobject)88 static void android_server_SystemServer_initZygoteChildHeapProfiling(JNIEnv* /* env */,
89 jobject /* clazz */) {
90 android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0);
91 }
92
get_current_max_fd()93 static int get_current_max_fd() {
94 // Not actually guaranteed to be the max, but close enough for our purposes.
95 int fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
96 LOG_ALWAYS_FATAL_IF(fd == -1, "failed to open /dev/null: %s", strerror(errno));
97 close(fd);
98 return fd;
99 }
100
101 static const char kFdLeakEnableThresholdProperty[] = "persist.sys.debug.fdtrack_enable_threshold";
102 static const char kFdLeakAbortThresholdProperty[] = "persist.sys.debug.fdtrack_abort_threshold";
103 static const char kFdLeakCheckIntervalProperty[] = "persist.sys.debug.fdtrack_interval";
104
android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv *,jobject)105 static void android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv*, jobject) {
106 std::thread([]() {
107 pthread_setname_np(pthread_self(), "FdLeakCheckThread");
108 bool loaded = false;
109 while (true) {
110 const int enable_threshold = GetIntProperty(kFdLeakEnableThresholdProperty, 1024);
111 const int abort_threshold = GetIntProperty(kFdLeakAbortThresholdProperty, 2048);
112 const int check_interval = GetIntProperty(kFdLeakCheckIntervalProperty, 120);
113 int max_fd = get_current_max_fd();
114 if (max_fd > enable_threshold && !loaded) {
115 loaded = true;
116 ALOGE("fd count above threshold of %d, starting fd backtraces", enable_threshold);
117 if (dlopen("libfdtrack.so", RTLD_GLOBAL) == nullptr) {
118 ALOGE("failed to load libfdtrack.so: %s", dlerror());
119 }
120 } else if (max_fd > abort_threshold) {
121 raise(BIONIC_SIGNAL_FDTRACK);
122
123 // Wait for a bit to allow fdtrack to dump backtraces to logcat.
124 std::this_thread::sleep_for(5s);
125
126 LOG_ALWAYS_FATAL(
127 "b/140703823: aborting due to fd leak: check logs for fd "
128 "backtraces");
129 }
130
131 std::this_thread::sleep_for(std::chrono::seconds(check_interval));
132 }
133 }).detach();
134 }
135
android_server_SystemServer_startIncrementalService(JNIEnv * env,jclass klass,jobject self)136 static jlong android_server_SystemServer_startIncrementalService(JNIEnv* env, jclass klass,
137 jobject self) {
138 return Incremental_IncrementalService_Start(env);
139 }
140
android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv * env,jclass klass,jlong handle)141 static void android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv* env, jclass klass,
142 jlong handle) {
143 Incremental_IncrementalService_OnSystemReady(handle);
144 }
145
146 /*
147 * JNI registration.
148 */
149 static const JNINativeMethod gMethods[] = {
150 /* name, signature, funcPtr */
151 {"startSensorService", "()V", (void*)android_server_SystemServer_startSensorService},
152 {"startHidlServices", "()V", (void*)android_server_SystemServer_startHidlServices},
153 {"initZygoteChildHeapProfiling", "()V",
154 (void*)android_server_SystemServer_initZygoteChildHeapProfiling},
155 {"spawnFdLeakCheckThread", "()V",
156 (void*)android_server_SystemServer_spawnFdLeakCheckThread},
157 {"startIncrementalService", "()J",
158 (void*)android_server_SystemServer_startIncrementalService},
159 {"setIncrementalServiceSystemReady", "(J)V",
160 (void*)android_server_SystemServer_setIncrementalServiceSystemReady},
161 };
162
register_android_server_SystemServer(JNIEnv * env)163 int register_android_server_SystemServer(JNIEnv* env)
164 {
165 return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
166 gMethods, NELEM(gMethods));
167 }
168
169 }; // namespace android
170