• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 
17 package android.os;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SystemApi;
25 import android.annotation.SystemService;
26 import android.annotation.TestApi;
27 import android.content.Context;
28 import android.net.NetworkStack;
29 import android.os.connectivity.CellularBatteryStats;
30 import android.os.connectivity.WifiBatteryStats;
31 import android.telephony.DataConnectionRealTimeInfo;
32 
33 import com.android.internal.app.IBatteryStats;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.List;
38 
39 /**
40  * This class provides an API surface for internal system components to report events that are
41  * needed for battery usage/estimation and battery blaming for apps.
42  *
43  * Note: This internally uses the same {@link IBatteryStats} binder service as the public
44  * {@link BatteryManager}.
45  * @hide
46  */
47 @SystemApi
48 @SystemService(Context.BATTERY_STATS_SERVICE)
49 public final class BatteryStatsManager {
50     /**
51      * Wifi states.
52      *
53      * @see #noteWifiState(int, String)
54      */
55     /**
56      * Wifi fully off.
57      */
58     public static final int WIFI_STATE_OFF = 0;
59     /**
60      * Wifi connectivity off, but scanning enabled.
61      */
62     public static final int WIFI_STATE_OFF_SCANNING = 1;
63     /**
64      * Wifi on, but no saved infrastructure networks to connect to.
65      */
66     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
67     /**
68      * Wifi on, but not connected to any infrastructure networks.
69      */
70     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
71     /**
72      * Wifi on and connected to a infrastructure network.
73      */
74     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
75     /**
76      * Wifi on and connected to a P2P device, but no infrastructure connection to a network.
77      */
78     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
79     /**
80      * Wifi on and connected to both a P2P device and infrastructure connection to a network.
81      */
82     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
83     /**
84      * SoftAp/Hotspot turned on.
85      */
86     public static final int WIFI_STATE_SOFT_AP = 7;
87 
88     /** @hide */
89     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP + 1;
90 
91     /** @hide */
92     @IntDef(prefix = { "WIFI_STATE_" }, value = {
93             WIFI_STATE_OFF,
94             WIFI_STATE_OFF_SCANNING,
95             WIFI_STATE_ON_NO_NETWORKS,
96             WIFI_STATE_ON_DISCONNECTED,
97             WIFI_STATE_ON_CONNECTED_STA,
98             WIFI_STATE_ON_CONNECTED_P2P,
99             WIFI_STATE_ON_CONNECTED_STA_P2P,
100             WIFI_STATE_SOFT_AP
101     })
102     @Retention(RetentionPolicy.SOURCE)
103     public @interface WifiState {}
104 
105     /**
106      * Wifi supplicant daemon states.
107      *
108      * @see android.net.wifi.SupplicantState for detailed description of states.
109      * @see #noteWifiSupplicantStateChanged(int)
110      */
111     /** @see android.net.wifi.SupplicantState#INVALID */
112     public static final int WIFI_SUPPL_STATE_INVALID = 0;
113     /** @see android.net.wifi.SupplicantState#DISCONNECTED*/
114     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
115     /** @see android.net.wifi.SupplicantState#INTERFACE_DISABLED */
116     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
117     /** @see android.net.wifi.SupplicantState#INACTIVE*/
118     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
119     /** @see android.net.wifi.SupplicantState#SCANNING*/
120     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
121     /** @see android.net.wifi.SupplicantState#AUTHENTICATING */
122     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
123     /** @see android.net.wifi.SupplicantState#ASSOCIATING */
124     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
125     /** @see android.net.wifi.SupplicantState#ASSOCIATED */
126     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
127     /** @see android.net.wifi.SupplicantState#FOUR_WAY_HANDSHAKE */
128     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
129     /** @see android.net.wifi.SupplicantState#GROUP_HANDSHAKE */
130     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
131     /** @see android.net.wifi.SupplicantState#COMPLETED */
132     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
133     /** @see android.net.wifi.SupplicantState#DORMANT */
134     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
135     /** @see android.net.wifi.SupplicantState#UNINITIALIZED */
136     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
137 
138     /** @hide */
139     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED + 1;
140 
141     /** @hide */
142     @IntDef(prefix = { "WIFI_SUPPL_STATE_" }, value = {
143             WIFI_SUPPL_STATE_INVALID,
144             WIFI_SUPPL_STATE_DISCONNECTED,
145             WIFI_SUPPL_STATE_INTERFACE_DISABLED,
146             WIFI_SUPPL_STATE_INACTIVE,
147             WIFI_SUPPL_STATE_SCANNING,
148             WIFI_SUPPL_STATE_AUTHENTICATING,
149             WIFI_SUPPL_STATE_ASSOCIATING,
150             WIFI_SUPPL_STATE_ASSOCIATED,
151             WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE,
152             WIFI_SUPPL_STATE_GROUP_HANDSHAKE,
153             WIFI_SUPPL_STATE_COMPLETED,
154             WIFI_SUPPL_STATE_DORMANT,
155             WIFI_SUPPL_STATE_UNINITIALIZED,
156     })
157     @Retention(RetentionPolicy.SOURCE)
158     public @interface WifiSupplState {}
159 
160     private final IBatteryStats mBatteryStats;
161 
162     /** @hide */
BatteryStatsManager(IBatteryStats batteryStats)163     public BatteryStatsManager(IBatteryStats batteryStats) {
164         mBatteryStats = batteryStats;
165     }
166 
167 
168     /**
169      * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
170      * and per-UID basis.
171      *
172      * @hide
173      */
174     @RequiresPermission(android.Manifest.permission.BATTERY_STATS)
175     @NonNull
getBatteryUsageStats()176     public BatteryUsageStats getBatteryUsageStats() {
177         return getBatteryUsageStats(BatteryUsageStatsQuery.DEFAULT);
178     }
179 
180     /**
181      * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
182      * and per-UID basis.
183      *
184      * @hide
185      */
186     @RequiresPermission(android.Manifest.permission.BATTERY_STATS)
187     @NonNull
getBatteryUsageStats(BatteryUsageStatsQuery query)188     public BatteryUsageStats getBatteryUsageStats(BatteryUsageStatsQuery query) {
189         return getBatteryUsageStats(List.of(query)).get(0);
190     }
191 
192     /**
193      * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
194      * and per-UID basis.
195      *
196      * @hide
197      */
198     @RequiresPermission(android.Manifest.permission.BATTERY_STATS)
199     @NonNull
getBatteryUsageStats(List<BatteryUsageStatsQuery> queries)200     public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) {
201         try {
202             return mBatteryStats.getBatteryUsageStats(queries);
203         } catch (RemoteException e) {
204             throw e.rethrowFromSystemServer();
205         }
206     }
207 
208     /**
209      * Indicates that the wifi connection RSSI has changed.
210      *
211      * @param newRssi The new RSSI value.
212      */
213     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiRssiChanged(@ntRangefrom = -127, to = 0) int newRssi)214     public void reportWifiRssiChanged(@IntRange(from = -127, to = 0) int newRssi) {
215         try {
216             mBatteryStats.noteWifiRssiChanged(newRssi);
217         } catch (RemoteException e) {
218             e.rethrowFromSystemServer();
219         }
220     }
221 
222     /**
223      * Indicates that wifi was toggled on.
224      */
225     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiOn()226     public void reportWifiOn() {
227         try {
228             mBatteryStats.noteWifiOn();
229         } catch (RemoteException e) {
230             e.rethrowFromSystemServer();
231         }
232     }
233 
234     /**
235      * Indicates that wifi was toggled off.
236      */
237     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiOff()238     public void reportWifiOff() {
239         try {
240             mBatteryStats.noteWifiOff();
241         } catch (RemoteException e) {
242             e.rethrowFromSystemServer();
243         }
244     }
245 
246     /**
247      * Indicates that wifi state has changed.
248      *
249      * @param newWifiState The new wifi State.
250      * @param accessPoint SSID of the network if wifi is connected to STA, else null.
251      */
252     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiState(@ifiState int newWifiState, @Nullable String accessPoint)253     public void reportWifiState(@WifiState int newWifiState,
254             @Nullable String accessPoint) {
255         try {
256             mBatteryStats.noteWifiState(newWifiState, accessPoint);
257         } catch (RemoteException e) {
258             e.rethrowFromSystemServer();
259         }
260     }
261 
262     /**
263      * Indicates that a new wifi scan has started.
264      *
265      * @param ws Worksource (to be used for battery blaming).
266      */
267     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiScanStartedFromSource(@onNull WorkSource ws)268     public void reportWifiScanStartedFromSource(@NonNull WorkSource ws) {
269         try {
270             mBatteryStats.noteWifiScanStartedFromSource(ws);
271         } catch (RemoteException e) {
272             e.rethrowFromSystemServer();
273         }
274     }
275 
276     /**
277      * Indicates that an ongoing wifi scan has stopped.
278      *
279      * @param ws Worksource (to be used for battery blaming).
280      */
281     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiScanStoppedFromSource(@onNull WorkSource ws)282     public void reportWifiScanStoppedFromSource(@NonNull WorkSource ws) {
283         try {
284             mBatteryStats.noteWifiScanStoppedFromSource(ws);
285         } catch (RemoteException e) {
286             e.rethrowFromSystemServer();
287         }
288     }
289 
290     /**
291      * Indicates that a new wifi batched scan has started.
292      *
293      * @param ws Worksource (to be used for battery blaming).
294      * @param csph Channels scanned per hour.
295      */
296     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiBatchedScanStartedFromSource(@onNull WorkSource ws, @IntRange(from = 0) int csph)297     public void reportWifiBatchedScanStartedFromSource(@NonNull WorkSource ws,
298             @IntRange(from = 0) int csph) {
299         try {
300             mBatteryStats.noteWifiBatchedScanStartedFromSource(ws, csph);
301         } catch (RemoteException e) {
302             e.rethrowFromSystemServer();
303         }
304     }
305 
306     /**
307      * Indicates that an ongoing wifi batched scan has stopped.
308      *
309      * @param ws Worksource (to be used for battery blaming).
310      */
311     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiBatchedScanStoppedFromSource(@onNull WorkSource ws)312     public void reportWifiBatchedScanStoppedFromSource(@NonNull WorkSource ws) {
313         try {
314             mBatteryStats.noteWifiBatchedScanStoppedFromSource(ws);
315         } catch (RemoteException e) {
316             e.rethrowFromSystemServer();
317         }
318     }
319 
320     /**
321      * Retrieves all the cellular related battery stats.
322      *
323      * @return Instance of {@link CellularBatteryStats}.
324      */
325     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
getCellularBatteryStats()326     public @NonNull CellularBatteryStats getCellularBatteryStats() {
327         try {
328             return mBatteryStats.getCellularBatteryStats();
329         } catch (RemoteException e) {
330             e.rethrowFromSystemServer();
331             return null;
332         }
333     }
334 
335     /**
336      * Retrieves all the wifi related battery stats.
337      *
338      * @return Instance of {@link WifiBatteryStats}.
339      */
340     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
getWifiBatteryStats()341     public @NonNull WifiBatteryStats getWifiBatteryStats() {
342         try {
343             return mBatteryStats.getWifiBatteryStats();
344         } catch (RemoteException e) {
345             e.rethrowFromSystemServer();
346             return null;
347         }
348     }
349 
350     /**
351      * Indicates an app acquiring full wifi lock.
352      *
353      * @param ws Worksource (to be used for battery blaming).
354      */
355     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportFullWifiLockAcquiredFromSource(@onNull WorkSource ws)356     public void reportFullWifiLockAcquiredFromSource(@NonNull WorkSource ws) {
357         try {
358             mBatteryStats.noteFullWifiLockAcquiredFromSource(ws);
359         } catch (RemoteException e) {
360             e.rethrowFromSystemServer();
361         }
362     }
363 
364     /**
365      * Indicates an app releasing full wifi lock.
366      *
367      * @param ws Worksource (to be used for battery blaming).
368      */
369     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportFullWifiLockReleasedFromSource(@onNull WorkSource ws)370     public void reportFullWifiLockReleasedFromSource(@NonNull WorkSource ws) {
371         try {
372             mBatteryStats.noteFullWifiLockReleasedFromSource(ws);
373         } catch (RemoteException e) {
374             e.rethrowFromSystemServer();
375         }
376     }
377 
378     /**
379      * Indicates that supplicant state has changed.
380      *
381      * @param newSupplState The new Supplicant state.
382      * @param failedAuth Boolean indicating whether there was a connection failure due to
383      *                   authentication failure.
384      */
385     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiSupplicantStateChanged(@ifiSupplState int newSupplState, boolean failedAuth)386     public void reportWifiSupplicantStateChanged(@WifiSupplState int newSupplState,
387             boolean failedAuth) {
388         try {
389             mBatteryStats.noteWifiSupplicantStateChanged(newSupplState, failedAuth);
390         } catch (RemoteException e) {
391             e.rethrowFromSystemServer();
392         }
393     }
394 
395     /**
396      * Indicates that an app has acquired the wifi multicast lock.
397      *
398      * @param ws Worksource with the uid of the app that acquired the wifi lock (to be used for
399      *           battery blaming).
400      */
401     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiMulticastEnabled(@onNull WorkSource ws)402     public void reportWifiMulticastEnabled(@NonNull WorkSource ws) {
403         try {
404             mBatteryStats.noteWifiMulticastEnabled(ws.getAttributionUid());
405         } catch (RemoteException e) {
406             e.rethrowFromSystemServer();
407         }
408     }
409 
410     /**
411      * Indicates that an app has released the wifi multicast lock.
412      *
413      * @param ws Worksource with the uid of the app that released the wifi lock (to be used for
414      *           battery blaming).
415      */
416     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiMulticastDisabled(@onNull WorkSource ws)417     public void reportWifiMulticastDisabled(@NonNull WorkSource ws) {
418         try {
419             mBatteryStats.noteWifiMulticastDisabled(ws.getAttributionUid());
420         } catch (RemoteException e) {
421             e.rethrowFromSystemServer();
422         }
423     }
424 
425     /**
426      * Indicates that the radio power state has changed.
427      *
428      * @param isActive indicates if the mobile radio is powered.
429      * @param uid Uid of this event. For the active state it represents the uid that was responsible
430      *            for waking the radio, or -1 if the system was responsible for waking the radio.
431      *            For inactive state, the UID should always be -1.
432      */
433     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportMobileRadioPowerState(boolean isActive, int uid)434     public void reportMobileRadioPowerState(boolean isActive, int uid) {
435         try {
436             mBatteryStats.noteMobileRadioPowerState(getDataConnectionPowerState(isActive),
437                     SystemClock.elapsedRealtimeNanos(), uid);
438         } catch (RemoteException e) {
439             e.rethrowFromSystemServer();
440         }
441     }
442 
443     /**
444      * Indicates that the wifi power state has changed.
445      *
446      * @param isActive indicates if the wifi radio is powered.
447      * @param uid Uid of this event. For the active state it represents the uid that was responsible
448      *            for waking the radio, or -1 if the system was responsible for waking the radio.
449      *            For inactive state, the UID should always be -1.
450      */
451     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
reportWifiRadioPowerState(boolean isActive, int uid)452     public void reportWifiRadioPowerState(boolean isActive, int uid) {
453         try {
454             mBatteryStats.noteWifiRadioPowerState(getDataConnectionPowerState(isActive),
455                     SystemClock.elapsedRealtimeNanos(), uid);
456         } catch (RemoteException e) {
457             e.rethrowFromSystemServer();
458         }
459     }
460 
461     /**
462      * Notifies the battery stats of a new interface, and the transport types of the network that
463      * includes that interface.
464      *
465      * @param iface The interface of the network.
466      * @param transportTypes The transport type of the network {@link Transport}.
467      * @hide
468      */
469     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
470     @RequiresPermission(anyOf = {
471             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
472             android.Manifest.permission.NETWORK_STACK})
reportNetworkInterfaceForTransports(@onNull String iface, @NonNull int[] transportTypes)473     public void reportNetworkInterfaceForTransports(@NonNull String iface,
474             @NonNull int[] transportTypes) throws RuntimeException {
475         try {
476             mBatteryStats.noteNetworkInterfaceForTransports(iface, transportTypes);
477         } catch (RemoteException e) {
478             e.rethrowFromSystemServer();
479         }
480     }
481 
getDataConnectionPowerState(boolean isActive)482     private static int getDataConnectionPowerState(boolean isActive) {
483         // TODO: DataConnectionRealTimeInfo is under telephony package but the constants are used
484         // for both Wifi and mobile. It would make more sense to separate the constants to a
485         // generic class or move it to generic package.
486         return isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
487                 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
488     }
489 
490     /**
491      * Sets battery AC charger to enabled/disabled, and freezes the battery state.
492      * @hide
493      */
494     @TestApi
495     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
setChargerAcOnline(boolean online, boolean forceUpdate)496     public void setChargerAcOnline(boolean online, boolean forceUpdate) {
497         try {
498             mBatteryStats.setChargerAcOnline(online, forceUpdate);
499         } catch (RemoteException e) {
500             e.rethrowFromSystemServer();
501         }
502     }
503 
504     /**
505      * Sets battery level, and freezes the battery state.
506      * @hide
507      */
508     @TestApi
509     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
setBatteryLevel(int level, boolean forceUpdate)510     public void setBatteryLevel(int level, boolean forceUpdate) {
511         try {
512             mBatteryStats.setBatteryLevel(level, forceUpdate);
513         } catch (RemoteException e) {
514             e.rethrowFromSystemServer();
515         }
516     }
517 
518     /**
519      * Unplugs battery, and freezes the battery state.
520      * @hide
521      */
522     @TestApi
523     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
unplugBattery(boolean forceUpdate)524     public void unplugBattery(boolean forceUpdate) {
525         try {
526             mBatteryStats.unplugBattery(forceUpdate);
527         } catch (RemoteException e) {
528             e.rethrowFromSystemServer();
529         }
530     }
531 
532     /**
533      * Unfreezes battery state, returning to current hardware values.
534      * @hide
535      */
536     @TestApi
537     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
resetBattery(boolean forceUpdate)538     public void resetBattery(boolean forceUpdate) {
539         try {
540             mBatteryStats.resetBattery(forceUpdate);
541         } catch (RemoteException e) {
542             e.rethrowFromSystemServer();
543         }
544     }
545 
546     /**
547      * Suspend charging even if plugged in.
548      * @hide
549      */
550     @TestApi
551     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
suspendBatteryInput()552     public void suspendBatteryInput() {
553         try {
554             mBatteryStats.suspendBatteryInput();
555         } catch (RemoteException e) {
556             e.rethrowFromSystemServer();
557         }
558     }
559 }