1 /*
2  * Copyright (C) 2021 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.health;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.BatteryProperty;
22 import android.os.HandlerThread;
23 import android.os.IBatteryPropertiesRegistrar;
24 import android.os.RemoteException;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 
28 import java.util.NoSuchElementException;
29 
30 /**
31  * HealthServiceWrapper wraps the internal IHealth service and refreshes the service when necessary.
32  * This is essentially a wrapper over IHealth that is useful for BatteryService.
33  *
34  * <p>The implementation may be backed by a HIDL or AIDL HAL.
35  *
36  * <p>On new registration of IHealth service, the internal service is refreshed. On death of an
37  * existing IHealth service, the internal service is NOT cleared to avoid race condition between
38  * death notification and new service notification. Hence, a caller must check for transaction
39  * errors when calling into the service.
40  *
41  * @hide Should only be used internally.
42  */
43 public abstract class HealthServiceWrapper {
44     /** @return the handler thread. Exposed for testing. */
45     @VisibleForTesting
getHandlerThread()46     abstract HandlerThread getHandlerThread();
47 
48     /**
49      * Calls into get*() functions in the health HAL. This reads into the kernel interfaces
50      * directly.
51      *
52      * @see IBatteryPropertiesRegistrar#getProperty
53      */
getProperty(int id, BatteryProperty prop)54     public abstract int getProperty(int id, BatteryProperty prop) throws RemoteException;
55 
56     /**
57      * Calls update() in the health HAL.
58      *
59      * @see IBatteryPropertiesRegistrar#scheduleUpdate
60      */
scheduleUpdate()61     public abstract void scheduleUpdate() throws RemoteException;
62 
63     /**
64      * Calls into getHealthInfo() in the health HAL. This returns a cached value in the health HAL
65      * implementation.
66      *
67      * @return health info. {@code null} if no health HAL service. {@code null} if any
68      *     service-specific error when calling {@code getHealthInfo}, e.g. it is unsupported.
69      * @throws RemoteException for any transaction-level errors
70      */
getHealthInfo()71     public abstract android.hardware.health.HealthInfo getHealthInfo() throws RemoteException;
72 
73     /**
74      * Create a new HealthServiceWrapper instance.
75      *
76      * @param healthInfoCallback the callback to call when health info changes
77      * @return the new HealthServiceWrapper instance, which may be backed by HIDL or AIDL service.
78      * @throws RemoteException transaction errors
79      * @throws NoSuchElementException no HIDL or AIDL service is available
80      */
create(@ullable HealthInfoCallback healthInfoCallback)81     public static HealthServiceWrapper create(@Nullable HealthInfoCallback healthInfoCallback)
82             throws RemoteException, NoSuchElementException {
83         return create(
84                 healthInfoCallback == null ? null : new HealthRegCallbackAidl(healthInfoCallback),
85                 new HealthServiceWrapperAidl.ServiceManagerStub() {},
86                 healthInfoCallback == null ? null : new HealthHalCallbackHidl(healthInfoCallback),
87                 new HealthServiceWrapperHidl.IServiceManagerSupplier() {},
88                 new HealthServiceWrapperHidl.IHealthSupplier() {});
89     }
90 
91     /**
92      * Create a new HealthServiceWrapper instance for testing.
93      *
94      * @param aidlRegCallback callback for AIDL service registration, or {@code null} if the client
95      *     does not care about AIDL service registration notifications
96      * @param aidlServiceManager Stub for AIDL ServiceManager
97      * @param hidlRegCallback callback for HIDL service registration, or {@code null} if the client
98      *     does not care about HIDL service registration notifications
99      * @param hidlServiceManagerSupplier supplier of HIDL service manager
100      * @param hidlHealthSupplier supplier of HIDL health HAL
101      * @return the new HealthServiceWrapper instance, which may be backed by HIDL or AIDL service.
102      */
103     @VisibleForTesting
create( @ullable HealthRegCallbackAidl aidlRegCallback, @NonNull HealthServiceWrapperAidl.ServiceManagerStub aidlServiceManager, @Nullable HealthServiceWrapperHidl.Callback hidlRegCallback, @NonNull HealthServiceWrapperHidl.IServiceManagerSupplier hidlServiceManagerSupplier, @NonNull HealthServiceWrapperHidl.IHealthSupplier hidlHealthSupplier)104     static @NonNull HealthServiceWrapper create(
105             @Nullable HealthRegCallbackAidl aidlRegCallback,
106             @NonNull HealthServiceWrapperAidl.ServiceManagerStub aidlServiceManager,
107             @Nullable HealthServiceWrapperHidl.Callback hidlRegCallback,
108             @NonNull HealthServiceWrapperHidl.IServiceManagerSupplier hidlServiceManagerSupplier,
109             @NonNull HealthServiceWrapperHidl.IHealthSupplier hidlHealthSupplier)
110             throws RemoteException, NoSuchElementException {
111         try {
112             return new HealthServiceWrapperAidl(aidlRegCallback, aidlServiceManager);
113         } catch (NoSuchElementException e) {
114             // Ignore, try HIDL
115         }
116         return new HealthServiceWrapperHidl(
117                 hidlRegCallback, hidlServiceManagerSupplier, hidlHealthSupplier);
118     }
119 }
120