1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.os;
17
18import android.annotation.IntDef;
19import android.annotation.NonNull;
20import android.annotation.SystemService;
21import android.content.Context;
22import android.hardware.thermal.V1_0.Constants;
23import android.util.Log;
24
25import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27
28/**
29 * The HardwarePropertiesManager class provides a mechanism of accessing hardware state of a
30 * device: CPU, GPU and battery temperatures, CPU usage per core, fan speed, etc.
31 */
32@SystemService(Context.HARDWARE_PROPERTIES_SERVICE)
33public class HardwarePropertiesManager {
34
35    private static final String TAG = HardwarePropertiesManager.class.getSimpleName();
36
37    private final IHardwarePropertiesManager mService;
38
39    /**
40     * @hide
41     */
42    @Retention(RetentionPolicy.SOURCE)
43    @IntDef(prefix = { "DEVICE_TEMPERATURE_" }, value = {
44            DEVICE_TEMPERATURE_CPU,
45            DEVICE_TEMPERATURE_GPU,
46            DEVICE_TEMPERATURE_BATTERY,
47            DEVICE_TEMPERATURE_SKIN
48    })
49    public @interface DeviceTemperatureType {}
50
51    /**
52     * @hide
53     */
54    @Retention(RetentionPolicy.SOURCE)
55    @IntDef(prefix = { "TEMPERATURE_" }, value = {
56            TEMPERATURE_CURRENT,
57            TEMPERATURE_THROTTLING,
58            TEMPERATURE_SHUTDOWN,
59            TEMPERATURE_THROTTLING_BELOW_VR_MIN
60    })
61    public @interface TemperatureSource {}
62
63    /**
64     * Device temperature types.
65     */
66    // These constants are also defined in android/os/enums.proto.
67    // Any change to the types here or in the thermal hal should be made in the proto as well.
68    /** Temperature of CPUs in Celsius. */
69    public static final int DEVICE_TEMPERATURE_CPU = Constants.TemperatureType.CPU;
70
71    /** Temperature of GPUs in Celsius. */
72    public static final int DEVICE_TEMPERATURE_GPU = Constants.TemperatureType.GPU;
73
74    /** Temperature of battery in Celsius. */
75    public static final int DEVICE_TEMPERATURE_BATTERY = Constants.TemperatureType.BATTERY;
76
77    /** Temperature of device skin in Celsius. */
78    public static final int DEVICE_TEMPERATURE_SKIN = Constants.TemperatureType.SKIN;
79
80    /** Get current temperature. */
81    public static final int TEMPERATURE_CURRENT = 0;
82
83    /** Get throttling temperature threshold. */
84    public static final int TEMPERATURE_THROTTLING = 1;
85
86    /** Get shutdown temperature threshold. */
87    public static final int TEMPERATURE_SHUTDOWN = 2;
88
89    /**
90     * Get throttling temperature threshold above which minimum clockrates for VR mode will not be
91     * met.
92     */
93    public static final int TEMPERATURE_THROTTLING_BELOW_VR_MIN = 3;
94
95    /** Undefined temperature constant. */
96    public static final float UNDEFINED_TEMPERATURE = -Float.MAX_VALUE;
97
98    /** Calling app context. */
99    private final Context mContext;
100
101    /** @hide */
102    public HardwarePropertiesManager(Context context, IHardwarePropertiesManager service) {
103        mContext = context;
104        mService = service;
105    }
106
107    /**
108     * Return an array of device temperatures in Celsius.
109     *
110     * @param type type of requested device temperature, one of {@link #DEVICE_TEMPERATURE_CPU},
111     * {@link #DEVICE_TEMPERATURE_GPU}, {@link #DEVICE_TEMPERATURE_BATTERY} or {@link
112     * #DEVICE_TEMPERATURE_SKIN}.
113     * @param source source of requested device temperature, one of {@link #TEMPERATURE_CURRENT},
114     * {@link #TEMPERATURE_THROTTLING}, {@link #TEMPERATURE_THROTTLING_BELOW_VR_MIN} or
115     * {@link #TEMPERATURE_SHUTDOWN}.
116     * @return an array of requested float device temperatures. Temperature equals to
117     *         {@link #UNDEFINED_TEMPERATURE} if undefined.
118     *         Empty if platform doesn't provide the queried temperature.
119     *
120     * @throws SecurityException if something other than the device owner or the current VR service
121     *         tries to retrieve information provided by this service.
122    */
123    public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type,
124            @TemperatureSource int source) {
125        switch (type) {
126            case DEVICE_TEMPERATURE_CPU:
127            case DEVICE_TEMPERATURE_GPU:
128            case DEVICE_TEMPERATURE_BATTERY:
129            case DEVICE_TEMPERATURE_SKIN:
130                switch (source) {
131                    case TEMPERATURE_CURRENT:
132                    case TEMPERATURE_THROTTLING:
133                    case TEMPERATURE_SHUTDOWN:
134                    case TEMPERATURE_THROTTLING_BELOW_VR_MIN:
135                        try {
136                            return mService.getDeviceTemperatures(mContext.getOpPackageName(), type,
137                                    source);
138                        } catch (RemoteException e) {
139                            throw e.rethrowFromSystemServer();
140                        }
141                    default:
142                        Log.w(TAG, "Unknown device temperature source.");
143                        return new float[0];
144                }
145            default:
146                Log.w(TAG, "Unknown device temperature type.");
147                return new float[0];
148        }
149    }
150
151    /**
152     * Return an array of CPU usage info for each core.
153     *
154     * @return an array of {@link android.os.CpuUsageInfo} for each core. Return {@code null} for
155     *         each unplugged core.
156     *         Empty if CPU usage is not supported on this system.
157     *
158     * @throws SecurityException if something other than the device owner or the current VR service
159     *         tries to retrieve information provided by this service.
160     */
161    public @NonNull CpuUsageInfo[] getCpuUsages() {
162        try {
163            return mService.getCpuUsages(mContext.getOpPackageName());
164        } catch (RemoteException e) {
165            throw e.rethrowFromSystemServer();
166        }
167    }
168
169    /**
170     * Return an array of fan speeds in RPM.
171     *
172     * @return an array of float fan speeds in RPM. Empty if there are no fans or fan speed is not
173     * supported on this system.
174     *
175     * @throws SecurityException if something other than the device owner or the current VR service
176     *         tries to retrieve information provided by this service.
177     */
178    public @NonNull float[] getFanSpeeds() {
179        try {
180            return mService.getFanSpeeds(mContext.getOpPackageName());
181        } catch (RemoteException e) {
182            throw e.rethrowFromSystemServer();
183        }
184    }
185}
186