diff --git a/src/main/java/org/kde/kdeconnect/Helpers/StorageHelper.java b/src/main/java/org/kde/kdeconnect/Helpers/StorageHelper.java new file mode 100644 index 00000000..7a9fd7d7 --- /dev/null +++ b/src/main/java/org/kde/kdeconnect/Helpers/StorageHelper.java @@ -0,0 +1,101 @@ +package org.kde.kdeconnect.Helpers; + +import android.os.Environment; +import android.util.Log; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.StringTokenizer; + +//Code from http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device/19982338#19982338 +public class StorageHelper { + + private static final String TAG = "StorageHelper"; + + public static class StorageInfo { + + public final String path; + public final boolean readonly; + public final boolean removable; + public final int number; + + StorageInfo(String path, boolean readonly, boolean removable, int number) { + this.path = path; + this.readonly = readonly; + this.removable = removable; + this.number = number; + } + + } + + public static List getStorageList() { + + List list = new ArrayList(); + String def_path = Environment.getExternalStorageDirectory().getPath(); + boolean def_path_removable = Environment.isExternalStorageRemovable(); + String def_path_state = Environment.getExternalStorageState(); + boolean def_path_available = def_path_state.equals(Environment.MEDIA_MOUNTED) + || def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY); + boolean def_path_readonly = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY); + + HashSet paths = new HashSet(); + int cur_removable_number = 1; + + if (def_path_available) { + paths.add(def_path); + list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1)); + } + + BufferedReader buf_reader = null; + try { + buf_reader = new BufferedReader(new FileReader("/proc/mounts")); + String line; + Log.d(TAG, "/proc/mounts"); + while ((line = buf_reader.readLine()) != null) { + Log.d(TAG, line); + if (line.contains("vfat") || line.contains("/mnt")) { + StringTokenizer tokens = new StringTokenizer(line, " "); + String unused = tokens.nextToken(); //device + String mount_point = tokens.nextToken(); //mount point + if (paths.contains(mount_point)) { + continue; + } + unused = tokens.nextToken(); //file system + List flags = Arrays.asList(tokens.nextToken().split(",")); //flags + boolean readonly = flags.contains("ro"); + + if (line.contains("/dev/block/vold")) { + if (!line.contains("/mnt/secure") + && !line.contains("/mnt/asec") + && !line.contains("/mnt/obb") + && !line.contains("/dev/mapper") + && !line.contains("tmpfs")) { + paths.add(mount_point); + list.add(new StorageInfo(mount_point, readonly, true, cur_removable_number++)); + } + } + } + } + + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (buf_reader != null) { + try { + buf_reader.close(); + } catch (IOException ex) {} + } + } + return list; + } + +} \ No newline at end of file diff --git a/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java index 3f633e7f..92259a3f 100644 --- a/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java +++ b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java @@ -7,10 +7,15 @@ import android.graphics.drawable.Drawable; import android.os.Environment; import android.widget.Button; +import org.kde.kdeconnect.Helpers.StorageHelper; import org.kde.kdeconnect.NetworkPackage; import org.kde.kdeconnect.Plugins.Plugin; import org.kde.kdeconnect_tp.R; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + public class SftpPlugin extends Plugin { private static final SimpleSftpServer server = new SimpleSftpServer(); @@ -39,7 +44,7 @@ public class SftpPlugin extends Plugin { } @Override - public boolean isEnabledByDefault() {return true;} + public boolean isEnabledByDefault() { return true; } @Override public boolean onCreate() { @@ -58,13 +63,56 @@ public class SftpPlugin extends Plugin { if (np.getBoolean("startBrowsing")) { if (server.start()) { + NetworkPackage np2 = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SFTP); + np2.set("ip", server.getLocalIpAddress()); np2.set("port", server.port); np2.set("user", server.passwordAuth.getUser()); np2.set("password", server.passwordAuth.getPassword()); + + //Kept for compatibility, but new desktop clients will read "multiPaths" instead, + // that supports devices with more than one external storage np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath()); + + List storageList = StorageHelper.getStorageList(); + ArrayList paths = new ArrayList(); + ArrayList pathNames = new ArrayList(); + + for (StorageHelper.StorageInfo storage : storageList) { + paths.add(storage.path); + StringBuilder res = new StringBuilder(); + + if (storageList.size() > 1) { + if (!storage.removable) { + res.append(context.getString(R.string.sftp_internal_storage)); + } else if (storage.number > 1) { + res.append(context.getString(R.string.sftp_sdcard_num, storage.number)); + } else { + res.append(context.getString(R.string.sftp_sdcard)); + } + } else { + res.append(context.getString(R.string.sftp_all_files)); + } + if (storage.readonly) { + res.append(" "); + res.append(context.getString(R.string.sftp_readonly)); + } + pathNames.add(res.toString()); + } + + //Shortcut for users that only want to browse camera pictures + String cameraDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera"; + if (new File(cameraDir).exists()) { + paths.add(cameraDir); + pathNames.add(context.getString(R.string.sftp_camera)); + } + + np2.set("multiPaths", paths); + np2.set("pathNames", pathNames); + device.sendPackage(np2); + return true; } } @@ -72,9 +120,9 @@ public class SftpPlugin extends Plugin { } @Override - public AlertDialog getErrorDialog(Activity deviceActivity) {return null;} + public AlertDialog getErrorDialog(Activity deviceActivity) { return null; } @Override - public Button getInterfaceButton(Activity activity) {return null;} + public Button getInterfaceButton(Activity activity) { return null; } } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index c09a0ac1..cd088795 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -89,6 +89,12 @@ Received text, saved to clipboard Noisy notifications Vibrate and play a sound when receiving a file + Internal storage + All files + SD card %d + SD card + (read only) + Camera pictures 10 seconds