Loading packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +50 −19 Original line number Diff line number Diff line Loading @@ -41,6 +41,10 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; Loading @@ -51,8 +55,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { private static final String TAG = "InstallationAsyncTask"; private static final int MIN_SHARED_MEMORY_SIZE = 8 << 10; // 8KiB private static final int MAX_SHARED_MEMORY_SIZE = 1024 << 10; // 1MiB private static final int DEFAULT_SHARED_MEMORY_SIZE = 64 << 10; // 64KiB private static final int MAX_SHARED_MEMORY_SIZE = 8 << 20; // 8MiB private static final int DEFAULT_SHARED_MEMORY_SIZE = 512 << 10; // 512KiB private static final String SHARED_MEMORY_SIZE_PROP = "dynamic_system.data_transfer.shared_memory.size"; Loading Loading @@ -488,7 +492,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { installWritablePartition("userdata", mUserdataSize); } private void installImages() throws IOException, ImageValidationException { private void installImages() throws ExecutionException, IOException, ImageValidationException { if (mStream != null) { if (mIsZip) { installStreamingZipUpdate(); Loading @@ -500,7 +504,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } } private void installStreamingGzUpdate() throws IOException, ImageValidationException { private void installStreamingGzUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a streaming GZ update"); installImage("system", mSystemSize, new GZIPInputStream(mStream)); } Loading Loading @@ -528,7 +533,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { return total; } private void installStreamingZipUpdate() throws IOException, ImageValidationException { private void installStreamingZipUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a streaming ZIP update"); ZipInputStream zis = new ZipInputStream(mStream); Loading @@ -548,7 +554,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } } private void installLocalZipUpdate() throws IOException, ImageValidationException { private void installLocalZipUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a local ZIP update"); Enumeration<? extends ZipEntry> entries = mZipFile.entries(); Loading @@ -569,7 +576,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } private void installImageFromAnEntry(ZipEntry entry, InputStream is) throws IOException, ImageValidationException { throws ExecutionException, IOException, ImageValidationException { String name = entry.getName(); Log.d(TAG, "ZipEntry: " + name); Loading @@ -581,7 +588,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } private void installImage(String partitionName, long uncompressedSize, InputStream is) throws IOException, ImageValidationException { throws ExecutionException, IOException, ImageValidationException { SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is)); Loading Loading @@ -637,27 +644,51 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { long prevInstalledSize = 0; long installedSize = 0; byte[] bytes = new byte[memoryFile.length()]; int numBytesRead; ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Boolean> submitPromise = null; while ((numBytesRead = sis.read(bytes, 0, bytes.length)) != -1) { if (isCancelled()) { return; } while (true) { final int numBytesRead = sis.read(bytes, 0, bytes.length); memoryFile.writeBytes(bytes, 0, 0, numBytesRead); if (!mInstallationSession.submitFromAshmem(numBytesRead)) { throw new IOException("Failed write() to DynamicSystem"); if (submitPromise != null) { // Wait until the previous submit task is complete. while (true) { try { if (!submitPromise.get()) { throw new IOException("Failed submitFromAshmem() to DynamicSystem"); } break; } catch (InterruptedException e) { // Ignore. } } installedSize += numBytesRead; // Publish the progress of the previous submit task. if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) { publishProgress(installedSize); prevInstalledSize = installedSize; } } // Ensure the previous submit task (submitPromise) is complete before exiting the loop. if (numBytesRead < 0) { break; } if (isCancelled()) { return; } memoryFile.writeBytes(bytes, 0, 0, numBytesRead); submitPromise = executor.submit(() -> mInstallationSession.submitFromAshmem(numBytesRead)); // Even though we update the bytes counter here, the actual progress is updated only // after the submit task (submitPromise) is complete. installedSize += numBytesRead; } // Ensure a 100% mark is published. if (prevInstalledSize != partitionSize) { publishProgress(partitionSize); } Loading Loading
packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +50 −19 Original line number Diff line number Diff line Loading @@ -41,6 +41,10 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; Loading @@ -51,8 +55,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { private static final String TAG = "InstallationAsyncTask"; private static final int MIN_SHARED_MEMORY_SIZE = 8 << 10; // 8KiB private static final int MAX_SHARED_MEMORY_SIZE = 1024 << 10; // 1MiB private static final int DEFAULT_SHARED_MEMORY_SIZE = 64 << 10; // 64KiB private static final int MAX_SHARED_MEMORY_SIZE = 8 << 20; // 8MiB private static final int DEFAULT_SHARED_MEMORY_SIZE = 512 << 10; // 512KiB private static final String SHARED_MEMORY_SIZE_PROP = "dynamic_system.data_transfer.shared_memory.size"; Loading Loading @@ -488,7 +492,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { installWritablePartition("userdata", mUserdataSize); } private void installImages() throws IOException, ImageValidationException { private void installImages() throws ExecutionException, IOException, ImageValidationException { if (mStream != null) { if (mIsZip) { installStreamingZipUpdate(); Loading @@ -500,7 +504,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } } private void installStreamingGzUpdate() throws IOException, ImageValidationException { private void installStreamingGzUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a streaming GZ update"); installImage("system", mSystemSize, new GZIPInputStream(mStream)); } Loading Loading @@ -528,7 +533,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { return total; } private void installStreamingZipUpdate() throws IOException, ImageValidationException { private void installStreamingZipUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a streaming ZIP update"); ZipInputStream zis = new ZipInputStream(mStream); Loading @@ -548,7 +554,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } } private void installLocalZipUpdate() throws IOException, ImageValidationException { private void installLocalZipUpdate() throws ExecutionException, IOException, ImageValidationException { Log.d(TAG, "To install a local ZIP update"); Enumeration<? extends ZipEntry> entries = mZipFile.entries(); Loading @@ -569,7 +576,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } private void installImageFromAnEntry(ZipEntry entry, InputStream is) throws IOException, ImageValidationException { throws ExecutionException, IOException, ImageValidationException { String name = entry.getName(); Log.d(TAG, "ZipEntry: " + name); Loading @@ -581,7 +588,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { } private void installImage(String partitionName, long uncompressedSize, InputStream is) throws IOException, ImageValidationException { throws ExecutionException, IOException, ImageValidationException { SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is)); Loading Loading @@ -637,27 +644,51 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { long prevInstalledSize = 0; long installedSize = 0; byte[] bytes = new byte[memoryFile.length()]; int numBytesRead; ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Boolean> submitPromise = null; while ((numBytesRead = sis.read(bytes, 0, bytes.length)) != -1) { if (isCancelled()) { return; } while (true) { final int numBytesRead = sis.read(bytes, 0, bytes.length); memoryFile.writeBytes(bytes, 0, 0, numBytesRead); if (!mInstallationSession.submitFromAshmem(numBytesRead)) { throw new IOException("Failed write() to DynamicSystem"); if (submitPromise != null) { // Wait until the previous submit task is complete. while (true) { try { if (!submitPromise.get()) { throw new IOException("Failed submitFromAshmem() to DynamicSystem"); } break; } catch (InterruptedException e) { // Ignore. } } installedSize += numBytesRead; // Publish the progress of the previous submit task. if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) { publishProgress(installedSize); prevInstalledSize = installedSize; } } // Ensure the previous submit task (submitPromise) is complete before exiting the loop. if (numBytesRead < 0) { break; } if (isCancelled()) { return; } memoryFile.writeBytes(bytes, 0, 0, numBytesRead); submitPromise = executor.submit(() -> mInstallationSession.submitFromAshmem(numBytesRead)); // Even though we update the bytes counter here, the actual progress is updated only // after the submit task (submitPromise) is complete. installedSize += numBytesRead; } // Ensure a 100% mark is published. if (prevInstalledSize != partitionSize) { publishProgress(partitionSize); } Loading