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