11
11
import android .view .WindowManager ;
12
12
13
13
import com .termux .R ;
14
+ import com .termux .app .file .FileUtils ;
14
15
import com .termux .app .utils .Logger ;
15
16
16
17
import java .io .BufferedReader ;
17
18
import java .io .ByteArrayInputStream ;
18
19
import java .io .File ;
19
20
import java .io .FileOutputStream ;
20
- import java .io .IOException ;
21
21
import java .io .InputStreamReader ;
22
22
import java .util .ArrayList ;
23
23
import java .util .List ;
32
32
* <p/>
33
33
* (2) A progress dialog is shown with "Installing..." message and a spinner.
34
34
* <p/>
35
- * (3) A staging directory, $STAGING_PREFIX, is {@link #deleteDirectory(File)} if left over from broken installation below.
35
+ * (3) A staging directory, $STAGING_PREFIX, is cleared if left over from broken installation below.
36
36
* <p/>
37
37
* (4) The zip file is loaded from a shared library.
38
38
* <p/>
@@ -47,10 +47,8 @@ final class TermuxInstaller {
47
47
48
48
private static final String LOG_TAG = "TermuxInstaller" ;
49
49
50
- /** Performs setup if necessary. */
51
- static void setupIfNeeded (final Activity activity , final Runnable whenDone ) {
52
- Logger .logInfo (LOG_TAG , "Installing " + TermuxConstants .TERMUX_APP_NAME + " bootstrap packages." );
53
-
50
+ /** Performs bootstrap setup if necessary. */
51
+ static void setupBootstrapIfNeeded (final Activity activity , final Runnable whenDone ) {
54
52
// Termux can only be run as the primary user (device owner) since only that
55
53
// account has the expected file system paths. Verify that:
56
54
UserManager um = (UserManager ) activity .getSystemService (Context .USER_SERVICE );
@@ -63,7 +61,6 @@ static void setupIfNeeded(final Activity activity, final Runnable whenDone) {
63
61
return ;
64
62
}
65
63
66
- Logger .logInfo (LOG_TAG , "Creating prefix directory \" " + TermuxConstants .TERMUX_PREFIX_DIR_PATH + "\" ." );
67
64
final File PREFIX_FILE = TermuxConstants .TERMUX_PREFIX_DIR ;
68
65
if (PREFIX_FILE .isDirectory ()) {
69
66
whenDone .run ();
@@ -75,12 +72,16 @@ static void setupIfNeeded(final Activity activity, final Runnable whenDone) {
75
72
@ Override
76
73
public void run () {
77
74
try {
75
+ Logger .logInfo (LOG_TAG , "Installing " + TermuxConstants .TERMUX_APP_NAME + " bootstrap packages." );
76
+
77
+ String errmsg ;
78
+
78
79
final String STAGING_PREFIX_PATH = TermuxConstants .TERMUX_STAGING_PREFIX_DIR_PATH ;
79
80
final File STAGING_PREFIX_FILE = new File (STAGING_PREFIX_PATH );
80
81
81
- if ( STAGING_PREFIX_FILE . exists ()) {
82
- Logger . logInfo ( LOG_TAG , "Deleting prefix staging directory \" " + TermuxConstants . TERMUX_STAGING_PREFIX_DIR_PATH + " \" ." );
83
- deleteDirectory ( STAGING_PREFIX_FILE );
82
+ errmsg = FileUtils . clearDirectory ( activity , "prefix staging directory" , STAGING_PREFIX_PATH );
83
+ if ( errmsg != null ) {
84
+ throw new RuntimeException ( errmsg );
84
85
}
85
86
86
87
Logger .logInfo (LOG_TAG , "Extracting bootstrap zip to prefix staging directory \" " + TermuxConstants .TERMUX_STAGING_PREFIX_DIR_PATH + "\" ." );
@@ -103,14 +104,14 @@ public void run() {
103
104
String newPath = STAGING_PREFIX_PATH + "/" + parts [1 ];
104
105
symlinks .add (Pair .create (oldPath , newPath ));
105
106
106
- ensureDirectoryExists (new File (newPath ).getParentFile ());
107
+ ensureDirectoryExists (activity , new File (newPath ).getParentFile ());
107
108
}
108
109
} else {
109
110
String zipEntryName = zipEntry .getName ();
110
111
File targetFile = new File (STAGING_PREFIX_PATH , zipEntryName );
111
112
boolean isDirectory = zipEntry .isDirectory ();
112
113
113
- ensureDirectoryExists (isDirectory ? targetFile : targetFile .getParentFile ());
114
+ ensureDirectoryExists (activity , isDirectory ? targetFile : targetFile .getParentFile ());
114
115
115
116
if (!isDirectory ) {
116
117
try (FileOutputStream outStream = new FileOutputStream (targetFile )) {
@@ -151,7 +152,7 @@ public void run() {
151
152
activity .finish ();
152
153
}).setPositiveButton (R .string .bootstrap_error_try_again , (dialog , which ) -> {
153
154
dialog .dismiss ();
154
- TermuxInstaller .setupIfNeeded (activity , whenDone );
155
+ TermuxInstaller .setupBootstrapIfNeeded (activity , whenDone );
155
156
}).show ();
156
157
} catch (WindowManager .BadTokenException e1 ) {
157
158
// Activity already dismissed - ignore.
@@ -170,37 +171,6 @@ public void run() {
170
171
}.start ();
171
172
}
172
173
173
- private static void ensureDirectoryExists (File directory ) {
174
- if (!directory .isDirectory () && !directory .mkdirs ()) {
175
- throw new RuntimeException ("Unable to create directory: " + directory .getAbsolutePath ());
176
- }
177
- }
178
-
179
- public static byte [] loadZipBytes () {
180
- // Only load the shared library when necessary to save memory usage.
181
- System .loadLibrary ("termux-bootstrap" );
182
- return getZip ();
183
- }
184
-
185
- public static native byte [] getZip ();
186
-
187
- /** Delete a directory and all its content or throw. Don't follow symlinks. */
188
- static void deleteDirectory (File fileOrDirectory ) throws IOException {
189
- if (fileOrDirectory .getCanonicalPath ().equals (fileOrDirectory .getAbsolutePath ()) && fileOrDirectory .isDirectory ()) {
190
- File [] children = fileOrDirectory .listFiles ();
191
-
192
- if (children != null ) {
193
- for (File child : children ) {
194
- deleteDirectory (child );
195
- }
196
- }
197
- }
198
-
199
- if (!fileOrDirectory .delete ()) {
200
- throw new RuntimeException ("Unable to delete " + (fileOrDirectory .isDirectory () ? "directory " : "file " ) + fileOrDirectory .getAbsolutePath ());
201
- }
202
- }
203
-
204
174
static void setupStorageSymlinks (final Context context ) {
205
175
final String LOG_TAG = "termux-storage" ;
206
176
@@ -209,19 +179,12 @@ static void setupStorageSymlinks(final Context context) {
209
179
new Thread () {
210
180
public void run () {
211
181
try {
182
+ String errmsg ;
212
183
File storageDir = TermuxConstants .TERMUX_STORAGE_HOME_DIR ;
213
184
214
- if (storageDir .exists ()) {
215
- try {
216
- deleteDirectory (storageDir );
217
- } catch (IOException e ) {
218
- Logger .logStackTraceWithMessage (LOG_TAG , "Failed to delete old ~/storage directory" , e );
219
- return ;
220
- }
221
- }
222
-
223
- if (!storageDir .mkdirs ()) {
224
- Logger .logError (LOG_TAG , "Unable to create ~/storage directory." );
185
+ errmsg = FileUtils .clearDirectory (context , "~/storage" , storageDir .getAbsolutePath ());
186
+ if (errmsg != null ) {
187
+ Logger .logErrorAndShowToast (context , LOG_TAG , errmsg );
225
188
return ;
226
189
}
227
190
@@ -264,4 +227,21 @@ public void run() {
264
227
}.start ();
265
228
}
266
229
230
+ private static void ensureDirectoryExists (Context context , File directory ) {
231
+ String errmsg ;
232
+
233
+ errmsg = FileUtils .createDirectoryFile (context , directory .getAbsolutePath ());
234
+ if (errmsg != null ) {
235
+ throw new RuntimeException (errmsg );
236
+ }
237
+ }
238
+
239
+ public static byte [] loadZipBytes () {
240
+ // Only load the shared library when necessary to save memory usage.
241
+ System .loadLibrary ("termux-bootstrap" );
242
+ return getZip ();
243
+ }
244
+
245
+ public static native byte [] getZip ();
246
+
267
247
}
0 commit comments