summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java62
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags2
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java142
3 files changed, 146 insertions, 60 deletions
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 02128d480678..98d4cf0d1182 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -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);
@@ -486,20 +489,28 @@ public class DynamicSystemInstallationService extends Service
builder.setContentText(getString(R.string.notification_install_inprogress));
if (mInstallTaskProgress != null) {
- int max = 1024;
- int progress = 0;
+ if (mInstallTaskProgress.totalPartitionNumber > 0) {
+ // totalProgressPercentage is defined iff totalPartitionNumber is defined
+ builder.setProgress(
+ 100,
+ mInstallTaskProgress.totalProgressPercentage,
+ /* indeterminate = */ false);
+ } else {
+ int max = 1024;
+ int progress = 0;
- int currentMax = max >> mInstallTaskProgress.partitionNumber;
- progress = max - currentMax * 2;
+ int currentMax = max >> mInstallTaskProgress.partitionNumber;
+ progress = max - currentMax * 2;
- long currentProgress =
- (mInstallTaskProgress.installedSize >> 20)
- * currentMax
- / Math.max(mInstallTaskProgress.partitionSize >> 20, 1);
+ long currentProgress =
+ (mInstallTaskProgress.installedBytes >> 20)
+ * currentMax
+ / Math.max(mInstallTaskProgress.totalBytes >> 20, 1);
- progress += (int) currentProgress;
+ progress += (int) currentProgress;
- builder.setProgress(max, progress, false);
+ builder.setProgress(max, progress, false);
+ }
}
builder.addAction(new Notification.Action.Builder(
null, getString(R.string.notification_action_cancel),
@@ -609,10 +620,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 +651,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) {
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
index eae9de937700..407314384be8 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
@@ -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)
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 998aeeab4b47..2af7e00f9128 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -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"));