Skip to content

Commit 92b804d

Browse files
Add logging for termux bootstrap package installation and setup of storage symlinks
1 parent 1b5e5b5 commit 92b804d

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
* Install the Termux bootstrap packages if necessary by following the below steps:
2929
* <p/>
3030
* (1) If $PREFIX already exist, assume that it is correct and be done. Note that this relies on that we do not create a
31-
* broken $PREFIX folder below.
31+
* broken $PREFIX directory below.
3232
* <p/>
3333
* (2) A progress dialog is shown with "Installing..." message and a spinner.
3434
* <p/>
35-
* (3) A staging folder, $STAGING_PREFIX, is {@link #deleteFolder(File)} if left over from broken installation below.
35+
* (3) A staging directory, $STAGING_PREFIX, is {@link #deleteDirectory(File)} if left over from broken installation below.
3636
* <p/>
3737
* (4) The zip file is loaded from a shared library.
3838
* <p/>
@@ -49,16 +49,21 @@ final class TermuxInstaller {
4949

5050
/** Performs setup if necessary. */
5151
static void setupIfNeeded(final Activity activity, final Runnable whenDone) {
52+
Logger.logInfo(LOG_TAG, "Installing " + TermuxConstants.TERMUX_APP_NAME + " bootstrap packages.");
53+
5254
// Termux can only be run as the primary user (device owner) since only that
5355
// account has the expected file system paths. Verify that:
5456
UserManager um = (UserManager) activity.getSystemService(Context.USER_SERVICE);
5557
boolean isPrimaryUser = um.getSerialNumberForUser(android.os.Process.myUserHandle()) == 0;
5658
if (!isPrimaryUser) {
57-
new AlertDialog.Builder(activity).setTitle(R.string.bootstrap_error_title).setMessage(R.string.bootstrap_error_not_primary_user_message)
59+
String bootstrapErrorMessage = activity.getString(R.string.bootstrap_error_not_primary_user_message, TermuxConstants.TERMUX_PREFIX_DIR_PATH);
60+
Logger.logError(LOG_TAG, bootstrapErrorMessage);
61+
new AlertDialog.Builder(activity).setTitle(R.string.bootstrap_error_title).setMessage(bootstrapErrorMessage)
5862
.setOnDismissListener(dialog -> System.exit(0)).setPositiveButton(android.R.string.ok, null).show();
5963
return;
6064
}
6165

66+
Logger.logInfo(LOG_TAG, "Creating prefix directory \"" + TermuxConstants.TERMUX_PREFIX_DIR_PATH + "\".");
6267
final File PREFIX_FILE = TermuxConstants.TERMUX_PREFIX_DIR;
6368
if (PREFIX_FILE.isDirectory()) {
6469
whenDone.run();
@@ -74,9 +79,12 @@ public void run() {
7479
final File STAGING_PREFIX_FILE = new File(STAGING_PREFIX_PATH);
7580

7681
if (STAGING_PREFIX_FILE.exists()) {
77-
deleteFolder(STAGING_PREFIX_FILE);
82+
Logger.logInfo(LOG_TAG, "Deleting prefix staging directory \"" + TermuxConstants.TERMUX_STAGING_PREFIX_DIR_PATH + "\".");
83+
deleteDirectory(STAGING_PREFIX_FILE);
7884
}
7985

86+
Logger.logInfo(LOG_TAG, "Extracting bootstrap zip to prefix staging directory \"" + TermuxConstants.TERMUX_STAGING_PREFIX_DIR_PATH + "\".");
87+
8088
final byte[] buffer = new byte[8096];
8189
final List<Pair<String, String>> symlinks = new ArrayList<>(50);
8290

@@ -125,10 +133,13 @@ public void run() {
125133
Os.symlink(symlink.first, symlink.second);
126134
}
127135

136+
Logger.logInfo(LOG_TAG, "Moving prefix staging to prefix directory.");
137+
128138
if (!STAGING_PREFIX_FILE.renameTo(PREFIX_FILE)) {
129-
throw new RuntimeException("Unable to rename staging folder");
139+
throw new RuntimeException("Moving prefix staging to prefix directory failed");
130140
}
131141

142+
Logger.logInfo(LOG_TAG, "Bootstrap packages installed successfully.");
132143
activity.runOnUiThread(whenDone);
133144
} catch (final Exception e) {
134145
Logger.logStackTraceWithMessage(LOG_TAG, "Bootstrap error", e);
@@ -139,9 +150,9 @@ public void run() {
139150
dialog.dismiss();
140151
activity.finish();
141152
}).setPositiveButton(R.string.bootstrap_error_try_again, (dialog, which) -> {
142-
dialog.dismiss();
143-
TermuxInstaller.setupIfNeeded(activity, whenDone);
144-
}).show();
153+
dialog.dismiss();
154+
TermuxInstaller.setupIfNeeded(activity, whenDone);
155+
}).show();
145156
} catch (WindowManager.BadTokenException e1) {
146157
// Activity already dismissed - ignore.
147158
}
@@ -173,14 +184,14 @@ public static byte[] loadZipBytes() {
173184

174185
public static native byte[] getZip();
175186

176-
/** Delete a folder and all its content or throw. Don't follow symlinks. */
177-
static void deleteFolder(File fileOrDirectory) throws IOException {
187+
/** Delete a directory and all its content or throw. Don't follow symlinks. */
188+
static void deleteDirectory(File fileOrDirectory) throws IOException {
178189
if (fileOrDirectory.getCanonicalPath().equals(fileOrDirectory.getAbsolutePath()) && fileOrDirectory.isDirectory()) {
179190
File[] children = fileOrDirectory.listFiles();
180191

181192
if (children != null) {
182193
for (File child : children) {
183-
deleteFolder(child);
194+
deleteDirectory(child);
184195
}
185196
}
186197
}
@@ -192,25 +203,30 @@ static void deleteFolder(File fileOrDirectory) throws IOException {
192203

193204
static void setupStorageSymlinks(final Context context) {
194205
final String LOG_TAG = "termux-storage";
206+
207+
Logger.logInfo(LOG_TAG, "Setting up storage symlinks.");
208+
195209
new Thread() {
196210
public void run() {
197211
try {
198212
File storageDir = TermuxConstants.TERMUX_STORAGE_HOME_DIR;
199213

200214
if (storageDir.exists()) {
201215
try {
202-
deleteFolder(storageDir);
216+
deleteDirectory(storageDir);
203217
} catch (IOException e) {
204-
Logger.logError(LOG_TAG, "Could not delete old $HOME/storage, " + e.getMessage());
218+
Logger.logStackTraceWithMessage(LOG_TAG, "Failed to delete old ~/storage directory", e);
205219
return;
206220
}
207221
}
208222

209223
if (!storageDir.mkdirs()) {
210-
Logger.logError(LOG_TAG, "Unable to mkdirs() for $HOME/storage");
224+
Logger.logError(LOG_TAG, "Unable to create ~/storage directory.");
211225
return;
212226
}
213227

228+
Logger.logInfo(LOG_TAG, "Setting up storage symlinks at ~/storage/shared, ~/storage/downloads, ~/storage/dcim, ~/storage/pictures, ~/storage/music and ~/storage/movies for directories in \"" + Environment.getExternalStorageDirectory().getAbsolutePath() + "\".");
229+
214230
File sharedDir = Environment.getExternalStorageDirectory();
215231
Os.symlink(sharedDir.getAbsolutePath(), new File(storageDir, "shared").getAbsolutePath());
216232

@@ -235,9 +251,12 @@ public void run() {
235251
File dir = dirs[i];
236252
if (dir == null) continue;
237253
String symlinkName = "external-" + i;
254+
Logger.logInfo(LOG_TAG, "Setting up storage symlinks at ~/storage/" + symlinkName + " for \"" + dir.getAbsolutePath() + "\".");
238255
Os.symlink(dir.getAbsolutePath(), new File(storageDir, symlinkName).getAbsolutePath());
239256
}
240257
}
258+
259+
Logger.logInfo(LOG_TAG, "Storage symlinks created successfully.");
241260
} catch (Exception e) {
242261
Logger.logStackTraceWithMessage(LOG_TAG, "Error setting up link", e);
243262
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void onDestroy() {
151151

152152
if (termuxTmpDir.exists()) {
153153
try {
154-
TermuxInstaller.deleteFolder(termuxTmpDir.getCanonicalFile());
154+
TermuxInstaller.deleteDirectory(termuxTmpDir.getCanonicalFile());
155155
} catch (Exception e) {
156156
Logger.logStackTraceWithMessage(LOG_TAG, "Error while removing file at " + termuxTmpDir.getAbsolutePath(), e);
157157
}

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
<string name="toggle_keep_screen_on">Keep screen on</string>
2929
<string name="autofill_password">Autofill password</string>
3030

31-
<string name="bootstrap_installer_body">Installing…</string>
32-
<string name="bootstrap_error_title">Unable to install</string>
31+
<string name="bootstrap_installer_body">Installing bootstrap packages…</string>
32+
<string name="bootstrap_error_title">Unable to install bootstrap</string>
3333
<string name="bootstrap_error_body">&TERMUX_APP_NAME; was unable to install the bootstrap packages.</string>
3434
<string name="bootstrap_error_abort">Abort</string>
3535
<string name="bootstrap_error_try_again">Try again</string>
36-
<string name="bootstrap_error_not_primary_user_message">&TERMUX_APP_NAME; can only be installed on the primary user account.</string>
36+
<string name="bootstrap_error_not_primary_user_message">&TERMUX_APP_NAME; can only be run as the primary user.\nBootstrap binaries compiled for &TERMUX_APP_NAME; have hardcoded $PREFIX path and cannot be installed under any path other than \"%1$s\".</string>
3737

3838
<string name="max_terminals_reached_title">Max terminals reached</string>
3939
<string name="max_terminals_reached_message">Close down existing ones before creating new.</string>

0 commit comments

Comments
 (0)