1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.recoverysystem.hal; 18 19 import android.hardware.boot.IBootControl; 20 import android.hardware.boot.V1_0.CommandResult; 21 import android.os.IBinder; 22 import android.os.RemoteException; 23 import android.util.Slog; 24 25 public class BootControlHIDL implements IBootControl { 26 private static final String TAG = "BootControlHIDL"; 27 28 final android.hardware.boot.V1_0.IBootControl v1_hal; 29 final android.hardware.boot.V1_1.IBootControl v1_1_hal; 30 final android.hardware.boot.V1_2.IBootControl v1_2_hal; 31 isServicePresent()32 public static boolean isServicePresent() { 33 try { 34 android.hardware.boot.V1_0.IBootControl.getService(true); 35 } catch (RemoteException e) { 36 return false; 37 } 38 return true; 39 } 40 isV1_2ServicePresent()41 public static boolean isV1_2ServicePresent() { 42 try { 43 android.hardware.boot.V1_2.IBootControl.getService(true); 44 } catch (RemoteException e) { 45 return false; 46 } 47 return true; 48 } 49 getService()50 public static BootControlHIDL getService() throws RemoteException { 51 android.hardware.boot.V1_0.IBootControl v1_hal = 52 android.hardware.boot.V1_0.IBootControl.getService(true); 53 android.hardware.boot.V1_1.IBootControl v1_1_hal = 54 android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal); 55 android.hardware.boot.V1_2.IBootControl v1_2_hal = 56 android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal); 57 return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal); 58 } 59 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)60 private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal, 61 android.hardware.boot.V1_1.IBootControl v1_1_hal, 62 android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException { 63 this.v1_hal = v1_hal; 64 this.v1_1_hal = v1_1_hal; 65 this.v1_2_hal = v1_2_hal; 66 if (v1_hal == null) { 67 throw new RemoteException("Failed to find V1.0 BootControl HIDL"); 68 } 69 if (v1_2_hal != null) { 70 Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2"); 71 } else if (v1_1_hal != null) { 72 Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1"); 73 } else { 74 Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0"); 75 } 76 } 77 78 @Override asBinder()79 public IBinder asBinder() { 80 return null; 81 } 82 83 @Override getActiveBootSlot()84 public int getActiveBootSlot() throws RemoteException { 85 if (v1_2_hal == null) { 86 throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL"); 87 } 88 return v1_2_hal.getActiveBootSlot(); 89 } 90 91 @Override getCurrentSlot()92 public int getCurrentSlot() throws RemoteException { 93 return v1_hal.getCurrentSlot(); 94 } 95 96 @Override getNumberSlots()97 public int getNumberSlots() throws RemoteException { 98 return v1_hal.getNumberSlots(); 99 } 100 101 @Override getSnapshotMergeStatus()102 public int getSnapshotMergeStatus() throws RemoteException { 103 if (v1_1_hal == null) { 104 throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); 105 } 106 return v1_1_hal.getSnapshotMergeStatus(); 107 } 108 109 @Override getSuffix(int slot)110 public String getSuffix(int slot) throws RemoteException { 111 return v1_hal.getSuffix(slot); 112 } 113 114 @Override isSlotBootable(int slot)115 public boolean isSlotBootable(int slot) throws RemoteException { 116 int ret = v1_hal.isSlotBootable(slot); 117 if (ret == -1) { 118 throw new RemoteException( 119 "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot)); 120 } 121 return ret != 0; 122 } 123 124 @Override isSlotMarkedSuccessful(int slot)125 public boolean isSlotMarkedSuccessful(int slot) throws RemoteException { 126 int ret = v1_hal.isSlotMarkedSuccessful(slot); 127 if (ret == -1) { 128 throw new RemoteException( 129 "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot)); 130 } 131 return ret != 0; 132 } 133 134 @Override markBootSuccessful()135 public void markBootSuccessful() throws RemoteException { 136 CommandResult res = v1_hal.markBootSuccessful(); 137 if (!res.success) { 138 throw new RemoteException("Error markBootSuccessful() " + res.errMsg); 139 } 140 } 141 142 @Override setActiveBootSlot(int slot)143 public void setActiveBootSlot(int slot) throws RemoteException { 144 CommandResult res = v1_hal.setActiveBootSlot(slot); 145 if (!res.success) { 146 throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg)); 147 } 148 } 149 150 @Override setSlotAsUnbootable(int slot)151 public void setSlotAsUnbootable(int slot) throws RemoteException { 152 CommandResult res = v1_hal.setSlotAsUnbootable(slot); 153 if (!res.success) { 154 throw new RemoteException( 155 "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg)); 156 } 157 } 158 159 @Override setSnapshotMergeStatus(int status)160 public void setSnapshotMergeStatus(int status) throws RemoteException { 161 if (v1_1_hal == null) { 162 throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); 163 } 164 if (!v1_1_hal.setSnapshotMergeStatus(status)) { 165 throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status)); 166 } 167 } 168 169 @Override getInterfaceVersion()170 public int getInterfaceVersion() throws RemoteException { 171 return 1; 172 } 173 174 @Override getInterfaceHash()175 public String getInterfaceHash() throws RemoteException { 176 return v1_hal.interfaceDescriptor(); 177 } 178 } 179