DSU installation service: Add event log tags
Log important events to the 'events' buffer so other tools can robustly
and progmatically parse the DSU logs.
Bug: 224909776
Test: adb logcat -b events -v descriptive \
'*:S dsu_progress_update dsu_install_complete dsu_install_failed'
Change-Id: Iac8d3ec31f51eb9410eb631487e26b4ccb0ccf81
diff --git a/packages/DynamicSystemInstallationService/Android.bp b/packages/DynamicSystemInstallationService/Android.bp
index ad86f46..b8f54b3 100644
--- a/packages/DynamicSystemInstallationService/Android.bp
+++ b/packages/DynamicSystemInstallationService/Android.bp
@@ -22,6 +22,9 @@
defaults: ["platform_app_defaults"],
srcs: ["src/**/*.java"],
+ static_libs: [
+ "DynamicSystemInstallationService-logtags",
+ ],
resource_dirs: ["res"],
certificate: "platform",
@@ -32,3 +35,8 @@
enabled: false,
},
}
+
+java_library {
+ name: "DynamicSystemInstallationService-logtags",
+ srcs: ["src/**/*.logtags"],
+}
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index f8cb5d3..02128d4 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -58,6 +58,7 @@
import android.os.image.DynamicSystemClient;
import android.os.image.DynamicSystemManager;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import android.widget.Toast;
@@ -104,6 +105,36 @@
private static final int NOTIFICATION_ID = 1;
/*
+ * Event log tags
+ */
+ private static final int EVENT_DSU_PROGRESS_UPDATE = 120000;
+ private static final int EVENT_DSU_INSTALL_COMPLETE = 120001;
+ private static final int EVENT_DSU_INSTALL_FAILED = 120002;
+
+ protected static void logEventProgressUpdate(
+ String partition,
+ long installedSize,
+ long partitionSize,
+ int partitionNumber,
+ int totalPartitionNumber) {
+ EventLog.writeEvent(
+ EVENT_DSU_PROGRESS_UPDATE,
+ partition,
+ installedSize,
+ partitionSize,
+ partitionNumber,
+ totalPartitionNumber);
+ }
+
+ protected static void logEventComplete() {
+ EventLog.writeEvent(EVENT_DSU_INSTALL_COMPLETE);
+ }
+
+ protected static void logEventFailed(String cause) {
+ EventLog.writeEvent(EVENT_DSU_INSTALL_FAILED, cause);
+ }
+
+ /*
* IPC
*/
/** Keeps track of all current registered clients. */
@@ -132,15 +163,10 @@
private DynamicSystemManager mDynSystem;
private NotificationManager mNM;
- private int mNumInstalledPartitions;
-
- private String mCurrentPartitionName;
- private long mCurrentPartitionSize;
- private long mCurrentPartitionInstalledSize;
-
// This is for testing only now
private boolean mEnableWhenCompleted;
+ private InstallationAsyncTask.Progress mInstallTaskProgress;
private InstallationAsyncTask mInstallTask;
@@ -203,17 +229,21 @@
@Override
public void onProgressUpdate(InstallationAsyncTask.Progress progress) {
- mCurrentPartitionName = progress.partitionName;
- mCurrentPartitionSize = progress.partitionSize;
- mCurrentPartitionInstalledSize = progress.installedSize;
- mNumInstalledPartitions = progress.numInstalledPartitions;
+ logEventProgressUpdate(
+ progress.partitionName,
+ progress.installedSize,
+ progress.partitionSize,
+ progress.partitionNumber,
+ progress.totalPartitionNumber);
+ mInstallTaskProgress = progress;
postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED, null);
}
@Override
public void onResult(int result, Throwable detail) {
if (result == RESULT_OK) {
+ logEventComplete();
postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED, null);
// For testing: enable DSU and restart the device when install completed
@@ -223,6 +253,12 @@
return;
}
+ if (result == RESULT_CANCELLED) {
+ logEventFailed("Dynamic System installation task is canceled by the user.");
+ } else {
+ logEventFailed("error: " + detail);
+ }
+
boolean removeNotification = false;
switch (result) {
case RESULT_CANCELLED:
@@ -251,16 +287,20 @@
private void executeInstallCommand(Intent intent) {
if (!verifyRequest(intent)) {
Log.e(TAG, "Verification failed. Did you use VerificationActivity?");
+ logEventFailed("VerificationActivity");
return;
}
if (mInstallTask != null) {
Log.e(TAG, "There is already an installation task running");
+ logEventFailed("There is already an ongoing installation task.");
return;
}
if (isInDynamicSystem()) {
Log.e(TAG, "We are already running in DynamicSystem");
+ logEventFailed(
+ "Cannot start a Dynamic System installation task within a Dynamic System.");
return;
}
@@ -445,19 +485,22 @@
case STATUS_IN_PROGRESS:
builder.setContentText(getString(R.string.notification_install_inprogress));
- int max = 1024;
- int progress = 0;
+ if (mInstallTaskProgress != null) {
+ int max = 1024;
+ int progress = 0;
- int currentMax = max >> (mNumInstalledPartitions + 1);
- progress = max - currentMax * 2;
+ int currentMax = max >> mInstallTaskProgress.partitionNumber;
+ progress = max - currentMax * 2;
- long currentProgress = (mCurrentPartitionInstalledSize >> 20) * currentMax
- / Math.max(mCurrentPartitionSize >> 20, 1);
+ long currentProgress =
+ (mInstallTaskProgress.installedSize >> 20)
+ * currentMax
+ / Math.max(mInstallTaskProgress.partitionSize >> 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),
createPendingIntent(ACTION_CANCEL_INSTALL)).build());
@@ -563,13 +606,13 @@
StringBuilder msg = new StringBuilder();
msg.append("status: " + statusString + ", cause: " + causeString);
- if (status == STATUS_IN_PROGRESS) {
+ if (status == STATUS_IN_PROGRESS && mInstallTaskProgress != null) {
msg.append(
String.format(
", partition name: %s, progress: %d/%d",
- mCurrentPartitionName,
- mCurrentPartitionInstalledSize,
- mCurrentPartitionSize));
+ mInstallTaskProgress.partitionName,
+ mInstallTaskProgress.installedSize,
+ mInstallTaskProgress.partitionSize));
}
if (detail != null) {
msg.append(", detail: " + detail);
@@ -594,7 +637,10 @@
Bundle bundle = new Bundle();
// TODO: send more info to the clients
- bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mCurrentPartitionInstalledSize);
+ if (mInstallTaskProgress != null) {
+ bundle.putLong(
+ DynamicSystemClient.KEY_INSTALLED_SIZE, mInstallTaskProgress.installedSize);
+ }
if (detail != null) {
bundle.putSerializable(DynamicSystemClient.KEY_EXCEPTION_DETAIL,
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
new file mode 100644
index 0000000..eae9de9
--- /dev/null
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
@@ -0,0 +1,7 @@
+# See system/logging/logcat/event.logtags for a description of the format of this file.
+
+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)
+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 f18d426..b439f84 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -44,7 +44,7 @@
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
-class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Progress, Throwable> {
+class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
private static final String TAG = "InstallationAsyncTask";
@@ -106,14 +106,22 @@
static class Progress {
public final String partitionName;
+ public final long installedSize;
public final long partitionSize;
- public final int numInstalledPartitions;
- public long installedSize;
+ public final int partitionNumber;
+ public final int totalPartitionNumber;
- Progress(String partitionName, long partitionSize, int numInstalledPartitions) {
+ Progress(
+ String partitionName,
+ long installedSize,
+ long partitionSize,
+ int partitionNumber,
+ int totalPartitionNumber) {
this.partitionName = partitionName;
+ this.installedSize = installedSize;
this.partitionSize = partitionSize;
- this.numInstalledPartitions = numInstalledPartitions;
+ this.partitionNumber = partitionNumber;
+ this.totalPartitionNumber = totalPartitionNumber;
}
}
@@ -139,7 +147,10 @@
private boolean mIsZip;
private boolean mIsCompleted;
- private int mNumInstalledPartitions;
+ private String mPartitionName;
+ private long mPartitionSize;
+ private int mPartitionNumber;
+ private int mTotalPartitionNumber;
private InputStream mStream;
private ZipFile mZipFile;
@@ -175,11 +186,15 @@
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);
@@ -198,7 +213,7 @@
return null;
}
- if (Build.IS_DEBUGGABLE) {
+ if (wantScratchPartition) {
// If host is debuggable, then install a scratch partition so that we can do
// adb remount in the guest system.
try {
@@ -262,9 +277,14 @@
}
@Override
- protected void onProgressUpdate(Progress... values) {
- Progress progress = values[0];
- mListener.onProgressUpdate(progress);
+ protected void onProgressUpdate(Long... installedSize) {
+ mListener.onProgressUpdate(
+ new Progress(
+ mPartitionName,
+ installedSize[0],
+ mPartitionSize,
+ mPartitionNumber,
+ mTotalPartitionNumber));
}
private void verifyAndPrepare() throws Exception {
@@ -281,12 +301,16 @@
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();
}
@@ -333,9 +357,13 @@
}
};
- thread.start();
- Progress progress = new Progress(partitionName, partitionSize, mNumInstalledPartitions++);
+ mPartitionName = partitionName;
+ mPartitionSize = partitionSize;
+ ++mPartitionNumber;
+ publishProgress(/* installedSize = */ 0L);
+ long prevInstalledSize = 0;
+ thread.start();
while (thread.isAlive()) {
if (isCancelled()) {
return;
@@ -343,9 +371,9 @@
final long installedSize = mDynSystem.getInstallationProgress().bytes_processed;
- if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) {
- progress.installedSize = installedSize;
- publishProgress(progress);
+ if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
+ publishProgress(installedSize);
+ prevInstalledSize = installedSize;
}
try {
@@ -392,14 +420,42 @@
installImage("system", mSystemSize, new GZIPInputStream(mStream));
}
+ private boolean shouldInstallEntry(String name) {
+ if (!name.endsWith(".img")) {
+ return false;
+ }
+ String partitionName = name.substring(0, name.length() - 4);
+ if (UNSUPPORTED_PARTITIONS.contains(partitionName)) {
+ return false;
+ }
+ return true;
+ }
+
+ private int calculateNumberOfImagesInLocalZip(ZipFile zipFile) {
+ int total = 0;
+ Enumeration<? extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ if (shouldInstallEntry(entry.getName())) {
+ ++total;
+ }
+ }
+ return total;
+ }
+
private void installStreamingZipUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a streaming ZIP update");
ZipInputStream zis = new ZipInputStream(mStream);
- ZipEntry zipEntry = null;
+ ZipEntry entry = null;
- while ((zipEntry = zis.getNextEntry()) != null) {
- installImageFromAnEntry(zipEntry, zis);
+ while ((entry = zis.getNextEntry()) != null) {
+ String name = entry.getName();
+ if (shouldInstallEntry(name)) {
+ installImageFromAnEntry(entry, zis);
+ } else {
+ Log.d(TAG, name + " installation is not supported, skip it.");
+ }
if (isCancelled()) {
break;
@@ -414,7 +470,12 @@
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
- installImageFromAnEntry(entry, mZipFile.getInputStream(entry));
+ String name = entry.getName();
+ if (shouldInstallEntry(name)) {
+ installImageFromAnEntry(entry, mZipFile.getInputStream(entry));
+ } else {
+ Log.d(TAG, name + " installation is not supported, skip it.");
+ }
if (isCancelled()) {
break;
@@ -422,28 +483,16 @@
}
}
- private boolean installImageFromAnEntry(ZipEntry entry, InputStream is)
+ private void installImageFromAnEntry(ZipEntry entry, InputStream is)
throws IOException, ImageValidationException {
String name = entry.getName();
Log.d(TAG, "ZipEntry: " + name);
- if (!name.endsWith(".img")) {
- return false;
- }
-
String partitionName = name.substring(0, name.length() - 4);
-
- if (UNSUPPORTED_PARTITIONS.contains(partitionName)) {
- Log.d(TAG, name + " installation is not supported, skip it.");
- return false;
- }
-
long uncompressedSize = entry.getSize();
installImage(partitionName, uncompressedSize, is);
-
- return true;
}
private void installImage(String partitionName, long uncompressedSize, InputStream is)
@@ -497,8 +546,12 @@
mInstallationSession.setAshmem(pfd, READ_BUFFER_SIZE);
- Progress progress = new Progress(partitionName, partitionSize, mNumInstalledPartitions++);
+ mPartitionName = partitionName;
+ mPartitionSize = partitionSize;
+ ++mPartitionNumber;
+ publishProgress(/* installedSize = */ 0L);
+ long prevInstalledSize = 0;
long installedSize = 0;
byte[] bytes = new byte[READ_BUFFER_SIZE];
int numBytesRead;
@@ -516,9 +569,9 @@
installedSize += numBytesRead;
- if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) {
- progress.installedSize = installedSize;
- publishProgress(progress);
+ if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
+ publishProgress(installedSize);
+ prevInstalledSize = installedSize;
}
}