1 /*
2  * Copyright (C) 2015 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ProcessInfo"
19 #include <utils/Log.h>
20 
21 #include <media/stagefright/ProcessInfo.h>
22 
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
25 #include <private/android_filesystem_config.h>
26 #include <processinfo/IProcessInfoService.h>
27 
28 namespace android {
29 
30 static constexpr int32_t INVALID_ADJ = -10000;
31 static constexpr int32_t NATIVE_ADJ = -1000;
32 
ProcessInfo()33 ProcessInfo::ProcessInfo() {}
34 
getPriority(int pid,int * priority)35 bool ProcessInfo::getPriority(int pid, int* priority) {
36     sp<IBinder> binder = defaultServiceManager()->getService(String16("processinfo"));
37     sp<IProcessInfoService> service = interface_cast<IProcessInfoService>(binder);
38 
39     size_t length = 1;
40     int32_t state;
41     int32_t score = INVALID_ADJ;
42     status_t err = service->getProcessStatesAndOomScoresFromPids(length, &pid, &state, &score);
43     if (err != OK) {
44         ALOGE("getProcessStatesAndOomScoresFromPids failed");
45         return false;
46     }
47     ALOGV("pid %d state %d score %d", pid, state, score);
48     if (score <= NATIVE_ADJ) {
49         std::scoped_lock lock{mOverrideLock};
50 
51         // If this process if not tracked by ActivityManagerService, look for overrides.
52         auto it = mOverrideMap.find(pid);
53         if (it != mOverrideMap.end()) {
54             ALOGI("pid %d invalid OOM score %d, override to %d", pid, score, it->second.oomScore);
55             score = it->second.oomScore;
56         } else {
57             ALOGE("pid %d invalid OOM score %d", pid, score);
58             return false;
59         }
60     }
61 
62     // Use OOM adjustments value as the priority. Lower the value, higher the priority.
63     *priority = score;
64     return true;
65 }
66 
isValidPid(int pid)67 bool ProcessInfo::isValidPid(int pid) {
68     int callingPid = IPCThreadState::self()->getCallingPid();
69     int callingUid = IPCThreadState::self()->getCallingUid();
70     // Trust it if this is called from the same process otherwise pid has to match the calling pid.
71     return (callingPid == getpid()) || (callingPid == pid) || (callingUid == AID_MEDIA);
72 }
73 
overrideProcessInfo(int pid,int procState,int oomScore)74 bool ProcessInfo::overrideProcessInfo(int pid, int procState, int oomScore) {
75     std::scoped_lock lock{mOverrideLock};
76 
77     mOverrideMap.erase(pid);
78 
79     // Disable the override if oomScore is set to NATIVE_ADJ or below.
80     if (oomScore <= NATIVE_ADJ) {
81         return false;
82     }
83 
84     mOverrideMap.emplace(pid, ProcessInfoOverride{procState, oomScore});
85     return true;
86 }
87 
removeProcessInfoOverride(int pid)88 void ProcessInfo::removeProcessInfoOverride(int pid) {
89     std::scoped_lock lock{mOverrideLock};
90 
91     mOverrideMap.erase(pid);
92 }
93 
~ProcessInfo()94 ProcessInfo::~ProcessInfo() {}
95 
96 }  // namespace android
97