diff options
author | 2022-03-19 06:50:37 +0000 | |
---|---|---|
committer | 2022-03-19 06:50:37 +0000 | |
commit | 172f4ac338ca5f4f76b458ad6d90b8e034b36df2 (patch) | |
tree | 9490c1235410de20a02bde3cf8b371bd01507318 | |
parent | bc6f905d380950dc95ddc1516cc68b47424a81f9 (diff) | |
parent | d43cfe48e95c6ae6147a976cbdf2e54849e40b5b (diff) |
Merge "DSU installation service: Add event log tags"
4 files changed, 176 insertions, 62 deletions
diff --git a/packages/DynamicSystemInstallationService/Android.bp b/packages/DynamicSystemInstallationService/Android.bp index ad86f4667f67..b8f54b3faf63 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 f8cb5d3d2419..02128d480678 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; @@ -104,6 +105,36 @@ public class DynamicSystemInstallationService extends Service 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 @@ 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; - - int currentMax = max >> (mNumInstalledPartitions + 1); - progress = max - currentMax * 2; + if (mInstallTaskProgress != null) { + int max = 1024; + int progress = 0; - long currentProgress = (mCurrentPartitionInstalledSize >> 20) * currentMax - / Math.max(mCurrentPartitionSize >> 20, 1); + int currentMax = max >> mInstallTaskProgress.partitionNumber; + progress = max - currentMax * 2; - progress += (int) currentProgress; + long currentProgress = + (mInstallTaskProgress.installedSize >> 20) + * currentMax + / Math.max(mInstallTaskProgress.partitionSize >> 20, 1); - 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 000000000000..eae9de937700 --- /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 f18d4269c3ef..b439f8421b73 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<String, InstallationAsyncTask.Progress, Throwable> { +class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { private static final String TAG = "InstallationAsyncTask"; @@ -106,14 +106,22 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog static class Progress { public final String partitionName; + public final long installedSize; public final long partitionSize; - public final int numInstalledPartitions; - public long installedSize; - - Progress(String partitionName, long partitionSize, int numInstalledPartitions) { + public final int partitionNumber; + public final int totalPartitionNumber; + + 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog } @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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog } }; - 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog } } - 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog 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; } } |