Merge changes I81b41460,I81561c19
* changes: DSU service: Show which partition is being installed in notification DSU service: Weighted progress bar
This commit is contained in:
@@ -112,18 +112,20 @@ public class DynamicSystemInstallationService extends Service
|
||||
private static final int EVENT_DSU_INSTALL_FAILED = 120002;
|
||||
|
||||
protected static void logEventProgressUpdate(
|
||||
String partition,
|
||||
long installedSize,
|
||||
long partitionSize,
|
||||
String partitionName,
|
||||
long installedBytes,
|
||||
long totalBytes,
|
||||
int partitionNumber,
|
||||
int totalPartitionNumber) {
|
||||
int totalPartitionNumber,
|
||||
int totalProgressPercentage) {
|
||||
EventLog.writeEvent(
|
||||
EVENT_DSU_PROGRESS_UPDATE,
|
||||
partition,
|
||||
installedSize,
|
||||
partitionSize,
|
||||
partitionName,
|
||||
installedBytes,
|
||||
totalBytes,
|
||||
partitionNumber,
|
||||
totalPartitionNumber);
|
||||
totalPartitionNumber,
|
||||
totalProgressPercentage);
|
||||
}
|
||||
|
||||
protected static void logEventComplete() {
|
||||
@@ -231,10 +233,11 @@ public class DynamicSystemInstallationService extends Service
|
||||
public void onProgressUpdate(InstallationAsyncTask.Progress progress) {
|
||||
logEventProgressUpdate(
|
||||
progress.partitionName,
|
||||
progress.installedSize,
|
||||
progress.partitionSize,
|
||||
progress.installedBytes,
|
||||
progress.totalBytes,
|
||||
progress.partitionNumber,
|
||||
progress.totalPartitionNumber);
|
||||
progress.totalPartitionNumber,
|
||||
progress.totalProgressPercentage);
|
||||
|
||||
mInstallTaskProgress = progress;
|
||||
postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED, null);
|
||||
@@ -483,23 +486,46 @@ public class DynamicSystemInstallationService extends Service
|
||||
|
||||
switch (status) {
|
||||
case STATUS_IN_PROGRESS:
|
||||
builder.setContentText(getString(R.string.notification_install_inprogress));
|
||||
String msgInProgress = getString(R.string.notification_install_inprogress);
|
||||
|
||||
if (mInstallTaskProgress != null) {
|
||||
int max = 1024;
|
||||
int progress = 0;
|
||||
if (mInstallTaskProgress == null) {
|
||||
builder.setContentText(msgInProgress);
|
||||
} else {
|
||||
if (mInstallTaskProgress.totalPartitionNumber > 0) {
|
||||
builder.setContentText(
|
||||
String.format(
|
||||
"%s: %s partition [%d/%d]",
|
||||
msgInProgress,
|
||||
mInstallTaskProgress.partitionName,
|
||||
mInstallTaskProgress.partitionNumber,
|
||||
mInstallTaskProgress.totalPartitionNumber));
|
||||
|
||||
int currentMax = max >> mInstallTaskProgress.partitionNumber;
|
||||
progress = max - currentMax * 2;
|
||||
// totalProgressPercentage is defined iff totalPartitionNumber is defined
|
||||
builder.setProgress(
|
||||
100,
|
||||
mInstallTaskProgress.totalProgressPercentage,
|
||||
/* indeterminate = */ false);
|
||||
} else {
|
||||
builder.setContentText(
|
||||
String.format(
|
||||
"%s: %s partition",
|
||||
msgInProgress, mInstallTaskProgress.partitionName));
|
||||
|
||||
long currentProgress =
|
||||
(mInstallTaskProgress.installedSize >> 20)
|
||||
* currentMax
|
||||
/ Math.max(mInstallTaskProgress.partitionSize >> 20, 1);
|
||||
int max = 1024;
|
||||
int progress = 0;
|
||||
|
||||
progress += (int) currentProgress;
|
||||
int currentMax = max >> mInstallTaskProgress.partitionNumber;
|
||||
progress = max - currentMax * 2;
|
||||
|
||||
builder.setProgress(max, progress, false);
|
||||
long currentProgress =
|
||||
(mInstallTaskProgress.installedBytes >> 20)
|
||||
* currentMax
|
||||
/ Math.max(mInstallTaskProgress.totalBytes >> 20, 1);
|
||||
|
||||
progress += (int) currentProgress;
|
||||
|
||||
builder.setProgress(max, progress, false);
|
||||
}
|
||||
}
|
||||
builder.addAction(new Notification.Action.Builder(
|
||||
null, getString(R.string.notification_action_cancel),
|
||||
@@ -609,10 +635,11 @@ public class DynamicSystemInstallationService extends Service
|
||||
if (status == STATUS_IN_PROGRESS && mInstallTaskProgress != null) {
|
||||
msg.append(
|
||||
String.format(
|
||||
", partition name: %s, progress: %d/%d",
|
||||
", partition name: %s, progress: %d/%d, total_progress: %d%%",
|
||||
mInstallTaskProgress.partitionName,
|
||||
mInstallTaskProgress.installedSize,
|
||||
mInstallTaskProgress.partitionSize));
|
||||
mInstallTaskProgress.installedBytes,
|
||||
mInstallTaskProgress.totalBytes,
|
||||
mInstallTaskProgress.totalProgressPercentage));
|
||||
}
|
||||
if (detail != null) {
|
||||
msg.append(", detail: " + detail);
|
||||
@@ -639,7 +666,7 @@ public class DynamicSystemInstallationService extends Service
|
||||
// TODO: send more info to the clients
|
||||
if (mInstallTaskProgress != null) {
|
||||
bundle.putLong(
|
||||
DynamicSystemClient.KEY_INSTALLED_SIZE, mInstallTaskProgress.installedSize);
|
||||
DynamicSystemClient.KEY_INSTALLED_SIZE, mInstallTaskProgress.installedBytes);
|
||||
}
|
||||
|
||||
if (detail != null) {
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
option java_package com.android.dynsystem
|
||||
|
||||
120000 dsu_progress_update (partition|3),(installed_size|2|5),(partition_size|2|5),(partition_number|1|5),(total_partition_number|1|5)
|
||||
120000 dsu_progress_update (partition_name|3),(installed_bytes|2|5),(total_bytes|2|5),(partition_number|1|5),(total_partition_number|1|5),(total_progress_percentage|1|5)
|
||||
120001 dsu_install_complete
|
||||
120002 dsu_install_failed (cause|3)
|
||||
|
||||
@@ -113,22 +113,25 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
|
||||
static class Progress {
|
||||
public final String partitionName;
|
||||
public final long installedSize;
|
||||
public final long partitionSize;
|
||||
public final long installedBytes;
|
||||
public final long totalBytes;
|
||||
public final int partitionNumber;
|
||||
public final int totalPartitionNumber;
|
||||
public final int totalProgressPercentage;
|
||||
|
||||
Progress(
|
||||
String partitionName,
|
||||
long installedSize,
|
||||
long partitionSize,
|
||||
long installedBytes,
|
||||
long totalBytes,
|
||||
int partitionNumber,
|
||||
int totalPartitionNumber) {
|
||||
int totalPartitionNumber,
|
||||
int totalProgressPercentage) {
|
||||
this.partitionName = partitionName;
|
||||
this.installedSize = installedSize;
|
||||
this.partitionSize = partitionSize;
|
||||
this.installedBytes = installedBytes;
|
||||
this.totalBytes = totalBytes;
|
||||
this.partitionNumber = partitionNumber;
|
||||
this.totalPartitionNumber = totalPartitionNumber;
|
||||
this.totalProgressPercentage = totalProgressPercentage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,20 +152,28 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
private final ProgressListener mListener;
|
||||
private final boolean mIsNetworkUrl;
|
||||
private final boolean mIsDeviceBootloaderUnlocked;
|
||||
private final boolean mWantScratchPartition;
|
||||
private DynamicSystemManager.Session mInstallationSession;
|
||||
private KeyRevocationList mKeyRevocationList;
|
||||
|
||||
private boolean mIsZip;
|
||||
private boolean mIsCompleted;
|
||||
|
||||
private String mPartitionName;
|
||||
private long mPartitionSize;
|
||||
private int mPartitionNumber;
|
||||
private int mTotalPartitionNumber;
|
||||
|
||||
private InputStream mStream;
|
||||
private ZipFile mZipFile;
|
||||
|
||||
private static final double PROGRESS_READONLY_PARTITION_WEIGHT = 0.8;
|
||||
private static final double PROGRESS_WRITABLE_PARTITION_WEIGHT = 0.2;
|
||||
|
||||
private String mProgressPartitionName;
|
||||
private long mProgressTotalBytes;
|
||||
private int mProgressPartitionNumber;
|
||||
private boolean mProgressPartitionIsReadonly;
|
||||
private int mProgressCompletedReadonlyPartitions;
|
||||
private int mProgressCompletedWritablePartitions;
|
||||
private int mTotalReadonlyPartitions;
|
||||
private int mTotalWritablePartitions;
|
||||
private int mTotalPartitionNumber;
|
||||
|
||||
InstallationAsyncTask(
|
||||
String url,
|
||||
String dsuSlot,
|
||||
@@ -193,21 +204,18 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
(pdbManager != null)
|
||||
&& (pdbManager.getFlashLockState()
|
||||
== PersistentDataBlockManager.FLASH_LOCK_UNLOCKED);
|
||||
mWantScratchPartition = Build.IS_DEBUGGABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Throwable doInBackground(String... voids) {
|
||||
Log.d(TAG, "Start doInBackground(), URL: " + mUrl);
|
||||
|
||||
final boolean wantScratchPartition = Build.IS_DEBUGGABLE;
|
||||
try {
|
||||
// call DynamicSystemManager to cleanup stuff
|
||||
mDynSystem.remove();
|
||||
|
||||
verifyAndPrepare();
|
||||
if (wantScratchPartition) {
|
||||
++mTotalPartitionNumber;
|
||||
}
|
||||
|
||||
mDynSystem.startInstallation(mDsuSlot);
|
||||
|
||||
@@ -226,7 +234,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (wantScratchPartition) {
|
||||
if (mWantScratchPartition) {
|
||||
// If host is debuggable, then install a scratch partition so that we can do
|
||||
// adb remount in the guest system.
|
||||
try {
|
||||
@@ -290,14 +298,54 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Long... installedSize) {
|
||||
protected void onProgressUpdate(Long... progress) {
|
||||
final long installedBytes = progress[0];
|
||||
int totalProgressPercentage = 0;
|
||||
if (mTotalPartitionNumber > 0) {
|
||||
final double readonlyPartitionWeight =
|
||||
mTotalReadonlyPartitions > 0
|
||||
? PROGRESS_READONLY_PARTITION_WEIGHT / mTotalReadonlyPartitions
|
||||
: 0;
|
||||
final double writablePartitionWeight =
|
||||
mTotalWritablePartitions > 0
|
||||
? PROGRESS_WRITABLE_PARTITION_WEIGHT / mTotalWritablePartitions
|
||||
: 0;
|
||||
double totalProgress = 0.0;
|
||||
if (mProgressTotalBytes > 0) {
|
||||
totalProgress +=
|
||||
(mProgressPartitionIsReadonly
|
||||
? readonlyPartitionWeight
|
||||
: writablePartitionWeight)
|
||||
* installedBytes
|
||||
/ mProgressTotalBytes;
|
||||
}
|
||||
totalProgress += readonlyPartitionWeight * mProgressCompletedReadonlyPartitions;
|
||||
totalProgress += writablePartitionWeight * mProgressCompletedWritablePartitions;
|
||||
totalProgressPercentage = (int) (totalProgress * 100);
|
||||
}
|
||||
mListener.onProgressUpdate(
|
||||
new Progress(
|
||||
mPartitionName,
|
||||
installedSize[0],
|
||||
mPartitionSize,
|
||||
mPartitionNumber,
|
||||
mTotalPartitionNumber));
|
||||
mProgressPartitionName,
|
||||
installedBytes,
|
||||
mProgressTotalBytes,
|
||||
mProgressPartitionNumber,
|
||||
mTotalPartitionNumber,
|
||||
totalProgressPercentage));
|
||||
}
|
||||
|
||||
private void initPartitionProgress(String partitionName, long totalBytes, boolean readonly) {
|
||||
if (mProgressPartitionNumber > 0) {
|
||||
// Assume previous partition completed successfully.
|
||||
if (mProgressPartitionIsReadonly) {
|
||||
++mProgressCompletedReadonlyPartitions;
|
||||
} else {
|
||||
++mProgressCompletedWritablePartitions;
|
||||
}
|
||||
}
|
||||
mProgressPartitionName = partitionName;
|
||||
mProgressTotalBytes = totalBytes;
|
||||
mProgressPartitionIsReadonly = readonly;
|
||||
++mProgressPartitionNumber;
|
||||
}
|
||||
|
||||
private void verifyAndPrepare() throws Exception {
|
||||
@@ -314,16 +362,12 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
throw new UnsupportedFormatException(
|
||||
String.format(Locale.US, "Unsupported file format: %s", mUrl));
|
||||
}
|
||||
// At least two partitions, {system, userdata}
|
||||
mTotalPartitionNumber = 2;
|
||||
|
||||
if (mIsNetworkUrl) {
|
||||
mStream = new URL(mUrl).openStream();
|
||||
} else if (URLUtil.isFileUrl(mUrl)) {
|
||||
if (mIsZip) {
|
||||
mZipFile = new ZipFile(new File(new URL(mUrl).toURI()));
|
||||
// {*.img in zip} + {userdata}
|
||||
mTotalPartitionNumber = calculateNumberOfImagesInLocalZip(mZipFile) + 1;
|
||||
} else {
|
||||
mStream = new URL(mUrl).openStream();
|
||||
}
|
||||
@@ -334,6 +378,32 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
String.format(Locale.US, "Unsupported URL: %s", mUrl));
|
||||
}
|
||||
|
||||
boolean hasTotalPartitionNumber = false;
|
||||
if (mIsZip) {
|
||||
if (mZipFile != null) {
|
||||
// {*.img in zip} + {userdata}
|
||||
hasTotalPartitionNumber = true;
|
||||
mTotalReadonlyPartitions = calculateNumberOfImagesInLocalZip(mZipFile);
|
||||
mTotalWritablePartitions = 1;
|
||||
} else {
|
||||
// TODO: Come up with a way to retrieve the number of total partitions from
|
||||
// network URL.
|
||||
}
|
||||
} else {
|
||||
// gzip has exactly two partitions, {system, userdata}
|
||||
hasTotalPartitionNumber = true;
|
||||
mTotalReadonlyPartitions = 1;
|
||||
mTotalWritablePartitions = 1;
|
||||
}
|
||||
|
||||
if (hasTotalPartitionNumber) {
|
||||
if (mWantScratchPartition) {
|
||||
// {scratch}
|
||||
++mTotalWritablePartitions;
|
||||
}
|
||||
mTotalPartitionNumber = mTotalReadonlyPartitions + mTotalWritablePartitions;
|
||||
}
|
||||
|
||||
try {
|
||||
String listUrl = mContext.getString(R.string.key_revocation_list_url);
|
||||
mKeyRevocationList = KeyRevocationList.fromUrl(new URL(listUrl));
|
||||
@@ -370,9 +440,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
}
|
||||
};
|
||||
|
||||
mPartitionName = partitionName;
|
||||
mPartitionSize = partitionSize;
|
||||
++mPartitionNumber;
|
||||
initPartitionProgress(partitionName, partitionSize, /* readonly = */ false);
|
||||
publishProgress(/* installedSize = */ 0L);
|
||||
|
||||
long prevInstalledSize = 0;
|
||||
@@ -396,6 +464,10 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
}
|
||||
}
|
||||
|
||||
if (prevInstalledSize != partitionSize) {
|
||||
publishProgress(partitionSize);
|
||||
}
|
||||
|
||||
if (mInstallationSession == null) {
|
||||
throw new IOException(
|
||||
"Failed to start installation with requested size: " + partitionSize);
|
||||
@@ -559,9 +631,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
|
||||
mInstallationSession.setAshmem(pfd, memoryFile.length());
|
||||
|
||||
mPartitionName = partitionName;
|
||||
mPartitionSize = partitionSize;
|
||||
++mPartitionNumber;
|
||||
initPartitionProgress(partitionName, partitionSize, /* readonly = */ true);
|
||||
publishProgress(/* installedSize = */ 0L);
|
||||
|
||||
long prevInstalledSize = 0;
|
||||
@@ -588,6 +658,10 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
|
||||
}
|
||||
}
|
||||
|
||||
if (prevInstalledSize != partitionSize) {
|
||||
publishProgress(partitionSize);
|
||||
}
|
||||
|
||||
AvbPublicKey avbPublicKey = new AvbPublicKey();
|
||||
if (!mInstallationSession.getAvbPublicKey(avbPublicKey)) {
|
||||
imageValidationThrowOrWarning(new PublicKeyException("getAvbPublicKey() failed"));
|
||||
|
||||
Reference in New Issue
Block a user