From 407f625a9b8e356e765a5ec587c443af1f3aadb5 Mon Sep 17 00:00:00 2001
From: Dianne Hackborn
Date: Mon, 4 Oct 2010 11:31:17 -0700
Subject: [PATCH] Add new API to find out whether external storage is
removable.
This is implemented based on whether we are using the "nosdcard"
product. Needed to tweak aapt to allow use of the product attribute
with other resource definition tags besides strings.
Change-Id: I49922d23b52a34183a8e2f4d2515adaf1fc9149a
---
api/current.xml | 11 ++++++++
core/java/android/os/Environment.java | 36 ++++++++++++++++++++++++---
core/res/res/values/config.xml | 9 +++++++
tools/aapt/ResourceTable.cpp | 18 ++++++++------
4 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/api/current.xml b/api/current.xml
index 03fc03a06f831..bffdccce73854 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -123739,6 +123739,17 @@
visibility="public"
>
+
+
Note: don't be confused by the word "external" here. This
+ * directory can better be thought as media/shared storage. It is a
+ * filesystem that can hold a relatively large amount of data and that
+ * is shared across all applications (does not enforce permissions).
+ * Traditionally this is an SD card, but it may also be implemented as
+ * built-in storage in a device that is distinct from the protected
+ * internal storage and can be mounted as a filesystem on a computer.
+ *
+ * In devices with multiple "external" storage directories (such as
+ * both secure app storage and mountable shared storage), this directory
+ * represents the "primary" external storage that the user will interact
+ * with.
+ *
* Applications should not directly use this top-level directory, in
* order to avoid polluting the user's root namespace. Any files that are
* private to the application should be placed in a directory returned
@@ -130,6 +144,9 @@ public class Environment {
*
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* monitor_storage}
+ *
+ * @see #getExternalStorageState()
+ * @see #isExternalStorageRemovable()
*/
public static File getExternalStorageDirectory() {
return EXTERNAL_STORAGE_DIRECTORY;
@@ -359,11 +376,9 @@ public class Environment {
public static final String MEDIA_UNMOUNTABLE = "unmountable";
/**
- * Gets the current state of the external storage device.
- * Note: This call should be deprecated as it doesn't support
- * multiple volumes.
+ * Gets the current state of the primary "external" storage device.
*
- *
See {@link #getExternalStorageDirectory()} for an example of its use.
+ *
See {@link #getExternalStorageDirectory()} for more information.
*/
public static String getExternalStorageState() {
try {
@@ -377,6 +392,19 @@ public class Environment {
}
}
+ /**
+ * Returns whether the primary "external" storage device is removable.
+ * If true is returned, this device is for example an SD card that the
+ * user can remove. If false is returned, the storage is built into
+ * the device and can not be physically removed.
+ *
+ *
See {@link #getExternalStorageDirectory()} for more information.
+ */
+ public static boolean isExternalStorageRemovable() {
+ return Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_externalStorageRemovable);
+ }
+
static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d120dd0548e2d..6e6dc26dac84e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -71,6 +71,15 @@
when there's no network connection. If the scan doesn't timeout, use zero -->
0
+
+ false
+
+ true
+
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 532fb653804c6..29644a69b4c7b 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -782,7 +782,6 @@ status_t compileResourceFile(Bundle* bundle,
const String16 translatable16("translatable");
const String16 formatted16("formatted");
const String16 false16("false");
- const String16 product16("product");
const String16 myPackage(assets->getPackage());
@@ -830,7 +829,6 @@ status_t compileResourceFile(Bundle* bundle,
bool curIsStyled = false;
bool curIsPseudolocalizable = false;
bool curIsFormatted = fileIsTranslatable;
- String16 curProduct;
bool localHasErrors = false;
if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
@@ -1228,8 +1226,6 @@ status_t compileResourceFile(Bundle* bundle,
translatable.setTo(block.getAttributeStringValue(i, &length));
} else if (strcmp16(attr, formatted16.string()) == 0) {
formatted.setTo(block.getAttributeStringValue(i, &length));
- } else if (strcmp16(attr, product16.string()) == 0) {
- curProduct.setTo(block.getAttributeStringValue(i, &length));
}
}
@@ -1356,6 +1352,12 @@ status_t compileResourceFile(Bundle* bundle,
hasErrors = localHasErrors = true;
}
+ String16 product;
+ identIdx = block.indexOfAttribute(NULL, "product");
+ if (identIdx >= 0) {
+ product = String16(block.getAttributeStringValue(identIdx, &len));
+ }
+
String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
if (curIsBag) {
@@ -1447,7 +1449,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
ident, parentIdent, itemIdent, curFormat, curIsFormatted,
- curProduct, false, overwrite, outTable);
+ product, false, overwrite, outTable);
if (err == NO_ERROR) {
if (curIsPseudolocalizable && localeIsDefined(curParams)
&& bundle->getPseudolocalize()) {
@@ -1456,7 +1458,7 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
curType, ident, parentIdent, itemIdent, curFormat,
- curIsFormatted, curProduct, true, overwrite, outTable);
+ curIsFormatted, product, true, overwrite, outTable);
#endif
}
}
@@ -1480,7 +1482,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
*curTag, curIsStyled, curFormat, curIsFormatted,
- curProduct, false, overwrite, outTable);
+ product, false, overwrite, outTable);
if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
hasErrors = localHasErrors = true;
@@ -1492,7 +1494,7 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
ident, *curTag, curIsStyled, curFormat,
- curIsFormatted, curProduct,
+ curIsFormatted, product,
true, overwrite, outTable);
if (err != NO_ERROR) {
hasErrors = localHasErrors = true;