M build.gradle => build.gradle +1 -1
@@ 14,7 14,7 @@ android {
buildToolsVersion '31'
defaultConfig {
- minSdkVersion 19
+ minSdkVersion 26
targetSdkVersion 28
}
D src/main/java/org/safsftp/ReadTask.java => src/main/java/org/safsftp/ReadTask.java +0 -50
@@ 1,50 0,0 @@
-package org.safsftp;
-
-import android.os.AsyncTask;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
-import android.util.Log;
-
-import com.trilead.ssh2.Connection;
-import com.trilead.ssh2.SFTPv3Client;
-import com.trilead.ssh2.SFTPv3FileHandle;
-
-import org.safsftp.ToastThread;
-
-public class ReadTask extends AsyncTask<Void,Void,Void> {
- private SFTPv3Client sftp;
- private SFTPv3FileHandle file;
- private ParcelFileDescriptor fd;
-
- public ReadTask(SFTPv3Client sftp,SFTPv3FileHandle file,ParcelFileDescriptor fd) {
- this.fd=fd;
- this.sftp=sftp;
- this.file=file;
- }
-
- @Override
- public Void doInBackground(Void... args) {
- AutoCloseOutputStream acos=new AutoCloseOutputStream(fd);
- int size,offset=0;
- byte[] buf=new byte[32768];
- try{
- while((size=sftp.read(file,offset,buf,0,32768))>0) {
- acos.write(buf,0,size);
- offset+=size;
- }
- acos.close();
- }
- catch(Exception e){
- Log.e("SFTP","read file "+e.toString());
- }
- try{
- sftp.closeFile(file);
- }
- catch(Exception e){
- Log.e("SFTP","close file "+e.toString());
- }
- sftp.close();
- return null;
- }
-}
M src/main/java/org/safsftp/SFTPDocumentsProvider.java => src/main/java/org/safsftp/SFTPDocumentsProvider.java +17 -12
@@ 1,13 1,16 @@
package org.safsftp;
+import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract.Document;
@@ 26,12 29,11 @@ import com.trilead.ssh2.SFTPv3FileHandle;
import java.io.IOException;
import java.util.Vector;
-import org.safsftp.ToastThread;
-import org.safsftp.ReadTask;
-
public class SFTPDocumentsProvider extends DocumentsProvider {
private Connection connection;
private String host=null,port=null; //TODO: multiple server support
+ private StorageManager sm;
+ private Handler ioHandler;
private ToastThread lthread;
private static final String[] DEFAULT_ROOT_PROJECTION=new String[]{
@@ 106,8 108,13 @@ public class SFTPDocumentsProvider extends DocumentsProvider {
@Override
public boolean onCreate() {
- lthread=new ToastThread(getContext());
+ sm = (StorageManager) getContext()
+ .getSystemService(Context.STORAGE_SERVICE);
+ lthread = new ToastThread(getContext());
lthread.start();
+ HandlerThread ioThread = new HandlerThread("IO thread");
+ ioThread.start();
+ ioHandler = new Handler(ioThread.getLooper());
return true;
}
@@ 124,20 131,18 @@ public class SFTPDocumentsProvider extends DocumentsProvider {
}
String filename=documentId.substring(documentId.indexOf("/")+1);
Log.v("SFTP","od "+documentId+" on "+host+":"+port);
- ParcelFileDescriptor[] fd;
SFTPv3FileHandle file;
try {
- fd=ParcelFileDescriptor.createReliablePipe();
- file=sftp.openFileRO(filename);
- }
- catch(IOException e) {
+ file = sftp.openFileRO(filename);
+ return sm.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY,
+ new SFTPProxyFileDescriptorCallback(sftp, file),
+ ioHandler);
+ } catch (IOException e) {
//TODO notify error
Log.e("SFTP","read file "+filename+" init "+e.toString());
return null;
}
- new ReadTask(sftp,file,fd[1]).execute();
- Log.v("SFTP","od "+documentId+" on "+host+":"+port+" return");
- return fd[0];
}
public Cursor queryChildDocuments(String parentDocumentId,
A src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java => src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java +48 -0
@@ 0,0 1,48 @@
+package org.safsftp;
+
+import android.os.ProxyFileDescriptorCallback;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+
+import java.io.IOException;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.SFTPv3Client;
+import com.trilead.ssh2.SFTPv3FileHandle;
+
+public class SFTPProxyFileDescriptorCallback extends ProxyFileDescriptorCallback {
+ private SFTPv3Client sftp;
+ private SFTPv3FileHandle file;
+
+
+ public SFTPProxyFileDescriptorCallback(SFTPv3Client sftp, SFTPv3FileHandle file) {
+ this.sftp = sftp;
+ this.file = file;
+ }
+
+ @Override
+ public long onGetSize() throws ErrnoException {
+ try {
+ return sftp.fstat(file).size;
+ } catch (IOException e) {
+ throw new ErrnoException("fstat", OsConstants.EIO);
+ }
+ }
+
+ @Override
+ public int onRead(long offset, int size, byte[] data)
+ throws ErrnoException {
+ try {
+ return sftp.read(file, offset, data, 0, size);
+ } catch (IOException e) {
+ throw new ErrnoException("read", OsConstants.EIO);
+ }
+ }
+
+ @Override
+ public void onRelease() {
+ try {
+ sftp.closeFile(file);
+ } catch (IOException e) {} //TODO
+ }
+}