• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import java.util.NoSuchElementException;
26 
27 public class BootControlHIDL implements IBootControl {
28     private static final String TAG = "BootControlHIDL";
29 
30     final android.hardware.boot.V1_0.IBootControl v1_hal;
31     final android.hardware.boot.V1_1.IBootControl v1_1_hal;
32     final android.hardware.boot.V1_2.IBootControl v1_2_hal;
33 
isServicePresent()34     public static boolean isServicePresent() {
35         try {
36             android.hardware.boot.V1_0.IBootControl.getService(true);
37         } catch (RemoteException | NoSuchElementException e) {
38             return false;
39         }
40         return true;
41     }
42 
isV1_2ServicePresent()43     public static boolean isV1_2ServicePresent() {
44         try {
45             android.hardware.boot.V1_2.IBootControl.getService(true);
46         } catch (RemoteException | NoSuchElementException e) {
47             return false;
48         }
49         return true;
50     }
51 
getService()52     public static BootControlHIDL getService() throws RemoteException {
53         android.hardware.boot.V1_0.IBootControl v1_hal =
54                 android.hardware.boot.V1_0.IBootControl.getService(true);
55         android.hardware.boot.V1_1.IBootControl v1_1_hal =
56                 android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal);
57         android.hardware.boot.V1_2.IBootControl v1_2_hal =
58                 android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal);
59         return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal);
60     }
61 
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)62     private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal,
63             android.hardware.boot.V1_1.IBootControl v1_1_hal,
64             android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException {
65         this.v1_hal = v1_hal;
66         this.v1_1_hal = v1_1_hal;
67         this.v1_2_hal = v1_2_hal;
68         if (v1_hal == null) {
69             throw new RemoteException("Failed to find V1.0 BootControl HIDL");
70         }
71         if (v1_2_hal != null) {
72             Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2");
73         } else if (v1_1_hal != null) {
74             Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1");
75         } else {
76             Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0");
77         }
78     }
79 
80     @Override
asBinder()81     public IBinder asBinder() {
82         return null;
83     }
84 
85     @Override
getActiveBootSlot()86     public int getActiveBootSlot() throws RemoteException {
87         if (v1_2_hal == null) {
88             throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL");
89         }
90         return v1_2_hal.getActiveBootSlot();
91     }
92 
93     @Override
getCurrentSlot()94     public int getCurrentSlot() throws RemoteException {
95         return v1_hal.getCurrentSlot();
96     }
97 
98     @Override
getNumberSlots()99     public int getNumberSlots() throws RemoteException {
100         return v1_hal.getNumberSlots();
101     }
102 
103     @Override
getSnapshotMergeStatus()104     public int getSnapshotMergeStatus() throws RemoteException {
105         if (v1_1_hal == null) {
106             throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
107         }
108         return v1_1_hal.getSnapshotMergeStatus();
109     }
110 
111     @Override
getSuffix(int slot)112     public String getSuffix(int slot) throws RemoteException {
113         return v1_hal.getSuffix(slot);
114     }
115 
116     @Override
isSlotBootable(int slot)117     public boolean isSlotBootable(int slot) throws RemoteException {
118         int ret = v1_hal.isSlotBootable(slot);
119         if (ret == -1) {
120             throw new RemoteException(
121                     "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot));
122         }
123         return ret != 0;
124     }
125 
126     @Override
isSlotMarkedSuccessful(int slot)127     public boolean isSlotMarkedSuccessful(int slot) throws RemoteException {
128         int ret = v1_hal.isSlotMarkedSuccessful(slot);
129         if (ret == -1) {
130             throw new RemoteException(
131                     "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot));
132         }
133         return ret != 0;
134     }
135 
136     @Override
markBootSuccessful()137     public void markBootSuccessful() throws RemoteException {
138         CommandResult res = v1_hal.markBootSuccessful();
139         if (!res.success) {
140             throw new RemoteException("Error markBootSuccessful() " + res.errMsg);
141         }
142     }
143 
144     @Override
setActiveBootSlot(int slot)145     public void setActiveBootSlot(int slot) throws RemoteException {
146         CommandResult res = v1_hal.setActiveBootSlot(slot);
147         if (!res.success) {
148             throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg));
149         }
150     }
151 
152     @Override
setSlotAsUnbootable(int slot)153     public void setSlotAsUnbootable(int slot) throws RemoteException {
154         CommandResult res = v1_hal.setSlotAsUnbootable(slot);
155         if (!res.success) {
156             throw new RemoteException(
157                     "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg));
158         }
159     }
160 
161     @Override
setSnapshotMergeStatus(int status)162     public void setSnapshotMergeStatus(int status) throws RemoteException {
163         if (v1_1_hal == null) {
164             throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
165         }
166         if (!v1_1_hal.setSnapshotMergeStatus(status)) {
167             throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status));
168         }
169     }
170 
171     @Override
getInterfaceVersion()172     public int getInterfaceVersion() throws RemoteException {
173         return 1;
174     }
175 
176     @Override
getInterfaceHash()177     public String getInterfaceHash() throws RemoteException {
178         return v1_hal.interfaceDescriptor();
179     }
180 }
181