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

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

Merge "Convert RecoverySystemService to use AIDL BootControl HAL"

parents c66a3908 ae97009e
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -143,9 +143,10 @@ java_library_static {

    static_libs: [
        "android.hardware.authsecret-V1.0-java",
        "android.hardware.boot-V1.0-java",
        "android.hardware.boot-V1.1-java",
        "android.hardware.boot-V1.2-java",
        "android.hardware.boot-V1.0-java", // HIDL
        "android.hardware.boot-V1.1-java", // HIDL
        "android.hardware.boot-V1.2-java", // HIDL
        "android.hardware.boot-V1-java",   // AIDL
        "android.hardware.broadcastradio-V2.0-java",
        "android.hardware.health-V1.0-java", // HIDL
        "android.hardware.health-V2.0-java", // HIDL
+32 −19
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ import android.content.Context;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.boot.V1_0.IBootControl;
import android.hardware.boot.IBootControl;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Binder;
@@ -48,6 +48,7 @@ import android.os.Process;
import android.os.RecoverySystem;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
@@ -66,6 +67,7 @@ import com.android.internal.widget.RebootEscrowListener;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.ApexManager;
import com.android.server.recoverysystem.hal.BootControlHIDL;

import libcore.io.IoUtils;

@@ -158,7 +160,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
    @IntDef({ROR_NEED_PREPARATION,
            ROR_SKIP_PREPARATION_AND_NOTIFY,
            ROR_SKIP_PREPARATION_NOT_NOTIFY})
    private @interface ResumeOnRebootActionsOnRequest {}
    private @interface ResumeOnRebootActionsOnRequest {
    }

    /**
     * The action to perform upon resume on reboot clear request for a given client.
@@ -166,7 +169,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
    @IntDef({ROR_NOT_REQUESTED,
            ROR_REQUESTED_NEED_CLEAR,
            ROR_REQUESTED_SKIP_CLEAR})
    private @interface ResumeOnRebootActionsOnClear {}
    private @interface ResumeOnRebootActionsOnClear {
    }

    /**
     * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients
@@ -306,19 +310,26 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
         * Throws remote exception if there's an error getting the boot control HAL.
         * Returns null if the boot control HAL's version is older than V1_2.
         */
        public android.hardware.boot.V1_2.IBootControl getBootControl() throws RemoteException {
            IBootControl bootControlV10 = IBootControl.getService(true);
            if (bootControlV10 == null) {
                throw new RemoteException("Failed to get boot control HAL V1_0.");
        public IBootControl getBootControl() throws RemoteException {
            String serviceName = IBootControl.DESCRIPTOR + "/default";
            if (ServiceManager.isDeclared(serviceName)) {
                Slog.i(TAG,
                        "AIDL version of BootControl HAL present, using instance " + serviceName);
                return IBootControl.Stub.asInterface(
                        ServiceManager.waitForDeclaredService(serviceName));
            }

            IBootControl bootcontrol = BootControlHIDL.getService();
            if (!BootControlHIDL.isServicePresent()) {
                Slog.e(TAG, "Neither AIDL nor HIDL version of the BootControl HAL is present.");
                return null;
            }

            android.hardware.boot.V1_2.IBootControl bootControlV12 =
                    android.hardware.boot.V1_2.IBootControl.castFrom(bootControlV10);
            if (bootControlV12 == null) {
            if (!BootControlHIDL.isV1_2ServicePresent()) {
                Slog.w(TAG, "Device doesn't implement boot control HAL V1_2.");
                return null;
            }
            return bootControlV12;
            return bootcontrol;
        }

        public void threadSleep(long millis) throws InterruptedException {
@@ -738,7 +749,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
            return true;
        }

        android.hardware.boot.V1_2.IBootControl bootControl;
        IBootControl bootControl;
        try {
            bootControl = mInjector.getBootControl();
        } catch (RemoteException e) {
@@ -1160,6 +1171,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo

        /**
         * Reads the status from the uncrypt service which is usually represented as a percentage.
         *
         * @return an integer representing the percentage completed
         * @throws IOException if there was an error reading the socket
         */
@@ -1169,6 +1181,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo

        /**
         * Sends a confirmation to the uncrypt service.
         *
         * @throws IOException if there was an error writing to the socket
         */
        public void sendAck() throws IOException {
+178 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.recoverysystem.hal;

import android.hardware.boot.IBootControl;
import android.hardware.boot.V1_0.CommandResult;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;

public class BootControlHIDL implements IBootControl {
    private static final String TAG = "BootControlHIDL";

    final android.hardware.boot.V1_0.IBootControl v1_hal;
    final android.hardware.boot.V1_1.IBootControl v1_1_hal;
    final android.hardware.boot.V1_2.IBootControl v1_2_hal;

    public static boolean isServicePresent() {
        try {
            android.hardware.boot.V1_0.IBootControl.getService(true);
        } catch (RemoteException e) {
            return false;
        }
        return true;
    }

    public static boolean isV1_2ServicePresent() {
        try {
            android.hardware.boot.V1_2.IBootControl.getService(true);
        } catch (RemoteException e) {
            return false;
        }
        return true;
    }

    public static BootControlHIDL getService() throws RemoteException {
        android.hardware.boot.V1_0.IBootControl v1_hal =
                android.hardware.boot.V1_0.IBootControl.getService(true);
        android.hardware.boot.V1_1.IBootControl v1_1_hal =
                android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal);
        android.hardware.boot.V1_2.IBootControl v1_2_hal =
                android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal);
        return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal);
    }

    private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal,
            android.hardware.boot.V1_1.IBootControl v1_1_hal,
            android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException {
        this.v1_hal = v1_hal;
        this.v1_1_hal = v1_1_hal;
        this.v1_2_hal = v1_2_hal;
        if (v1_hal == null) {
            throw new RemoteException("Failed to find V1.0 BootControl HIDL");
        }
        if (v1_2_hal != null) {
            Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2");
        } else if (v1_1_hal != null) {
            Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1");
        } else {
            Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0");
        }
    }

    @Override
    public IBinder asBinder() {
        return null;
    }

    @Override
    public int getActiveBootSlot() throws RemoteException {
        if (v1_2_hal == null) {
            throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL");
        }
        return v1_2_hal.getActiveBootSlot();
    }

    @Override
    public int getCurrentSlot() throws RemoteException {
        return v1_hal.getCurrentSlot();
    }

    @Override
    public int getNumberSlots() throws RemoteException {
        return v1_hal.getNumberSlots();
    }

    @Override
    public int getSnapshotMergeStatus() throws RemoteException {
        if (v1_1_hal == null) {
            throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
        }
        return v1_1_hal.getSnapshotMergeStatus();
    }

    @Override
    public String getSuffix(int slot) throws RemoteException {
        return v1_hal.getSuffix(slot);
    }

    @Override
    public boolean isSlotBootable(int slot) throws RemoteException {
        int ret = v1_hal.isSlotBootable(slot);
        if (ret == -1) {
            throw new RemoteException(
                    "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot));
        }
        return ret != 0;
    }

    @Override
    public boolean isSlotMarkedSuccessful(int slot) throws RemoteException {
        int ret = v1_hal.isSlotMarkedSuccessful(slot);
        if (ret == -1) {
            throw new RemoteException(
                    "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot));
        }
        return ret != 0;
    }

    @Override
    public void markBootSuccessful() throws RemoteException {
        CommandResult res = v1_hal.markBootSuccessful();
        if (!res.success) {
            throw new RemoteException("Error markBootSuccessful() " + res.errMsg);
        }
    }

    @Override
    public void setActiveBootSlot(int slot) throws RemoteException {
        CommandResult res = v1_hal.setActiveBootSlot(slot);
        if (!res.success) {
            throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg));
        }
    }

    @Override
    public void setSlotAsUnbootable(int slot) throws RemoteException {
        CommandResult res = v1_hal.setSlotAsUnbootable(slot);
        if (!res.success) {
            throw new RemoteException(
                    "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg));
        }
    }

    @Override
    public void setSnapshotMergeStatus(int status) throws RemoteException {
        if (v1_1_hal == null) {
            throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
        }
        if (!v1_1_hal.setSnapshotMergeStatus(status)) {
            throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status));
        }
    }

    @Override
    public int getInterfaceVersion() throws RemoteException {
        return 1;
    }

    @Override
    public String getInterfaceHash() throws RemoteException {
        return v1_hal.interfaceDescriptor();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.hardware.boot.V1_2.IBootControl;
import android.hardware.boot.IBootControl;
import android.os.Handler;
import android.os.IPowerManager;
import android.os.IRecoverySystemProgressListener;
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.server.recoverysystem;

import android.content.Context;
import android.hardware.boot.V1_2.IBootControl;
import android.hardware.boot.IBootControl;
import android.os.PowerManager;

import com.android.internal.widget.LockSettingsInternal;