Add a new "virtual disk" feature.
It's extremely difficult to test storage related logic on devices
that don't have physical SD card slots. So to support better
debugging and testing, add a new "virtual disk" feature which mounts
a 512MB file through loop device.
Also move ParcelFileDescriptor.open() over to using Os.open() so
that it gets StrictMode treatment.
Bug: 34903607
Test: builds, boots, virtual disk works
Change-Id: I072a3a412cfcc8a2a3472919b7273a1ed794fd98
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index db3772d..658d662 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -94,6 +94,8 @@
runGetFbeMode();
} else if ("fstrim".equals(op)) {
runFstrim();
+ } else if ("set-virtual-disk".equals(op)) {
+ runSetVirtualDisk();
} else {
throw new IllegalArgumentException();
}
@@ -225,6 +227,12 @@
mSm.fstrim(0);
}
+ public void runSetVirtualDisk() throws RemoteException {
+ final boolean virtualDisk = Boolean.parseBoolean(nextArg());
+ mSm.setDebugFlags(virtualDisk ? StorageManager.DEBUG_VIRTUAL_DISK : 0,
+ StorageManager.DEBUG_VIRTUAL_DISK);
+ }
+
private String nextArg() {
if (mNextArg >= mArgs.length) {
return null;
@@ -240,6 +248,7 @@
System.err.println(" sm has-adoptable");
System.err.println(" sm get-primary-storage-uuid");
System.err.println(" sm set-force-adoptable [true|false]");
+ System.err.println(" sm set-virtual-disk [true|false]");
System.err.println("");
System.err.println(" sm partition DISK [public|private|mixed] [ratio]");
System.err.println(" sm mount VOLUME");
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 7a39d23..034edcf 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -2036,14 +2036,20 @@
}
}
+ /** @deprecated use {@link android.system.Os#open(String, int, int)} */
+ @Deprecated
+ static native FileDescriptor openFileDescriptor(String file, int mode)
+ throws FileNotFoundException;
- /*package*/ static native FileDescriptor openFileDescriptor(String file,
- int mode) throws FileNotFoundException;
- /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
- throws IOException;
- /*package*/ static native void closeFileDescriptor(FileDescriptor desc)
- throws IOException;
- /*package*/ static native void clearFileDescriptor(FileDescriptor desc);
+ /** @deprecated use {@link android.system.Os#dup(FileDescriptor)} */
+ @Deprecated
+ static native FileDescriptor dupFileDescriptor(FileDescriptor orig) throws IOException;
+
+ /** @deprecated use {@link android.system.Os#close(FileDescriptor)} */
+ @Deprecated
+ static native void closeFileDescriptor(FileDescriptor desc) throws IOException;
+
+ static native void clearFileDescriptor(FileDescriptor desc);
/**
* Read a byte value from the parcel at the current dataPosition().
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 8882672..3212139 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -17,11 +17,21 @@
package android.os;
import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.O_APPEND;
+import static android.system.OsConstants.O_CREAT;
+import static android.system.OsConstants.O_RDONLY;
+import static android.system.OsConstants.O_RDWR;
+import static android.system.OsConstants.O_TRUNC;
+import static android.system.OsConstants.O_WRONLY;
import static android.system.OsConstants.SEEK_SET;
-import static android.system.OsConstants.SOCK_STREAM;
import static android.system.OsConstants.SOCK_SEQPACKET;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.S_IROTH;
+import static android.system.OsConstants.S_IRWXG;
+import static android.system.OsConstants.S_IRWXU;
import static android.system.OsConstants.S_ISLNK;
import static android.system.OsConstants.S_ISREG;
+import static android.system.OsConstants.S_IWOTH;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
@@ -33,6 +43,7 @@
import android.util.Log;
import dalvik.system.CloseGuard;
+
import libcore.io.IoUtils;
import libcore.io.Memory;
@@ -279,8 +290,28 @@
"Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
}
+ int flags = 0;
+ switch (mode & MODE_READ_WRITE) {
+ case 0:
+ case MODE_READ_ONLY: flags = O_RDONLY; break;
+ case MODE_WRITE_ONLY: flags = O_WRONLY; break;
+ case MODE_READ_WRITE: flags = O_RDWR; break;
+ }
+
+ if ((mode & MODE_CREATE) != 0) flags |= O_CREAT;
+ if ((mode & MODE_TRUNCATE) != 0) flags |= O_TRUNC;
+ if ((mode & MODE_APPEND) != 0) flags |= O_APPEND;
+
+ int realMode = S_IRWXU | S_IRWXG;
+ if ((mode & MODE_WORLD_READABLE) != 0) realMode |= S_IROTH;
+ if ((mode & MODE_WORLD_WRITEABLE) != 0) realMode |= S_IWOTH;
+
final String path = file.getPath();
- return Parcel.openFileDescriptor(path, mode);
+ try {
+ return Os.open(path, flags, realMode);
+ } catch (ErrnoException e) {
+ throw new FileNotFoundException(e.getMessage());
+ }
}
/**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 53c9a23..7e1b5ab 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -113,6 +113,8 @@
public static final String PROP_EMULATE_FBE = "persist.sys.emulate_fbe";
/** {@hide} */
public static final String PROP_SDCARDFS = "persist.sys.sdcardfs";
+ /** {@hide} */
+ public static final String PROP_VIRTUAL_DISK = "persist.sys.virtual_disk";
/** {@hide} */
public static final String UUID_PRIVATE_INTERNAL = null;
@@ -140,6 +142,8 @@
public static final int DEBUG_SDCARDFS_FORCE_ON = 1 << 2;
/** {@hide} */
public static final int DEBUG_SDCARDFS_FORCE_OFF = 1 << 3;
+ /** {@hide} */
+ public static final int DEBUG_VIRTUAL_DISK = 1 << 4;
// NOTE: keep in sync with installd
/** {@hide} */
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 8e6310f..9b4b55e 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2078,6 +2078,20 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ if ((mask & StorageManager.DEBUG_VIRTUAL_DISK) != 0) {
+ final boolean enabled = (flags & StorageManager.DEBUG_VIRTUAL_DISK) != 0;
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ SystemProperties.set(StorageManager.PROP_VIRTUAL_DISK, Boolean.toString(enabled));
+
+ // Reset storage to kick new setting into place
+ mHandler.obtainMessage(H_RESET).sendToTarget();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
@Override