Skip to content

Commit b54e597

Browse files
committed
[Refactor] Use ProcFs to fetch CPU info
1 parent 43c0f9a commit b54e597

File tree

5 files changed

+272
-22
lines changed

5 files changed

+272
-22
lines changed

app/src/main/java/io/github/muntashirakon/AppManager/misc/DeviceInfo2.java

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
package io.github.muntashirakon.AppManager.misc;
44

5+
import static io.github.muntashirakon.AppManager.utils.UIUtils.getStyledKeyValue;
6+
import static io.github.muntashirakon.AppManager.utils.UIUtils.getTitleText;
7+
58
import android.annotation.SuppressLint;
69
import android.app.ActivityManager;
710
import android.content.Context;
@@ -28,7 +31,6 @@
2831

2932
import com.android.internal.util.TextUtils;
3033

31-
import java.io.BufferedReader;
3234
import java.security.Provider;
3335
import java.security.Security;
3436
import java.text.ParseException;
@@ -46,14 +48,9 @@
4648
import io.github.muntashirakon.AppManager.users.UserInfo;
4749
import io.github.muntashirakon.AppManager.users.Users;
4850
import io.github.muntashirakon.AppManager.utils.Utils;
49-
import io.github.muntashirakon.io.Path;
50-
import io.github.muntashirakon.io.PathReader;
51-
import io.github.muntashirakon.io.Paths;
51+
import io.github.muntashirakon.proc.ProcFs;
5252
import io.github.muntashirakon.util.LocalizedString;
5353

54-
import static io.github.muntashirakon.AppManager.utils.UIUtils.getStyledKeyValue;
55-
import static io.github.muntashirakon.AppManager.utils.UIUtils.getTitleText;
56-
5754
public class DeviceInfo2 implements LocalizedString {
5855
public final String osVersion = Build.VERSION.RELEASE;
5956
public final String bootloader = Build.BOOTLOADER;
@@ -364,21 +361,7 @@ private String getEncryptionStatus() {
364361

365362
@Nullable
366363
private String getCpuHardware() {
367-
Path cpuInfoPath = Paths.getUnprivileged("/proc/cpuinfo");
368-
try (BufferedReader reader = new BufferedReader(new PathReader(cpuInfoPath))) {
369-
String line;
370-
while ((line = reader.readLine()) != null) {
371-
if (line.trim().startsWith("Hardware")) {
372-
int colonLoc = line.indexOf(':');
373-
if (colonLoc == -1) continue;
374-
colonLoc += 2;
375-
return line.substring(colonLoc).trim();
376-
}
377-
}
378-
} catch (Throwable e) {
379-
e.printStackTrace();
380-
}
381-
return null;
364+
return ProcFs.getInstance().getCpuInfoHardware();
382365
}
383366

384367
@SuppressLint("PrivateApi")

app/src/main/java/io/github/muntashirakon/AppManager/utils/FileUtils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
package io.github.muntashirakon.AppManager.utils;
44

5+
import static android.system.OsConstants.O_ACCMODE;
6+
import static android.system.OsConstants.O_APPEND;
7+
import static android.system.OsConstants.O_RDONLY;
8+
import static android.system.OsConstants.O_RDWR;
9+
import static android.system.OsConstants.O_TRUNC;
10+
import static android.system.OsConstants.O_WRONLY;
11+
512
import android.content.Context;
613
import android.content.res.AssetFileDescriptor;
714
import android.os.Environment;
@@ -213,4 +220,24 @@ public static boolean canRead(@NonNull File file) {
213220
}
214221
return false;
215222
}
223+
224+
public static String translateModePosixToString(int mode) {
225+
String res = "";
226+
if ((mode & O_ACCMODE) == O_RDWR) {
227+
res = "rw";
228+
} else if ((mode & O_ACCMODE) == O_WRONLY) {
229+
res = "w";
230+
} else if ((mode & O_ACCMODE) == O_RDONLY) {
231+
res = "r";
232+
} else {
233+
throw new IllegalArgumentException("Bad mode: " + mode);
234+
}
235+
if ((mode & O_TRUNC) == O_TRUNC) {
236+
res += "t";
237+
}
238+
if ((mode & O_APPEND) == O_APPEND) {
239+
res += "a";
240+
}
241+
return res;
242+
}
216243
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
package io.github.muntashirakon.proc;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.annotation.Nullable;
7+
8+
import java.util.Collection;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
import io.github.muntashirakon.AppManager.utils.FileUtils;
13+
import io.github.muntashirakon.io.Path;
14+
15+
public class ProcFdInfoList {
16+
public static class ProcFdInfo {
17+
public final int id;
18+
public final long offset;
19+
public final int mode;
20+
public final int mountId;
21+
@NonNull
22+
public final Path realPath;
23+
@NonNull
24+
public final String[] extras;
25+
26+
private ProcFdInfo(int id, @NonNull Path realPath, @NonNull String[] info) {
27+
this.id = id;
28+
this.realPath = realPath;
29+
this.extras = new String[info.length - 3]; // Ignore three mandatory fields
30+
int i = 0;
31+
long offset = -1;
32+
int mode = -1;
33+
int mountId = -1;
34+
for (String line : info) {
35+
if (line.startsWith("pos:")) {
36+
offset = Long.decode(line.substring(4).trim());
37+
} else if (line.startsWith("flags:")) {
38+
mode = Integer.decode(line.substring(6).trim());
39+
} else if (line.startsWith("mnt_id:")) {
40+
mountId = Integer.decode(line.substring(7).trim());
41+
} else {
42+
extras[i++] = line;
43+
}
44+
}
45+
assert offset != -1;
46+
assert mode != -1;
47+
assert mountId != -1;
48+
49+
this.offset = offset;
50+
this.mode = mode;
51+
this.mountId = mountId;
52+
}
53+
54+
public String getModeString() {
55+
return FileUtils.translateModePosixToString(mode);
56+
}
57+
}
58+
59+
private final Map<Integer, ProcFdInfo> mFdInfoMap;
60+
61+
ProcFdInfoList(@NonNull Path[] fdFiles, @NonNull String[] fdInfoList) {
62+
assert fdFiles.length == fdInfoList.length;
63+
mFdInfoMap = new HashMap<>(fdFiles.length);
64+
for (int i = 0; i < fdFiles.length; ++i) {
65+
String fdInfo = fdInfoList[i];
66+
if (fdInfo == null) {
67+
// FD no longer exists
68+
continue;
69+
}
70+
Path fdFile = fdFiles[i];
71+
int fd = Integer.decode(fdFile.getName());
72+
ProcFdInfo procFdInfo = new ProcFdInfo(fd, fdFile, fdInfo.split("\\n"));
73+
mFdInfoMap.put(fd, procFdInfo);
74+
}
75+
}
76+
77+
public Collection<Integer> getFds() {
78+
return mFdInfoMap.keySet();
79+
}
80+
81+
@Nullable
82+
public ProcFdInfo getFdInfo(int fd) {
83+
return mFdInfoMap.get(fd);
84+
}
85+
}

app/src/main/java/io/github/muntashirakon/proc/ProcFs.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010

1111
import com.android.internal.util.TextUtils;
1212

13+
import java.io.BufferedReader;
14+
import java.io.IOException;
15+
1316
import io.github.muntashirakon.io.Path;
17+
import io.github.muntashirakon.io.PathReader;
1418
import io.github.muntashirakon.io.Paths;
1519

1620
public class ProcFs {
@@ -90,6 +94,30 @@ public ProcFs(Path procRoot) {
9094
this.procRoot = procRoot;
9195
}
9296

97+
@Nullable
98+
public String getCpuInfoHardware() {
99+
// Only hardware is the relevant output, other outputs can be parsed from
100+
// /sys/devices/system/cpu/
101+
Path cpuInfoPath = Paths.build(procRoot, CPU_INFO);
102+
if (cpuInfoPath == null) {
103+
return null;
104+
}
105+
try (BufferedReader reader = new BufferedReader(new PathReader(cpuInfoPath))) {
106+
String line;
107+
while ((line = reader.readLine()) != null) {
108+
if (line.trim().startsWith("Hardware")) {
109+
int colonLoc = line.indexOf(':');
110+
if (colonLoc == -1) continue;
111+
colonLoc += 2;
112+
return line.substring(colonLoc).trim();
113+
}
114+
}
115+
} catch (Throwable e) {
116+
e.printStackTrace();
117+
}
118+
return null;
119+
}
120+
93121
public ProcMemoryInfo getMemoryInfo() {
94122
String statFileContents = getStringOrNull(Paths.build(procRoot, MEM_INFO));
95123
if (statFileContents == null) {
@@ -124,6 +152,58 @@ public String getCmdline(int pid) {
124152
return getStringOrNull(Paths.build(procRoot, String.valueOf(pid), CMDLINE));
125153
}
126154

155+
@Nullable
156+
public String getCwd(int pid) {
157+
Path cwdPath = Paths.build(procRoot, String.valueOf(pid), CWD);
158+
if (cwdPath != null) {
159+
try {
160+
return cwdPath.getRealFilePath();
161+
} catch (IOException e) {
162+
e.printStackTrace();
163+
}
164+
}
165+
return null;
166+
}
167+
168+
public String[] getEnvVars(int pid) {
169+
String data = getStringOrNull(Paths.build(procRoot, String.valueOf(pid), ENVIRON));
170+
return data != null ? data.split("\0") : null;
171+
}
172+
173+
@Nullable
174+
public String getExe(int pid) {
175+
Path exePath = Paths.build(procRoot, String.valueOf(pid), EXE);
176+
if (exePath != null) {
177+
try {
178+
return exePath.getRealFilePath();
179+
} catch (IOException e) {
180+
e.printStackTrace();
181+
}
182+
}
183+
return null;
184+
}
185+
186+
public ProcFdInfoList getFdInfo(int pid) {
187+
Path fdDir = Paths.build(procRoot, String.valueOf(pid), FD);
188+
Path fdInfoDir = Paths.build(procRoot, String.valueOf(pid), FD_INFO);
189+
if (fdDir == null || fdInfoDir == null) {
190+
return null;
191+
}
192+
Path[] fdList = fdDir.listFiles();
193+
String[] fdInfoList = new String[fdList.length];
194+
for (int i = 0; i < fdList.length; ++i) {
195+
Path fdInfoFile = Paths.build(fdInfoDir, fdList[i].getName());
196+
fdInfoList[i] = fdInfoFile != null ? fdInfoFile.getContentAsString(null) : null;
197+
}
198+
return new ProcFdInfoList(fdList, fdInfoList);
199+
}
200+
201+
@Nullable
202+
public ProcMappedFiles getMapFiles(int pid) {
203+
Path mapFilesDir = Paths.build(procRoot, String.valueOf(pid), MAP_FILES);
204+
return mapFilesDir != null ? new ProcMappedFiles(mapFilesDir.listFiles()) : null;
205+
}
206+
127207
@Nullable
128208
public ProcStat getStat(int pid) {
129209
String statFileContents = getStringOrNull(Paths.build(procRoot, String.valueOf(pid), STAT));
@@ -142,6 +222,18 @@ public ProcMemStat getMemStat(int pid) {
142222
return ProcMemStat.parse(statFileContents);
143223
}
144224

225+
@Nullable
226+
public String getRoot(int pid) {
227+
Path rootPath = Paths.build(procRoot, String.valueOf(pid), ROOT);
228+
if (rootPath != null) {
229+
try {
230+
return rootPath.getRealFilePath();
231+
} catch (IOException e) {
232+
e.printStackTrace();
233+
}
234+
}
235+
return null;
236+
}
145237
@Nullable
146238
public ProcStatus getStatus(int pid) {
147239
String statFileContents = getStringOrNull(Paths.build(procRoot, String.valueOf(pid), STATUS));
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
package io.github.muntashirakon.proc;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.annotation.Nullable;
7+
8+
import java.io.IOException;
9+
import java.util.Collection;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Objects;
14+
15+
import io.github.muntashirakon.io.Path;
16+
import kotlin.collections.ArrayDeque;
17+
18+
public class ProcMappedFiles {
19+
public static class MappedFile {
20+
public final Path memoryPath;
21+
public final String realPath;
22+
public final long vmStart;
23+
public final long vmEnd;
24+
25+
private MappedFile(@NonNull Path memoryPath, @NonNull String realPath) {
26+
this.memoryPath = memoryPath;
27+
this.realPath = realPath;
28+
String[] vmAreaStruct = memoryPath.getName().split("-");
29+
vmStart = Long.decode("0x" + vmAreaStruct[0]);
30+
vmEnd = Long.decode("0x" + vmAreaStruct[1]);
31+
}
32+
}
33+
34+
private final Map<String, List<MappedFile>> mMappedFiles;
35+
36+
ProcMappedFiles(@NonNull Path[] mappedFiles) {
37+
mMappedFiles = new HashMap<>(mappedFiles.length);
38+
for (Path file : mappedFiles) {
39+
try {
40+
String realPath = Objects.requireNonNull(file.getRealFilePath());
41+
MappedFile mappedFile = new MappedFile(file, realPath);
42+
List<MappedFile> mappedFileList = mMappedFiles.get(realPath);
43+
if (mappedFileList == null) {
44+
mappedFileList = new ArrayDeque<>();
45+
mMappedFiles.put(realPath, mappedFileList);
46+
}
47+
mappedFileList.add(mappedFile);
48+
} catch (IOException e) {
49+
e.printStackTrace();
50+
}
51+
}
52+
}
53+
54+
@NonNull
55+
public Collection<String> getRealFiles() {
56+
return mMappedFiles.keySet();
57+
}
58+
59+
@Nullable
60+
public List<MappedFile> getMappedFiles(@NonNull String realPath) {
61+
return mMappedFiles.get(realPath);
62+
}
63+
}

0 commit comments

Comments
 (0)