Skip to content

Commit 3491956

Browse files
Update TermuxUtils to add support for getting device and termux info as markdown
1 parent 134e217 commit 3491956

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

app/src/main/java/com/termux/app/utils/TermuxUtils.java

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
package com.termux.app.utils;
22

3+
import android.annotation.SuppressLint;
34
import android.content.ComponentName;
45
import android.content.Context;
56
import android.content.Intent;
67
import android.content.pm.ResolveInfo;
8+
import android.os.Build;
9+
10+
import androidx.annotation.NonNull;
11+
12+
import com.google.common.base.Joiner;
13+
import com.termux.BuildConfig;
714

815
import com.termux.app.TermuxConstants;
916

17+
import java.io.BufferedReader;
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
import java.io.InputStreamReader;
21+
import java.text.SimpleDateFormat;
22+
import java.util.Date;
1023
import java.util.List;
24+
import java.util.Properties;
25+
import java.util.TimeZone;
26+
import java.util.regex.Matcher;
27+
import java.util.regex.Pattern;
1128

1229
public class TermuxUtils {
1330

@@ -42,4 +59,144 @@ public static void sendTermuxOpenedBroadcast(Context context) {
4259
}
4360
}
4461

62+
/**
63+
* Get a markdown {@link String} for the device details.
64+
*
65+
* @param context The context for operations.
66+
* @return Returns the markdown {@link String}.
67+
*/
68+
public static String getDeviceDetailsMarkdownString(final Context context) {
69+
if (context == null) return "null";
70+
71+
// Some properties cannot be read with {@link System#getProperty(String)} but can be read
72+
// directly by running getprop command
73+
Properties systemProperties = getSystemProperties();
74+
75+
StringBuilder markdownString = new StringBuilder();
76+
77+
markdownString.append("#### Software\n");
78+
appendPropertyMarkdown(markdownString,
79+
TermuxConstants.TERMUX_APP_NAME.toUpperCase() + "_VERSION", getTermuxAppVersionName() + "(" + getTermuxAppVersionCode() + ")");
80+
appendPropertyMarkdown(markdownString,TermuxConstants.TERMUX_APP_NAME.toUpperCase() + "_DEBUG_BUILD", isTermuxAppDebugBuild());
81+
appendPropertyMarkdown(markdownString,"OS_VERSION", getSystemPropertyWithAndroidAPI("os.version"));
82+
appendPropertyMarkdown(markdownString, "SDK_INT", Build.VERSION.SDK_INT);
83+
// If its a release version
84+
if ("REL".equals(Build.VERSION.CODENAME))
85+
appendPropertyMarkdown(markdownString, "RELEASE", Build.VERSION.RELEASE);
86+
else
87+
appendPropertyMarkdown(markdownString, "CODENAME", Build.VERSION.CODENAME);
88+
appendPropertyMarkdown(markdownString, "INCREMENTAL", Build.VERSION.INCREMENTAL);
89+
appendPropertyMarkdownIfSet(markdownString, "SECURITY_PATCH", systemProperties.getProperty("ro.build.version.security_patch"));
90+
appendPropertyMarkdownIfSet(markdownString, "IS_DEBUGGABLE", systemProperties.getProperty("ro.debuggable"));
91+
appendPropertyMarkdownIfSet(markdownString, "IS_EMULATOR", systemProperties.getProperty("ro.boot.qemu"));
92+
appendPropertyMarkdownIfSet(markdownString, "IS_TREBLE_ENABLED", systemProperties.getProperty("ro.treble.enabled"));
93+
appendPropertyMarkdown(markdownString, "TYPE", Build.TYPE);
94+
appendPropertyMarkdown(markdownString, "TAGS", Build.TAGS);
95+
96+
markdownString.append("\n\n#### Hardware\n");
97+
appendPropertyMarkdown(markdownString, "MANUFACTURER", Build.MANUFACTURER);
98+
appendPropertyMarkdown(markdownString, "BRAND", Build.BRAND);
99+
appendPropertyMarkdown(markdownString, "MODEL", Build.MODEL);
100+
appendPropertyMarkdown(markdownString, "PRODUCT", Build.PRODUCT);
101+
appendPropertyMarkdown(markdownString, "DISPLAY", Build.DISPLAY);
102+
appendPropertyMarkdown(markdownString, "ID", Build.ID);
103+
appendPropertyMarkdown(markdownString, "BOARD", Build.BOARD);
104+
appendPropertyMarkdown(markdownString, "HARDWARE", Build.HARDWARE);
105+
appendPropertyMarkdown(markdownString, "DEVICE", Build.DEVICE);
106+
appendPropertyMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS));
107+
108+
return markdownString.toString();
109+
}
110+
111+
public static Properties getSystemProperties() {
112+
Properties systemProperties = new Properties();
113+
114+
// getprop commands returns values in the format `[key]: [value]`
115+
// Regex matches string starting with a literal `[`,
116+
// followed by one or more characters that do not match a closing square bracket as the key,
117+
// followed by a literal `]: [`,
118+
// followed by one or more characters as the value,
119+
// followed by string ending with literal `]`
120+
// multiline values will be ignored
121+
Pattern propertiesPattern = Pattern.compile("^\\[([^]]+)]: \\[(.+)]$");
122+
123+
try {
124+
Process process = new ProcessBuilder()
125+
.command("/system/bin/getprop")
126+
.redirectErrorStream(true)
127+
.start();
128+
129+
InputStream inputStream = process.getInputStream();
130+
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
131+
String line, key, value;
132+
133+
while ((line = bufferedReader.readLine()) != null) {
134+
Matcher matcher = propertiesPattern.matcher(line);
135+
if (matcher.matches()) {
136+
key = matcher.group(1);
137+
value = matcher.group(2);
138+
if(key != null && value != null && !key.isEmpty() && !value.isEmpty())
139+
systemProperties.put(key, value);
140+
}
141+
}
142+
143+
bufferedReader.close();
144+
process.destroy();
145+
146+
} catch (IOException e) {
147+
Logger.logStackTraceWithMessage("Failed to get run \"/system/bin/getprop\" to get system properties.", e);
148+
}
149+
150+
//for (String key : systemProperties.stringPropertyNames()) {
151+
// Logger.logVerbose(key + ": " + systemProperties.get(key));
152+
//}
153+
154+
return systemProperties;
155+
}
156+
157+
private static String getSystemPropertyWithAndroidAPI(@NonNull String property) {
158+
try {
159+
return System.getProperty(property);
160+
} catch (Exception e) {
161+
Logger.logVerbose("Failed to get system property \"" + property + "\":" + e.getMessage());
162+
return null;
163+
}
164+
}
165+
166+
private static void appendPropertyMarkdownIfSet(StringBuilder markdownString, String label, Object value) {
167+
if(value == null) return;
168+
if(value instanceof String && (((String) value).isEmpty()) || "REL".equals(value)) return;
169+
markdownString.append("\n").append(getPropertyMarkdown(label, value));
170+
}
171+
172+
private static void appendPropertyMarkdown(StringBuilder markdownString, String label, Object value) {
173+
markdownString.append("\n").append(getPropertyMarkdown(label, value));
174+
}
175+
176+
private static String getPropertyMarkdown(String label, Object value) {
177+
return MarkdownUtils.getSingleLineMarkdownStringEntry(label, value, "-");
178+
}
179+
180+
181+
182+
public static int getTermuxAppVersionCode() {
183+
return BuildConfig.VERSION_CODE;
184+
}
185+
186+
public static String getTermuxAppVersionName() {
187+
return BuildConfig.VERSION_NAME;
188+
}
189+
190+
public static boolean isTermuxAppDebugBuild() {
191+
return BuildConfig.DEBUG;
192+
}
193+
194+
public static String getCurrentTimeStamp() {
195+
@SuppressLint("SimpleDateFormat")
196+
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
197+
df.setTimeZone(TimeZone.getTimeZone("UTC"));
198+
return df.format(new Date());
199+
}
200+
201+
45202
}

0 commit comments

Comments
 (0)