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