From 9e9faf345b6c87d007cb5fb3dbcf9ebf7bdb9c3e Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Wed, 23 Aug 2023 08:18:07 +0200 Subject: [PATCH 1/9] style(android): remove private field 'permissions' never used --- src/android/FileUtils.java | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java index de973da8..901a3cdb 100644 --- a/src/android/FileUtils.java +++ b/src/android/FileUtils.java @@ -99,27 +99,6 @@ public class FileUtils extends CordovaPlugin { private PendingRequests pendingRequests; - /* - * We need both read and write when accessing the storage, I think. (SDK Version < 33) - * - * If your app targets Android 13 (SDK 33) or higher and needs to access media files that other apps have created, - * you must request one or more of the following granular media permissions - * instead of the READ_EXTERNAL_STORAGE permission: - * - * READ_MEDIA_IMAGES - * READ_MEDIA_VIDEO - * READ_MEDIA_AUDIO - * - * Refer to: https://developer.android.com/about/versions/13/behavior-changes-13 - */ - - private String [] permissions = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_MEDIA_IMAGES, - Manifest.permission.READ_MEDIA_VIDEO, - Manifest.permission.READ_MEDIA_AUDIO}; - // This field exists only to support getEntry, below, which has been deprecated private static FileUtils filePlugin; From aec7ce72897032d1abbc6e5eb32558509e44f501 Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Wed, 23 Aug 2023 08:35:39 +0200 Subject: [PATCH 2/9] style(android): java code format by the ide --- src/android/AssetFilesystem.java | 26 +- src/android/ContentFilesystem.java | 118 ++--- src/android/DirectoryManager.java | 22 +- src/android/FileUtils.java | 718 +++++++++++++--------------- src/android/Filesystem.java | 68 +-- src/android/LocalFilesystem.java | 142 +++--- src/android/LocalFilesystemURL.java | 16 +- src/android/PendingRequests.java | 19 +- 8 files changed, 550 insertions(+), 579 deletions(-) diff --git a/src/android/AssetFilesystem.java b/src/android/AssetFilesystem.java index 6d766a4a..262d547c 100644 --- a/src/android/AssetFilesystem.java +++ b/src/android/AssetFilesystem.java @@ -137,7 +137,7 @@ private long getAssetSize(String assetPath) throws FileNotFoundException { public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi, CordovaPreferences preferences) { super(Uri.parse("file:///android_asset/"), "assets", resourceApi, preferences); this.assetManager = assetManager; - } + } @Override public Uri toNativeUri(LocalFilesystemURL inputURL) { @@ -204,7 +204,7 @@ public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws Fil entries[i] = localUrlforFullPath(new File(inputURL.path, files[i]).getPath()); } return entries; - } + } @Override public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, @@ -241,25 +241,25 @@ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, } @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { + public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { JSONObject metadata = new JSONObject(); long size = inputURL.isDirectory ? 0 : getAssetSize(inputURL.path); try { - metadata.put("size", size); - metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL))); - metadata.put("name", new File(inputURL.path).getName()); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", 0); + metadata.put("size", size); + metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL))); + metadata.put("name", new File(inputURL.path).getName()); + metadata.put("fullPath", inputURL.path); + metadata.put("lastModifiedDate", 0); } catch (JSONException e) { return null; } return metadata; - } + } - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - return false; - } + @Override + public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { + return false; + } @Override long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException { diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java index d528bd3a..8231581d 100644 --- a/src/android/ContentFilesystem.java +++ b/src/android/ContentFilesystem.java @@ -25,6 +25,7 @@ Licensed to the Apache Software Foundation (ASF) under one import android.provider.DocumentsContract; import android.provider.MediaStore; import android.provider.OpenableColumns; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -38,10 +39,10 @@ public class ContentFilesystem extends Filesystem { private final Context context; - public ContentFilesystem(Context context, CordovaResourceApi resourceApi, CordovaPreferences preferences) { - super(Uri.parse("content://"), "content", resourceApi, preferences); + public ContentFilesystem(Context context, CordovaResourceApi resourceApi, CordovaPreferences preferences) { + super(Uri.parse("content://"), "content", resourceApi, preferences); this.context = context; - } + } @Override public Uri toNativeUri(LocalFilesystemURL inputURL) { @@ -78,47 +79,47 @@ public LocalFilesystemURL toLocalUri(Uri inputURL) { b.appendEncodedPath(subPath); } Uri localUri = b.encodedQuery(inputURL.getEncodedQuery()) - .encodedFragment(inputURL.getEncodedFragment()) - .build(); + .encodedFragment(inputURL.getEncodedFragment()) + .build(); return LocalFilesystemURL.parse(localUri); } @Override - public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, - String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException { + public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, + String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException { throw new UnsupportedOperationException("getFile() not supported for content:. Use resolveLocalFileSystemURL instead."); - } + } - @Override - public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) - throws NoModificationAllowedException { + @Override + public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) + throws NoModificationAllowedException { Uri contentUri = toNativeUri(inputURL); - try { + try { context.getContentResolver().delete(contentUri, null, null); - } catch (UnsupportedOperationException t) { - // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator. - // The ContentResolver applies only when the file was registered in the - // first case, which is generally only the case with images. + } catch (UnsupportedOperationException t) { + // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator. + // The ContentResolver applies only when the file was registered in the + // first case, which is generally only the case with images. NoModificationAllowedException nmae = new NoModificationAllowedException("Deleting not supported for content uri: " + contentUri); nmae.initCause(t); throw nmae; - } + } return true; - } + } - @Override - public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) - throws NoModificationAllowedException { - throw new NoModificationAllowedException("Cannot remove content url"); - } + @Override + public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) + throws NoModificationAllowedException { + throw new NoModificationAllowedException("Cannot remove content url"); + } @Override public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException { throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead."); } - @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { + @Override + public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { long size = -1; long lastModified = 0; Uri nativeUri = toNativeUri(inputURL); @@ -143,55 +144,56 @@ public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws fnfe.initCause(e); throw fnfe; } finally { - if (cursor != null) - cursor.close(); + if (cursor != null) + cursor.close(); } JSONObject metadata = new JSONObject(); try { - metadata.put("size", size); - metadata.put("type", mimeType); - metadata.put("name", name); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", lastModified); + metadata.put("size", size); + metadata.put("type", mimeType); + metadata.put("name", name); + metadata.put("fullPath", inputURL.path); + metadata.put("lastModifiedDate", lastModified); } catch (JSONException e) { - return null; + return null; } return metadata; - } + } - @Override - public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, - int offset, boolean isBinary) throws NoModificationAllowedException { + @Override + public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, + int offset, boolean isBinary) throws NoModificationAllowedException { throw new NoModificationAllowedException("Couldn't write to file given its content URI"); } - @Override - public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) - throws NoModificationAllowedException { + + @Override + public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) + throws NoModificationAllowedException { throw new NoModificationAllowedException("Couldn't truncate file given its content URI"); - } + } - protected Cursor openCursorForURL(Uri nativeUri) { + protected Cursor openCursorForURL(Uri nativeUri) { ContentResolver contentResolver = context.getContentResolver(); try { return contentResolver.query(nativeUri, null, null, null, null); } catch (UnsupportedOperationException e) { return null; } - } + } - private Long resourceSizeForCursor(Cursor cursor) { + private Long resourceSizeForCursor(Cursor cursor) { int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE); if (columnIndex != -1) { String sizeStr = cursor.getString(columnIndex); if (sizeStr != null) { - return Long.parseLong(sizeStr); + return Long.parseLong(sizeStr); } } return null; - } - - protected Long lastModifiedDateForCursor(Cursor cursor) { + } + + protected Long lastModifiedDateForCursor(Cursor cursor) { int columnIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED); if (columnIndex == -1) { columnIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED); @@ -203,7 +205,7 @@ protected Long lastModifiedDateForCursor(Cursor cursor) { } } return null; - } + } @Override public String filesystemPathForURL(LocalFilesystemURL url) { @@ -211,14 +213,14 @@ public String filesystemPathForURL(LocalFilesystemURL url) { return f == null ? null : f.getAbsolutePath(); } - @Override - public LocalFilesystemURL URLforFilesystemPath(String path) { - // Returns null as we don't support reverse mapping back to content:// URLs - return null; - } + @Override + public LocalFilesystemURL URLforFilesystemPath(String path) { + // Returns null as we don't support reverse mapping back to content:// URLs + return null; + } - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - return true; - } + @Override + public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { + return true; + } } diff --git a/src/android/DirectoryManager.java b/src/android/DirectoryManager.java index 07af5ea2..9e3ffc8e 100644 --- a/src/android/DirectoryManager.java +++ b/src/android/DirectoryManager.java @@ -26,7 +26,7 @@ Licensed to the Apache Software Foundation (ASF) under one /** * This class provides file directory utilities. * All file operations are performed on the SD card. - * + *

* It is used by the FileUtils class. */ public class DirectoryManager { @@ -36,8 +36,9 @@ public class DirectoryManager { /** * Determine if a file or directory exists. - * @param name The name of the file to check. - * @return T=exists, F=not found + * + * @param name The name of the file to check. + * @return T=exists, F=not found */ public static boolean testFileExists(String name) { boolean status; @@ -58,7 +59,7 @@ public static boolean testFileExists(String name) { /** * Get the free space in external storage * - * @return Size in KB or -1 if not available + * @return Size in KB or -1 if not available */ public static long getFreeExternalStorageSpace() { String status = Environment.getExternalStorageState(); @@ -96,7 +97,7 @@ public static long getFreeSpaceInBytes(String path) { /** * Determine if SD card exists. * - * @return T=exists, F=not found + * @return T=exists, F=not found */ public static boolean testSaveLocationExists() { String sDCardStatus = Environment.getExternalStorageState(); @@ -117,16 +118,15 @@ public static boolean testSaveLocationExists() { /** * Create a new file object from two file paths. * - * @param file1 Base file path - * @param file2 Remaining file path - * @return File object + * @param file1 Base file path + * @param file2 Remaining file path + * @return File object */ - private static File constructFilePaths (String file1, String file2) { + private static File constructFilePaths(String file1, String file2) { File newPath; if (file2.startsWith(file1)) { newPath = new File(file2); - } - else { + } else { newPath = new File(file1 + "/" + file2); } return newPath; diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java index 901a3cdb..54225880 100644 --- a/src/android/FileUtils.java +++ b/src/android/FileUtils.java @@ -109,18 +109,18 @@ private interface FileOp { private ArrayList filesystems; public void registerFilesystem(Filesystem fs) { - if (fs != null && filesystemForName(fs.name)== null) { - this.filesystems.add(fs); - } + if (fs != null && filesystemForName(fs.name) == null) { + this.filesystems.add(fs); + } } private Filesystem filesystemForName(String name) { - for (Filesystem fs:filesystems) { - if (fs != null && fs.name != null && fs.name.equals(name)) { - return fs; - } - } - return null; + for (Filesystem fs : filesystems) { + if (fs != null && fs.name != null && fs.name.equals(name)) { + return fs; + } + } + return null; } protected String[] getExtraFileSystemsPreference(Activity activity) { @@ -152,21 +152,20 @@ protected void registerExtraFileSystems(String[] filesystems, HashMap getAvailableFileSystems(Activity activity) { Context context = activity.getApplicationContext(); - HashMap availableFileSystems = new HashMap(); + HashMap availableFileSystems = new HashMap(); availableFileSystems.put("files", context.getFilesDir().getAbsolutePath()); availableFileSystems.put("documents", new File(context.getFilesDir(), "Documents").getAbsolutePath()); availableFileSystems.put("cache", context.getCacheDir().getAbsolutePath()); availableFileSystems.put("root", "/"); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - try { - availableFileSystems.put("files-external", context.getExternalFilesDir(null).getAbsolutePath()); - availableFileSystems.put("sdcard", Environment.getExternalStorageDirectory().getAbsolutePath()); - availableFileSystems.put("cache-external", context.getExternalCacheDir().getAbsolutePath()); - } - catch(NullPointerException e) { - LOG.d(LOG_TAG, "External storage unavailable, check to see if USB Mass Storage Mode is on"); - } + try { + availableFileSystems.put("files-external", context.getExternalFilesDir(null).getAbsolutePath()); + availableFileSystems.put("sdcard", Environment.getExternalStorageDirectory().getAbsolutePath()); + availableFileSystems.put("cache-external", context.getExternalCacheDir().getAbsolutePath()); + } catch (NullPointerException e) { + LOG.d(LOG_TAG, "External storage unavailable, check to see if USB Mass Storage Mode is on"); + } } return availableFileSystems; @@ -174,75 +173,75 @@ protected HashMap getAvailableFileSystems(Activity activity) { @Override public void initialize(CordovaInterface cordova, CordovaWebView webView) { - super.initialize(cordova, webView); - this.filesystems = new ArrayList(); + super.initialize(cordova, webView); + this.filesystems = new ArrayList(); this.pendingRequests = new PendingRequests(); - String tempRoot = null; - String persistentRoot = null; + String tempRoot = null; + String persistentRoot = null; - Activity activity = cordova.getActivity(); - String packageName = activity.getPackageName(); + Activity activity = cordova.getActivity(); + String packageName = activity.getPackageName(); String location = preferences.getString("androidpersistentfilelocation", "internal"); - tempRoot = activity.getCacheDir().getAbsolutePath(); - if ("internal".equalsIgnoreCase(location)) { - persistentRoot = activity.getFilesDir().getAbsolutePath() + "/files/"; - this.configured = true; - } else if ("compatibility".equalsIgnoreCase(location)) { - /* - * Fall-back to compatibility mode -- this is the logic implemented in - * earlier versions of this plugin, and should be maintained here so - * that apps which were originally deployed with older versions of the - * plugin can continue to provide access to files stored under those - * versions. - */ - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath(); - tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + - "/Android/data/" + packageName + "/cache/"; - } else { - persistentRoot = "/data/data/" + packageName; - } - this.configured = true; - } - - if (this.configured) { - // Create the directories if they don't exist. - File tmpRootFile = new File(tempRoot); + tempRoot = activity.getCacheDir().getAbsolutePath(); + if ("internal".equalsIgnoreCase(location)) { + persistentRoot = activity.getFilesDir().getAbsolutePath() + "/files/"; + this.configured = true; + } else if ("compatibility".equalsIgnoreCase(location)) { + /* + * Fall-back to compatibility mode -- this is the logic implemented in + * earlier versions of this plugin, and should be maintained here so + * that apps which were originally deployed with older versions of the + * plugin can continue to provide access to files stored under those + * versions. + */ + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath(); + tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + + "/Android/data/" + packageName + "/cache/"; + } else { + persistentRoot = "/data/data/" + packageName; + } + this.configured = true; + } + + if (this.configured) { + // Create the directories if they don't exist. + File tmpRootFile = new File(tempRoot); File persistentRootFile = new File(persistentRoot); tmpRootFile.mkdirs(); persistentRootFile.mkdirs(); - // Register initial filesystems - // Note: The temporary and persistent filesystems need to be the first two - // registered, so that they will match window.TEMPORARY and window.PERSISTENT, - // per spec. - this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tmpRootFile, preferences)); + // Register initial filesystems + // Note: The temporary and persistent filesystems need to be the first two + // registered, so that they will match window.TEMPORARY and window.PERSISTENT, + // per spec. + this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tmpRootFile, preferences)); this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRootFile, preferences)); this.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi(), preferences)); this.registerFilesystem(new AssetFilesystem(webView.getContext().getAssets(), webView.getResourceApi(), preferences)); registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity)); - // Initialize static plugin reference for deprecated getEntry method - if (filePlugin == null) { - FileUtils.filePlugin = this; - } - } else { - LOG.e(LOG_TAG, "File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \"internal\" (for new applications) or \"compatibility\" (for compatibility with previous versions)"); - activity.finish(); - } + // Initialize static plugin reference for deprecated getEntry method + if (filePlugin == null) { + FileUtils.filePlugin = this; + } + } else { + LOG.e(LOG_TAG, "File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \"internal\" (for new applications) or \"compatibility\" (for compatibility with previous versions)"); + activity.finish(); + } } public static FileUtils getFilePlugin() { - return filePlugin; - } + return filePlugin; + } - private Filesystem filesystemForURL(LocalFilesystemURL localURL) { - if (localURL == null) return null; - return filesystemForName(localURL.fsName); + private Filesystem filesystemForURL(LocalFilesystemURL localURL) { + if (localURL == null) return null; + return filesystemForName(localURL.fsName); } @Override @@ -253,19 +252,19 @@ public Uri remapUri(Uri uri) { } try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - return null; - } - String path = fs.filesystemPathForURL(inputURL); - - if (path != null) { - return Uri.parse("file://" + fs.filesystemPathForURL(inputURL)); - } - return null; + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + return null; + } + String path = fs.filesystemPathForURL(inputURL); + + if (path != null) { + return Uri.parse("file://" + fs.filesystemPathForURL(inputURL)); + } + return null; } catch (IllegalArgumentException e) { - return null; + return null; } } @@ -278,14 +277,13 @@ public boolean execute(String action, final String rawArgs, final CallbackContex if (action.equals("testSaveLocationExists")) { threadhelper(new FileOp() { public void run(JSONArray args) { - + boolean b = DirectoryManager.testSaveLocationExists(); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); } }, rawArgs, callbackContext); - } - else if (action.equals("getFreeDiskSpace")) { - threadhelper( new FileOp( ){ + } else if (action.equals("getFreeDiskSpace")) { + threadhelper(new FileOp() { public void run(JSONArray args) { // The getFreeDiskSpace plugin API is not documented, but some apps call it anyway via exec(). // For compatibility it always returns free space in the primary external storage, and @@ -294,98 +292,88 @@ public void run(JSONArray args) { callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l)); } }, rawArgs, callbackContext); - } - else if (action.equals("testFileExists")) { - threadhelper( new FileOp( ){ + } else if (action.equals("testFileExists")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException { - String fname=args.getString(0); + String fname = args.getString(0); boolean b = DirectoryManager.testFileExists(fname); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); } }, rawArgs, callbackContext); - } - else if (action.equals("testDirectoryExists")) { - threadhelper( new FileOp( ){ + } else if (action.equals("testDirectoryExists")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException { - String fname=args.getString(0); + String fname = args.getString(0); boolean b = DirectoryManager.testFileExists(fname); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); } }, rawArgs, callbackContext); - } - else if (action.equals("readAsText")) { - threadhelper( new FileOp( ){ + } else if (action.equals("readAsText")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, MalformedURLException { String encoding = args.getString(1); int start = args.getInt(2); int end = args.getInt(3); - String fname=args.getString(0); + String fname = args.getString(0); readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING); } }, rawArgs, callbackContext); - } - else if (action.equals("readAsDataURL")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { + } else if (action.equals("readAsDataURL")) { + threadhelper(new FileOp() { + public void run(JSONArray args) throws JSONException, MalformedURLException { int start = args.getInt(1); int end = args.getInt(2); - String fname=args.getString(0); + String fname = args.getString(0); readFileAs(fname, start, end, callbackContext, null, -1); } }, rawArgs, callbackContext); - } - else if (action.equals("readAsArrayBuffer")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { + } else if (action.equals("readAsArrayBuffer")) { + threadhelper(new FileOp() { + public void run(JSONArray args) throws JSONException, MalformedURLException { int start = args.getInt(1); int end = args.getInt(2); - String fname=args.getString(0); + String fname = args.getString(0); readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER); } }, rawArgs, callbackContext); - } - else if (action.equals("readAsBinaryString")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { + } else if (action.equals("readAsBinaryString")) { + threadhelper(new FileOp() { + public void run(JSONArray args) throws JSONException, MalformedURLException { int start = args.getInt(1); int end = args.getInt(2); - String fname=args.getString(0); + String fname = args.getString(0); readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING); } }, rawArgs, callbackContext); - } - else if (action.equals("write")) { - threadhelper( new FileOp( ){ + } else if (action.equals("write")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException { - String fname=args.getString(0); + String fname = args.getString(0); String nativeURL = resolveLocalFileSystemURI(fname).getString("nativeURL"); - String data=args.getString(1); - int offset=args.getInt(2); - Boolean isBinary=args.getBoolean(3); + String data = args.getString(1); + int offset = args.getInt(2); + Boolean isBinary = args.getBoolean(3); - if(needPermission(nativeURL, WRITE)) { + if (needPermission(nativeURL, WRITE)) { getWritePermission(rawArgs, ACTION_WRITE, callbackContext); - } - else { + } else { long fileSize = write(fname, data, offset, isBinary); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize)); } } }, rawArgs, callbackContext); - } - else if (action.equals("truncate")) { - threadhelper( new FileOp( ){ + } else if (action.equals("truncate")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException { - String fname=args.getString(0); - int offset=args.getInt(1); + String fname = args.getString(0); + int offset = args.getInt(1); long fileSize = truncateFile(fname, offset); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize)); } }, rawArgs, callbackContext); - } - else if (action.equals("requestAllFileSystems")) { - threadhelper( new FileOp( ){ + } else if (action.equals("requestAllFileSystems")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws IOException, JSONException { callbackContext.success(requestAllFileSystems()); } @@ -394,74 +382,67 @@ public void run(JSONArray args) throws IOException, JSONException { cordova.getThreadPool().execute( new Runnable() { public void run() { - try { - callbackContext.success(requestAllPaths()); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + try { + callbackContext.success(requestAllPaths()); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } } ); } else if (action.equals("requestFileSystem")) { - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException { int fstype = args.getInt(0); long requiredSize = args.optLong(1); requestFileSystem(fstype, requiredSize, callbackContext); } }, rawArgs, callbackContext); - } - else if (action.equals("resolveLocalFileSystemURI")) { - threadhelper( new FileOp( ){ + } else if (action.equals("resolveLocalFileSystemURI")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws IOException, JSONException { - String fname=args.getString(0); + String fname = args.getString(0); JSONObject obj = resolveLocalFileSystemURI(fname); callbackContext.success(obj); } }, rawArgs, callbackContext); - } - else if (action.equals("getFileMetadata")) { - threadhelper( new FileOp( ){ + } else if (action.equals("getFileMetadata")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { - String fname=args.getString(0); + String fname = args.getString(0); JSONObject obj = getFileMetadata(fname); callbackContext.success(obj); } }, rawArgs, callbackContext); - } - else if (action.equals("getParent")) { - threadhelper( new FileOp( ){ + } else if (action.equals("getParent")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, IOException { - String fname=args.getString(0); + String fname = args.getString(0); JSONObject obj = getParent(fname); callbackContext.success(obj); } }, rawArgs, callbackContext); - } - else if (action.equals("getDirectory")) { - threadhelper( new FileOp( ){ + } else if (action.equals("getDirectory")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { String dirname = args.getString(0); String path = args.getString(1); String nativeURL = resolveLocalFileSystemURI(dirname).getString("nativeURL"); boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false); - if(containsCreate && needPermission(nativeURL, WRITE)) { + if (containsCreate && needPermission(nativeURL, WRITE)) { getWritePermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext); - } - else if(!containsCreate && needPermission(nativeURL, READ)) { + } else if (!containsCreate && needPermission(nativeURL, READ)) { getReadPermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext); - } - else { + } else { JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true); callbackContext.success(obj); } } }, rawArgs, callbackContext); - } - else if (action.equals("getFile")) { - threadhelper( new FileOp( ){ + } else if (action.equals("getFile")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { String dirname = args.getString(0); String path = args.getString(1); @@ -473,24 +454,21 @@ public void run(JSONArray args) throws FileExistsException, IOException, TypeMis String nativeURL = resolveLocalFileSystemURI(dirname).getString("nativeURL"); boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false); - if(containsCreate && needPermission(nativeURL, WRITE)) { + if (containsCreate && needPermission(nativeURL, WRITE)) { getWritePermission(rawArgs, ACTION_GET_FILE, callbackContext); - } - else if(!containsCreate && needPermission(nativeURL, READ)) { + } else if (!containsCreate && needPermission(nativeURL, READ)) { getReadPermission(rawArgs, ACTION_GET_FILE, callbackContext); - } - else { + } else { JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false); callbackContext.success(obj); } } } }, rawArgs, callbackContext); - } - else if (action.equals("remove")) { - threadhelper( new FileOp( ){ + } else if (action.equals("remove")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, NoModificationAllowedException, InvalidModificationException, MalformedURLException { - String fname=args.getString(0); + String fname = args.getString(0); boolean success = remove(fname); if (success) { callbackContext.success(); @@ -499,11 +477,10 @@ public void run(JSONArray args) throws JSONException, NoModificationAllowedExcep } } }, rawArgs, callbackContext); - } - else if (action.equals("removeRecursively")) { - threadhelper( new FileOp( ){ + } else if (action.equals("removeRecursively")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, FileExistsException, MalformedURLException, NoModificationAllowedException { - String fname=args.getString(0); + String fname = args.getString(0); boolean success = removeRecursively(fname); if (success) { callbackContext.success(); @@ -512,56 +489,50 @@ public void run(JSONArray args) throws JSONException, FileExistsException, Malfo } } }, rawArgs, callbackContext); - } - else if (action.equals("moveTo")) { - threadhelper( new FileOp( ){ + } else if (action.equals("moveTo")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { - String fname=args.getString(0); - String newParent=args.getString(1); - String newName=args.getString(2); + String fname = args.getString(0); + String newParent = args.getString(1); + String newName = args.getString(2); JSONObject entry = transferTo(fname, newParent, newName, true); callbackContext.success(entry); } }, rawArgs, callbackContext); - } - else if (action.equals("copyTo")) { - threadhelper( new FileOp( ){ + } else if (action.equals("copyTo")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { - String fname=args.getString(0); - String newParent=args.getString(1); - String newName=args.getString(2); + String fname = args.getString(0); + String newParent = args.getString(1); + String newName = args.getString(2); JSONObject entry = transferTo(fname, newParent, newName, false); callbackContext.success(entry); } }, rawArgs, callbackContext); - } - else if (action.equals("readEntries")) { - threadhelper( new FileOp( ){ + } else if (action.equals("readEntries")) { + threadhelper(new FileOp() { public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException, IOException { String directory = args.getString(0); String nativeURL = resolveLocalFileSystemURI(directory).getString("nativeURL"); if (needPermission(nativeURL, READ)) { getReadPermission(rawArgs, ACTION_READ_ENTRIES, callbackContext); - } - else { + } else { JSONArray entries = readEntries(directory); callbackContext.success(entries); } } }, rawArgs, callbackContext); - } - else if (action.equals("_getLocalFilesystemPath")) { + } else if (action.equals("_getLocalFilesystemPath")) { // Internal method for testing: Get the on-disk location of a local filesystem url. // [Currently used for testing file-transfer] - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { String localURLstr = args.getString(0); String fname = filesystemPathForURL(localURLstr); callbackContext.success(fname); } }, rawArgs, callbackContext); - } - else { + } else { return false; } return true; @@ -570,11 +541,11 @@ public void run(JSONArray args) throws FileNotFoundException, JSONException, Mal private void getReadPermission(String rawArgs, int action, CallbackContext callbackContext) { int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - PermissionHelper.requestPermissions(this, requestCode, - new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO}); - } else { + PermissionHelper.requestPermissions(this, requestCode, + new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO}); + } else { PermissionHelper.requestPermission(this, requestCode, Manifest.permission.READ_EXTERNAL_STORAGE); - } + } } private void getWritePermission(String rawArgs, int action, CallbackContext callbackContext) { @@ -584,12 +555,12 @@ private void getWritePermission(String rawArgs, int action, CallbackContext call private boolean hasReadPermission() { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - return PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_IMAGES) - && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_VIDEO) - && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_AUDIO); - } else { + return PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_IMAGES) + && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_VIDEO) + && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_AUDIO); + } else { return PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); - } + } } private boolean hasWritePermission() { @@ -601,20 +572,19 @@ private boolean needPermission(String nativeURL, int permissionType) throws JSON ArrayList allowedStorageDirectories = new ArrayList(); allowedStorageDirectories.add(j.getString("applicationDirectory")); allowedStorageDirectories.add(j.getString("applicationStorageDirectory")); - if(j.has("externalApplicationStorageDirectory")) { + if (j.has("externalApplicationStorageDirectory")) { allowedStorageDirectories.add(j.getString("externalApplicationStorageDirectory")); } - if(permissionType == READ && hasReadPermission()) { + if (permissionType == READ && hasReadPermission()) { return false; - } - else if(permissionType == WRITE && hasWritePermission()) { + } else if (permissionType == WRITE && hasWritePermission()) { return false; } // Permission required if the native url lies outside the allowed storage directories - for(String directory : allowedStorageDirectories) { - if(nativeURL.startsWith(directory)) { + for (String directory : allowedStorageDirectories) { + if (nativeURL.startsWith(directory)) { return false; } } @@ -657,7 +627,7 @@ public String filesystemPathForURL(String localURLstr) throws MalformedURLExcept } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -667,7 +637,7 @@ public LocalFilesystemURL filesystemURLforLocalPath(String localPath) { // Try all installed filesystems. Return the best matching URL // (determined by the shortest resulting URL) - for (Filesystem fs: filesystems) { + for (Filesystem fs : filesystems) { LocalFilesystemURL url = fs.URLforFilesystemPath(localPath); if (url != null) { // A shorter fullPath implies that the filesystem is a better @@ -682,41 +652,41 @@ public LocalFilesystemURL filesystemURLforLocalPath(String localPath) { } - /* helper to execute functions async and handle the result codes + /* helper to execute functions async and handle the result codes * */ - private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext){ + private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { try { JSONArray args = new JSONArray(rawArgs); f.run(args); - } catch ( Exception e) { - if( e instanceof EncodingException){ + } catch (Exception e) { + if (e instanceof EncodingException) { callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof FileNotFoundException) { + } else if (e instanceof FileNotFoundException) { callbackContext.error(FileUtils.NOT_FOUND_ERR); - } else if(e instanceof FileExistsException) { + } else if (e instanceof FileExistsException) { callbackContext.error(FileUtils.PATH_EXISTS_ERR); - } else if(e instanceof NoModificationAllowedException ) { + } else if (e instanceof NoModificationAllowedException) { callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR); - } else if(e instanceof InvalidModificationException ) { + } else if (e instanceof InvalidModificationException) { callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR); - } else if(e instanceof MalformedURLException ) { + } else if (e instanceof MalformedURLException) { callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof IOException ) { + } else if (e instanceof IOException) { callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR); - } else if(e instanceof EncodingException ) { + } else if (e instanceof EncodingException) { callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof TypeMismatchException ) { + } else if (e instanceof TypeMismatchException) { callbackContext.error(FileUtils.TYPE_MISMATCH_ERR); - } else if(e instanceof JSONException ) { + } else if (e instanceof JSONException) { callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); } else if (e instanceof SecurityException) { callbackContext.error(FileUtils.SECURITY_ERR); } else { e.printStackTrace(); - callbackContext.error(FileUtils.UNKNOWN_ERR); + callbackContext.error(FileUtils.UNKNOWN_ERR); } } } @@ -730,7 +700,7 @@ public void run() { * @return a JSONObject representing a Entry from the filesystem * @throws MalformedURLException if the url is not valid * @throws FileNotFoundException if the file does not exist - * @throws IOException if the user can't read the file + * @throws IOException if the user can't read the file * @throws JSONException */ private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException { @@ -764,7 +734,7 @@ private JSONObject resolveLocalFileSystemURI(String uriString) throws IOExceptio } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } throw new FileNotFoundException(); } @@ -779,17 +749,17 @@ private JSONObject resolveLocalFileSystemURI(String uriString) throws IOExceptio */ private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.readEntriesAtLocalURL(inputURL); + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.readEntriesAtLocalURL(inputURL); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -797,7 +767,7 @@ private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, J * A setup method that handles the move/copy of files/directories * * @param newName for the file directory to be called, if null use existing file name - * @param move if false do a copy, if true do a move + * @param move if false do a copy, if true do a move * @return a Entry object * @throws NoModificationAllowedException * @throws IOException @@ -809,7 +779,7 @@ private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, J private JSONObject transferTo(String srcURLstr, String destURLstr, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { if (srcURLstr == null || destURLstr == null) { // either no source or no destination provided - throw new FileNotFoundException(); + throw new FileNotFoundException(); } LocalFilesystemURL srcURL = LocalFilesystemURL.parse(srcURLstr); @@ -839,22 +809,22 @@ private JSONObject transferTo(String srcURLstr, String destURLstr, String newNam */ private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - // You can't delete the root directory. - if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { - throw new NoModificationAllowedException("You can't delete the root directory"); - } - - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.recursiveRemoveFileAtLocalURL(inputURL); + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + // You can't delete the root directory. + if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { + throw new NoModificationAllowedException("You can't delete the root directory"); + } + + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.recursiveRemoveFileAtLocalURL(inputURL); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -870,23 +840,23 @@ private boolean removeRecursively(String baseURLstr) throws FileExistsException, */ private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - // You can't delete the root directory. - if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + // You can't delete the root directory. + if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { - throw new NoModificationAllowedException("You can't delete the root directory"); - } + throw new NoModificationAllowedException("You can't delete the root directory"); + } - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.removeFileAtLocalURL(inputURL); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.removeFileAtLocalURL(inputURL); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -894,9 +864,9 @@ private boolean remove(String baseURLstr) throws NoModificationAllowedException, * Creates or looks up a file. * * @param baseURLstr base directory - * @param path file/directory to lookup or create - * @param options specify whether to create or not - * @param directory if true look up directory, if false look up file + * @param path file/directory to lookup or create + * @param options specify whether to create or not + * @param directory if true look up directory, if false look up file * @return a Entry object * @throws FileExistsException * @throws IOException @@ -906,18 +876,18 @@ private boolean remove(String baseURLstr) throws NoModificationAllowedException, */ private JSONObject getFile(String baseURLstr, String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getFileForLocalURL(inputURL, path, options, directory); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.getFileForLocalURL(inputURL, path, options, directory); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -928,17 +898,17 @@ private JSONObject getFile(String baseURLstr, String path, JSONObject options, b */ private JSONObject getParent(String baseURLstr) throws JSONException, IOException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getParentForLocalURL(inputURL); + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.getParentForLocalURL(inputURL); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -949,25 +919,25 @@ private JSONObject getParent(String baseURLstr) throws JSONException, IOExceptio */ private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getFileMetadataForLocalURL(inputURL); + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } + return fs.getFileMetadataForLocalURL(inputURL); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } /** * Requests a filesystem in which to store application data. * - * @param type of file system requested - * @param requiredSize required free space in the file system in bytes + * @param type of file system requested + * @param requiredSize required free space in the file system in bytes * @param callbackContext context for returning the result or error * @throws JSONException */ @@ -1023,21 +993,20 @@ private JSONObject requestAllPaths() throws JSONException { ret.put("dataDirectory", toDirUrl(context.getFilesDir())); ret.put("cacheDirectory", toDirUrl(context.getCacheDir())); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - try { - ret.put("externalApplicationStorageDirectory", toDirUrl(context.getExternalFilesDir(null).getParentFile())); - ret.put("externalDataDirectory", toDirUrl(context.getExternalFilesDir(null))); - ret.put("externalCacheDirectory", toDirUrl(context.getExternalCacheDir())); - ret.put("externalRootDirectory", toDirUrl(Environment.getExternalStorageDirectory())); - } - catch(NullPointerException e) { - /* If external storage is unavailable, context.getExternal* returns null */ - LOG.d(LOG_TAG, "Unable to access these paths, most liklely due to USB storage"); - } + try { + ret.put("externalApplicationStorageDirectory", toDirUrl(context.getExternalFilesDir(null).getParentFile())); + ret.put("externalDataDirectory", toDirUrl(context.getExternalFilesDir(null))); + ret.put("externalCacheDirectory", toDirUrl(context.getExternalCacheDir())); + ret.put("externalRootDirectory", toDirUrl(Environment.getExternalStorageDirectory())); + } catch (NullPointerException e) { + /* If external storage is unavailable, context.getExternal* returns null */ + LOG.d(LOG_TAG, "Unable to access these paths, most liklely due to USB storage"); + } } return ret; } - /** + /** * Returns a JSON object representing the given File. Internal APIs should be modified * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin. * @@ -1049,10 +1018,10 @@ public JSONObject getEntryForFile(File file) throws JSONException { JSONObject entry; for (Filesystem fs : filesystems) { - entry = fs.makeEntryForFile(file); - if (entry != null) { - return entry; - } + entry = fs.makeEntryForFile(file); + if (entry != null) { + return entry; + } } return null; } @@ -1069,39 +1038,39 @@ public JSONObject getEntryForFile(File file) throws JSONException { */ @Deprecated public static JSONObject getEntry(File file) throws JSONException { - if (getFilePlugin() != null) { - return getFilePlugin().getEntryForFile(file); - } - return null; + if (getFilePlugin() != null) { + return getFilePlugin().getEntryForFile(file); + } + return null; } /** * Read the contents of a file. * This is done in a background thread; the result is sent to the callback. * - * @param start Start position in the file. - * @param end End position to stop at (exclusive). - * @param callbackContext The context through which to send the result. - * @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets) - * @param resultType The desired type of data to send to the callback. - * @return Contents of file. + * @param start Start position in the file. + * @param end End position to stop at (exclusive). + * @param callbackContext The context through which to send the result. + * @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets) + * @param resultType The desired type of data to send to the callback. + * @return Contents of file. */ public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } fs.readFileAtURL(inputURL, start, end, new Filesystem.ReadFileCallback() { public void handleData(InputStream inputStream, String contentType) { - try { + try { ByteArrayOutputStream os = new ByteArrayOutputStream(); final int BUFFER_SIZE = 8192; byte[] buffer = new byte[BUFFER_SIZE]; - for (;;) { + for (; ; ) { int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE); if (bytesRead <= 0) { @@ -1110,41 +1079,41 @@ public void handleData(InputStream inputStream, String contentType) { os.write(buffer, 0, bytesRead); } - PluginResult result; - switch (resultType) { - case PluginResult.MESSAGE_TYPE_STRING: - result = new PluginResult(PluginResult.Status.OK, os.toString(encoding)); - break; - case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: - result = new PluginResult(PluginResult.Status.OK, os.toByteArray()); - break; - case PluginResult.MESSAGE_TYPE_BINARYSTRING: - result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true); - break; - default: // Base64. - byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP); - String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII"); - result = new PluginResult(PluginResult.Status.OK, s); - } - - callbackContext.sendPluginResult(result); - } catch (IOException e) { - LOG.d(LOG_TAG, e.getLocalizedMessage()); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); + PluginResult result; + switch (resultType) { + case PluginResult.MESSAGE_TYPE_STRING: + result = new PluginResult(PluginResult.Status.OK, os.toString(encoding)); + break; + case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: + result = new PluginResult(PluginResult.Status.OK, os.toByteArray()); + break; + case PluginResult.MESSAGE_TYPE_BINARYSTRING: + result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true); + break; + default: // Base64. + byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP); + String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII"); + result = new PluginResult(PluginResult.Status.OK, s); + } + + callbackContext.sendPluginResult(result); + } catch (IOException e) { + LOG.d(LOG_TAG, e.getLocalizedMessage()); + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); } - } + } }); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } catch (FileNotFoundException e) { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR)); + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR)); } catch (IOException e) { - LOG.d(LOG_TAG, e.getLocalizedMessage()); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); + LOG.d(LOG_TAG, e.getLocalizedMessage()); + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); } } @@ -1152,24 +1121,24 @@ public void handleData(InputStream inputStream, String contentType) { /** * Write contents of file. * - * @param data The contents of the file. - * @param offset The position to begin writing the file. - * @param isBinary True if the file contents are base64-encoded binary data + * @param data The contents of the file. + * @param offset The position to begin writing the file. + * @param isBinary True if the file contents are base64-encoded binary data */ /**/ public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } return fs.writeToFileAtURL(inputURL, data, offset, isBinary); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -1179,17 +1148,17 @@ public long write(String srcURLstr, String data, int offset, boolean isBinary) t */ private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException { try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } + LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); + Filesystem fs = this.filesystemForURL(inputURL); + if (fs == null) { + throw new MalformedURLException("No installed handlers for this URL"); + } return fs.truncateFileAtURL(inputURL, size); } catch (IllegalArgumentException e) { MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL"); mue.initCause(e); - throw mue; + throw mue; } } @@ -1203,18 +1172,15 @@ public void onRequestPermissionResult(int requestCode, String[] permissions, final PendingRequests.Request req = pendingRequests.getAndRemove(requestCode); if (req != null) { - for(int r:grantResults) - { - if(r == PackageManager.PERMISSION_DENIED) - { + for (int r : grantResults) { + if (r == PackageManager.PERMISSION_DENIED) { req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR)); return; } } - switch(req.getAction()) - { + switch (req.getAction()) { case ACTION_GET_FILE: - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { String dirname = args.getString(0); @@ -1225,7 +1191,7 @@ public void run(JSONArray args) throws FileExistsException, IOException, TypeMis }, req.getRawArgs(), req.getCallbackContext()); break; case ACTION_GET_DIRECTORY: - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { String dirname = args.getString(0); @@ -1236,21 +1202,21 @@ public void run(JSONArray args) throws FileExistsException, IOException, TypeMis }, req.getRawArgs(), req.getCallbackContext()); break; case ACTION_WRITE: - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException { - String fname=args.getString(0); - String data=args.getString(1); - int offset=args.getInt(2); - Boolean isBinary=args.getBoolean(3); + String fname = args.getString(0); + String data = args.getString(1); + int offset = args.getInt(2); + Boolean isBinary = args.getBoolean(3); long fileSize = write(fname, data, offset, isBinary); req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize)); } }, req.getRawArgs(), req.getCallbackContext()); break; case ACTION_READ_ENTRIES: - threadhelper( new FileOp( ){ + threadhelper(new FileOp() { public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { - String fname=args.getString(0); + String fname = args.getString(0); JSONArray entries = readEntries(fname); req.getCallbackContext().success(entries); } @@ -1258,13 +1224,13 @@ public void run(JSONArray args) throws FileNotFoundException, JSONException, Mal break; } } else { - LOG.d(LOG_TAG, "Received permission callback for unknown request code"); + LOG.d(LOG_TAG, "Received permission callback for unknown request code"); } } private String getMimeType(Uri uri) { String fileExtensionFromUrl = MimeTypeMap.getFileExtensionFromUrl(uri.toString()).toLowerCase(); - return MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtensionFromUrl); + return MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtensionFromUrl); } public CordovaPluginPathHandler getPathHandler() { @@ -1319,8 +1285,8 @@ public CordovaPluginPathHandler getPathHandler() { try { InputStream fileIS = !isAssetsFS ? - new FileInputStream(file) : - webView.getContext().getAssets().open(fileTarget); + new FileInputStream(file) : + webView.getContext().getAssets().open(fileTarget); String filePath = !isAssetsFS ? file.toString() : fileTarget; Uri fileUri = Uri.parse(filePath); diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java index 54532211..7c36ac15 100644 --- a/src/android/Filesystem.java +++ b/src/android/Filesystem.java @@ -54,8 +54,8 @@ public Filesystem(Uri rootUri, String name, CordovaResourceApi resourceApi, Cord } public interface ReadFileCallback { - public void handleData(InputStream inputStream, String contentType) throws IOException; - } + public void handleData(InputStream inputStream, String contentType) throws IOException; + } public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Uri nativeURL) { try { @@ -106,13 +106,13 @@ public JSONObject makeEntryForFile(File file) { } abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path, - JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException; + JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException; - abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException; + abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException; - abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException; + abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException; - abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException; + abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException; public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { LocalFilesystemURL[] children = listChildren(inputURL); @@ -125,7 +125,7 @@ public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws return entries; } - abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException; + abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException; public Uri getRootUri() { return rootUri; @@ -174,13 +174,13 @@ protected static String normalizePath(String rawPath) { if (components.get(index).equals("..")) { components.remove(index); if (index > 0) { - components.remove(index-1); + components.remove(index - 1); --index; } } } StringBuilder normalizedPath = new StringBuilder(); - for(String component: components) { + for (String component : components) { normalizedPath.append("/"); normalizedPath.append(component); } @@ -200,6 +200,7 @@ public long getFreeSpaceInBytes() { } public abstract Uri toNativeUri(LocalFilesystemURL inputURL); + public abstract LocalFilesystemURL toLocalUri(Uri inputURL); public JSONObject getRootEntry() { @@ -209,19 +210,19 @@ public JSONObject getRootEntry() { return rootEntry; } - public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException { + public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException { Uri parentUri = inputURL.uri; String parentPath = new File(inputURL.uri.getPath()).getParent(); if (!"/".equals(parentPath)) { parentUri = inputURL.uri.buildUpon().path(parentPath + '/').build(); - } - return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri)); - } + } + return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri)); + } protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL, boolean isDirectory) { // I know this looks weird but it is to work around a JSON bug. if ("null".equals(newName) || "".equals(newName)) { - newName = srcURL.uri.getLastPathSegment();; + newName = srcURL.uri.getLastPathSegment(); } String newDest = destURL.uri.toString(); @@ -236,13 +237,13 @@ protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemU return LocalFilesystemURL.parse(newDest); } - /* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to - * the destination URL on this filesystem, optionally with a new filename. - * If move is true, then this method should either perform an atomic move operation - * or remove the source file when finished. - */ + /* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to + * the destination URL on this filesystem, optionally with a new filename. + * If move is true, then this method should either perform an atomic move operation + * or remove the source file when finished. + */ public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, - Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { + Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { // First, check to see that we can do it if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) { throw new NoModificationAllowedException("Cannot move file at source URL"); @@ -293,25 +294,27 @@ public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end, } } - abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, - boolean isBinary) throws NoModificationAllowedException, IOException; + abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, + boolean isBinary) throws NoModificationAllowedException, IOException; - abstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size) - throws IOException, NoModificationAllowedException; + abstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size) + throws IOException, NoModificationAllowedException; - // This method should return null if filesystem urls cannot be mapped to paths - abstract String filesystemPathForURL(LocalFilesystemURL url); + // This method should return null if filesystem urls cannot be mapped to paths + abstract String filesystemPathForURL(LocalFilesystemURL url); - abstract LocalFilesystemURL URLforFilesystemPath(String path); + abstract LocalFilesystemURL URLforFilesystemPath(String path); - abstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL); + abstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL); protected class LimitedInputStream extends FilterInputStream { long numBytesToRead; + public LimitedInputStream(InputStream in, long numBytesToRead) { super(in); this.numBytesToRead = numBytesToRead; } + @Override public int read() throws IOException { if (numBytesToRead <= 0) { @@ -320,6 +323,7 @@ public int read() throws IOException { numBytesToRead--; return in.read(); } + @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { if (numBytesToRead <= 0) { @@ -327,7 +331,7 @@ public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException } int bytesToRead = byteCount; if (byteCount > numBytesToRead) { - bytesToRead = (int)numBytesToRead; // Cast okay; long is less than int here. + bytesToRead = (int) numBytesToRead; // Cast okay; long is less than int here. } int numBytesRead = in.read(buffer, byteOffset, bytesToRead); numBytesToRead -= numBytesRead; @@ -341,8 +345,8 @@ protected Uri.Builder createLocalUriBuilder() { String path = LocalFilesystemURL.fsNameToCdvKeyword(name); return new Uri.Builder() - .scheme(scheme) - .authority(hostname) - .path(path); + .scheme(scheme) + .authority(hostname) + .path(path); } } diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java index 97e48882..8d2a54df 100644 --- a/src/android/LocalFilesystem.java +++ b/src/android/LocalFilesystem.java @@ -52,20 +52,20 @@ public LocalFilesystem(String name, Context context, CordovaResourceApi resource } public String filesystemPathForFullPath(String fullPath) { - return new File(rootUri.getPath(), fullPath).toString(); - } + return new File(rootUri.getPath(), fullPath).toString(); + } - @Override - public String filesystemPathForURL(LocalFilesystemURL url) { - return filesystemPathForFullPath(url.path); - } + @Override + public String filesystemPathForURL(LocalFilesystemURL url) { + return filesystemPathForFullPath(url.path); + } - private String fullPathForFilesystemPath(String absolutePath) { - if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) { - return absolutePath.substring(rootUri.getPath().length() - 1); - } - return null; - } + private String fullPathForFilesystemPath(String absolutePath) { + if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) { + return absolutePath.substring(rootUri.getPath().length() - 1); + } + return null; + } @Override public Uri toNativeUri(LocalFilesystemURL inputURL) { @@ -103,14 +103,14 @@ public LocalFilesystemURL toLocalUri(Uri inputURL) { return LocalFilesystemURL.parse(b.build()); } - @Override - public LocalFilesystemURL URLforFilesystemPath(String path) { - return localUrlforFullPath(fullPathForFilesystemPath(path)); - } + @Override + public LocalFilesystemURL URLforFilesystemPath(String path) { + return localUrlforFullPath(fullPathForFilesystemPath(path)); + } - @Override - public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, - String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { + @Override + public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, + String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { boolean create = false; boolean exclusive = false; @@ -133,9 +133,9 @@ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, path += "/"; } if (path.startsWith("/")) { - requestedURL = localUrlforFullPath(normalizePath(path)); + requestedURL = localUrlforFullPath(normalizePath(path)); } else { - requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path)); + requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path)); } File fp = new File(this.filesystemPathForURL(requestedURL)); @@ -152,8 +152,7 @@ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, if (!fp.exists()) { throw new FileExistsException("create fails"); } - } - else { + } else { if (!fp.exists()) { throw new FileNotFoundException("path does not exist"); } @@ -170,10 +169,10 @@ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, // Return the directory return makeEntryForURL(requestedURL); - } + } - @Override - public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException { + @Override + public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException { File fp = new File(filesystemPathForURL(inputURL)); @@ -183,7 +182,7 @@ public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidM } return fp.delete(); - } + } @Override public boolean exists(LocalFilesystemURL inputURL) { @@ -197,12 +196,12 @@ public long getFreeSpaceInBytes() { } @Override - public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException { + public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException { File directory = new File(filesystemPathForURL(inputURL)); - return removeDirRecursively(directory); - } + return removeDirRecursively(directory); + } - protected boolean removeDirRecursively(File directory) throws FileExistsException { + protected boolean removeDirRecursively(File directory) throws FileExistsException { if (directory.isDirectory()) { for (File file : directory.listFiles()) { removeDirRecursively(file); @@ -214,7 +213,7 @@ protected boolean removeDirRecursively(File directory) throws FileExistsExceptio } else { return true; } - } + } @Override public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException { @@ -236,10 +235,10 @@ public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws Fil } return entries; - } + } - @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { + @Override + public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { File file = new File(filesystemPathForURL(inputURL)); if (!file.exists()) { @@ -249,16 +248,16 @@ public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws JSONObject metadata = new JSONObject(); try { // Ensure that directories report a size of 0 - metadata.put("size", file.isDirectory() ? 0 : file.length()); - metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file))); - metadata.put("name", file.getName()); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", file.lastModified()); + metadata.put("size", file.isDirectory() ? 0 : file.length()); + metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file))); + metadata.put("name", file.getName()); + metadata.put("fullPath", inputURL.path); + metadata.put("lastModifiedDate", file.lastModified()); } catch (JSONException e) { - return null; + return null; } return metadata; - } + } private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException { if (move) { @@ -326,11 +325,11 @@ private void copyDirectory(Filesystem srcFs, LocalFilesystemURL srcURL, File dst } } - @Override - public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, - Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { + @Override + public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, + Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { - // Check to see if the destination directory exists + // Check to see if the destination directory exists String newParent = this.filesystemPathForURL(destURL); File destinationDir = new File(newParent); if (!destinationDir.exists()) { @@ -371,11 +370,11 @@ public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, copyFile(srcFs, srcURL, destFile, move); } return makeEntryForURL(destinationURL); - } + } - @Override - public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, - int offset, boolean isBinary) throws IOException, NoModificationAllowedException { + @Override + public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, + int offset, boolean isBinary) throws IOException, NoModificationAllowedException { boolean append = false; if (offset > 0) { @@ -390,25 +389,22 @@ public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, rawData = data.getBytes(Charset.defaultCharset()); } ByteArrayInputStream in = new ByteArrayInputStream(rawData); - try - { - byte buff[] = new byte[rawData.length]; + try { + byte buff[] = new byte[rawData.length]; String absolutePath = filesystemPathForURL(inputURL); FileOutputStream out = new FileOutputStream(absolutePath, append); try { - in.read(buff, 0, buff.length); - out.write(buff, 0, rawData.length); - out.flush(); + in.read(buff, 0, buff.length); + out.write(buff, 0, rawData.length); + out.flush(); } finally { - // Always close the output - out.close(); + // Always close the output + out.close(); } if (isPublicDirectory(absolutePath)) { broadcastNewFile(Uri.fromFile(new File(absolutePath))); } - } - catch (NullPointerException e) - { + } catch (NullPointerException e) { // This is a bug in the Android implementation of the Java Stack NoModificationAllowedException realException = new NoModificationAllowedException(inputURL.toString()); realException.initCause(e); @@ -416,14 +412,14 @@ public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, } return rawData.length; - } + } private boolean isPublicDirectory(String absolutePath) { // TODO: should expose a way to scan app's private files (maybe via a flag). if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Lollipop has a bug where SD cards are null. for (File f : context.getExternalMediaDirs()) { - if(f != null && absolutePath.startsWith(f.getAbsolutePath())) { + if (f != null && absolutePath.startsWith(f.getAbsolutePath())) { return true; } } @@ -433,7 +429,7 @@ private boolean isPublicDirectory(String absolutePath) { return absolutePath.startsWith(extPath); } - /** + /** * Send broadcast of new file so files appear over MTP */ private void broadcastNewFile(Uri nativeUri) { @@ -441,8 +437,8 @@ private void broadcastNewFile(Uri nativeUri) { context.sendBroadcast(intent); } - @Override - public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException { + @Override + public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException { File file = new File(filesystemPathForURL(inputURL)); if (!file.exists()) { @@ -463,12 +459,12 @@ public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOE } - } + } - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - String path = filesystemPathForURL(inputURL); - File file = new File(path); - return file.exists(); - } + @Override + public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { + String path = filesystemPathForURL(inputURL); + File file = new File(path); + return file.exists(); + } } diff --git a/src/android/LocalFilesystemURL.java b/src/android/LocalFilesystemURL.java index d3f41d07..5c6bb95a 100644 --- a/src/android/LocalFilesystemURL.java +++ b/src/android/LocalFilesystemURL.java @@ -21,8 +21,8 @@ Licensed to the Apache Software Foundation (ASF) under one import android.net.Uri; public class LocalFilesystemURL { - - public static final String FILESYSTEM_PROTOCOL = "cdvfile"; + + public static final String FILESYSTEM_PROTOCOL = "cdvfile"; public static final String CDVFILE_KEYWORD = "__cdvfile_"; public final Uri uri; @@ -30,15 +30,15 @@ public class LocalFilesystemURL { public final String path; public final boolean isDirectory; - private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) { - this.uri = uri; + private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) { + this.uri = uri; this.fsName = fsName; this.path = fsPath; this.isDirectory = isDirectory; - } + } public static LocalFilesystemURL parse(Uri uri) { - if(!uri.toString().contains(CDVFILE_KEYWORD)) { + if (!uri.toString().contains(CDVFILE_KEYWORD)) { return null; } @@ -66,7 +66,9 @@ public static LocalFilesystemURL parse(String uri) { return parse(Uri.parse(uri)); } - public static String fsNameToCdvKeyword(String fsName) { return CDVFILE_KEYWORD + fsName + "__"; } + public static String fsNameToCdvKeyword(String fsName) { + return CDVFILE_KEYWORD + fsName + "__"; + } public String toString() { return uri.toString(); diff --git a/src/android/PendingRequests.java b/src/android/PendingRequests.java index 4c75f423..279aa2dc 100644 --- a/src/android/PendingRequests.java +++ b/src/android/PendingRequests.java @@ -32,12 +32,13 @@ class PendingRequests { /** * Creates a request and adds it to the array of pending requests. Each created request gets a * unique result code for use with requestPermission() - * @param rawArgs The raw arguments passed to the plugin - * @param action The action this request corresponds to (get file, etc.) - * @param callbackContext The CallbackContext for this plugin call - * @return The request code that can be used to retrieve the Request object + * + * @param rawArgs The raw arguments passed to the plugin + * @param action The action this request corresponds to (get file, etc.) + * @param callbackContext The CallbackContext for this plugin call + * @return The request code that can be used to retrieve the Request object */ - public synchronized int createRequest(String rawArgs, int action, CallbackContext callbackContext) { + public synchronized int createRequest(String rawArgs, int action, CallbackContext callbackContext) { Request req = new Request(rawArgs, action, callbackContext); requests.put(req.requestCode, req); return req.requestCode; @@ -45,9 +46,9 @@ public synchronized int createRequest(String rawArgs, int action, CallbackContex /** * Gets the request corresponding to this request code and removes it from the pending requests - * @param requestCode The request code for the desired request - * @return The request corresponding to the given request code or null if such a - * request is not found + * + * @param requestCode The request code for the desired request + * @return The request corresponding to the given request code or null if such a request is not found */ public synchronized Request getAndRemove(int requestCode) { Request result = requests.get(requestCode); @@ -76,7 +77,7 @@ private Request(String rawArgs, int action, CallbackContext callbackContext) { this.rawArgs = rawArgs; this.action = action; this.callbackContext = callbackContext; - this.requestCode = currentReqId ++; + this.requestCode = currentReqId++; } public int getAction() { From 6ed82dac8e6fe9a45302fbfc33046a5582e32612 Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 02:33:48 +0200 Subject: [PATCH 3/9] publish as @ns0m/cordova-plugin-file --- .github/workflows/android.yml | 137 ------------------------------ .github/workflows/chrome.yml | 73 ---------------- .github/workflows/ios.yml | 101 ---------------------- .github/workflows/lint.yml | 56 ------------ .github/workflows/publish-npm.yml | 17 ++++ package-lock.json | 4 +- package.json | 8 +- 7 files changed, 23 insertions(+), 373 deletions(-) delete mode 100644 .github/workflows/android.yml delete mode 100644 .github/workflows/chrome.yml delete mode 100644 .github/workflows/ios.yml delete mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/publish-npm.yml diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml deleted file mode 100644 index 3159b6b4..00000000 --- a/.github/workflows/android.yml +++ /dev/null @@ -1,137 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -name: Android Testsuite - -on: - push: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - pull_request: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - -jobs: - test: - name: Android ${{ matrix.versions.android }} Test - runs-on: macos-latest - continue-on-error: true - - # hoist configurations to top that are expected to be updated - env: - # Storing a copy of the repo - repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - - node-version: 16 - - # These are the default Java configurations used by most tests. - # To customize these options, add "java-distro" or "java-version" to the strategy matrix with its overriding value. - default_java-distro: temurin - default_java-version: 11 - - # These are the default Android System Image configurations used by most tests. - # To customize these options, add "system-image-arch" or "system-image-target" to the strategy matrix with its overriding value. - default_system-image-arch: x86_64 - default_system-image-target: google_apis # Most system images have a google_api option. Set this as default. - - # configurations for each testing strategy (test matrix) - strategy: - matrix: - versions: - # Test the lowest minimum supported APIs - - android: 7 - android-api: 24 - - # Test the last 3-4 supported APIs - - android: 10 - android-api: 29 - - - android: 11 - android-api: 30 - - - android: 12L - android-api: 32 - - - android: 13 - android-api: 33 - - timeout-minutes: 60 - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: ${{ env.node-version }} - - uses: actions/setup-java@v3 - env: - java-version: ${{ matrix.versions.java-version == '' && env.default_java-version || matrix.versions.java-version }} - java-distro: ${{ matrix.versions.java-distro == '' && env.default_java-distro || matrix.versions.java-distro }} - with: - distribution: ${{ env.java-distro }} - java-version: ${{ env.java-version }} - - - name: Run Environment Information - run: | - node --version - npm --version - java -version - - - name: Run npm install - run: | - export PATH="/usr/local/lib/android/sdk/platform-tools":$PATH - export JAVA_HOME=$JAVA_HOME_11_X64 - npm i -g cordova@latest - npm ci - - - name: Run paramedic install - if: ${{ endswith(env.repo, '/cordova-paramedic') != true }} - run: npm i -g github:apache/cordova-paramedic - - - uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b - env: - system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }} - system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }} - with: - api-level: ${{ matrix.versions.android-api }} - target: ${{ env.system-image-target }} - arch: ${{ env.system-image-arch }} - force-avd-creation: false - disable-animations: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim - script: echo "Pregenerate the AVD before running Paramedic" - - - name: Run paramedic tests - uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b - env: - system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }} - system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }} - test_config: 'android-${{ matrix.versions.android }}.config.json' - # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed. - test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }} - paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }} - with: - api-level: ${{ matrix.versions.android-api }} - target: ${{ env.system-image-target }} - arch: ${{ env.system-image-arch }} - force-avd-creation: false - disable-animations: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim - script: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }} diff --git a/.github/workflows/chrome.yml b/.github/workflows/chrome.yml deleted file mode 100644 index 72c92ff9..00000000 --- a/.github/workflows/chrome.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -name: Chrome Testsuite - -on: - push: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - pull_request: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - -jobs: - test: - name: Chrome Latest Test - runs-on: ubuntu-latest - - # hoist configurations to top that are expected to be updated - env: - # Storing a copy of the repo - repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - - node-version: 16 - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: ${{ env.node-version }} - - - name: Run install xvfb - run: sudo apt-get install xvfb - - - name: Run Environment Information - run: | - node --version - npm --version - - - name: Run npm install - run: | - npm i -g cordova@latest - npm ci - - - name: Run paramedic install - if: ${{ endswith(env.repo, '/cordova-paramedic') != true }} - run: npm i -g github:apache/cordova-paramedic - - - name: Run paramedic tests - env: - test_config: 'browser.config.json' - # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed. - test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }} - paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }} - run: xvfb-run --auto-servernum ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }} diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml deleted file mode 100644 index fc293b7f..00000000 --- a/.github/workflows/ios.yml +++ /dev/null @@ -1,101 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -name: iOS Testsuite - -on: - push: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - pull_request: - paths-ignore: - - '**.md' - - 'LICENSE' - - '.eslint*' - -jobs: - test: - name: iOS ${{ matrix.versions.ios-version }} Test - runs-on: ${{ matrix.versions.os-version }} - continue-on-error: true - - # hoist configurations to top that are expected to be updated - env: - # Storing a copy of the repo - repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - - node-version: 16 - - # > Starting April 26, 2021, all iOS and iPadOS apps submitted to the App Store must be built with Xcode 12 and the iOS 14 SDK. - # Because of Apple's requirement, listed above, We will only be using the latest Xcode release for testing. - # To customize these options, add "xcode-version" to the strategy matrix with its overriding value. - default_xcode-version: latest-stable - - strategy: - matrix: - versions: - - os-version: macos-11 - ios-version: 13.x - xcode-version: 11.x - - - os-version: macos-11 - ios-version: 14.x - xcode-version: 12.x - - - os-version: macos-11 - ios-version: 15.x - xcode-version: 13.x - - - os-version: macos-12 - ios-version: 16.x - xcode-version: 14.x - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: ${{ env.node-version }} - - uses: maxim-lobanov/setup-xcode@9a697e2b393340c3cacd97468baa318e4c883d98 - env: - xcode-version: ${{ matrix.versions.xcode-version == '' && env.default_xcode-version || matrix.versions.xcode-version }} - with: - xcode-version: ${{ env.xcode-version }} - - - name: Run Environment Information - run: | - node --version - npm --version - xcodebuild -version - - - name: Run npm install - run: | - npm i -g cordova@latest ios-deploy@latest - npm ci - - - name: Run paramedic install - if: ${{ endswith(env.repo, '/cordova-paramedic') != true }} - run: npm i -g github:apache/cordova-paramedic - - - name: Run paramedic tests - env: - test_config: 'ios-${{ matrix.versions.ios-version }}.config.json' - # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed. - test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }} - paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }} - run: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 0f82eb4c..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -name: Lint Test - -on: - push: - paths: - - '**.js' - - '.eslint*' - - '.github/workflow/lint.yml' - pull_request: - paths: - - '**.js' - - '.eslint*' - - '.github/workflow/lint.yml' - -jobs: - test: - name: Lint Test - runs-on: ubuntu-latest - env: - node-version: 16 - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: ${{ env.node-version }} - - - name: Run Environment Information - run: | - node --version - npm --version - - - name: Run npm install - run: | - npm ci - - - name: Run lint test - run: | - npm run lint diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml new file mode 100644 index 00000000..95c3b121 --- /dev/null +++ b/.github/workflows/publish-npm.yml @@ -0,0 +1,17 @@ +name: Publish NPM +on: + release: + types: [created] +jobs: + publish-npm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/package-lock.json b/package-lock.json index 8aa5c043..70412080 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "cordova-plugin-file", + "name": "@ns0m/cordova-plugin-file", "version": "8.0.1-dev", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "cordova-plugin-file", + "name": "@ns0m/cordova-plugin-file", "version": "8.0.1-dev", "license": "Apache-2.0", "devDependencies": { diff --git a/package.json b/package.json index b5cbd29e..bc1f9427 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "cordova-plugin-file", + "name": "@ns0m/cordova-plugin-file", "version": "8.0.1-dev", "description": "Cordova File Plugin", "types": "./types/index.d.ts", "cordova": { - "id": "cordova-plugin-file", + "id": "@ns0m/cordova-plugin-file", "platforms": [ "android", "browser", @@ -13,8 +13,8 @@ "windows" ] }, - "repository": "github:apache/cordova-plugin-file", - "bugs": "https://github.com/apache/cordova-plugin-file/issues", + "repository": "github:ns0m/cordova-plugin-file", + "bugs": "https://github.com/ns0m/cordova-plugin-file/issues", "keywords": [ "cordova", "file", From c527a6d8bd92e5c5723e7253b345df0c54a49ffe Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 02:41:41 +0200 Subject: [PATCH 4/9] release version 8.0.1-1 --- package-lock.json | 4 ++-- package.json | 2 +- plugin.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70412080..ff03756c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-dev", + "version": "8.0.1-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-dev", + "version": "8.0.1-1", "license": "Apache-2.0", "devDependencies": { "@cordova/eslint-config": "^5.0.0" diff --git a/package.json b/package.json index bc1f9427..ee709e65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-dev", + "version": "8.0.1-1", "description": "Cordova File Plugin", "types": "./types/index.d.ts", "cordova": { diff --git a/plugin.xml b/plugin.xml index a4c55e2f..574923be 100644 --- a/plugin.xml +++ b/plugin.xml @@ -21,7 +21,7 @@ + version="8.0.1-1"> File Cordova File Plugin Apache 2.0 From 26ed4faaf8701f486d7748c8304fd9efb9025acb Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 02:54:27 +0200 Subject: [PATCH 5/9] chore: restore cordova.id in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee709e65..b8e5c475 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Cordova File Plugin", "types": "./types/index.d.ts", "cordova": { - "id": "@ns0m/cordova-plugin-file", + "id": "cordova-plugin-file", "platforms": [ "android", "browser", From 9d1950cd22e5353fb28bddeaa6509f4c38aa22cf Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 02:54:58 +0200 Subject: [PATCH 6/9] release version 8.0.1-2 --- package-lock.json | 4 ++-- package.json | 2 +- plugin.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff03756c..1ba04747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-1", + "version": "8.0.1-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-1", + "version": "8.0.1-2", "license": "Apache-2.0", "devDependencies": { "@cordova/eslint-config": "^5.0.0" diff --git a/package.json b/package.json index b8e5c475..6208825b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-1", + "version": "8.0.1-2", "description": "Cordova File Plugin", "types": "./types/index.d.ts", "cordova": { diff --git a/plugin.xml b/plugin.xml index 574923be..5d29c5ce 100644 --- a/plugin.xml +++ b/plugin.xml @@ -21,7 +21,7 @@ + version="8.0.1-2"> File Cordova File Plugin Apache 2.0 From ecf48bd9ef36e026d934437610cdb1f556638d28 Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 13:37:16 +0200 Subject: [PATCH 7/9] release version 8.0.1- --- package-lock.json | 4 ++-- package.json | 2 +- plugin.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ba04747..4bc6ba25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-2", + "version": "8.0.1-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-2", + "version": "8.0.1-3", "license": "Apache-2.0", "devDependencies": { "@cordova/eslint-config": "^5.0.0" diff --git a/package.json b/package.json index 6208825b..5a62203e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ns0m/cordova-plugin-file", - "version": "8.0.1-2", + "version": "8.0.1-3", "description": "Cordova File Plugin", "types": "./types/index.d.ts", "cordova": { diff --git a/plugin.xml b/plugin.xml index 5d29c5ce..a4c55e2f 100644 --- a/plugin.xml +++ b/plugin.xml @@ -21,7 +21,7 @@ + version="8.0.1-dev"> File Cordova File Plugin Apache 2.0 From f53f21b64d40edc89258843ae74c28512bc9e9d3 Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Fri, 25 Aug 2023 13:41:08 +0200 Subject: [PATCH 8/9] release version 8.0.1-3 From 68856d5c0a1fef41d34e0936432b5c40a20bf3ed Mon Sep 17 00:00:00 2001 From: Alexis THOMAS Date: Wed, 30 Aug 2023 23:56:38 +0200 Subject: [PATCH 9/9] fix: replace deprecated StatFs functions `getAvailableBytes` is available since api 18 while current cordova-android must be >=12.0.0, so minSdk 24 --- src/android/DirectoryManager.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/android/DirectoryManager.java b/src/android/DirectoryManager.java index 07af5ea2..d1bce613 100644 --- a/src/android/DirectoryManager.java +++ b/src/android/DirectoryManager.java @@ -84,9 +84,7 @@ public static long getFreeExternalStorageSpace() { public static long getFreeSpaceInBytes(String path) { try { StatFs stat = new StatFs(path); - long blockSize = stat.getBlockSize(); - long availableBlocks = stat.getAvailableBlocks(); - return availableBlocks * blockSize; + return stat.getAvailableBytes(); } catch (IllegalArgumentException e) { // The path was invalid. Just return 0 free bytes. return 0;