Merge changes from topic "cow_pdb"
* changes: Support copy-on-write persistent data block when running a DSU Support PersistentDataBlockService in DSU
This commit is contained in:
@@ -23,6 +23,7 @@ import android.app.ActivityManager;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.FileUtils;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
@@ -103,6 +104,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class PersistentDataBlockService extends SystemService {
|
public class PersistentDataBlockService extends SystemService {
|
||||||
private static final String TAG = PersistentDataBlockService.class.getSimpleName();
|
private static final String TAG = PersistentDataBlockService.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String GSI_SANDBOX = "/data/gsi_persistent_data";
|
||||||
|
private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";
|
||||||
|
|
||||||
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
|
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
|
||||||
private static final int HEADER_SIZE = 8;
|
private static final int HEADER_SIZE = 8;
|
||||||
// Magic number to mark block device as adhering to the format consumed by this service
|
// Magic number to mark block device as adhering to the format consumed by this service
|
||||||
@@ -127,12 +131,13 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
private static final String FLASH_LOCK_UNLOCKED = "0";
|
private static final String FLASH_LOCK_UNLOCKED = "0";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final String mDataBlockFile;
|
private final boolean mIsRunningDSU;
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
private final CountDownLatch mInitDoneSignal = new CountDownLatch(1);
|
private final CountDownLatch mInitDoneSignal = new CountDownLatch(1);
|
||||||
|
|
||||||
private int mAllowedUid = -1;
|
private int mAllowedUid = -1;
|
||||||
private long mBlockDeviceSize;
|
private long mBlockDeviceSize;
|
||||||
|
private String mDataBlockFile;
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private boolean mIsWritable = true;
|
private boolean mIsWritable = true;
|
||||||
@@ -141,6 +146,7 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
super(context);
|
super(context);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
|
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
|
||||||
|
mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false);
|
||||||
mBlockDeviceSize = -1; // Load lazily
|
mBlockDeviceSize = -1; // Load lazily
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,14 +290,28 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FileOutputStream getBlockOutputStream() throws IOException {
|
||||||
|
if (!mIsRunningDSU) {
|
||||||
|
return new FileOutputStream(new File(mDataBlockFile));
|
||||||
|
} else {
|
||||||
|
File sandbox = new File(GSI_SANDBOX);
|
||||||
|
File realpdb = new File(SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP));
|
||||||
|
if (!sandbox.exists()) {
|
||||||
|
FileUtils.copy(realpdb, sandbox);
|
||||||
|
mDataBlockFile = GSI_SANDBOX;
|
||||||
|
}
|
||||||
|
Slog.i(TAG, "PersistentDataBlock copy-on-write");
|
||||||
|
return new FileOutputStream(sandbox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean computeAndWriteDigestLocked() {
|
private boolean computeAndWriteDigestLocked() {
|
||||||
byte[] digest = computeDigestLocked(null);
|
byte[] digest = computeDigestLocked(null);
|
||||||
if (digest != null) {
|
if (digest != null) {
|
||||||
DataOutputStream outputStream;
|
DataOutputStream outputStream;
|
||||||
try {
|
try {
|
||||||
outputStream = new DataOutputStream(
|
outputStream = new DataOutputStream(getBlockOutputStream());
|
||||||
new FileOutputStream(new File(mDataBlockFile)));
|
} catch (IOException e) {
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Slog.e(TAG, "partition not available?", e);
|
Slog.e(TAG, "partition not available?", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -356,8 +376,8 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
private void formatPartitionLocked(boolean setOemUnlockEnabled) {
|
private void formatPartitionLocked(boolean setOemUnlockEnabled) {
|
||||||
DataOutputStream outputStream;
|
DataOutputStream outputStream;
|
||||||
try {
|
try {
|
||||||
outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile)));
|
outputStream = new DataOutputStream(getBlockOutputStream());
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available?", e);
|
Slog.e(TAG, "partition not available?", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -382,8 +402,8 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
private void doSetOemUnlockEnabledLocked(boolean enabled) {
|
private void doSetOemUnlockEnabledLocked(boolean enabled) {
|
||||||
FileOutputStream outputStream;
|
FileOutputStream outputStream;
|
||||||
try {
|
try {
|
||||||
outputStream = new FileOutputStream(new File(mDataBlockFile));
|
outputStream = getBlockOutputStream();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available", e);
|
Slog.e(TAG, "partition not available", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -459,8 +479,8 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
|
|
||||||
DataOutputStream outputStream;
|
DataOutputStream outputStream;
|
||||||
try {
|
try {
|
||||||
outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile)));
|
outputStream = new DataOutputStream(getBlockOutputStream());
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available?", e);
|
Slog.e(TAG, "partition not available?", e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -545,6 +565,17 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
public void wipe() {
|
public void wipe() {
|
||||||
enforceOemUnlockWritePermission();
|
enforceOemUnlockWritePermission();
|
||||||
|
|
||||||
|
if (mIsRunningDSU) {
|
||||||
|
File sandbox = new File(GSI_SANDBOX);
|
||||||
|
if (sandbox.exists()) {
|
||||||
|
if (sandbox.delete()) {
|
||||||
|
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
|
||||||
|
} else {
|
||||||
|
Slog.e(TAG, "Failed to wipe sandbox persistent data block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
int ret = nativeWipe(mDataBlockFile);
|
int ret = nativeWipe(mDataBlockFile);
|
||||||
|
|
||||||
@@ -704,8 +735,8 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
private void writeDataBuffer(long offset, ByteBuffer dataBuffer) {
|
private void writeDataBuffer(long offset, ByteBuffer dataBuffer) {
|
||||||
FileOutputStream outputStream;
|
FileOutputStream outputStream;
|
||||||
try {
|
try {
|
||||||
outputStream = new FileOutputStream(new File(mDataBlockFile));
|
outputStream = getBlockOutputStream();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available", e);
|
Slog.e(TAG, "partition not available", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,8 +332,6 @@ public final class SystemServer {
|
|||||||
private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
|
private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
|
||||||
private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map";
|
private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map";
|
||||||
|
|
||||||
private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";
|
|
||||||
|
|
||||||
// maximum number of binder threads used for system_server
|
// maximum number of binder threads used for system_server
|
||||||
// will be higher than the system default
|
// will be higher than the system default
|
||||||
private static final int sMaxBinderThreads = 31;
|
private static final int sMaxBinderThreads = 31;
|
||||||
@@ -1443,8 +1441,7 @@ public final class SystemServer {
|
|||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
|
|
||||||
final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
|
final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
|
||||||
final boolean hasGsi = SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
|
if (hasPdb) {
|
||||||
if (hasPdb && !hasGsi) {
|
|
||||||
t.traceBegin("StartPersistentDataBlock");
|
t.traceBegin("StartPersistentDataBlock");
|
||||||
mSystemServiceManager.startService(PersistentDataBlockService.class);
|
mSystemServiceManager.startService(PersistentDataBlockService.class);
|
||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
|
|||||||
Reference in New Issue
Block a user