From d43cfe48e95c6ae6147a976cbdf2e54849e40b5b Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Wed, 16 Mar 2022 23:52:15 +0800 Subject: [PATCH] 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 --- .../Android.bp | 8 ++ .../DynamicSystemInstallationService.java | 94 +++++++++---- .../android/dynsystem/EventLogTags.logtags | 7 + .../dynsystem/InstallationAsyncTask.java | 125 +++++++++++++----- 4 files changed, 174 insertions(+), 60 deletions(-) create mode 100644 packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags diff --git a/packages/DynamicSystemInstallationService/Android.bp b/packages/DynamicSystemInstallationService/Android.bp index ad86f4667f67a..b8f54b3faf630 100644 --- a/packages/DynamicSystemInstallationService/Android.bp +++ b/packages/DynamicSystemInstallationService/Android.bp @@ -22,6 +22,9 @@ android_app { defaults: ["platform_app_defaults"], srcs: ["src/**/*.java"], + static_libs: [ + "DynamicSystemInstallationService-logtags", + ], resource_dirs: ["res"], certificate: "platform", @@ -32,3 +35,8 @@ android_app { 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 f8cb5d3d2419c..02128d4806789 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.RemoteException; 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; @@ -103,6 +104,36 @@ public class DynamicSystemInstallationService extends Service private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem"; 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 */ @@ -132,15 +163,10 @@ public class DynamicSystemInstallationService extends Service 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 @@ public class DynamicSystemInstallationService extends Service @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 @@ public class DynamicSystemInstallationService extends Service 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 @@ public class DynamicSystemInstallationService extends Service 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 @@ public class DynamicSystemInstallationService extends Service 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; - - builder.setProgress(max, progress, false); + progress += (int) currentProgress; + 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 @@ public class DynamicSystemInstallationService extends Service 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 @@ public class DynamicSystemInstallationService extends Service 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 0000000000000..eae9de937700d --- /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 f18d4269c3ef7..b439f8421b738 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.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; -class InstallationAsyncTask extends AsyncTask { +class InstallationAsyncTask extends AsyncTask { private static final String TAG = "InstallationAsyncTask"; @@ -106,14 +106,22 @@ class InstallationAsyncTask extends AsyncTask 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 @@ class InstallationAsyncTask extends AsyncTask 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 @@ class InstallationAsyncTask extends AsyncTask progress.installedSize + MIN_PROGRESS_TO_PUBLISH) { - progress.installedSize = installedSize; - publishProgress(progress); + if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) { + publishProgress(installedSize); + prevInstalledSize = installedSize; } }