Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddd9dc84 authored by Yi-yo Chiang's avatar Yi-yo Chiang Committed by Automerger Merge Worker
Browse files

Merge "dynsystem: Fix memory leak" am: a2271921 am: c066ef1f am: a26312c2

parents de71ca35 a26312c2
Loading
Loading
Loading
Loading
+71 −46
Original line number Diff line number Diff line
@@ -16,17 +16,18 @@

package com.android.dynsystem;

import android.annotation.NonNull;
import android.content.Context;
import android.gsi.AvbPublicKey;
import android.gsi.IGsiService;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.os.SharedMemory;
import android.os.SystemProperties;
import android.os.image.DynamicSystemManager;
import android.service.persistentdata.PersistentDataBlockManager;
import android.system.ErrnoException;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
@@ -39,6 +40,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
@@ -154,6 +156,22 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
        void onResult(int resultCode, Throwable detail);
    }

    private static class MappedMemoryBuffer implements AutoCloseable {
        public ByteBuffer mBuffer;

        MappedMemoryBuffer(@NonNull ByteBuffer buffer) {
            mBuffer = buffer;
        }

        @Override
        public void close() {
            if (mBuffer != null) {
                SharedMemory.unmap(mBuffer);
                mBuffer = null;
            }
        }
    }

    private final int mSharedMemorySize;
    private final String mUrl;
    private final String mDsuSlot;
@@ -674,22 +692,24 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {

        Log.d(TAG, "Start installing: " + partitionName);

        MemoryFile memoryFile = new MemoryFile("dsu_" + partitionName, mSharedMemorySize);
        ParcelFileDescriptor pfd = new ParcelFileDescriptor(memoryFile.getFileDescriptor());

        mInstallationSession.setAshmem(pfd, memoryFile.length());
        long prevInstalledSize = 0;
        try (SharedMemory sharedMemory =
                        SharedMemory.create("dsu_buffer_" + partitionName, mSharedMemorySize);
                MappedMemoryBuffer mappedBuffer =
                        new MappedMemoryBuffer(sharedMemory.mapReadWrite())) {
            mInstallationSession.setAshmem(sharedMemory.getFdDup(), sharedMemory.getSize());

            initPartitionProgress(partitionName, partitionSize, /* readonly = */ true);
            publishProgress(/* installedSize = */ 0L);

        long prevInstalledSize = 0;
            long installedSize = 0;
        byte[] bytes = new byte[memoryFile.length()];
            byte[] readBuffer = new byte[sharedMemory.getSize()];
            ByteBuffer buffer = mappedBuffer.mBuffer;
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Future<Boolean> submitPromise = null;

            while (true) {
            final int numBytesRead = sis.read(bytes, 0, bytes.length);
                final int numBytesRead = sis.read(readBuffer, 0, readBuffer.length);

                if (submitPromise != null) {
                    // Wait until the previous submit task is complete.
@@ -711,7 +731,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
                    }
                }

            // Ensure the previous submit task (submitPromise) is complete before exiting the loop.
                // Ensure the previous submit task (submitPromise) is complete before exiting the
                // loop.
                if (numBytesRead < 0) {
                    break;
                }
@@ -720,7 +741,8 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
                    return;
                }

            memoryFile.writeBytes(bytes, 0, 0, numBytesRead);
                buffer.position(0);
                buffer.put(readBuffer, 0, numBytesRead);
                submitPromise =
                        executor.submit(() -> mInstallationSession.submitFromAshmem(numBytesRead));

@@ -728,6 +750,9 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
                // after the submit task (submitPromise) is complete.
                installedSize += numBytesRead;
            }
        } catch (ErrnoException e) {
            e.rethrowAsIOException();
        }

        AvbPublicKey avbPublicKey = new AvbPublicKey();
        if (!mInstallationSession.getAvbPublicKey(avbPublicKey)) {