From 63558d4b90ee4d1731cdf5cd00900c7ce0715b04 Mon Sep 17 00:00:00 2001 From: xdavidwu Date: Thu, 7 Jul 2022 23:35:25 +0800 Subject: [PATCH] seekable reader, bump min sdk level to 26 --- build.gradle | 2 +- src/main/java/org/safsftp/ReadTask.java | 50 ------------------- .../org/safsftp/SFTPDocumentsProvider.java | 29 ++++++----- .../SFTPProxyFileDescriptorCallback.java | 48 ++++++++++++++++++ 4 files changed, 66 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/org/safsftp/ReadTask.java create mode 100644 src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java diff --git a/build.gradle b/build.gradle index 8094e12..f97c70d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ android { buildToolsVersion '31' defaultConfig { - minSdkVersion 19 + minSdkVersion 26 targetSdkVersion 28 } diff --git a/src/main/java/org/safsftp/ReadTask.java b/src/main/java/org/safsftp/ReadTask.java deleted file mode 100644 index 2769377..0000000 --- a/src/main/java/org/safsftp/ReadTask.java +++ /dev/null @@ -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 { - 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; - } -} diff --git a/src/main/java/org/safsftp/SFTPDocumentsProvider.java b/src/main/java/org/safsftp/SFTPDocumentsProvider.java index b4f05d4..ed6f7cb 100644 --- a/src/main/java/org/safsftp/SFTPDocumentsProvider.java +++ b/src/main/java/org/safsftp/SFTPDocumentsProvider.java @@ -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, diff --git a/src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java b/src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java new file mode 100644 index 0000000..170fb2f --- /dev/null +++ b/src/main/java/org/safsftp/SFTPProxyFileDescriptorCallback.java @@ -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 + } +} -- 2.43.0