diff options
| -rw-r--r-- | core/java/android/os/CoolingDevice.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/os/CoolingDevice.java | 166 | ||||
| -rw-r--r-- | core/java/android/os/IThermalService.aidl | 18 | ||||
| -rw-r--r-- | core/java/android/os/Temperature.java | 92 | ||||
| -rw-r--r-- | services/core/java/com/android/server/power/ThermalManagerService.java | 193 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java | 60 |
6 files changed, 470 insertions, 78 deletions
diff --git a/core/java/android/os/CoolingDevice.aidl b/core/java/android/os/CoolingDevice.aidl new file mode 100644 index 000000000000..478e4bd71e6d --- /dev/null +++ b/core/java/android/os/CoolingDevice.aidl @@ -0,0 +1,19 @@ +/* +** Copyright 2019, 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 android.os; + +parcelable CoolingDevice; diff --git a/core/java/android/os/CoolingDevice.java b/core/java/android/os/CoolingDevice.java new file mode 100644 index 000000000000..0e86a381932d --- /dev/null +++ b/core/java/android/os/CoolingDevice.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2019 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 android.os; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.hardware.thermal.V2_0.CoolingType; + +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Cooling device values used by IThermalService. + * + * @hide + */ +public final class CoolingDevice implements Parcelable { + /** + * Current throttle state of the cooling device. The value can any unsigned integer + * numbers between 0 and max_state defined in its driver, usually representing the + * associated device's power state. 0 means device is not in throttling, higher value + * means deeper throttling. + */ + private final long mValue; + /** A cooling device type from ThermalHAL */ + private final int mType; + /** Name of this cooling device */ + private final String mName; + + @IntDef(prefix = { "TYPE_" }, value = { + TYPE_FAN, + TYPE_BATTERY, + TYPE_CPU, + TYPE_GPU, + TYPE_MODEM, + TYPE_NPU, + TYPE_COMPONENT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Type {} + + /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */ + /** Fan for active cooling */ + public static final int TYPE_FAN = CoolingType.FAN; + /** Battery charging cooling deivice */ + public static final int TYPE_BATTERY = CoolingType.BATTERY; + /** CPU cooling deivice */ + public static final int TYPE_CPU = CoolingType.CPU; + /** GPU cooling deivice */ + public static final int TYPE_GPU = CoolingType.GPU; + /** Modem cooling deivice */ + public static final int TYPE_MODEM = CoolingType.MODEM; + /** NPU/TPU cooling deivice */ + public static final int TYPE_NPU = CoolingType.NPU; + /** Generic passive cooling deivice */ + public static final int TYPE_COMPONENT = CoolingType.COMPONENT; + + /** + * Verify a valid cooling device type. + * + * @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; + } + + public CoolingDevice(long value, @Type int type, @NonNull String name) { + Preconditions.checkArgument(isValidType(type), "Invalid Type"); + mValue = value; + mType = type; + mName = Preconditions.checkStringNotEmpty(name); + } + + /** + * Return the cooling device value. + * + * @return a cooling device value in int. + */ + public long getValue() { + return mValue; + } + + /** + * Return the cooling device type. + * + * @return a cooling device type: TYPE_* + */ + public @Type int getType() { + return mType; + } + + /** + * Return the cooling device name. + * + * @return a cooling device name as String. + */ + public String getName() { + return mName; + } + + @Override + public String toString() { + return "CoolingDevice{mValue=" + mValue + ", mType=" + mType + ", mName=" + mName + "}"; + } + + @Override + public int hashCode() { + int hash = mName.hashCode(); + hash = 31 * hash + Long.hashCode(mValue); + hash = 31 * hash + mType; + return hash; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof CoolingDevice)) { + return false; + } + CoolingDevice other = (CoolingDevice) o; + return other.mValue == mValue && other.mType == mType && other.mName.equals(mName); + } + + @Override + public void writeToParcel(Parcel p, int flags) { + p.writeLong(mValue); + p.writeInt(mType); + p.writeString(mName); + } + + public static final @android.annotation.NonNull Parcelable.Creator<CoolingDevice> CREATOR = + new Parcelable.Creator<CoolingDevice>() { + @Override + public CoolingDevice createFromParcel(Parcel p) { + long value = p.readLong(); + int type = p.readInt(); + String name = p.readString(); + return new CoolingDevice(value, type, name); + } + + @Override + public CoolingDevice[] newArray(int size) { + return new CoolingDevice[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl index 9280cb9f18b8..8c989607e8db 100644 --- a/core/java/android/os/IThermalService.aidl +++ b/core/java/android/os/IThermalService.aidl @@ -16,6 +16,7 @@ package android.os; +import android.os.CoolingDevice; import android.os.IThermalEventListener; import android.os.IThermalStatusListener; import android.os.Temperature; @@ -52,7 +53,7 @@ interface IThermalService { /** * Get current temperature with its throttling status. - * @return list of android.os.Temperature + * @return list of {@link android.os.Temperature}. * {@hide} */ List<Temperature> getCurrentTemperatures(); @@ -87,4 +88,19 @@ interface IThermalService { * {@hide} */ int getCurrentThermalStatus(); + + /** + * Get current cooling devices. + * @return list of {@link android.os.CoolingDevice}. + * {@hide} + */ + List<CoolingDevice> getCurrentCoolingDevices(); + + /** + * Get current cooling devices on given type. + * @param type the cooling device type to query. + * @return list of {@link android.os.CoolingDevice}. + * {@hide} + */ + List<CoolingDevice> getCurrentCoolingDevicesWithType(in int type); } diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java index be7e824c49fb..7caffcd2ddfd 100644 --- a/core/java/android/os/Temperature.java +++ b/core/java/android/os/Temperature.java @@ -17,9 +17,12 @@ package android.os; import android.annotation.IntDef; +import android.annotation.NonNull; import android.hardware.thermal.V2_0.TemperatureType; import android.hardware.thermal.V2_0.ThrottlingSeverity; +import com.android.internal.util.Preconditions; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -30,13 +33,13 @@ import java.lang.annotation.RetentionPolicy; */ public final class Temperature implements Parcelable { /** Temperature value */ - private float mValue; - /** A temperature type from ThermalHAL */ - private int mType; - /** Name of this temperature */ - private String mName; + private final float mValue; + /** A Temperature type from ThermalHAL */ + private final int mType; + /** Name of this Temperature */ + private final String mName; /** The level of the sensor is currently in throttling */ - private int mStatus; + private final int mStatus; @IntDef(prefix = { "THROTTLING_" }, value = { THROTTLING_NONE, @@ -75,7 +78,7 @@ public final class Temperature implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface Type {} - /* Keep in sync with hardware/interfaces/thermal/2.0/types.hal */ + /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */ public static final int TYPE_UNKNOWN = TemperatureType.UNKNOWN; public static final int TYPE_CPU = TemperatureType.CPU; public static final int TYPE_GPU = TemperatureType.GPU; @@ -89,9 +92,9 @@ public final class Temperature implements Parcelable { public static final int TYPE_NPU = TemperatureType.NPU; /** - * Verify a valid temperature type. + * Verify a valid Temperature type. * - * @return true if a temperature type is valid otherwise false. + * @return true if a Temperature type is valid otherwise false. */ public static boolean isValidType(@Type int type) { return type >= TYPE_UNKNOWN && type <= TYPE_NPU; @@ -106,67 +109,75 @@ public final class Temperature implements Parcelable { return status >= THROTTLING_NONE && status <= THROTTLING_SHUTDOWN; } - public Temperature() { - this(Float.NaN, TYPE_UNKNOWN, "", THROTTLING_NONE); - } - - public Temperature(float value, @Type int type, String name, @ThrottlingStatus int status) { + public Temperature(float value, @Type int type, + @NonNull String name, @ThrottlingStatus int status) { + Preconditions.checkArgument(isValidType(type), "Invalid Type"); + Preconditions.checkArgument(isValidStatus(status) , "Invalid Status"); mValue = value; - mType = isValidType(type) ? type : TYPE_UNKNOWN; - mName = name; - mStatus = isValidStatus(status) ? status : THROTTLING_NONE; + mType = type; + mName = Preconditions.checkStringNotEmpty(name); + mStatus = status; } /** - * Return the temperature value. + * Return the Temperature value. * - * @return a temperature value in floating point could be NaN. + * @return a Temperature value in floating point could be NaN. */ public float getValue() { return mValue; } /** - * Return the temperature type. + * Return the Temperature type. * - * @return a temperature type: TYPE_* + * @return a Temperature type: TYPE_* */ public @Type int getType() { return mType; } /** - * Return the temperature name. + * Return the Temperature name. * - * @return a temperature name as String. + * @return a Temperature name as String. */ public String getName() { return mName; } /** - * Return the temperature throttling status. + * Return the Temperature throttling status. * - * @return a temperature throttling status: THROTTLING_* + * @return a Temperature throttling status: THROTTLING_* */ public @ThrottlingStatus int getStatus() { return mStatus; } - private Temperature(Parcel p) { - readFromParcel(p); + @Override + public String toString() { + return "Temperature{mValue=" + mValue + ", mType=" + mType + + ", mName=" + mName + ", mStatus=" + mStatus + "}"; } - /** - * Fill in Temperature members from a Parcel. - * - * @param p the parceled Temperature object. - */ - public void readFromParcel(Parcel p) { - mValue = p.readFloat(); - mType = p.readInt(); - mName = p.readString(); - mStatus = p.readInt(); + @Override + public int hashCode() { + int hash = mName.hashCode(); + hash = 31 * hash + Float.hashCode(mValue); + hash = 31 * hash + mType; + hash = 31 * hash + mStatus; + return hash; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Temperature)) { + return false; + } + Temperature other = (Temperature) o; + return other.mValue == mValue && other.mType == mType + && other.mName.equals(mName) && other.mStatus == mStatus; } @Override @@ -181,13 +192,18 @@ public final class Temperature implements Parcelable { new Parcelable.Creator<Temperature>() { @Override public Temperature createFromParcel(Parcel p) { - return new Temperature(p); + float value = p.readFloat(); + int type = p.readInt(); + String name = p.readString(); + int status = p.readInt(); + return new Temperature(value, type, name, status); } @Override public Temperature[] newArray(int size) { return new Temperature[size]; } + }; @Override diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java index 16d11efb0738..03814453fc52 100644 --- a/services/core/java/com/android/server/power/ThermalManagerService.java +++ b/services/core/java/com/android/server/power/ThermalManagerService.java @@ -24,6 +24,7 @@ import android.hardware.thermal.V1_1.IThermalCallback; import android.hardware.thermal.V2_0.IThermalChangedCallback; import android.hardware.thermal.V2_0.ThrottlingSeverity; import android.os.Binder; +import android.os.CoolingDevice; import android.os.HwBinder; import android.os.IThermalEventListener; import android.os.IThermalService; @@ -49,8 +50,10 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicBoolean; /** * This is a system service that listens to HAL thermal events and dispatch those to listeners. @@ -93,8 +96,7 @@ public class ThermalManagerService extends SystemService { private ThermalHalWrapper mHalWrapper; /** Hal ready. */ - @GuardedBy("mLock") - private boolean mHalReady; + private final AtomicBoolean mHalReady = new AtomicBoolean(); /** Invalid throttling status */ private static final int INVALID_THROTTLING = Integer.MIN_VALUE; @@ -150,7 +152,7 @@ public class ThermalManagerService extends SystemService { onTemperatureChanged(temperatures.get(i), false); } onTemperatureMapChangedLocked(); - mHalReady = halConnected /* true */; + mHalReady.set(true); } } @@ -298,20 +300,6 @@ public class ThermalManagerService extends SystemService { } } - private void dumpTemperaturesLocked(PrintWriter pw, String prefix, - Collection<Temperature> temperatures) { - for (Temperature t : temperatures) { - pw.print(prefix); - String out = String.format("Name: %s, Type: %d, Status: %d, Value: %f", - t.getName(), - t.getType(), - t.getStatus(), - t.getValue() - ); - pw.println(out); - } - } - @VisibleForTesting final IThermalService.Stub mService = new IThermalService.Stub() { @Override @@ -324,7 +312,7 @@ public class ThermalManagerService extends SystemService { if (!mThermalEventListeners.register(listener, null)) { return false; } - if (mHalReady) { + if (mHalReady.get()) { // Notify its callback after new client registered. postEventListenerCurrentTemperatures(listener, null); } @@ -346,7 +334,7 @@ public class ThermalManagerService extends SystemService { if (!mThermalEventListeners.register(listener, new Integer(type))) { return false; } - if (mHalReady) { + if (mHalReady.get()) { // Notify its callback after new client registered. postEventListenerCurrentTemperatures(listener, new Integer(type)); } @@ -377,7 +365,7 @@ public class ThermalManagerService extends SystemService { android.Manifest.permission.DEVICE_POWER, null); final long token = Binder.clearCallingIdentity(); try { - if (!mHalReady) { + if (!mHalReady.get()) { return new ArrayList<>(); } return mHalWrapper.getCurrentTemperatures(false, 0 /* not used */); @@ -392,7 +380,7 @@ public class ThermalManagerService extends SystemService { android.Manifest.permission.DEVICE_POWER, null); final long token = Binder.clearCallingIdentity(); try { - if (!mHalReady) { + if (!mHalReady.get()) { return new ArrayList<>(); } return mHalWrapper.getCurrentTemperatures(true, type); @@ -410,7 +398,7 @@ public class ThermalManagerService extends SystemService { if (!mThermalStatusListeners.register(listener)) { return false; } - if (mHalReady) { + if (mHalReady.get()) { // Notify its callback after new client registered. postStatusListener(listener); } @@ -447,6 +435,43 @@ public class ThermalManagerService extends SystemService { } @Override + public List<CoolingDevice> getCurrentCoolingDevices() { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.DEVICE_POWER, null); + final long token = Binder.clearCallingIdentity(); + try { + if (!mHalReady.get()) { + return new ArrayList<>(); + } + return mHalWrapper.getCurrentCoolingDevices(false, 0); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public List<CoolingDevice> getCurrentCoolingDevicesWithType(int type) { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.DEVICE_POWER, null); + final long token = Binder.clearCallingIdentity(); + try { + if (!mHalReady.get()) { + return new ArrayList<>(); + } + return mHalWrapper.getCurrentCoolingDevices(true, type); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private void dumpItemsLocked(PrintWriter pw, String prefix, + Collection<?> items) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + pw.println(prefix + iterator.next().toString()); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { return; @@ -461,17 +486,19 @@ public class ThermalManagerService extends SystemService { mThermalStatusListeners.dump(pw, "\t"); pw.println("Thermal Status: " + mStatus); pw.println("Cached temperatures:"); - dumpTemperaturesLocked(pw, "\t", mTemperatureMap.values()); - pw.println("HAL Ready: " + mHalReady); - if (mHalReady) { + dumpItemsLocked(pw, "\t", mTemperatureMap.values()); + pw.println("HAL Ready: " + mHalReady.get()); + if (mHalReady.get()) { pw.println("HAL connection:"); mHalWrapper.dump(pw, "\t"); pw.println("Current temperatures from HAL:"); - dumpTemperaturesLocked(pw, "\t", + dumpItemsLocked(pw, "\t", mHalWrapper.getCurrentTemperatures(false, 0)); + pw.println("Current cooling devices from HAL:"); + dumpItemsLocked(pw, "\t", + mHalWrapper.getCurrentCoolingDevices(false, 0)); } } - } finally { Binder.restoreCallingIdentity(token); } @@ -588,6 +615,9 @@ public class ThermalManagerService extends SystemService { protected abstract List<Temperature> getCurrentTemperatures(boolean shouldFilter, int type); + protected abstract List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, + int type); + protected abstract boolean connectToHal(); protected abstract void dump(PrintWriter pw, String prefix); @@ -664,6 +694,42 @@ public class ThermalManagerService extends SystemService { } @Override + protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, + int type) { + synchronized (mHalLock) { + List<CoolingDevice> ret = new ArrayList<>(); + if (mThermalHal10 == null) { + return ret; + } + try { + mThermalHal10.getCoolingDevices((status, coolingDevices) -> { + if (ThermalStatusCode.SUCCESS == status.code) { + for (android.hardware.thermal.V1_0.CoolingDevice + coolingDevice : coolingDevices) { + if (shouldFilter && type != coolingDevice.type) { + continue; + } + ret.add(new CoolingDevice( + (long) coolingDevice.currentValue, + coolingDevice.type, + coolingDevice.name)); + } + } else { + Slog.e(TAG, + "Couldn't get cooling device because of HAL error: " + + status.debugMessage); + } + + }); + } catch (RemoteException e) { + Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e); + connectToHal(); + } + return ret; + } + } + + @Override protected boolean connectToHal() { synchronized (mHalLock) { try { @@ -757,6 +823,42 @@ public class ThermalManagerService extends SystemService { } @Override + protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, + int type) { + synchronized (mHalLock) { + List<CoolingDevice> ret = new ArrayList<>(); + if (mThermalHal11 == null) { + return ret; + } + try { + mThermalHal11.getCoolingDevices((status, coolingDevices) -> { + if (ThermalStatusCode.SUCCESS == status.code) { + for (android.hardware.thermal.V1_0.CoolingDevice + coolingDevice : coolingDevices) { + if (shouldFilter && type != coolingDevice.type) { + continue; + } + ret.add(new CoolingDevice( + (long) coolingDevice.currentValue, + coolingDevice.type, + coolingDevice.name)); + } + } else { + Slog.e(TAG, + "Couldn't get cooling device because of HAL error: " + + status.debugMessage); + } + + }); + } catch (RemoteException e) { + Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e); + connectToHal(); + } + return ret; + } + } + + @Override protected boolean connectToHal() { synchronized (mHalLock) { try { @@ -817,9 +919,7 @@ public class ThermalManagerService extends SystemService { } try { mThermalHal20.getCurrentTemperatures(shouldFilter, type, - (ThermalStatus status, - ArrayList<android.hardware.thermal.V2_0.Temperature> - temperatures) -> { + (status, temperatures) -> { if (ThermalStatusCode.SUCCESS == status.code) { for (android.hardware.thermal.V2_0.Temperature temperature : temperatures) { @@ -844,6 +944,39 @@ public class ThermalManagerService extends SystemService { } @Override + protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, + int type) { + synchronized (mHalLock) { + List<CoolingDevice> ret = new ArrayList<>(); + if (mThermalHal20 == null) { + return ret; + } + try { + mThermalHal20.getCurrentCoolingDevices(shouldFilter, type, + (status, coolingDevices) -> { + if (ThermalStatusCode.SUCCESS == status.code) { + for (android.hardware.thermal.V2_0.CoolingDevice + coolingDevice : coolingDevices) { + ret.add(new CoolingDevice( + coolingDevice.value, coolingDevice.type, + coolingDevice.name)); + } + } else { + Slog.e(TAG, + "Couldn't get cooling device because of HAL error: " + + status.debugMessage); + } + + }); + } catch (RemoteException e) { + Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e); + connectToHal(); + } + return ret; + } + } + + @Override protected boolean connectToHal() { synchronized (mHalLock) { try { 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 94d293efd204..27d529635b70 100644 --- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.os.CoolingDevice; import android.os.IBinder; import android.os.IPowerManager; import android.os.IThermalEventListener; @@ -85,6 +86,8 @@ public class ThermalManagerServiceTest { private class ThermalHalFake extends ThermalHalWrapper { private static final int INIT_STATUS = Temperature.THROTTLING_NONE; private ArrayList<Temperature> mTemperatureList = new ArrayList<>(); + private ArrayList<CoolingDevice> mCoolingDeviceList = new ArrayList<>(); + private Temperature mSkin1 = new Temperature(0, Temperature.TYPE_SKIN, "skin1", INIT_STATUS); private Temperature mSkin2 = new Temperature(0, Temperature.TYPE_SKIN, "skin2", @@ -93,17 +96,40 @@ public class ThermalManagerServiceTest { INIT_STATUS); private Temperature mUsbPort = new Temperature(0, Temperature.TYPE_USB_PORT, "usbport", INIT_STATUS); + private CoolingDevice mCpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "cpu"); + private CoolingDevice mGpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "gpu"); ThermalHalFake() { mTemperatureList.add(mSkin1); mTemperatureList.add(mSkin2); mTemperatureList.add(mBattery); mTemperatureList.add(mUsbPort); + mCoolingDeviceList.add(mCpu); + mCoolingDeviceList.add(mGpu); } @Override protected List<Temperature> getCurrentTemperatures(boolean shouldFilter, int type) { - return mTemperatureList; + List<Temperature> ret = new ArrayList<>(); + for (Temperature temperature : mTemperatureList) { + if (shouldFilter && type != temperature.getType()) { + continue; + } + ret.add(temperature); + } + return ret; + } + + @Override + protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, int type) { + List<CoolingDevice> ret = new ArrayList<>(); + for (CoolingDevice cdev : mCoolingDeviceList) { + if (shouldFilter && type != cdev.getType()) { + continue; + } + ret.add(cdev); + } + return ret; } @Override @@ -117,8 +143,10 @@ public class ThermalManagerServiceTest { } } - private void assertTemperatureEquals(List<Temperature> expected, List<Temperature> value) { - assertEquals(new HashSet<>(expected), new HashSet<>(value)); + private void assertListEqualsIgnoringOrder(List<?> actual, List<?> expected) { + HashSet<?> actualSet = new HashSet<>(actual); + HashSet<?> expectedSet = new HashSet<>(expected); + assertEquals(expectedSet, actualSet); } @Before @@ -148,13 +176,14 @@ public class ThermalManagerServiceTest { ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class); verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(4)).notifyThrottling(captor.capture()); - assertTemperatureEquals(mFakeHal.mTemperatureList, captor.getAllValues()); + assertListEqualsIgnoringOrder(mFakeHal.mTemperatureList, captor.getAllValues()); verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(1)).onStatusChange(Temperature.THROTTLING_NONE); captor = ArgumentCaptor.forClass(Temperature.class); verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(2)).notifyThrottling(captor.capture()); - assertTemperatureEquals(new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)), + assertListEqualsIgnoringOrder( + new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)), captor.getAllValues()); verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(1)).onStatusChange(Temperature.THROTTLING_NONE); @@ -185,7 +214,7 @@ public class ThermalManagerServiceTest { ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class); verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(4)).notifyThrottling(captor.capture()); - assertTemperatureEquals(mFakeHal.mTemperatureList, captor.getAllValues()); + assertListEqualsIgnoringOrder(mFakeHal.mTemperatureList, captor.getAllValues()); verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(1)).onStatusChange(Temperature.THROTTLING_NONE); // Register new callbacks and verify old ones are not called (remained same) while new @@ -200,7 +229,8 @@ public class ThermalManagerServiceTest { captor = ArgumentCaptor.forClass(Temperature.class); verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(2)).notifyThrottling(captor.capture()); - assertTemperatureEquals(new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)), + assertListEqualsIgnoringOrder( + new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)), captor.getAllValues()); verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(1)).onStatusChange(Temperature.THROTTLING_NONE); @@ -260,9 +290,9 @@ public class ThermalManagerServiceTest { @Test public void testGetCurrentTemperatures() throws RemoteException { - assertTemperatureEquals(mFakeHal.getCurrentTemperatures(false, 0), + assertListEqualsIgnoringOrder(mFakeHal.getCurrentTemperatures(false, 0), mService.mService.getCurrentTemperatures()); - assertTemperatureEquals(mFakeHal.getCurrentTemperatures(true, Temperature.TYPE_SKIN), + assertListEqualsIgnoringOrder(mFakeHal.getCurrentTemperatures(true, Temperature.TYPE_SKIN), mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN)); } @@ -300,4 +330,16 @@ public class ThermalManagerServiceTest { mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size()); assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus()); } + + @Test + public void testGetCurrentCoolingDevices() throws RemoteException { + assertListEqualsIgnoringOrder(mFakeHal.getCurrentCoolingDevices(false, 0), + mService.mService.getCurrentCoolingDevices()); + assertListEqualsIgnoringOrder( + mFakeHal.getCurrentCoolingDevices(false, CoolingDevice.TYPE_BATTERY), + mService.mService.getCurrentCoolingDevices()); + assertListEqualsIgnoringOrder( + mFakeHal.getCurrentCoolingDevices(true, CoolingDevice.TYPE_CPU), + mService.mService.getCurrentCoolingDevicesWithType(CoolingDevice.TYPE_CPU)); + } } |