Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2290136 authored by Xiang Wang's avatar Xiang Wang
Browse files

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
parent 47e17f78
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ filegroup {
        ":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",
+17 −4
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ package android.os;
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 @@ public final class CoolingDevice implements Parcelable {
            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 final class CoolingDevice implements Parcelable {
    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 @@ public final class CoolingDevice implements Parcelable {
     * @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) {
+15 −5
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@ package android.os;
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 @@ public final class Temperature implements Parcelable {
    @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 @@ public final class Temperature implements Parcelable {
            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 final class Temperature implements Parcelable {
    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 @@ public final class Temperature implements Parcelable {
     * @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;
    }

    /**
+188 −10
Original line number Diff line number Diff line
@@ -19,16 +19,18 @@ package com.android.server.power;
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.Process;
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 com.android.server.SystemService;
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.
@@ -143,6 +148,10 @@ public class ThermalManagerService extends SystemService {
        synchronized (mLock) {
            // 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 @@ public class ThermalManagerService extends SystemService {
        }
    }

    @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 @@ public class ThermalManagerService extends SystemService {
                            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 @@ public class ThermalManagerService extends SystemService {
        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) {
@@ -1043,7 +1209,9 @@ public class ThermalManagerService extends SystemService {
                    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 @@ public class ThermalManagerService extends SystemService {
            }
        }

        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) {
+218 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading