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
This commit is contained in:
@@ -94,6 +94,8 @@ public final class Sm {
|
||||
runGetFbeMode();
|
||||
} else if ("fstrim".equals(op)) {
|
||||
runFstrim();
|
||||
} else if ("set-virtual-disk".equals(op)) {
|
||||
runSetVirtualDisk();
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@@ -225,6 +227,12 @@ public final class Sm {
|
||||
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 @@ public final class Sm {
|
||||
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");
|
||||
|
||||
@@ -2036,14 +2036,20 @@ public final class Parcel {
|
||||
}
|
||||
}
|
||||
|
||||
/** @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().
|
||||
|
||||
@@ -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.system.StructStat;
|
||||
import android.util.Log;
|
||||
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
import libcore.io.Memory;
|
||||
|
||||
@@ -279,8 +290,28 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
|
||||
"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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -113,6 +113,8 @@ public class StorageManager {
|
||||
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 class StorageManager {
|
||||
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} */
|
||||
|
||||
@@ -2078,6 +2078,20 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user