Migrate thermal HAL wrapper from HIDL to AIDL
Pixel HAL impl is WIP and the AIDL migration is backward compatible
with HIDL 2.0 so they can be isolated
Bug: b/205762943
Test: atest ThermalManagerServiceTest ThermalManagerServiceMockingTest
Change-Id: Ia6d132ab0b022d47c97262c4cb3e942989179fed
diff --git a/Android.bp b/Android.bp
index c0a2abb..8c02a27 100644
--- a/Android.bp
+++ b/Android.bp
@@ -102,6 +102,7 @@
":android.hardware.keymaster-V4-java-source",
":android.hardware.security.keymint-V3-java-source",
":android.hardware.security.secureclock-V1-java-source",
+ ":android.hardware.thermal-V1-java-source",
":android.hardware.tv.tuner-V2-java-source",
":android.security.apc-java-source",
":android.security.authorization-java-source",
diff --git a/core/java/android/os/CoolingDevice.java b/core/java/android/os/CoolingDevice.java
index 4babd4b..4ddcd9d 100644
--- a/core/java/android/os/CoolingDevice.java
+++ b/core/java/android/os/CoolingDevice.java
@@ -19,7 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.thermal.V2_0.CoolingType;
+import android.hardware.thermal.CoolingType;
import com.android.internal.util.Preconditions;
@@ -52,11 +52,16 @@
TYPE_MODEM,
TYPE_NPU,
TYPE_COMPONENT,
+ TYPE_TPU,
+ TYPE_POWER_AMPLIFIER,
+ TYPE_DISPLAY,
+ TYPE_SPEAKER
})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
- /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
+ /** Keep in sync with hardware/interfaces/thermal/aidl/android/hardware/thermal
+ * /ThrottlingSeverity.aidl */
/** Fan for active cooling */
public static final int TYPE_FAN = CoolingType.FAN;
/** Battery charging cooling deivice */
@@ -67,10 +72,18 @@
public static final int TYPE_GPU = CoolingType.GPU;
/** Modem cooling deivice */
public static final int TYPE_MODEM = CoolingType.MODEM;
- /** NPU/TPU cooling deivice */
+ /** NPU cooling deivice */
public static final int TYPE_NPU = CoolingType.NPU;
/** Generic passive cooling deivice */
public static final int TYPE_COMPONENT = CoolingType.COMPONENT;
+ /** TPU cooling deivice */
+ public static final int TYPE_TPU = CoolingType.TPU;
+ /** Power amplifier cooling device */
+ public static final int TYPE_POWER_AMPLIFIER = CoolingType.POWER_AMPLIFIER;
+ /** Display cooling device */
+ public static final int TYPE_DISPLAY = CoolingType.DISPLAY;
+ /** Speaker cooling device */
+ public static final int TYPE_SPEAKER = CoolingType.SPEAKER;
/**
* Verify a valid cooling device type.
@@ -78,7 +91,7 @@
* @return true if a cooling device type is valid otherwise false.
*/
public static boolean isValidType(@Type int type) {
- return type >= TYPE_FAN && type <= TYPE_COMPONENT;
+ return type >= TYPE_FAN && type <= TYPE_SPEAKER;
}
public CoolingDevice(long value, @Type int type, @NonNull String name) {
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index 55785f3..a138431 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -19,8 +19,8 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.thermal.V2_0.TemperatureType;
-import android.hardware.thermal.V2_0.ThrottlingSeverity;
+import android.hardware.thermal.TemperatureType;
+import android.hardware.thermal.ThrottlingSeverity;
import com.android.internal.util.Preconditions;
@@ -54,7 +54,8 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ThrottlingStatus {}
- /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
+ /** Keep in sync with hardware/interfaces/thermal/aidl/android/hardware/thermal
+ * /ThrottlingSeverity.aidl */
public static final int THROTTLING_NONE = ThrottlingSeverity.NONE;
public static final int THROTTLING_LIGHT = ThrottlingSeverity.LIGHT;
public static final int THROTTLING_MODERATE = ThrottlingSeverity.MODERATE;
@@ -75,11 +76,16 @@
TYPE_BCL_CURRENT,
TYPE_BCL_PERCENTAGE,
TYPE_NPU,
+ TYPE_TPU,
+ TYPE_DISPLAY,
+ TYPE_MODEM,
+ TYPE_SOC
})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
- /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
+ /** Keep in sync with hardware/interfaces/thermal/aidl/android/hardware/thermal
+ * /TemperatureType.aidl */
public static final int TYPE_UNKNOWN = TemperatureType.UNKNOWN;
public static final int TYPE_CPU = TemperatureType.CPU;
public static final int TYPE_GPU = TemperatureType.GPU;
@@ -91,6 +97,10 @@
public static final int TYPE_BCL_CURRENT = TemperatureType.BCL_CURRENT;
public static final int TYPE_BCL_PERCENTAGE = TemperatureType.BCL_PERCENTAGE;
public static final int TYPE_NPU = TemperatureType.NPU;
+ public static final int TYPE_TPU = TemperatureType.TPU;
+ public static final int TYPE_DISPLAY = TemperatureType.DISPLAY;
+ public static final int TYPE_MODEM = TemperatureType.MODEM;
+ public static final int TYPE_SOC = TemperatureType.SOC;
/**
* Verify a valid Temperature type.
@@ -98,7 +108,7 @@
* @return true if a Temperature type is valid otherwise false.
*/
public static boolean isValidType(@Type int type) {
- return type >= TYPE_UNKNOWN && type <= TYPE_NPU;
+ return type >= TYPE_UNKNOWN && type <= TYPE_SOC;
}
/**
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index f378588..6b2c6e3 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -19,16 +19,18 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.thermal.IThermal;
+import android.hardware.thermal.IThermalChangedCallback;
+import android.hardware.thermal.TemperatureThreshold;
+import android.hardware.thermal.ThrottlingSeverity;
import android.hardware.thermal.V1_0.ThermalStatus;
import android.hardware.thermal.V1_0.ThermalStatusCode;
import android.hardware.thermal.V1_1.IThermalCallback;
-import android.hardware.thermal.V2_0.IThermalChangedCallback;
-import android.hardware.thermal.V2_0.TemperatureThreshold;
-import android.hardware.thermal.V2_0.ThrottlingSeverity;
import android.os.Binder;
import android.os.CoolingDevice;
import android.os.Handler;
import android.os.HwBinder;
+import android.os.IBinder;
import android.os.IThermalEventListener;
import android.os.IThermalService;
import android.os.IThermalStatusListener;
@@ -37,6 +39,7 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemClock;
@@ -56,12 +59,14 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
/**
* This is a system service that listens to HAL thermal events and dispatch those to listeners.
@@ -98,7 +103,7 @@
@GuardedBy("mLock")
private int mStatus;
- /** If override status takes effect*/
+ /** If override status takes effect */
@GuardedBy("mLock")
private boolean mIsStatusOverride;
@@ -144,6 +149,10 @@
// Connect to HAL and post to listeners.
boolean halConnected = (mHalWrapper != null);
if (!halConnected) {
+ mHalWrapper = new ThermalHalAidlWrapper();
+ halConnected = mHalWrapper.connectToHal();
+ }
+ if (!halConnected) {
mHalWrapper = new ThermalHal20Wrapper();
halConnected = mHalWrapper.connectToHal();
}
@@ -684,6 +693,162 @@
}
}
+ @VisibleForTesting
+ static class ThermalHalAidlWrapper extends ThermalHalWrapper implements IBinder.DeathRecipient {
+ /* Proxy object for the Thermal HAL AIDL service. */
+ private IThermal mInstance = null;
+
+ /** Callback for Thermal HAL AIDL. */
+ private final IThermalChangedCallback mThermalChangedCallback =
+ new IThermalChangedCallback.Stub() {
+ @Override public void notifyThrottling(
+ android.hardware.thermal.Temperature temperature)
+ throws RemoteException {
+ Temperature svcTemperature = new Temperature(temperature.value,
+ temperature.type, temperature.name, temperature.throttlingStatus);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mCallback.onValues(svcTemperature);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override public int getInterfaceVersion() throws RemoteException {
+ return this.VERSION;
+ }
+
+ @Override public String getInterfaceHash() throws RemoteException {
+ return this.HASH;
+ }
+ };
+
+ @Override
+ protected List<Temperature> getCurrentTemperatures(boolean shouldFilter,
+ int type) {
+ synchronized (mHalLock) {
+ final List<Temperature> ret = new ArrayList<>();
+ if (mInstance == null) {
+ return ret;
+ }
+ try {
+ final android.hardware.thermal.Temperature[] halRet =
+ shouldFilter ? mInstance.getTemperaturesWithType(type)
+ : mInstance.getTemperatures();
+ for (android.hardware.thermal.Temperature t : halRet) {
+ if (!Temperature.isValidStatus(t.throttlingStatus)) {
+ Slog.e(TAG, "Invalid temperature status " + t.throttlingStatus
+ + " received from AIDL HAL");
+ t.throttlingStatus = Temperature.THROTTLING_NONE;
+ }
+ if (shouldFilter && t.type != type) {
+ continue;
+ }
+ ret.add(new Temperature(t.value, t.type, t.name, t.throttlingStatus));
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't getCurrentTemperatures, reconnecting", e);
+ connectToHal();
+ }
+ return ret;
+ }
+ }
+
+ @Override
+ protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter,
+ int type) {
+ synchronized (mHalLock) {
+ final List<CoolingDevice> ret = new ArrayList<>();
+ if (mInstance == null) {
+ return ret;
+ }
+ try {
+ final android.hardware.thermal.CoolingDevice[] halRet = shouldFilter
+ ? mInstance.getCoolingDevicesWithType(type)
+ : mInstance.getCoolingDevices();
+ for (android.hardware.thermal.CoolingDevice t : halRet) {
+ if (!CoolingDevice.isValidType(t.type)) {
+ Slog.e(TAG, "Invalid cooling device type " + t.type + " from AIDL HAL");
+ continue;
+ }
+ if (shouldFilter && t.type != type) {
+ continue;
+ }
+ ret.add(new CoolingDevice(t.value, t.type, t.name));
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting", e);
+ connectToHal();
+ }
+ return ret;
+ }
+ }
+
+ @Override
+ @NonNull protected List<TemperatureThreshold> getTemperatureThresholds(
+ boolean shouldFilter, int type) {
+ synchronized (mHalLock) {
+ final List<TemperatureThreshold> ret = new ArrayList<>();
+ if (mInstance == null) {
+ return ret;
+ }
+ try {
+ final TemperatureThreshold[] halRet =
+ shouldFilter ? mInstance.getTemperatureThresholdsWithType(type)
+ : mInstance.getTemperatureThresholds();
+
+ return Arrays.stream(halRet).filter(t -> t.type == type).collect(
+ Collectors.toList());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't getTemperatureThresholds, reconnecting...", e);
+ connectToHal();
+ }
+ return ret;
+ }
+ }
+
+ @Override
+ protected boolean connectToHal() {
+ synchronized (mHalLock) {
+ IBinder binder = Binder.allowBlocking(ServiceManager.waitForDeclaredService(
+ IThermal.DESCRIPTOR + "/default"));
+ initProxyAndRegisterCallback(binder);
+ }
+ return mInstance != null;
+ }
+
+ @VisibleForTesting
+ void initProxyAndRegisterCallback(IBinder binder) {
+ synchronized (mHalLock) {
+ if (binder != null) {
+ mInstance = IThermal.Stub.asInterface(binder);
+ try {
+ binder.linkToDeath(this, 0);
+ mInstance.registerThermalChangedCallback(mThermalChangedCallback);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to connect IThermal AIDL instance", e);
+ mInstance = null;
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void dump(PrintWriter pw, String prefix) {
+ synchronized (mHalLock) {
+ pw.print(prefix);
+ pw.println(
+ "ThermalHAL AIDL " + IThermal.VERSION + " connected: " + (mInstance != null
+ ? "yes" : "no"));
+ }
+ }
+
+ @Override
+ public synchronized void binderDied() {
+ Slog.w(TAG, "IThermal HAL instance died");
+ mInstance = null;
+ }
+ }
static class ThermalHal10Wrapper extends ThermalHalWrapper {
/** Proxy object for the Thermal HAL 1.0 service. */
@@ -814,8 +979,8 @@
android.hardware.thermal.V1_0.Temperature temperature) {
Temperature thermalSvcTemp = new Temperature(
temperature.currentValue, temperature.type, temperature.name,
- isThrottling ? ThrottlingSeverity.SEVERE
- : ThrottlingSeverity.NONE);
+ isThrottling ? Temperature.THROTTLING_SEVERE
+ : Temperature.THROTTLING_NONE);
final long token = Binder.clearCallingIdentity();
try {
mCallback.onValues(thermalSvcTemp);
@@ -941,8 +1106,9 @@
private android.hardware.thermal.V2_0.IThermal mThermalHal20 = null;
/** HWbinder callback for Thermal HAL 2.0. */
- private final IThermalChangedCallback.Stub mThermalCallback20 =
- new IThermalChangedCallback.Stub() {
+ private final android.hardware.thermal.V2_0.IThermalChangedCallback.Stub
+ mThermalCallback20 =
+ new android.hardware.thermal.V2_0.IThermalChangedCallback.Stub() {
@Override
public void notifyThrottling(
android.hardware.thermal.V2_0.Temperature temperature) {
@@ -976,7 +1142,7 @@
temperature.throttlingStatus)) {
Slog.e(TAG, "Invalid status data from HAL");
temperature.throttlingStatus =
- Temperature.THROTTLING_NONE;
+ Temperature.THROTTLING_NONE;
}
ret.add(new Temperature(
temperature.value, temperature.type,
@@ -1043,7 +1209,9 @@
mThermalHal20.getTemperatureThresholds(shouldFilter, type,
(status, thresholds) -> {
if (ThermalStatusCode.SUCCESS == status.code) {
- ret.addAll(thresholds);
+ ret.addAll(thresholds.stream().map(
+ this::convertToAidlTemperatureThreshold).collect(
+ Collectors.toList()));
} else {
Slog.e(TAG,
"Couldn't get temperature thresholds because of HAL "
@@ -1057,6 +1225,16 @@
}
}
+ private TemperatureThreshold convertToAidlTemperatureThreshold(
+ android.hardware.thermal.V2_0.TemperatureThreshold threshold) {
+ final TemperatureThreshold ret = new TemperatureThreshold();
+ ret.name = threshold.name;
+ ret.type = threshold.type;
+ ret.coldThrottlingThresholds = threshold.coldThrottlingThresholds;
+ ret.hotThrottlingThresholds = threshold.hotThrottlingThresholds;
+ return ret;
+ }
+
@Override
protected boolean connectToHal() {
synchronized (mHalLock) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java
new file mode 100644
index 0000000..34b17c7
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 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.power;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.hardware.thermal.CoolingType;
+import android.hardware.thermal.IThermal;
+import android.hardware.thermal.IThermalChangedCallback;
+import android.hardware.thermal.TemperatureThreshold;
+import android.hardware.thermal.TemperatureType;
+import android.hardware.thermal.ThrottlingSeverity;
+import android.os.Binder;
+import android.os.CoolingDevice;
+import android.os.RemoteException;
+import android.os.Temperature;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+
+public class ThermalManagerServiceMockingTest {
+ @Mock private IThermal mAidlHalMock;
+ private Binder mAidlBinder = new Binder();
+ private CompletableFuture<Temperature> mTemperatureFuture;
+ private ThermalManagerService.ThermalHalWrapper.TemperatureChangedCallback mTemperatureCallback;
+ private ThermalManagerService.ThermalHalAidlWrapper mAidlWrapper;
+ @Captor
+ ArgumentCaptor<IThermalChangedCallback> mAidlCallbackCaptor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ Mockito.when(mAidlHalMock.asBinder()).thenReturn(mAidlBinder);
+ mAidlBinder.attachInterface(mAidlHalMock, IThermal.class.getName());
+ mTemperatureFuture = new CompletableFuture<>();
+ mTemperatureCallback = temperature -> mTemperatureFuture.complete(temperature);
+ mAidlWrapper = new ThermalManagerService.ThermalHalAidlWrapper();
+ mAidlWrapper.setCallback(mTemperatureCallback);
+ mAidlWrapper.initProxyAndRegisterCallback(mAidlBinder);
+ }
+
+ @Test
+ public void setCallback_aidl() throws Exception {
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).registerThermalChangedCallback(
+ mAidlCallbackCaptor.capture());
+ android.hardware.thermal.Temperature halT =
+ new android.hardware.thermal.Temperature();
+ halT.type = TemperatureType.SOC;
+ halT.name = "test";
+ halT.throttlingStatus = ThrottlingSeverity.SHUTDOWN;
+ halT.value = 99.0f;
+ mAidlCallbackCaptor.getValue().notifyThrottling(halT);
+ Temperature temperature = mTemperatureFuture.get(100, TimeUnit.MILLISECONDS);
+ assertEquals(halT.name, temperature.getName());
+ assertEquals(halT.type, temperature.getType());
+ assertEquals(halT.value, temperature.getValue(), 0.1f);
+ assertEquals(halT.throttlingStatus, temperature.getStatus());
+ }
+
+ @Test
+ public void getCurrentTemperatures_withFilter_aidl() throws RemoteException {
+ android.hardware.thermal.Temperature halT1 = new android.hardware.thermal.Temperature();
+ halT1.type = TemperatureType.MODEM;
+ halT1.name = "test1";
+ halT1.throttlingStatus = ThrottlingSeverity.EMERGENCY;
+ halT1.value = 99.0f;
+ android.hardware.thermal.Temperature halT2 = new android.hardware.thermal.Temperature();
+ halT2.name = "test2";
+ halT2.type = TemperatureType.MODEM;
+ halT2.throttlingStatus = ThrottlingSeverity.NONE;
+
+ android.hardware.thermal.Temperature halT3WithDiffType =
+ new android.hardware.thermal.Temperature();
+ halT3WithDiffType.type = TemperatureType.BCL_CURRENT;
+ halT3WithDiffType.throttlingStatus = ThrottlingSeverity.CRITICAL;
+
+ Mockito.when(mAidlHalMock.getTemperaturesWithType(Mockito.anyInt())).thenReturn(
+ new android.hardware.thermal.Temperature[]{
+ halT2, halT1, halT3WithDiffType,
+ });
+ List<Temperature> ret = mAidlWrapper.getCurrentTemperatures(true, TemperatureType.MODEM);
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).getTemperaturesWithType(
+ TemperatureType.MODEM);
+
+ Temperature expectedT1 = new Temperature(halT1.value, halT1.type, halT1.name,
+ halT1.throttlingStatus);
+ Temperature expectedT2 = new Temperature(halT2.value, halT2.type, halT2.name,
+ halT2.throttlingStatus);
+ List<Temperature> expectedRet = List.of(expectedT1, expectedT2);
+ assertTrue("Got temperature list as " + ret + " with different values compared to "
+ + expectedRet, expectedRet.containsAll(ret));
+ }
+
+ @Test
+ public void getCurrentTemperatures_invalidStatus_aidl() throws RemoteException {
+ android.hardware.thermal.Temperature halTInvalid =
+ new android.hardware.thermal.Temperature();
+ halTInvalid.name = "test";
+ halTInvalid.type = TemperatureType.MODEM;
+ halTInvalid.throttlingStatus = 99;
+
+ Mockito.when(mAidlHalMock.getTemperatures()).thenReturn(
+ new android.hardware.thermal.Temperature[]{
+ halTInvalid
+ });
+ List<Temperature> ret = mAidlWrapper.getCurrentTemperatures(false, 0);
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).getTemperatures();
+
+ List<Temperature> expectedRet = List.of(
+ new Temperature(halTInvalid.value, halTInvalid.type, halTInvalid.name,
+ ThrottlingSeverity.NONE));
+ assertEquals(expectedRet, ret);
+ }
+
+ @Test
+ public void getCurrentCoolingDevices_withFilter_aidl() throws RemoteException {
+ android.hardware.thermal.CoolingDevice halC1 = new android.hardware.thermal.CoolingDevice();
+ halC1.type = CoolingType.SPEAKER;
+ halC1.name = "test1";
+ halC1.value = 10;
+ android.hardware.thermal.CoolingDevice halC2 = new android.hardware.thermal.CoolingDevice();
+ halC2.type = CoolingType.MODEM;
+ halC2.name = "test2";
+ halC2.value = 110;
+
+ Mockito.when(mAidlHalMock.getCoolingDevicesWithType(Mockito.anyInt())).thenReturn(
+ new android.hardware.thermal.CoolingDevice[]{
+ halC1, halC2
+ }
+ );
+ List<CoolingDevice> ret = mAidlWrapper.getCurrentCoolingDevices(true, CoolingType.SPEAKER);
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).getCoolingDevicesWithType(
+ CoolingType.SPEAKER);
+
+ CoolingDevice expectedC1 = new CoolingDevice(halC1.value, halC1.type, halC1.name);
+ List<CoolingDevice> expectedRet = List.of(expectedC1);
+ assertTrue("Got cooling device list as " + ret + " with different values compared to "
+ + expectedRet, expectedRet.containsAll(ret));
+ }
+
+ @Test
+ public void getCurrentCoolingDevices_invalidType_aidl() throws RemoteException {
+ android.hardware.thermal.CoolingDevice halC1 = new android.hardware.thermal.CoolingDevice();
+ halC1.type = 99;
+ halC1.name = "test1";
+ halC1.value = 10;
+ android.hardware.thermal.CoolingDevice halC2 = new android.hardware.thermal.CoolingDevice();
+ halC2.type = -1;
+ halC2.name = "test2";
+ halC2.value = 110;
+
+ Mockito.when(mAidlHalMock.getCoolingDevices()).thenReturn(
+ new android.hardware.thermal.CoolingDevice[]{
+ halC1, halC2
+ }
+ );
+ List<CoolingDevice> ret = mAidlWrapper.getCurrentCoolingDevices(false, 0);
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).getCoolingDevices();
+
+ assertTrue("Got cooling device list as " + ret + ", expecting empty list", ret.isEmpty());
+ }
+
+ @Test
+ public void getTemperatureThresholds_withFilter_aidl() throws RemoteException {
+ TemperatureThreshold halT1 = new TemperatureThreshold();
+ halT1.name = "test1";
+ halT1.type = Temperature.TYPE_SKIN;
+ halT1.hotThrottlingThresholds = new float[]{1, 2, 3};
+ halT1.coldThrottlingThresholds = new float[]{};
+
+ TemperatureThreshold halT2 = new TemperatureThreshold();
+ halT1.name = "test2";
+ halT1.type = Temperature.TYPE_SOC;
+ halT1.hotThrottlingThresholds = new float[]{};
+ halT1.coldThrottlingThresholds = new float[]{3, 2, 1};
+
+ Mockito.when(mAidlHalMock.getTemperatureThresholdsWithType(Mockito.anyInt())).thenReturn(
+ new TemperatureThreshold[]{halT1, halT2}
+ );
+ List<TemperatureThreshold> ret = mAidlWrapper.getTemperatureThresholds(true,
+ Temperature.TYPE_SOC);
+ Mockito.verify(mAidlHalMock, Mockito.times(1)).getTemperatureThresholdsWithType(
+ Temperature.TYPE_SOC);
+
+ assertEquals("Got unexpected temperature thresholds size", 1, ret.size());
+ TemperatureThreshold threshold = ret.get(0);
+ assertEquals(halT1.name, threshold.name);
+ assertEquals(halT1.type, threshold.type);
+ assertArrayEquals(halT1.hotThrottlingThresholds, threshold.hotThrottlingThresholds, 0.1f);
+ assertArrayEquals(halT1.coldThrottlingThresholds, threshold.coldThrottlingThresholds, 0.1f);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 3848bab..57f9f18 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -30,8 +30,8 @@
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.hardware.thermal.V2_0.TemperatureThreshold;
-import android.hardware.thermal.V2_0.ThrottlingSeverity;
+import android.hardware.thermal.TemperatureThreshold;
+import android.hardware.thermal.ThrottlingSeverity;
import android.os.CoolingDevice;
import android.os.IBinder;
import android.os.IPowerManager;