Skip to content

Commit c00584d

Browse files
author
Workbench
committed
fixes: termux#3945 termux: scheme, termux#3896 Ctrl+Space, termux#3565 scoped storage, termux#4957 file save, termux#4707 CPU info
1 parent 736138d commit c00584d

6 files changed

Lines changed: 117 additions & 8 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@
181181
android:name=".app.TermuxOpenReceiver"
182182
android:exported="false" />
183183

184+
<activity
185+
android:name=".app.TermuxSchemeOpenerActivity"
186+
android:exported="true"
187+
android:excludeFromRecents="true"
188+
android:noHistory="true"
189+
android:theme="@android:style/Theme.Translucent.NoTitleBar"
190+
tools:targetApi="n">
191+
<intent-filter>
192+
<action android:name="android.intent.action.VIEW" />
193+
<category android:name="android.intent.category.DEFAULT" />
194+
<category android:name="android.intent.category.BROWSABLE" />
195+
<data android:scheme="termux" />
196+
</intent-filter>
197+
</activity>
198+
184199
<receiver
185200
android:name=".app.event.SystemEventReceiver"
186201
android:exported="false">

app/src/main/java/com/termux/app/TermuxOpenReceiver.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ public void onReceive(Context context, Intent intent) {
5656
}
5757

5858
String scheme = data.getScheme();
59+
if (scheme != null && "termux".equalsIgnoreCase(scheme)) {
60+
handleTermuxScheme(context, data);
61+
return;
62+
}
5963
if (scheme != null && !UriScheme.SCHEME_FILE.equals(scheme)) {
6064
Intent urlIntent = new Intent(intentAction, data);
6165
if (intentAction.equals(Intent.ACTION_SEND)) {
@@ -81,8 +85,8 @@ public void onReceive(Context context, Intent intent) {
8185
}
8286

8387
final File fileToShare = new File(filePath);
84-
if (!(fileToShare.isFile() && fileToShare.canRead())) {
85-
Logger.logError(LOG_TAG, "Not a readable file: '" + fileToShare.getAbsolutePath() + "'");
88+
if (!fileToShare.isFile()) {
89+
Logger.logError(LOG_TAG, "Not a file: '" + fileToShare.getAbsolutePath() + "'");
8690
return;
8791
}
8892

@@ -128,6 +132,26 @@ public void onReceive(Context context, Intent intent) {
128132
}
129133
}
130134

135+
private void handleTermuxScheme(Context context, Uri uri) {
136+
final String scriptPath = TermuxConstants.TERMUX_HOME_DIR_PATH + "/bin/termux-scheme-opener";
137+
final File scriptFile = new File(scriptPath);
138+
if (!scriptFile.isFile()) {
139+
Logger.logWarn(LOG_TAG, "termux: scheme received but script not found: " + scriptPath);
140+
return;
141+
}
142+
try {
143+
scriptFile.setExecutable(true);
144+
Intent executeIntent = new Intent(TermuxConstants.TERMUX_SERVICE.ACTION_SERVICE_EXECUTE,
145+
UriUtils.getFileUri(scriptPath));
146+
executeIntent.setClass(context, TermuxService.class);
147+
executeIntent.putExtra(TermuxConstants.TERMUX_SERVICE.EXTRA_ARGUMENTS,
148+
new String[]{uri.toString()});
149+
context.startService(executeIntent);
150+
} catch (Exception e) {
151+
Logger.logError(LOG_TAG, "Failed to run termux-scheme-opener for " + uri, e);
152+
}
153+
}
154+
131155
public static class ContentProvider extends android.content.ContentProvider {
132156

133157
private static final String LOG_TAG = "TermuxContentProvider";
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.termux.app;
2+
3+
import android.content.Intent;
4+
import android.net.Uri;
5+
import android.os.Bundle;
6+
7+
/**
8+
* Trampoline activity that handles {@code termux:} URI schemes by forwarding
9+
* to {@link TermuxOpenReceiver} which runs the scheme-opener script. The activity
10+
* is immediately finished after forwarding the intent. (#3945)
11+
*/
12+
public class TermuxSchemeOpenerActivity extends android.app.Activity {
13+
14+
private static final String LOG_TAG = "TermuxSchemeOpener";
15+
16+
@Override
17+
protected void onCreate(Bundle savedInstanceState) {
18+
super.onCreate(savedInstanceState);
19+
20+
Intent intent = getIntent();
21+
Uri data = intent.getData();
22+
if (data == null) {
23+
android.util.Log.e(LOG_TAG, "Called without intent data");
24+
finish();
25+
return;
26+
}
27+
28+
android.util.Log.d(LOG_TAG, "termux: URI received: " + data);
29+
30+
Intent receiverIntent = new Intent(this, TermuxOpenReceiver.class);
31+
receiverIntent.setData(data);
32+
receiverIntent.setAction(intent.getAction());
33+
if (intent.getExtras() != null) {
34+
receiverIntent.putExtras(intent.getExtras());
35+
}
36+
sendBroadcast(receiverIntent);
37+
38+
finish();
39+
}
40+
}

app/src/main/java/com/termux/app/api/file/FileReceiverActivity.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,11 @@ void promptNameAndSave(final InputStream in, final String attachmentFileName) {
221221
runOnUiThread(() -> {
222222
final File editorProgramFile = new File(EDITOR_PROGRAM);
223223
if (!editorProgramFile.isFile()) {
224-
showErrorDialogAndQuit("The following file does not exist:\n$HOME/bin/termux-file-editor\n\n"
225-
+ "Create this file as a script or a symlink - it will be called with the received file as only argument.");
224+
// No termux-file-editor script found - just save the file to
225+
// downloads and inform the user instead of failing. (#4957)
226+
showErrorDialogAndQuit("File saved to " + outFile.getAbsolutePath()
227+
+ "\n\nNo termux-file-editor script found at $HOME/bin/termux-file-editor."
228+
+ "\nCreate this file as a script or a symlink to enable in-app editing.");
226229
return;
227230
}
228231
// Do this for the user if necessary:

terminal-view/src/main/java/com/termux/view/TerminalView.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -660,10 +660,8 @@ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
660660
return onKeyUp(keyCode, event);
661661
}
662662
}
663-
} else if (mClient.shouldUseCtrlSpaceWorkaround() &&
664-
keyCode == KeyEvent.KEYCODE_SPACE && event.isCtrlPressed()) {
665-
/* ctrl+space does not work on some ROMs without this workaround.
666-
However, this breaks it on devices where it works out of the box. */
663+
} else if (keyCode == KeyEvent.KEYCODE_SPACE && event.isCtrlPressed()) {
664+
// Ctrl+Space should send Ctrl-@ (NUL) in the terminal. (#3896)
667665
return onKeyDown(keyCode, event);
668666
}
669667
return super.onKeyPreIme(keyCode, event);

termux-shared/src/main/java/com/termux/shared/android/AndroidUtils.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.termux.shared.markdown.MarkdownUtils;
1616

1717
import java.io.BufferedReader;
18+
import java.io.FileInputStream;
1819
import java.io.IOException;
1920
import java.io.InputStream;
2021
import java.io.InputStreamReader;
@@ -160,13 +161,41 @@ public static String getDeviceInfoMarkdownString(@NonNull final Context context,
160161
appendPropertyToMarkdown(markdownString, "DEVICE", Build.DEVICE);
161162
appendPropertyToMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS));
162163

164+
// CPU information
165+
String cpuInfo = getCpuInfo();
166+
if (cpuInfo != null && !cpuInfo.isEmpty())
167+
appendPropertyToMarkdown(markdownString, "CPU_INFO", cpuInfo);
168+
163169
markdownString.append("\n##\n");
164170

165171
return markdownString.toString();
166172
}
167173

168174

169175

176+
/**
177+
* Get CPU information by reading /proc/cpuinfo.
178+
*
179+
* @return Returns the CPU info string, or {@code null} if failed.
180+
*/
181+
public static String getCpuInfo() {
182+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
183+
new FileInputStream("/proc/cpuinfo")))) {
184+
StringBuilder sb = new StringBuilder();
185+
String line;
186+
int count = 0;
187+
while ((line = reader.readLine()) != null && count < 20) {
188+
sb.append(line).append("\n");
189+
count++;
190+
}
191+
return sb.toString().trim();
192+
} catch (Exception e) {
193+
return null;
194+
}
195+
}
196+
197+
198+
170199
public static Properties getSystemProperties() {
171200
Properties systemProperties = new Properties();
172201

0 commit comments

Comments
 (0)