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

Commit ec987d3e authored by Wei Wang's avatar Wei Wang Committed by android-build-merger
Browse files

Merge "Add cooling device into thermal service" into qt-dev

am: 6e14a032

Change-Id: Ib78a454205c03ef3960674f9ce48d6ad9dc8530d
parents a7e033a3 6e14a032
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
** 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;
+166 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -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);
}
+54 −38
Original line number Diff line number Diff line
@@ -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
+163 −30
Original line number Diff line number Diff line
@@ -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);
                    }
@@ -446,6 +434,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)) {
@@ -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);
@@ -663,6 +693,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) {
@@ -756,6 +822,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) {
@@ -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) {
@@ -843,6 +943,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) {
Loading