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

Commit e0b53a90 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Merge "DSU service: Log insufficient storage space error" am:...

Merge "Merge "DSU service: Log insufficient storage space error" am: 9b420e66 am: 1e43855f am: 8c48dc11" into tm-dev am: a39853a0

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2049806



Change-Id: Idd4167c8f4b18885d2a7578fd4d8348ba69352e7
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents e9d7fa22 a39853a0
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -16,13 +16,16 @@

package android.os.image;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.gsi.AvbPublicKey;
import android.gsi.GsiProgress;
import android.gsi.IGsiService;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Pair;

/**
 * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the
@@ -138,17 +141,18 @@ public class DynamicSystemManager {
     * @param name The DSU partition name
     * @param size Size of the DSU image in bytes
     * @param readOnly True if the partition is read only, e.g. system.
     * @return {@code true} if the call succeeds. {@code false} either the device does not contain
     *     enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be
     *     true.
     * @return {@code Integer} an IGsiService.INSTALL_* status code. {@link Session} an installation
     *     session object if successful, otherwise {@code null}.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public Session createPartition(String name, long size, boolean readOnly) {
    public @NonNull Pair<Integer, Session> createPartition(
            String name, long size, boolean readOnly) {
        try {
            if (mService.createPartition(name, size, readOnly)) {
                return new Session();
            int status = mService.createPartition(name, size, readOnly);
            if (status == IGsiService.INSTALL_OK) {
                return new Pair<>(status, new Session());
            } else {
                return null;
                return new Pair<>(status, null);
            }
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
+2 −2
Original line number Diff line number Diff line
@@ -35,10 +35,10 @@ interface IDynamicSystemService
     * @param name The DSU partition name
     * @param size Size of the DSU image in bytes
     * @param readOnly True if this partition is readOnly
     * @return true if the call succeeds
     * @return IGsiService.INSTALL_* status code
     */
    @EnforcePermission("MANAGE_DYNAMIC_SYSTEM")
    boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
    int createPartition(@utf8InCpp String name, long size, boolean readOnly);

    /**
     * Complete the current partition installation.
+7 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ public class DynamicSystemInstallationService extends Service
    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;
    private static final int EVENT_DSU_INSTALL_INSUFFICIENT_SPACE = 120003;

    protected static void logEventProgressUpdate(
            String partitionName,
@@ -136,6 +137,10 @@ public class DynamicSystemInstallationService extends Service
        EventLog.writeEvent(EVENT_DSU_INSTALL_FAILED, cause);
    }

    protected static void logEventInsufficientSpace() {
        EventLog.writeEvent(EVENT_DSU_INSTALL_INSUFFICIENT_SPACE);
    }

    /*
     * IPC
     */
@@ -258,6 +263,8 @@ public class DynamicSystemInstallationService extends Service

        if (result == RESULT_CANCELLED) {
            logEventFailed("Dynamic System installation task is canceled by the user.");
        } else if (detail instanceof InstallationAsyncTask.InsufficientSpaceException) {
            logEventInsufficientSpace();
        } else {
            logEventFailed("error: " + detail);
        }
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ option java_package com.android.dynsystem
120000 dsu_progress_update (partition_name|3),(installed_bytes|2|5),(total_bytes|2|5),(partition_number|1|5),(total_partition_number|1|5),(total_progress_percentage|1|5)
120001 dsu_install_complete
120002 dsu_install_failed (cause|3)
120003 dsu_install_insufficient_space
+67 −26
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.dynsystem;

import android.content.Context;
import android.gsi.AvbPublicKey;
import android.gsi.IGsiService;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -27,6 +28,7 @@ import android.os.SystemProperties;
import android.os.image.DynamicSystemManager;
import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.webkit.URLUtil;

@@ -106,8 +108,15 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
        }
    }

    static class InsufficientSpaceException extends IOException {
        InsufficientSpaceException(String message) {
            super(message);
        }
    }

    /** UNSET means the installation is not completed */
    static final int RESULT_UNSET = 0;

    static final int RESULT_OK = 1;
    static final int RESULT_CANCELLED = 2;
    static final int RESULT_ERROR_IO = 3;
@@ -157,6 +166,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
    private final boolean mIsNetworkUrl;
    private final boolean mIsDeviceBootloaderUnlocked;
    private final boolean mWantScratchPartition;
    private int mCreatePartitionStatus;
    private DynamicSystemManager.Session mInstallationSession;
    private KeyRevocationList mKeyRevocationList;

@@ -435,12 +445,17 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
            throws IOException {
        Log.d(TAG, "Creating writable partition: " + partitionName + ", size: " + partitionSize);

        Thread thread = new Thread() {
        mCreatePartitionStatus = 0;
        mInstallationSession = null;
        Thread thread =
                new Thread() {
                    @Override
                    public void run() {
                mInstallationSession =
                        Pair<Integer, DynamicSystemManager.Session> result =
                                mDynSystem.createPartition(
                                        partitionName, partitionSize, /* readOnly = */ false);
                        mCreatePartitionStatus = result.first;
                        mInstallationSession = result.second;
                    }
                };

@@ -468,20 +483,29 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
            }
        }

        if (prevInstalledSize != partitionSize) {
            publishProgress(partitionSize);
        }

        if (mInstallationSession == null) {
            if (mCreatePartitionStatus == IGsiService.INSTALL_ERROR_NO_SPACE
                    || mCreatePartitionStatus == IGsiService.INSTALL_ERROR_FILE_SYSTEM_CLUTTERED) {
                throw new InsufficientSpaceException(
                        "Failed to create "
                                + partitionName
                                + " partition: storage media has insufficient free space");
            } else {
                throw new IOException(
                        "Failed to start installation with requested size: " + partitionSize);
            }
        }

        // Reset installation session and verify that installation completes successfully.
        mInstallationSession = null;
        if (!mDynSystem.closePartition()) {
            throw new IOException("Failed to complete partition installation: " + partitionName);
        }

        // Ensure a 100% mark is published.
        if (prevInstalledSize != partitionSize) {
            publishProgress(partitionSize);
        }
    }

    private void installScratch() throws IOException {
@@ -606,10 +630,19 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
            throw new IOException("Cannot get raw size for " + partitionName);
        }

        Thread thread = new Thread(() -> {
            mInstallationSession =
                    mDynSystem.createPartition(partitionName, partitionSize, true);
        });
        mCreatePartitionStatus = 0;
        mInstallationSession = null;
        Thread thread =
                new Thread() {
                    @Override
                    public void run() {
                        Pair<Integer, DynamicSystemManager.Session> result =
                                mDynSystem.createPartition(
                                        partitionName, partitionSize, /* readOnly = */ true);
                        mCreatePartitionStatus = result.first;
                        mInstallationSession = result.second;
                    }
                };

        Log.d(TAG, "Start creating partition: " + partitionName);
        thread.start();
@@ -627,9 +660,17 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
        }

        if (mInstallationSession == null) {
            if (mCreatePartitionStatus == IGsiService.INSTALL_ERROR_NO_SPACE
                    || mCreatePartitionStatus == IGsiService.INSTALL_ERROR_FILE_SYSTEM_CLUTTERED) {
                throw new InsufficientSpaceException(
                        "Failed to create "
                                + partitionName
                                + " partition: storage media has insufficient free space");
            } else {
                throw new IOException(
                        "Failed to start installation with requested size: " + partitionSize);
            }
        }

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

@@ -688,11 +729,6 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
            installedSize += numBytesRead;
        }

        // Ensure a 100% mark is published.
        if (prevInstalledSize != partitionSize) {
            publishProgress(partitionSize);
        }

        AvbPublicKey avbPublicKey = new AvbPublicKey();
        if (!mInstallationSession.getAvbPublicKey(avbPublicKey)) {
            imageValidationThrowOrWarning(new PublicKeyException("getAvbPublicKey() failed"));
@@ -708,6 +744,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
        if (!mDynSystem.closePartition()) {
            throw new IOException("Failed to complete partition installation: " + partitionName);
        }

        // Ensure a 100% mark is published.
        if (prevInstalledSize != partitionSize) {
            publishProgress(partitionSize);
        }
    }

    private static String toHexString(byte[] bytes) {
Loading