• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006-2007 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 com.android.server.am;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothHeadset;
21 import android.bluetooth.BluetoothProfile;
22 import android.content.Context;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.PackageManager;
25 import android.os.Binder;
26 import android.os.IBinder;
27 import android.os.Parcel;
28 import android.os.Process;
29 import android.os.ServiceManager;
30 import android.os.WorkSource;
31 import android.telephony.SignalStrength;
32 import android.telephony.TelephonyManager;
33 import android.util.Slog;
34 
35 import com.android.internal.app.IBatteryStats;
36 import com.android.internal.os.BatteryStatsImpl;
37 import com.android.internal.os.PowerProfile;
38 
39 import java.io.FileDescriptor;
40 import java.io.PrintWriter;
41 import java.util.List;
42 
43 /**
44  * All information we are collecting about things that can happen that impact
45  * battery life.
46  */
47 public final class BatteryStatsService extends IBatteryStats.Stub {
48     static IBatteryStats sService;
49 
50     final BatteryStatsImpl mStats;
51     Context mContext;
52     private boolean mBluetoothPendingStats;
53     private BluetoothHeadset mBluetoothHeadset;
54 
BatteryStatsService(String filename)55     BatteryStatsService(String filename) {
56         mStats = new BatteryStatsImpl(filename);
57     }
58 
publish(Context context)59     public void publish(Context context) {
60         mContext = context;
61         ServiceManager.addService("batteryinfo", asBinder());
62         mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
63         mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
64                 com.android.internal.R.integer.config_radioScanningTimeout)
65                 * 1000L);
66     }
67 
shutdown()68     public void shutdown() {
69         Slog.w("BatteryStats", "Writing battery stats before shutdown...");
70         synchronized (mStats) {
71             mStats.shutdownLocked();
72         }
73     }
74 
getService()75     public static IBatteryStats getService() {
76         if (sService != null) {
77             return sService;
78         }
79         IBinder b = ServiceManager.getService("batteryinfo");
80         sService = asInterface(b);
81         return sService;
82     }
83 
84     /**
85      * @return the current statistics object, which may be modified
86      * to reflect events that affect battery usage.  You must lock the
87      * stats object before doing anything with it.
88      */
getActiveStatistics()89     public BatteryStatsImpl getActiveStatistics() {
90         return mStats;
91     }
92 
getStatistics()93     public byte[] getStatistics() {
94         mContext.enforceCallingPermission(
95                 android.Manifest.permission.BATTERY_STATS, null);
96         //Slog.i("foo", "SENDING BATTERY INFO:");
97         //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
98         Parcel out = Parcel.obtain();
99         mStats.writeToParcel(out, 0);
100         byte[] data = out.marshall();
101         out.recycle();
102         return data;
103     }
104 
noteStartWakelock(int uid, int pid, String name, int type)105     public void noteStartWakelock(int uid, int pid, String name, int type) {
106         enforceCallingPermission();
107         synchronized (mStats) {
108             mStats.noteStartWakeLocked(uid, pid, name, type);
109         }
110     }
111 
noteStopWakelock(int uid, int pid, String name, int type)112     public void noteStopWakelock(int uid, int pid, String name, int type) {
113         enforceCallingPermission();
114         synchronized (mStats) {
115             mStats.noteStopWakeLocked(uid, pid, name, type);
116         }
117     }
118 
noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type)119     public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type) {
120         enforceCallingPermission();
121         synchronized (mStats) {
122             mStats.noteStartWakeFromSourceLocked(ws, pid, name, type);
123         }
124     }
125 
noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type)126     public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type) {
127         enforceCallingPermission();
128         synchronized (mStats) {
129             mStats.noteStopWakeFromSourceLocked(ws, pid, name, type);
130         }
131     }
132 
noteStartSensor(int uid, int sensor)133     public void noteStartSensor(int uid, int sensor) {
134         enforceCallingPermission();
135         synchronized (mStats) {
136             mStats.noteStartSensorLocked(uid, sensor);
137         }
138     }
139 
noteStopSensor(int uid, int sensor)140     public void noteStopSensor(int uid, int sensor) {
141         enforceCallingPermission();
142         synchronized (mStats) {
143             mStats.noteStopSensorLocked(uid, sensor);
144         }
145     }
146 
noteStartGps(int uid)147     public void noteStartGps(int uid) {
148         enforceCallingPermission();
149         synchronized (mStats) {
150             mStats.noteStartGpsLocked(uid);
151         }
152     }
153 
noteStopGps(int uid)154     public void noteStopGps(int uid) {
155         enforceCallingPermission();
156         synchronized (mStats) {
157             mStats.noteStopGpsLocked(uid);
158         }
159     }
160 
noteScreenOn()161     public void noteScreenOn() {
162         enforceCallingPermission();
163         synchronized (mStats) {
164             mStats.noteScreenOnLocked();
165         }
166     }
167 
noteScreenBrightness(int brightness)168     public void noteScreenBrightness(int brightness) {
169         enforceCallingPermission();
170         synchronized (mStats) {
171             mStats.noteScreenBrightnessLocked(brightness);
172         }
173     }
174 
noteScreenOff()175     public void noteScreenOff() {
176         enforceCallingPermission();
177         synchronized (mStats) {
178             mStats.noteScreenOffLocked();
179         }
180     }
181 
noteInputEvent()182     public void noteInputEvent() {
183         enforceCallingPermission();
184         mStats.noteInputEventAtomic();
185     }
186 
noteUserActivity(int uid, int event)187     public void noteUserActivity(int uid, int event) {
188         enforceCallingPermission();
189         synchronized (mStats) {
190             mStats.noteUserActivityLocked(uid, event);
191         }
192     }
193 
notePhoneOn()194     public void notePhoneOn() {
195         enforceCallingPermission();
196         synchronized (mStats) {
197             mStats.notePhoneOnLocked();
198         }
199     }
200 
notePhoneOff()201     public void notePhoneOff() {
202         enforceCallingPermission();
203         synchronized (mStats) {
204             mStats.notePhoneOffLocked();
205         }
206     }
207 
notePhoneSignalStrength(SignalStrength signalStrength)208     public void notePhoneSignalStrength(SignalStrength signalStrength) {
209         enforceCallingPermission();
210         synchronized (mStats) {
211             mStats.notePhoneSignalStrengthLocked(signalStrength);
212         }
213     }
214 
notePhoneDataConnectionState(int dataType, boolean hasData)215     public void notePhoneDataConnectionState(int dataType, boolean hasData) {
216         enforceCallingPermission();
217         synchronized (mStats) {
218             mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
219         }
220     }
221 
notePhoneState(int state)222     public void notePhoneState(int state) {
223         enforceCallingPermission();
224         int simState = TelephonyManager.getDefault().getSimState();
225         synchronized (mStats) {
226             mStats.notePhoneStateLocked(state, simState);
227         }
228     }
229 
noteWifiOn()230     public void noteWifiOn() {
231         enforceCallingPermission();
232         synchronized (mStats) {
233             mStats.noteWifiOnLocked();
234         }
235     }
236 
noteWifiOff()237     public void noteWifiOff() {
238         enforceCallingPermission();
239         synchronized (mStats) {
240             mStats.noteWifiOffLocked();
241         }
242     }
243 
noteStartAudio(int uid)244     public void noteStartAudio(int uid) {
245         enforceCallingPermission();
246         synchronized (mStats) {
247             mStats.noteAudioOnLocked(uid);
248         }
249     }
250 
noteStopAudio(int uid)251     public void noteStopAudio(int uid) {
252         enforceCallingPermission();
253         synchronized (mStats) {
254             mStats.noteAudioOffLocked(uid);
255         }
256     }
257 
noteStartVideo(int uid)258     public void noteStartVideo(int uid) {
259         enforceCallingPermission();
260         synchronized (mStats) {
261             mStats.noteVideoOnLocked(uid);
262         }
263     }
264 
noteStopVideo(int uid)265     public void noteStopVideo(int uid) {
266         enforceCallingPermission();
267         synchronized (mStats) {
268             mStats.noteVideoOffLocked(uid);
269         }
270     }
271 
noteWifiRunning(WorkSource ws)272     public void noteWifiRunning(WorkSource ws) {
273         enforceCallingPermission();
274         synchronized (mStats) {
275             mStats.noteWifiRunningLocked(ws);
276         }
277     }
278 
noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs)279     public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
280         enforceCallingPermission();
281         synchronized (mStats) {
282             mStats.noteWifiRunningChangedLocked(oldWs, newWs);
283         }
284     }
285 
noteWifiStopped(WorkSource ws)286     public void noteWifiStopped(WorkSource ws) {
287         enforceCallingPermission();
288         synchronized (mStats) {
289             mStats.noteWifiStoppedLocked(ws);
290         }
291     }
292 
noteBluetoothOn()293     public void noteBluetoothOn() {
294         enforceCallingPermission();
295         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
296         if (adapter != null) {
297             adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
298                                     BluetoothProfile.HEADSET);
299         }
300         synchronized (mStats) {
301             if (mBluetoothHeadset != null) {
302                 mStats.noteBluetoothOnLocked();
303                 mStats.setBtHeadset(mBluetoothHeadset);
304             } else {
305                 mBluetoothPendingStats = true;
306             }
307         }
308     }
309 
310     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
311         new BluetoothProfile.ServiceListener() {
312         public void onServiceConnected(int profile, BluetoothProfile proxy) {
313             mBluetoothHeadset = (BluetoothHeadset) proxy;
314             synchronized (mStats) {
315                 if (mBluetoothPendingStats) {
316                     mStats.noteBluetoothOnLocked();
317                     mStats.setBtHeadset(mBluetoothHeadset);
318                     mBluetoothPendingStats = false;
319                 }
320             }
321         }
322 
323         public void onServiceDisconnected(int profile) {
324             mBluetoothHeadset = null;
325         }
326     };
327 
noteBluetoothOff()328     public void noteBluetoothOff() {
329         enforceCallingPermission();
330         synchronized (mStats) {
331             mBluetoothPendingStats = false;
332             mStats.noteBluetoothOffLocked();
333         }
334     }
335 
noteFullWifiLockAcquired(int uid)336     public void noteFullWifiLockAcquired(int uid) {
337         enforceCallingPermission();
338         synchronized (mStats) {
339             mStats.noteFullWifiLockAcquiredLocked(uid);
340         }
341     }
342 
noteFullWifiLockReleased(int uid)343     public void noteFullWifiLockReleased(int uid) {
344         enforceCallingPermission();
345         synchronized (mStats) {
346             mStats.noteFullWifiLockReleasedLocked(uid);
347         }
348     }
349 
noteScanWifiLockAcquired(int uid)350     public void noteScanWifiLockAcquired(int uid) {
351         enforceCallingPermission();
352         synchronized (mStats) {
353             mStats.noteScanWifiLockAcquiredLocked(uid);
354         }
355     }
356 
noteScanWifiLockReleased(int uid)357     public void noteScanWifiLockReleased(int uid) {
358         enforceCallingPermission();
359         synchronized (mStats) {
360             mStats.noteScanWifiLockReleasedLocked(uid);
361         }
362     }
363 
noteWifiMulticastEnabled(int uid)364     public void noteWifiMulticastEnabled(int uid) {
365         enforceCallingPermission();
366         synchronized (mStats) {
367             mStats.noteWifiMulticastEnabledLocked(uid);
368         }
369     }
370 
noteWifiMulticastDisabled(int uid)371     public void noteWifiMulticastDisabled(int uid) {
372         enforceCallingPermission();
373         synchronized (mStats) {
374             mStats.noteWifiMulticastDisabledLocked(uid);
375         }
376     }
377 
noteFullWifiLockAcquiredFromSource(WorkSource ws)378     public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
379         enforceCallingPermission();
380         synchronized (mStats) {
381             mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
382         }
383     }
384 
noteFullWifiLockReleasedFromSource(WorkSource ws)385     public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
386         enforceCallingPermission();
387         synchronized (mStats) {
388             mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
389         }
390     }
391 
noteScanWifiLockAcquiredFromSource(WorkSource ws)392     public void noteScanWifiLockAcquiredFromSource(WorkSource ws) {
393         enforceCallingPermission();
394         synchronized (mStats) {
395             mStats.noteScanWifiLockAcquiredFromSourceLocked(ws);
396         }
397     }
398 
noteScanWifiLockReleasedFromSource(WorkSource ws)399     public void noteScanWifiLockReleasedFromSource(WorkSource ws) {
400         enforceCallingPermission();
401         synchronized (mStats) {
402             mStats.noteScanWifiLockReleasedFromSourceLocked(ws);
403         }
404     }
405 
noteWifiMulticastEnabledFromSource(WorkSource ws)406     public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
407         enforceCallingPermission();
408         synchronized (mStats) {
409             mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
410         }
411     }
412 
noteWifiMulticastDisabledFromSource(WorkSource ws)413     public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
414         enforceCallingPermission();
415         synchronized (mStats) {
416             mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
417         }
418     }
419 
noteNetworkInterfaceType(String iface, int type)420     public void noteNetworkInterfaceType(String iface, int type) {
421         enforceCallingPermission();
422         synchronized (mStats) {
423             mStats.noteNetworkInterfaceTypeLocked(iface, type);
424         }
425     }
426 
isOnBattery()427     public boolean isOnBattery() {
428         return mStats.isOnBattery();
429     }
430 
setBatteryState(int status, int health, int plugType, int level, int temp, int volt)431     public void setBatteryState(int status, int health, int plugType, int level,
432             int temp, int volt) {
433         enforceCallingPermission();
434         mStats.setBatteryState(status, health, plugType, level, temp, volt);
435     }
436 
getAwakeTimeBattery()437     public long getAwakeTimeBattery() {
438         mContext.enforceCallingOrSelfPermission(
439                 android.Manifest.permission.BATTERY_STATS, null);
440         return mStats.getAwakeTimeBattery();
441     }
442 
getAwakeTimePlugged()443     public long getAwakeTimePlugged() {
444         mContext.enforceCallingOrSelfPermission(
445                 android.Manifest.permission.BATTERY_STATS, null);
446         return mStats.getAwakeTimePlugged();
447     }
448 
enforceCallingPermission()449     public void enforceCallingPermission() {
450         if (Binder.getCallingPid() == Process.myPid()) {
451             return;
452         }
453         mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
454                 Binder.getCallingPid(), Binder.getCallingUid(), null);
455     }
456 
dumpHelp(PrintWriter pw)457     private void dumpHelp(PrintWriter pw) {
458         pw.println("Battery stats (batteryinfo) dump options:");
459         pw.println("  [--checkin] [--reset] [--write] [-h]");
460         pw.println("  --checkin: format output for a checkin report.");
461         pw.println("  --reset: reset the stats, clearing all current data.");
462         pw.println("  --write: force write current collected stats to disk.");
463         pw.println("  -h: print this help text.");
464     }
465 
466     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)467     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
468         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
469                 != PackageManager.PERMISSION_GRANTED) {
470             pw.println("Permission Denial: can't dump BatteryStats from from pid="
471                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
472                     + " without permission " + android.Manifest.permission.DUMP);
473             return;
474         }
475 
476         boolean isCheckin = false;
477         boolean noOutput = false;
478         if (args != null) {
479             for (String arg : args) {
480                 if ("--checkin".equals(arg)) {
481                     isCheckin = true;
482                 } else if ("--reset".equals(arg)) {
483                     synchronized (mStats) {
484                         mStats.resetAllStatsLocked();
485                         pw.println("Battery stats reset.");
486                         noOutput = true;
487                     }
488                 } else if ("--write".equals(arg)) {
489                     synchronized (mStats) {
490                         mStats.writeSyncLocked();
491                         pw.println("Battery stats written.");
492                         noOutput = true;
493                     }
494                 } else if ("-h".equals(arg)) {
495                     dumpHelp(pw);
496                     return;
497                 } else if ("-a".equals(arg)) {
498                     // fall through
499                 } else {
500                     pw.println("Unknown option: " + arg);
501                     dumpHelp(pw);
502                 }
503             }
504         }
505         if (noOutput) {
506             return;
507         }
508         if (isCheckin) {
509             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
510             synchronized (mStats) {
511                 mStats.dumpCheckinLocked(pw, args, apps);
512             }
513         } else {
514             synchronized (mStats) {
515                 mStats.dumpLocked(pw);
516             }
517         }
518     }
519 }
520