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

Commit 417aed2c authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topics "dsu_ashmem", "dsu_clean_up"

* changes:
  Use Ashmem to reduce buffer copies
  Clean up usage on deprecated GSID methods
parents b44f88b3 ae615b32
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.gsi.GsiProgress;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;

/**
@@ -52,21 +53,38 @@ public class DynamicSystemManager {
    /** The DynamicSystemManager.Session represents a started session for the installation. */
    public class Session {
        private Session() {}

        /**
         * Write a chunk of the DynamicSystem system image
         * Set the file descriptor that points to a ashmem which will be used
         * to fetch data during the submitFromAshmem.
         *
         * @return {@code true} if the call succeeds. {@code false} if there is any native runtime
         *     error.
         * @param ashmem fd that points to a ashmem
         * @param size size of the ashmem file
         */
        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
        public boolean write(byte[] buf) {
        public boolean setAshmem(ParcelFileDescriptor ashmem, long size) {
            try {
                return mService.write(buf);
                return mService.setAshmem(ashmem, size);
            } catch (RemoteException e) {
                throw new RuntimeException(e.toString());
            }
        }

        /**
         * Submit bytes to the DSU partition from the ashmem previously set with
         * setAshmem.
         *
         * @param size Number of bytes
         * @return true on success, false otherwise.
         */
        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
        public boolean submitFromAshmem(int size) {
            try {
                return mService.submitFromAshmem(size);
            } catch (RemoteException e) {
                throw new RuntimeException(e.toString());
            }
        }
        /**
         * Finish write and make device to boot into the it after reboot.
         *
@@ -76,7 +94,7 @@ public class DynamicSystemManager {
        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
        public boolean commit() {
            try {
                return mService.commit();
                return mService.setEnable(true, true);
            } catch (RemoteException e) {
                throw new RuntimeException(e.toString());
            }
@@ -188,9 +206,9 @@ public class DynamicSystemManager {
     * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean setEnable(boolean enable) {
    public boolean setEnable(boolean enable, boolean oneShot) {
        try {
            return mService.setEnable(enable);
            return mService.setEnable(enable, oneShot);
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
+13 −7
Original line number Diff line number Diff line
@@ -72,21 +72,27 @@ interface IDynamicSystemService
    /**
     * Enable or disable DynamicSystem.
     *
     * @param oneShot       If true, the GSI will boot once and then disable itself.
     *
     * @return true if the call succeeds
     */
    boolean setEnable(boolean enable);
    boolean setEnable(boolean enable, boolean oneShot);

    /**
     * Write a chunk of the DynamicSystem system image
     * Set the file descriptor that points to a ashmem which will be used
     * to fetch data during the submitFromAshmem.
     *
     * @return true if the call succeeds
     * @param fd            fd that points to a ashmem
     * @param size          size of the ashmem file
     */
    boolean write(in byte[] buf);
    boolean setAshmem(in ParcelFileDescriptor fd, long size);

    /**
     * Finish write and make device to boot into the it after reboot.
     * Submit bytes to the DSU partition from the ashmem previously set with
     * setAshmem.
     *
     * @return true if the call succeeds
     * @param bytes         number of bytes that can be read from stream.
     * @return              true on success, false otherwise.
     */
    boolean commit();
    boolean submitFromAshmem(long bytes);
}
+1 −1
Original line number Diff line number Diff line
@@ -291,7 +291,7 @@ public class DynamicSystemInstallationService extends Service
        if (mInstallTask != null && mInstallTask.getResult() == RESULT_OK) {
            enabled = mInstallTask.commit();
        } else if (isDynamicSystemInstalled()) {
            enabled = mDynSystem.setEnable(true);
            enabled = mDynSystem.setEnable(true, true);
        } else {
            Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
            return;
+10 −13
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.content.Context;
import android.gsi.GsiProgress;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.os.image.DynamicSystemManager;
import android.util.Log;
import android.webkit.URLUtil;
@@ -28,11 +30,9 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Locale;
import java.util.zip.GZIPInputStream;


class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {

    private static final String TAG = "InstallationAsyncTask";
@@ -125,28 +125,26 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
                Thread.sleep(10);
            }


            if (mInstallationSession == null) {
                throw new IOException("Failed to start installation with requested size: "
                throw new IOException(
                        "Failed to start installation with requested size: "
                                + (mSystemSize + mUserdataSize));
            }

            installedSize = mUserdataSize;

            MemoryFile memoryFile = new MemoryFile("dsu", READ_BUFFER_SIZE);
            byte[] bytes = new byte[READ_BUFFER_SIZE];

            mInstallationSession.setAshmem(
                    new ParcelFileDescriptor(memoryFile.getFileDescriptor()), READ_BUFFER_SIZE);
            int numBytesRead;

            Log.d(TAG, "Start installation loop");
            while ((numBytesRead = mStream.read(bytes, 0, READ_BUFFER_SIZE)) != -1) {
                memoryFile.writeBytes(bytes, 0, 0, numBytesRead);
                if (isCancelled()) {
                    break;
                }

                byte[] writeBuffer = numBytesRead == READ_BUFFER_SIZE
                        ? bytes : Arrays.copyOf(bytes, numBytesRead);

                if (!mInstallationSession.write(writeBuffer)) {
                if (!mInstallationSession.submitFromAshmem(numBytesRead)) {
                    throw new IOException("Failed write() to DynamicSystem");
                }

@@ -157,7 +155,6 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
                    reportedInstalledSize = installedSize;
                }
            }

            return null;

        } catch (Exception e) {
+17 −10
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.gsi.IGsid;
import android.os.Environment;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -181,28 +182,34 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements

    @Override
    public boolean remove() throws RemoteException {
        return getGsiService().removeGsiInstall();
        return getGsiService().removeGsi();
    }

    @Override
    public boolean setEnable(boolean enable) throws RemoteException {
    public boolean setEnable(boolean enable, boolean oneShot) throws RemoteException {
        IGsiService gsiService = getGsiService();
        if (enable) {
            final int status = gsiService.getGsiBootStatus();
            final boolean singleBoot = (status == IGsiService.BOOT_STATUS_SINGLE_BOOT);
            return gsiService.setGsiBootable(singleBoot) == 0;
            return gsiService.enableGsi(oneShot) == 0;
        } else {
            return gsiService.disableGsiInstall();
            return gsiService.disableGsi();
        }
    }

    @Override
    public boolean write(byte[] buf) throws RemoteException {
        return getGsiService().commitGsiChunkFromMemory(buf);
    public boolean setAshmem(ParcelFileDescriptor ashmem, long size) {
        try {
            return getGsiService().setGsiAshmem(ashmem, size);
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    @Override
    public boolean commit() throws RemoteException {
        return getGsiService().setGsiBootable(true) == 0;
    public boolean submitFromAshmem(long size) {
        try {
            return getGsiService().commitGsiChunkFromAshmem(size);
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }
}