xref: /aosp_15_r20/frameworks/native/cmds/lshal/libprocpartition/procpartition.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <procpartition/procpartition.h>
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <android-base/file.h>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker namespace android {
22*38e8c45fSAndroid Build Coastguard Worker namespace procpartition {
23*38e8c45fSAndroid Build Coastguard Worker 
operator <<(std::ostream & os,Partition p)24*38e8c45fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, Partition p) {
25*38e8c45fSAndroid Build Coastguard Worker     switch (p) {
26*38e8c45fSAndroid Build Coastguard Worker         case Partition::SYSTEM: return os << "system";
27*38e8c45fSAndroid Build Coastguard Worker         case Partition::VENDOR: return os << "vendor";
28*38e8c45fSAndroid Build Coastguard Worker         case Partition::ODM: return os << "odm";
29*38e8c45fSAndroid Build Coastguard Worker         case Partition::UNKNOWN: // fallthrough
30*38e8c45fSAndroid Build Coastguard Worker         default:
31*38e8c45fSAndroid Build Coastguard Worker             return os << "(unknown)";
32*38e8c45fSAndroid Build Coastguard Worker     }
33*38e8c45fSAndroid Build Coastguard Worker }
34*38e8c45fSAndroid Build Coastguard Worker 
getExe(pid_t pid)35*38e8c45fSAndroid Build Coastguard Worker std::string getExe(pid_t pid) {
36*38e8c45fSAndroid Build Coastguard Worker     std::string exe;
37*38e8c45fSAndroid Build Coastguard Worker     std::string real;
38*38e8c45fSAndroid Build Coastguard Worker     if (!android::base::Readlink("/proc/" + std::to_string(pid) + "/exe", &exe)) {
39*38e8c45fSAndroid Build Coastguard Worker         return "";
40*38e8c45fSAndroid Build Coastguard Worker     }
41*38e8c45fSAndroid Build Coastguard Worker     if (!android::base::Realpath(exe, &real)) {
42*38e8c45fSAndroid Build Coastguard Worker         return "";
43*38e8c45fSAndroid Build Coastguard Worker     }
44*38e8c45fSAndroid Build Coastguard Worker     return real;
45*38e8c45fSAndroid Build Coastguard Worker }
46*38e8c45fSAndroid Build Coastguard Worker 
getCmdline(pid_t pid)47*38e8c45fSAndroid Build Coastguard Worker std::string getCmdline(pid_t pid) {
48*38e8c45fSAndroid Build Coastguard Worker     std::string content;
49*38e8c45fSAndroid Build Coastguard Worker     if (!android::base::ReadFileToString("/proc/" + std::to_string(pid) + "/cmdline", &content,
50*38e8c45fSAndroid Build Coastguard Worker                                          false /* follow symlinks */)) {
51*38e8c45fSAndroid Build Coastguard Worker         return "";
52*38e8c45fSAndroid Build Coastguard Worker     }
53*38e8c45fSAndroid Build Coastguard Worker     return std::string{content.c_str()};
54*38e8c45fSAndroid Build Coastguard Worker }
55*38e8c45fSAndroid Build Coastguard Worker 
parsePartition(const std::string & s)56*38e8c45fSAndroid Build Coastguard Worker Partition parsePartition(const std::string& s) {
57*38e8c45fSAndroid Build Coastguard Worker     if (s == "system") {
58*38e8c45fSAndroid Build Coastguard Worker         return Partition::SYSTEM;
59*38e8c45fSAndroid Build Coastguard Worker     }
60*38e8c45fSAndroid Build Coastguard Worker     if (s == "vendor") {
61*38e8c45fSAndroid Build Coastguard Worker         return Partition::VENDOR;
62*38e8c45fSAndroid Build Coastguard Worker     }
63*38e8c45fSAndroid Build Coastguard Worker     if (s == "odm") {
64*38e8c45fSAndroid Build Coastguard Worker         return Partition::ODM;
65*38e8c45fSAndroid Build Coastguard Worker     }
66*38e8c45fSAndroid Build Coastguard Worker     return Partition::UNKNOWN;
67*38e8c45fSAndroid Build Coastguard Worker }
68*38e8c45fSAndroid Build Coastguard Worker 
getPartitionFromRealpath(const std::string & path)69*38e8c45fSAndroid Build Coastguard Worker Partition getPartitionFromRealpath(const std::string& path) {
70*38e8c45fSAndroid Build Coastguard Worker     if (path == "/system/bin/app_process64" ||
71*38e8c45fSAndroid Build Coastguard Worker         path == "/system/bin/app_process32") {
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker         return Partition::UNKNOWN; // cannot determine
74*38e8c45fSAndroid Build Coastguard Worker     }
75*38e8c45fSAndroid Build Coastguard Worker     size_t backslash = path.find_first_of('/', 1);
76*38e8c45fSAndroid Build Coastguard Worker     std::string partition = (backslash != std::string::npos) ? path.substr(1, backslash - 1) : path;
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker     return parsePartition(partition);
79*38e8c45fSAndroid Build Coastguard Worker }
80*38e8c45fSAndroid Build Coastguard Worker 
getPartitionFromCmdline(pid_t pid)81*38e8c45fSAndroid Build Coastguard Worker Partition getPartitionFromCmdline(pid_t pid) {
82*38e8c45fSAndroid Build Coastguard Worker     const auto& cmdline = getCmdline(pid);
83*38e8c45fSAndroid Build Coastguard Worker     if (cmdline == "system_server") {
84*38e8c45fSAndroid Build Coastguard Worker         return Partition::SYSTEM;
85*38e8c45fSAndroid Build Coastguard Worker     }
86*38e8c45fSAndroid Build Coastguard Worker     if (cmdline.empty() || cmdline.front() != '/') {
87*38e8c45fSAndroid Build Coastguard Worker         return Partition::UNKNOWN;
88*38e8c45fSAndroid Build Coastguard Worker     }
89*38e8c45fSAndroid Build Coastguard Worker     return getPartitionFromRealpath(cmdline);
90*38e8c45fSAndroid Build Coastguard Worker }
91*38e8c45fSAndroid Build Coastguard Worker 
getPartitionFromExe(pid_t pid)92*38e8c45fSAndroid Build Coastguard Worker Partition getPartitionFromExe(pid_t pid) {
93*38e8c45fSAndroid Build Coastguard Worker     const auto& real = getExe(pid);
94*38e8c45fSAndroid Build Coastguard Worker     if (real.empty() || real.front() != '/') {
95*38e8c45fSAndroid Build Coastguard Worker         return Partition::UNKNOWN;
96*38e8c45fSAndroid Build Coastguard Worker     }
97*38e8c45fSAndroid Build Coastguard Worker     return getPartitionFromRealpath(real);
98*38e8c45fSAndroid Build Coastguard Worker }
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker 
getPartition(pid_t pid)101*38e8c45fSAndroid Build Coastguard Worker Partition getPartition(pid_t pid) {
102*38e8c45fSAndroid Build Coastguard Worker     Partition partition = getPartitionFromExe(pid);
103*38e8c45fSAndroid Build Coastguard Worker     if (partition == Partition::UNKNOWN) {
104*38e8c45fSAndroid Build Coastguard Worker         partition = getPartitionFromCmdline(pid);
105*38e8c45fSAndroid Build Coastguard Worker     }
106*38e8c45fSAndroid Build Coastguard Worker     return partition;
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker }  // namespace procpartition
110*38e8c45fSAndroid Build Coastguard Worker }  // namespace android
111