Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9DE2A10A9A for ; Mon, 10 Feb 2014 23:26:34 +0000 (UTC) Received: (qmail 79031 invoked by uid 500); 10 Feb 2014 23:23:12 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 78158 invoked by uid 500); 10 Feb 2014 23:22:45 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 77538 invoked by uid 99); 10 Feb 2014 23:22:29 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 Feb 2014 23:22:29 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id A06E4922DF9; Mon, 10 Feb 2014 23:22:28 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: steven@apache.org To: commits@cordova.apache.org Date: Mon, 10 Feb 2014 23:23:01 -0000 Message-Id: In-Reply-To: <4f6ca4f3c16b4269bc790ad4ed976363@git.apache.org> References: <4f6ca4f3c16b4269bc790ad4ed976363@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [35/50] git commit: CB-5916: Android: Add config preference for Android persistent storage location CB-5916: Android: Add config preference for Android persistent storage location Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/3fa16d04 Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/3fa16d04 Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/3fa16d04 Branch: refs/heads/master Commit: 3fa16d04cd1b5e68ad8075c22ba549c4fa24fff5 Parents: aaadfec Author: Ian Clelland Authored: Mon Jan 27 23:29:44 2014 -0500 Committer: Ian Clelland Committed: Tue Jan 28 09:52:09 2014 -0500 ---------------------------------------------------------------------- doc/index.md | 41 +++++++++++++++++++++++ src/android/FileUtils.java | 73 +++++++++++++++++++++++++++-------------- 2 files changed, 89 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/3fa16d04/doc/index.md ---------------------------------------------------------------------- diff --git a/doc/index.md b/doc/index.md index 192cae5..003ba0e 100644 --- a/doc/index.md +++ b/doc/index.md @@ -39,6 +39,47 @@ on the subject. For an overview of other storage options, refer to Cordova's \* _These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`._ +## Android Quirks + +### Android Persistent storage location + +There are multiple valid locations to store persistent files on an Android +device. See [this page](http://developer.android.com/guide/topics/data/data-storage.html) +for an extensive discussion of the various possibilities. + +Previous versions of thie plugin would choose the location of the temporary and +persistent files on startup, based on whether the device claimed that the SD +Card (or equivalent storage partition) was mounted. If the SD Card was mounted, +or if a large internal storage partition was available (such as on Nexus +devices,) then the persistent files would be stored in the root of that space. +This meant that all Cordova apps could see all of the files available on the +card. + +If the SD card was not available, then previous versions would store data under +/data/data/, which isolates apps from each other, but may still +cause data to be shared between users. + +It is now possible to choose whether to store files in the internal file +storage location, or using the previous logic, with a preference in your +application's config.xml file. To do this, add one of these two lines to +config.xml: + + + + + +Without this line, the File plugin will not initialize, and your application +will not start. + +If your application has previously been shipped to users, using an older (pre- +1.0) version of this plugin, and has stored files in the persistent filesystem, +then you should set the preference to "Compatibility". Switching the location to +"Internal" would mean that existing users who upgrade their application may be +unable to access their previously-stored files, depending on their device. + +If your application is new, or has never previously stored files in the +persistent filesystem, then the "internal" setting is generally recommended. + ## BlackBerry Quirks `DirectoryEntry.removeRecursively()` may fail with a `ControlledAccessException` in the following cases: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/3fa16d04/src/android/FileUtils.java ---------------------------------------------------------------------- diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java index ac24413..7983be1 100644 --- a/src/android/FileUtils.java +++ b/src/android/FileUtils.java @@ -18,6 +18,7 @@ */ package org.apache.cordova.file; +import android.app.Activity; import android.net.Uri; import android.os.Environment; import android.util.Base64; @@ -93,33 +94,55 @@ public class FileUtils extends CordovaPlugin { public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); this.filesystems = new ArrayList(); + + String tempRoot = null; + String persistentRoot = null; + + Activity activity = cordova.getActivity(); + String packageName = activity.getPackageName(); - File fp; - String tempRoot; - String persistentRoot; - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath(); - tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + - "/Android/data/" + cordova.getActivity().getPackageName() + "/cache/"; - } else { - persistentRoot = "/data/data/" + cordova.getActivity().getPackageName(); - tempRoot = "/data/data/" + cordova.getActivity().getPackageName() + "/cache/"; + String location = activity.getIntent().getStringExtra("androidpersistentfilelocation"); + if (!(location.equalsIgnoreCase("internal") || location.equalsIgnoreCase("compatibility"))) { + 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(); } - // Create the cache dir if it doesn't exist. - fp = new File(tempRoot); - fp.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", cordova, tempRoot)); - this.registerFilesystem(new LocalFilesystem("persistent", cordova, persistentRoot)); - this.registerFilesystem(new ContentFilesystem("content", cordova, webView)); - - // Initialize static plugin reference for deprecated getEntry method - if (filePlugin == null) { - FileUtils.filePlugin = this; + else { + if (location.equalsIgnoreCase("internal")) { + persistentRoot = activity.getFilesDir().getAbsolutePath(); + tempRoot = activity.getCacheDir().getAbsolutePath(); + } else { + /* + * 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. + */ + File fp; + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath(); + tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + + "/Android/data/" + packageName + "/cache/"; + } else { + persistentRoot = "/data/data/" + packageName; + tempRoot = "/data/data/" + packageName + "/cache/"; + } + // Create the cache dir if it doesn't exist. + fp = new File(tempRoot); + fp.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", cordova, tempRoot)); + this.registerFilesystem(new LocalFilesystem("persistent", cordova, persistentRoot)); + this.registerFilesystem(new ContentFilesystem("content", cordova, webView)); + + // Initialize static plugin reference for deprecated getEntry method + if (filePlugin == null) { + FileUtils.filePlugin = this; + } } }