• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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