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  */
16 package android.os;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.SystemService;
21 import android.content.Context;
22 import android.hardware.thermal.V1_0.Constants;
23 import android.util.Log;
24 
25 import java.lang.annotation.Retention;
26 import 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)
33 public 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 */
HardwarePropertiesManager(Context context, IHardwarePropertiesManager service)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     */
getDeviceTemperatures(@eviceTemperatureType int type, @TemperatureSource int source)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      */
getCpuUsages()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      */
getFanSpeeds()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