BatteryStatsImpl.java revision 3bee5af8162c177f8c8f4199489a401058ab26a9
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2006-2007 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huberpackage com.android.internal.os; 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport com.android.internal.util.JournaledFile; 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.bluetooth.BluetoothHeadset; 225bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.net.TrafficStats; 235bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.os.BatteryManager; 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.os.BatteryStats; 2543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberimport android.os.Parcel; 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.os.ParcelFormatException; 275bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.os.Parcelable; 285bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.os.Process; 295bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.os.SystemClock; 305bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.telephony.ServiceState; 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.telephony.SignalStrength; 323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huberimport android.telephony.TelephonyManager; 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.util.Log; 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.util.PrintWriterPrinter; 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.util.Printer; 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.util.Slog; 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.util.SparseArray; 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.BufferedReader; 401173118eace0e9e347cb007f0da817cee87579edGlenn Kastenimport java.io.File; 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.FileInputStream; 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.FileOutputStream; 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.FileReader; 44f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.IOException; 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.io.PrintWriter; 46f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.util.ArrayList; 479b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huberimport java.util.HashMap; 489b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huberimport java.util.Iterator; 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport java.util.Map; 505bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport java.util.concurrent.atomic.AtomicInteger; 511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/** 531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * All information we are collecting about things that can happen that impact 541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * battery life. All times are represented in microseconds except where indicated 551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * otherwise. 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huberpublic final class BatteryStatsImpl extends BatteryStats { 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private static final String TAG = "BatteryStatsImpl"; 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private static final boolean DEBUG = false; 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private static final boolean DEBUG_HISTORY = false; 619b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 629b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 639b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber private static final int MAGIC = 0xBA757475; // 'BATSTATS' 649b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 659b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber // Current on-disk Parcel version 6643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber private static final int VERSION = 49; 6743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Maximum number of items we will record in the history. 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private static final int MAX_HISTORY_ITEMS = 1000; 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The maximum number of names wakelocks we will keep track of 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // per uid; once the limit is reached, we batch the remaining wakelocks 735bc087c573c70c84c6a39946457590b42d392a33Andreas Huber // in to one common name. 745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber private static final int MAX_WAKELOCKS_PER_UID = 20; 755bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 765bc087c573c70c84c6a39946457590b42d392a33Andreas Huber private static final String BATCHED_WAKELOCK_NAME = "*overflow*"; 775bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 785bc087c573c70c84c6a39946457590b42d392a33Andreas Huber private static int sNumSpeedSteps; 795bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private final JournaledFile mFile; 819b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /** 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * The statistics we have collected organized by uids. 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final SparseArray<BatteryStatsImpl.Uid> mUidStats = 861173118eace0e9e347cb007f0da817cee87579edGlenn Kasten new SparseArray<BatteryStatsImpl.Uid>(); 871173118eace0e9e347cb007f0da817cee87579edGlenn Kasten 881173118eace0e9e347cb007f0da817cee87579edGlenn Kasten // A set of pools of currently active timers. When a timer is queried, we will divide the 891173118eace0e9e347cb007f0da817cee87579edGlenn Kasten // elapsed time by the number of active timers to arrive at that timer's share of the time. 901173118eace0e9e347cb007f0da817cee87579edGlenn Kasten // In order to do this, we must refresh each timer whenever the number of active timers 911173118eace0e9e347cb007f0da817cee87579edGlenn Kasten // changes. 921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>(); 931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>(); 941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>(); 951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber = new SparseArray<ArrayList<StopwatchTimer>>(); 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // These are the objects that will want to do something when the device 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // is unplugged from power. 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mShuttingDown; 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mHistoryBaseTime; 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mHaveBatteryLevel = false; 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mRecordingHistory = true; 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mNumHistoryItems; 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber HistoryItem mHistory; 10943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber HistoryItem mHistoryEnd; 110b408222bd9479c291874b607acae1425d6154fe7Andreas Huber HistoryItem mHistoryCache; 11143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber final HistoryItem mHistoryCur = new HistoryItem(); 11243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 11343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int mStartCount; 114b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 11543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mBatteryUptime; 11643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mBatteryLastUptime; 1171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mBatteryRealtime; 1181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mBatteryLastRealtime; 1191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 1201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mUptime; 12143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mUptimeStart; 12243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mLastUptime; 12343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mRealtime; 12443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mRealtimeStart; 12543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber long mLastRealtime; 12643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 12753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber boolean mScreenOn; 1281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber StopwatchTimer mScreenOnTimer; 12953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 13053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber int mScreenBrightnessBin = -1; 1311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 13353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber Counter mInputEventCounter; 13453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 13553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber boolean mPhoneOn; 1361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber StopwatchTimer mPhoneOnTimer; 1371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 1381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber boolean mAudioOn; 13953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber StopwatchTimer mAudioOnTimer; 14053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 14153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber boolean mVideoOn; 14253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber StopwatchTimer mVideoOnTimer; 14353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 14453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber int mPhoneSignalStrengthBin = -1; 14553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber final StopwatchTimer[] mPhoneSignalStrengthsTimer = 14653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS]; 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber StopwatchTimer mPhoneSignalScanningTimer; 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mPhoneDataConnectionType = -1; 1511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber final StopwatchTimer[] mPhoneDataConnectionsTimer = 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mWifiOn; 1555bc087c573c70c84c6a39946457590b42d392a33Andreas Huber StopwatchTimer mWifiOnTimer; 1565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber int mWifiOnUid = -1; 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1585bc087c573c70c84c6a39946457590b42d392a33Andreas Huber boolean mWifiRunning; 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber StopwatchTimer mWifiRunningTimer; 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mBluetoothOn; 1621173118eace0e9e347cb007f0da817cee87579edGlenn Kasten StopwatchTimer mBluetoothOnTimer; 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten /** Bluetooth headset object */ 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BluetoothHeadset mBtHeadset; 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1671173118eace0e9e347cb007f0da817cee87579edGlenn Kasten /** 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * These provide time bases that discount the time the device is plugged 1691173118eace0e9e347cb007f0da817cee87579edGlenn Kasten * in to power. 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mOnBattery; 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean mOnBatteryInternal; 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mTrackBatteryPastUptime; 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mTrackBatteryUptimeStart; 1751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mTrackBatteryPastRealtime; 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mTrackBatteryRealtimeStart; 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mUnpluggedBatteryUptime; 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mUnpluggedBatteryRealtime; 180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /* 182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mDischargeStartLevel; 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mDischargeUnplugLevel; 18643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int mDischargeCurrentLevel; 18743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int mLowDischargeAmountSinceCharge; 1881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber int mHighDischargeAmountSinceCharge; 1891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 19032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber long mLastWriteTime = 0; // Milliseconds 19132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 1921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // Mobile data transferred while on battery 1935bc087c573c70c84c6a39946457590b42d392a33Andreas Huber private long[] mMobileDataTx = new long[4]; 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private long[] mMobileDataRx = new long[4]; 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private long[] mTotalDataTx = new long[4]; 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private long[] mTotalDataRx = new long[4]; 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private long mRadioDataUptime; 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private long mRadioDataStart; 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber private int mBluetoothPingCount; 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private int mBluetoothPingStart = -1; 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private int mPhoneServiceState = -1; 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /* 2071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 2081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 2091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber private final HashMap<String, SamplingTimer> mKernelWakelockStats = 2101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber new HashMap<String, SamplingTimer>(); 2111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 2121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber public Map<String, ? extends SamplingTimer> getKernelWakelockStats() { 2131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber return mKernelWakelockStats; 2145bc087c573c70c84c6a39946457590b42d392a33Andreas Huber } 2155bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 21643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber private static int sKernelWakelockUpdateVersion = 0; 21743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 21843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber private static final int[] PROC_WAKELOCKS_FORMAT = new int[] { 2195bc087c573c70c84c6a39946457590b42d392a33Andreas Huber Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name 220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count 221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Process.PROC_TAB_TERM, 2225bc087c573c70c84c6a39946457590b42d392a33Andreas Huber Process.PROC_TAB_TERM, 223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Process.PROC_TAB_TERM, 224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime 2255bc087c573c70c84c6a39946457590b42d392a33Andreas Huber }; 2261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 2271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber private final String[] mProcWakelocksName = new String[3]; 2281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber private final long[] mProcWakelocksData = new long[3]; 2291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 2301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /* 231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added 232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * to mKernelWakelockStats. 233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private final Map<String, KernelWakelockStats> mProcWakelockFileStats = 235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new HashMap<String, KernelWakelockStats>(); 2365bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>(); 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // For debugging 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public BatteryStatsImpl() { 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFile = null; 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public static interface Unpluggable { 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void unplug(long batteryUptime, long batteryRealtime); 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void plug(long batteryUptime, long batteryRealtime); 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /** 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * State for keeping track of counting information. 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public static class Counter extends BatteryStats.Counter implements Unpluggable { 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final AtomicInteger mCount = new AtomicInteger(); 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final ArrayList<Unpluggable> mUnpluggables; 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mLoadedCount; 2565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber int mLastCount; 2575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber int mUnpluggedCount; 2585bc087c573c70c84c6a39946457590b42d392a33Andreas Huber int mPluggedCount; 2595bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Counter(ArrayList<Unpluggable> unpluggables, Parcel in) { 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggables = unpluggables; 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPluggedCount = in.readInt(); 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCount.set(mPluggedCount); 2641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mLoadedCount = in.readInt(); 26553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber mLastCount = 0; 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedCount = in.readInt(); 2671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber unpluggables.add(this); 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber Counter(ArrayList<Unpluggable> unpluggables) { 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggables = unpluggables; 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber unpluggables.add(this); 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void writeToParcel(Parcel out) { 2761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mCount.get()); 2771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mLoadedCount); 27853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber out.writeInt(mUnpluggedCount); 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 28053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void unplug(long batteryUptime, long batteryRealtime) { 28253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber mUnpluggedCount = mPluggedCount; 28353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber mCount.set(mPluggedCount); 28453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 28553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 28653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber public void plug(long batteryUptime, long batteryRealtime) { 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPluggedCount = mCount.get(); 2883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 2893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 2902c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber /** 29131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber * Writes a possibly null Counter to a Parcel. 29231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber * 29331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber * @param out the Parcel to be written to. 2942c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber * @param counter a Counter, or null. 29531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber */ 29631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber public static void writeCounterToParcel(Parcel out, Counter counter) { 2972c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber if (counter == null) { 29831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber out.writeInt(0); // indicates null 29931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber return; 3002c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber } 30131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber out.writeInt(1); // indicates non-null 30231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 30331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber counter.writeToParcel(out); 3043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 30531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 30631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber @Override 30731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber public int getCountLocked(int which) { 30831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int val; 30931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (which == STATS_LAST) { 31031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber val = mLastCount; 31131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } else { 31231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber val = mCount.get(); 31331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (which == STATS_SINCE_UNPLUGGED) { 31431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber val -= mUnpluggedCount; 31531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } else if (which != STATS_SINCE_CHARGED) { 31631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber val -= mLoadedCount; 31731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 31831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 31931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 32031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber return val; 32131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 32231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 32331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber public void logState(Printer pw, String prefix) { 32431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber pw.println(prefix + "mCount=" + mCount.get() 32531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 32631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber + " mUnpluggedCount=" + mUnpluggedCount 32731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber + " mPluggedCount=" + mPluggedCount); 3283831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 3291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 3303831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber void stepAtomic() { 3313831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mCount.incrementAndGet(); 3323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 3333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 3343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber /** 3353831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber * Clear state of this counter. 3363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber */ 3373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber void reset(boolean detachIfReset) { 3383831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mCount.set(0); 3393831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 3403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (detachIfReset) { 3413831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber detach(); 3423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void detach() { 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggables.remove(this); 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void writeSummaryFromParcelLocked(Parcel out) { 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int count = mCount.get(); 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber out.writeInt(count); 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void readSummaryFromParcelLocked(Parcel in) { 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLoadedCount = in.readInt(); 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCount.set(mLoadedCount); 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLastCount = 0; 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedCount = mPluggedCount = mLoadedCount; 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public static class SamplingCounter extends Counter { 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super(unpluggables, in); 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SamplingCounter(ArrayList<Unpluggable> unpluggables) { 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super(unpluggables); 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void addCountAtomic(long count) { 37343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mCount.addAndGet((int)count); 37443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 37543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 37643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 37743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber /** 37843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber * State for keeping track of timing information. 37943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber */ 38043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber public static abstract class Timer extends BatteryStats.Timer implements Unpluggable { 38143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber final int mType; 38243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber final ArrayList<Unpluggable> mUnpluggables; 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mCount; 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mLoadedCount; 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mLastCount; 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mUnpluggedCount; 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // Times are in microseconds for better accuracy when dividing by the 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // lock count, and are in "battery realtime" units. 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /** 393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * The total time we have accumulated since the start of the original 394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * boot, to the last time something interesting happened in the 395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * current run. 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long mTotalTime; 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /** 4001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * The total time we loaded for the previous runs. Subtract this from 4011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * mTotalTime to find the time for the current run of the system. 4021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 4031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mLoadedTime; 4041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 4051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /** 4061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * The run time of the last run of the system, as loaded from the 4071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * saved data. 4081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 4091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mLastTime; 4101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 4111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /** 4121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * The value of mTotalTime when unplug() was last called. Subtract 4131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * this from mTotalTime to find the time since the last unplug from 4141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * power. 4151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 4161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long mUnpluggedTime; 4171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 4181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /** 4191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * Constructs from a parcel. 4201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param type 4211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param unpluggables 4221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param powerType 4231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param in 4241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 4251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) { 4261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mType = type; 4271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mUnpluggables = unpluggables; 4281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 4291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mCount = in.readInt(); 43043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mLoadedCount = in.readInt(); 43143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mLastCount = 0; 43243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mUnpluggedCount = in.readInt(); 43343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mTotalTime = in.readLong(); 43443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mLoadedTime = in.readLong(); 43522fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber mLastTime = 0; 43643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mUnpluggedTime = in.readLong(); 43743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber unpluggables.add(this); 43843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 43943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber Timer(int type, ArrayList<Unpluggable> unpluggables) { 44143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mType = type; 44243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mUnpluggables = unpluggables; 44343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber unpluggables.add(this); 44443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 44543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber protected abstract long computeRunTimeLocked(long curBatteryRealtime); 44743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber protected abstract int computeCurrentCountLocked(); 44943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 450b408222bd9479c291874b607acae1425d6154fe7Andreas Huber /** 451b408222bd9479c291874b607acae1425d6154fe7Andreas Huber * Clear state of this timer. Returns true if the timer is inactive 452b408222bd9479c291874b607acae1425d6154fe7Andreas Huber * so can be completely dropped. 453b408222bd9479c291874b607acae1425d6154fe7Andreas Huber */ 454b408222bd9479c291874b607acae1425d6154fe7Andreas Huber boolean reset(boolean detachIfReset) { 455b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mTotalTime = mLoadedTime = mLastTime = 0; 456b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mCount = mLoadedCount = mLastCount = 0; 457b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (detachIfReset) { 458b408222bd9479c291874b607acae1425d6154fe7Andreas Huber detach(); 459b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 460b408222bd9479c291874b607acae1425d6154fe7Andreas Huber return true; 461b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 462b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 463b408222bd9479c291874b607acae1425d6154fe7Andreas Huber void detach() { 464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggables.remove(this); 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void writeToParcel(Parcel out, long batteryRealtime) { 468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber out.writeInt(mCount); 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber out.writeInt(mLoadedCount); 4703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber out.writeInt(mUnpluggedCount); 4713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber out.writeLong(computeRunTimeLocked(batteryRealtime)); 4723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber out.writeLong(mLoadedTime); 4733831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber out.writeLong(mUnpluggedTime); 4743831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 4763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber public void unplug(long batteryUptime, long batteryRealtime) { 4773831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (DEBUG && mType < 0) { 4783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime 4791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber + " old mUnpluggedTime=" + mUnpluggedTime 4803831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber + " old mUnpluggedCount=" + mUnpluggedCount); 4813831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mUnpluggedTime = computeRunTimeLocked(batteryRealtime); 48322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber mUnpluggedCount = mCount; 4843831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (DEBUG && mType < 0) { 4853831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber Log.v(TAG, "unplug #" + mType 4863831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber + ": new mUnpluggedTime=" + mUnpluggedTime 48722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber + " new mUnpluggedCount=" + mUnpluggedCount); 4883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4903831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 4913831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber public void plug(long batteryUptime, long batteryRealtime) { 4923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (DEBUG && mType < 0) { 493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime 4941aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber + " old mTotalTime=" + mTotalTime); 4951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 4961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mTotalTime = computeRunTimeLocked(batteryRealtime); 4971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mCount = computeCurrentCountLocked(); 4981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (DEBUG && mType < 0) { 4991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber Log.v(TAG, "plug #" + mType 5001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber + ": new mTotalTime=" + mTotalTime); 5011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 50222fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 5031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber /** 5051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * Writes a possibly null Timer to a Parcel. 5061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * 5071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param out the Parcel to be written to. 5081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber * @param timer a Timer, or null. 5091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber */ 5101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber public static void writeTimerToParcel(Parcel out, Timer timer, 5111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long batteryRealtime) { 5121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (timer == null) { 5131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(0); // indicates null 51443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber return; 51543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 51643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber out.writeInt(1); // indicates non-null 51743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 51843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber timer.writeToParcel(out, batteryRealtime); 51943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 5201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber @Override 5221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber public long getTotalTimeLocked(long batteryRealtime, int which) { 5231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber long val; 5241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (which == STATS_LAST) { 525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber val = mLastTime; 5261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } else { 5271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber val = computeRunTimeLocked(batteryRealtime); 5281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (which == STATS_SINCE_UNPLUGGED) { 5291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber val -= mUnpluggedTime; 5301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } else if (which != STATS_SINCE_CHARGED) { 5311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber val -= mLoadedTime; 532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5345bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return val; 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber @Override 5395bc087c573c70c84c6a39946457590b42d392a33Andreas Huber public int getCountLocked(int which) { 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int val; 5415bc087c573c70c84c6a39946457590b42d392a33Andreas Huber if (which == STATS_LAST) { 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber val = mLastCount; 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber val = computeCurrentCountLocked(); 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (which == STATS_SINCE_UNPLUGGED) { 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber val -= mUnpluggedCount; 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (which != STATS_SINCE_CHARGED) { 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber val -= mLoadedCount; 5491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten } 5501173118eace0e9e347cb007f0da817cee87579edGlenn Kasten } 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return val; 5535bc087c573c70c84c6a39946457590b42d392a33Andreas Huber } 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber public void logState(Printer pw, String prefix) { 55643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber pw.println(prefix + " mCount=" + mCount 55743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 55843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber + " mUnpluggedCount=" + mUnpluggedCount); 55943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber pw.println(prefix + "mTotalTime=" + mTotalTime 56043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber + " mLoadedTime=" + mLoadedTime); 56143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber pw.println(prefix + "mLastTime=" + mLastTime 56243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber + " mUnpluggedTime=" + mUnpluggedTime); 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber long runTime = computeRunTimeLocked(batteryRealtime); 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Divide by 1000 for backwards compatibility 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber out.writeLong((runTime + 500) / 1000); 57053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber out.writeInt(mCount); 57153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void readSummaryFromParcelLocked(Parcel in) { 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Multiply by 1000 for backwards compatibility 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalTime = mLoadedTime = in.readLong() * 1000; 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLastTime = 0; 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedTime = mTotalTime; 5785bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mCount = mLoadedCount = in.readInt(); 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLastCount = 0; 580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedCount = mCount; 581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber public static final class SamplingTimer extends Timer { 5855bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 5865bc087c573c70c84c6a39946457590b42d392a33Andreas Huber /** 5875bc087c573c70c84c6a39946457590b42d392a33Andreas Huber * The most recent reported count from /proc/wakelocks. 5885bc087c573c70c84c6a39946457590b42d392a33Andreas Huber */ 58953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber int mCurrentReportedCount; 5901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 59153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber /** 59253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber * The reported count from /proc/wakelocks when unplug() was last 59332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * called. 59432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber */ 59532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber int mUnpluggedReportedCount; 59632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 59732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber /** 59832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * The most recent reported total_time from /proc/wakelocks. 59932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber */ 60032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber long mCurrentReportedTotalTime; 60132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 60232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 60332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber /** 60432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * The reported total_time from /proc/wakelocks when unplug() was last 60532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * called. 60632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber */ 60732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber long mUnpluggedReportedTotalTime; 60832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 60932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber /** 61032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * Whether we are currently in a discharge cycle. 61132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber */ 61232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber boolean mInDischarge; 61332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 61432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber /** 61532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber * Whether we are currently recording reported values. 61632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber */ 61732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber boolean mTrackingReportedValues; 6181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /* 620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * A sequnce counter, incremented once for each update of the stats. 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int mUpdateVersion; 623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) { 625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super(0, unpluggables, in); 62643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mCurrentReportedCount = in.readInt(); 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedReportedCount = in.readInt(); 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCurrentReportedTotalTime = in.readLong(); 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedReportedTotalTime = in.readLong(); 630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTrackingReportedValues = in.readInt() == 1; 6311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mInDischarge = inDischarge; 632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber boolean trackReportedValues) { 636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super(0, unpluggables); 637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTrackingReportedValues = trackReportedValues; 638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mInDischarge = inDischarge; 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void setStale() { 642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTrackingReportedValues = false; 64343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mUnpluggedReportedTotalTime = 0; 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedReportedCount = 0; 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void setUpdateVersion(int version) { 648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUpdateVersion = version; 649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public int getUpdateVersion() { 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return mUpdateVersion; 65332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 65432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 65532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber public void updateCurrentReportedCount(int count) { 65632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber if (mInDischarge && mUnpluggedReportedCount == 0) { 65732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber // Updating the reported value for the first time. 65832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mUnpluggedReportedCount = count; 65932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber // If we are receiving an update update mTrackingReportedValues; 66032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mTrackingReportedValues = true; 66132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 66232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mCurrentReportedCount = count; 66332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 66432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 66532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber public void updateCurrentReportedTotalTime(long totalTime) { 66632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber if (mInDischarge && mUnpluggedReportedTotalTime == 0) { 66732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber // Updating the reported value for the first time. 66832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mUnpluggedReportedTotalTime = totalTime; 66932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber // If we are receiving an update update mTrackingReportedValues; 67032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mTrackingReportedValues = true; 67132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 67232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mCurrentReportedTotalTime = totalTime; 67332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void unplug(long batteryUptime, long batteryRealtime) { 676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super.unplug(batteryUptime, batteryRealtime); 677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mTrackingReportedValues) { 67843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUnpluggedReportedCount = mCurrentReportedCount; 680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mInDischarge = true; 68243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 68443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber public void plug(long batteryUptime, long batteryRealtime) { 685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super.plug(batteryUptime, batteryRealtime); 686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mInDischarge = false; 687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 68843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void logState(Printer pw, String prefix) { 690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber super.logState(pw, prefix); 6911aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 6921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 6931aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 69443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 6951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 6961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber protected long computeRunTimeLocked(long curBatteryRealtime) { 6981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber return mTotalTime + (mInDischarge && mTrackingReportedValues 6991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 7001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 7011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 7021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber protected int computeCurrentCountLocked() { 7031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber return mCount + (mInDischarge && mTrackingReportedValues 7041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 7051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 7061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 7071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber public void writeToParcel(Parcel out, long batteryRealtime) { 7081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber super.writeToParcel(out, batteryRealtime); 7091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mCurrentReportedCount); 7101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mUnpluggedReportedCount); 7111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeLong(mCurrentReportedTotalTime); 7121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeLong(mUnpluggedReportedTotalTime); 7131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mTrackingReportedValues ? 1 : 0); 7141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 7151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 7161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber boolean reset(boolean detachIfReset) { 7171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber super.reset(detachIfReset); 7181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber setStale(); 7191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber return true; 7201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 7211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 7221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 7231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber super.writeSummaryFromParcelLocked(out, batteryRealtime); 7241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeLong(mCurrentReportedTotalTime); 7251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mCurrentReportedCount); 7261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber out.writeInt(mTrackingReportedValues ? 1 : 0); 727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 728 729 void readSummaryFromParcelLocked(Parcel in) { 730 super.readSummaryFromParcelLocked(in); 731 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong(); 732 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt(); 733 mTrackingReportedValues = in.readInt() == 1; 734 } 735 } 736 737 /** 738 * State for keeping track of timing information. 739 */ 740 public static final class StopwatchTimer extends Timer { 741 final ArrayList<StopwatchTimer> mTimerPool; 742 int mNesting; 743 744 /** 745 * The last time at which we updated the timer. If mNesting is > 0, 746 * subtract this from the current battery time to find the amount of 747 * time we have been running since we last computed an update. 748 */ 749 long mUpdateTime; 750 751 /** 752 * The total time at which the timer was acquired, to determine if 753 * was actually held for an interesting duration. 754 */ 755 long mAcquireTime; 756 757 long mTimeout; 758 759 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, 760 ArrayList<Unpluggable> unpluggables, Parcel in) { 761 super(type, unpluggables, in); 762 mTimerPool = timerPool; 763 mUpdateTime = in.readLong(); 764 } 765 766 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, 767 ArrayList<Unpluggable> unpluggables) { 768 super(type, unpluggables); 769 mTimerPool = timerPool; 770 } 771 772 void setTimeout(long timeout) { 773 mTimeout = timeout; 774 } 775 776 public void writeToParcel(Parcel out, long batteryRealtime) { 777 super.writeToParcel(out, batteryRealtime); 778 out.writeLong(mUpdateTime); 779 } 780 781 public void plug(long batteryUptime, long batteryRealtime) { 782 if (mNesting > 0) { 783 if (DEBUG && mType < 0) { 784 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 785 } 786 super.plug(batteryUptime, batteryRealtime); 787 mUpdateTime = batteryRealtime; 788 if (DEBUG && mType < 0) { 789 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 790 } 791 } 792 } 793 794 public void logState(Printer pw, String prefix) { 795 super.logState(pw, prefix); 796 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime 797 + " mAcquireTime=" + mAcquireTime); 798 } 799 800 void startRunningLocked(BatteryStatsImpl stats) { 801 if (mNesting++ == 0) { 802 mUpdateTime = stats.getBatteryRealtimeLocked( 803 SystemClock.elapsedRealtime() * 1000); 804 if (mTimerPool != null) { 805 // Accumulate time to all currently active timers before adding 806 // this new one to the pool. 807 refreshTimersLocked(stats, mTimerPool); 808 // Add this timer to the active pool 809 mTimerPool.add(this); 810 } 811 // Increment the count 812 mCount++; 813 mAcquireTime = mTotalTime; 814 if (DEBUG && mType < 0) { 815 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 816 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 817 + " mAcquireTime=" + mAcquireTime); 818 } 819 } 820 } 821 822 boolean isRunningLocked() { 823 return mNesting > 0; 824 } 825 826 void stopRunningLocked(BatteryStatsImpl stats) { 827 // Ignore attempt to stop a timer that isn't running 828 if (mNesting == 0) { 829 return; 830 } 831 if (--mNesting == 0) { 832 if (mTimerPool != null) { 833 // Accumulate time to all active counters, scaled by the total 834 // active in the pool, before taking this one out of the pool. 835 refreshTimersLocked(stats, mTimerPool); 836 // Remove this timer from the active pool 837 mTimerPool.remove(this); 838 } else { 839 final long realtime = SystemClock.elapsedRealtime() * 1000; 840 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 841 mNesting = 1; 842 mTotalTime = computeRunTimeLocked(batteryRealtime); 843 mNesting = 0; 844 } 845 846 if (DEBUG && mType < 0) { 847 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 848 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 849 + " mAcquireTime=" + mAcquireTime); 850 } 851 852 if (mTotalTime == mAcquireTime) { 853 // If there was no change in the time, then discard this 854 // count. A somewhat cheezy strategy, but hey. 855 mCount--; 856 } 857 } 858 } 859 860 // Update the total time for all other running Timers with the same type as this Timer 861 // due to a change in timer count 862 private static void refreshTimersLocked(final BatteryStatsImpl stats, 863 final ArrayList<StopwatchTimer> pool) { 864 final long realtime = SystemClock.elapsedRealtime() * 1000; 865 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 866 final int N = pool.size(); 867 for (int i=N-1; i>= 0; i--) { 868 final StopwatchTimer t = pool.get(i); 869 long heldTime = batteryRealtime - t.mUpdateTime; 870 if (heldTime > 0) { 871 t.mTotalTime += heldTime / N; 872 } 873 t.mUpdateTime = batteryRealtime; 874 } 875 } 876 877 @Override 878 protected long computeRunTimeLocked(long curBatteryRealtime) { 879 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 880 curBatteryRealtime = mUpdateTime + mTimeout; 881 } 882 return mTotalTime + (mNesting > 0 883 ? (curBatteryRealtime - mUpdateTime) 884 / (mTimerPool != null ? mTimerPool.size() : 1) 885 : 0); 886 } 887 888 @Override 889 protected int computeCurrentCountLocked() { 890 return mCount; 891 } 892 893 boolean reset(boolean detachIfReset) { 894 boolean canDetach = mNesting <= 0; 895 super.reset(canDetach && detachIfReset); 896 return canDetach; 897 } 898 899 void detach() { 900 super.detach(); 901 if (mTimerPool != null) { 902 mTimerPool.remove(this); 903 } 904 } 905 906 void readSummaryFromParcelLocked(Parcel in) { 907 super.readSummaryFromParcelLocked(in); 908 mNesting = 0; 909 } 910 } 911 912 private final Map<String, KernelWakelockStats> readKernelWakelockStats() { 913 914 byte[] buffer = new byte[4096]; 915 int len; 916 917 try { 918 FileInputStream is = new FileInputStream("/proc/wakelocks"); 919 len = is.read(buffer); 920 is.close(); 921 922 if (len > 0) { 923 int i; 924 for (i=0; i<len; i++) { 925 if (buffer[i] == '\0') { 926 len = i; 927 break; 928 } 929 } 930 } 931 } catch (java.io.FileNotFoundException e) { 932 return null; 933 } catch (java.io.IOException e) { 934 return null; 935 } 936 937 return parseProcWakelocks(buffer, len); 938 } 939 940 private final Map<String, KernelWakelockStats> parseProcWakelocks( 941 byte[] wlBuffer, int len) { 942 String name; 943 int count; 944 long totalTime; 945 int startIndex, endIndex; 946 int numUpdatedWlNames = 0; 947 948 // Advance past the first line. 949 int i; 950 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++); 951 startIndex = endIndex = i + 1; 952 953 synchronized(this) { 954 Map<String, KernelWakelockStats> m = mProcWakelockFileStats; 955 956 sKernelWakelockUpdateVersion++; 957 while (endIndex < len) { 958 for (endIndex=startIndex; 959 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; 960 endIndex++); 961 // Don't go over the end of the buffer 962 if (endIndex < len) { 963 endIndex++; // endIndex is an exclusive upper bound. 964 } 965 966 String[] nameStringArray = mProcWakelocksName; 967 long[] wlData = mProcWakelocksData; 968 // Stomp out any bad characters since this is from a circular buffer 969 // A corruption is seen sometimes that results in the vm crashing 970 // This should prevent crashes and the line will probably fail to parse 971 for (int j = startIndex; j < endIndex; j++) { 972 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?'; 973 } 974 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex, 975 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null); 976 977 name = nameStringArray[0]; 978 count = (int) wlData[1]; 979 // convert nanoseconds to microseconds with rounding. 980 totalTime = (wlData[2] + 500) / 1000; 981 982 if (parsed && name.length() > 0) { 983 if (!m.containsKey(name)) { 984 m.put(name, new KernelWakelockStats(count, totalTime, 985 sKernelWakelockUpdateVersion)); 986 numUpdatedWlNames++; 987 } else { 988 KernelWakelockStats kwlStats = m.get(name); 989 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) { 990 kwlStats.mCount += count; 991 kwlStats.mTotalTime += totalTime; 992 } else { 993 kwlStats.mCount = count; 994 kwlStats.mTotalTime = totalTime; 995 kwlStats.mVersion = sKernelWakelockUpdateVersion; 996 numUpdatedWlNames++; 997 } 998 } 999 } 1000 startIndex = endIndex; 1001 } 1002 1003 if (m.size() != numUpdatedWlNames) { 1004 // Don't report old data. 1005 Iterator<KernelWakelockStats> itr = m.values().iterator(); 1006 while (itr.hasNext()) { 1007 if (itr.next().mVersion != sKernelWakelockUpdateVersion) { 1008 itr.remove(); 1009 } 1010 } 1011 } 1012 return m; 1013 } 1014 } 1015 1016 private class KernelWakelockStats { 1017 public int mCount; 1018 public long mTotalTime; 1019 public int mVersion; 1020 1021 KernelWakelockStats(int count, long totalTime, int version) { 1022 mCount = count; 1023 mTotalTime = totalTime; 1024 mVersion = version; 1025 } 1026 } 1027 1028 /* 1029 * Get the KernelWakelockTimer associated with name, and create a new one if one 1030 * doesn't already exist. 1031 */ 1032 public SamplingTimer getKernelWakelockTimerLocked(String name) { 1033 SamplingTimer kwlt = mKernelWakelockStats.get(name); 1034 if (kwlt == null) { 1035 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 1036 true /* track reported values */); 1037 mKernelWakelockStats.put(name, kwlt); 1038 } 1039 return kwlt; 1040 } 1041 1042 private void doDataPlug(long[] dataTransfer, long currentBytes) { 1043 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED]; 1044 dataTransfer[STATS_SINCE_UNPLUGGED] = -1; 1045 } 1046 1047 private void doDataUnplug(long[] dataTransfer, long currentBytes) { 1048 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes; 1049 } 1050 1051 /** 1052 * Radio uptime in microseconds when transferring data. This value is very approximate. 1053 * @return 1054 */ 1055 private long getCurrentRadioDataUptime() { 1056 try { 1057 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms"); 1058 if (!awakeTimeFile.exists()) return 0; 1059 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile)); 1060 String line = br.readLine(); 1061 br.close(); 1062 return Long.parseLong(line) * 1000; 1063 } catch (NumberFormatException nfe) { 1064 // Nothing 1065 } catch (IOException ioe) { 1066 // Nothing 1067 } 1068 return 0; 1069 } 1070 1071 /** 1072 * @deprecated use getRadioDataUptime 1073 */ 1074 public long getRadioDataUptimeMs() { 1075 return getRadioDataUptime() / 1000; 1076 } 1077 1078 /** 1079 * Returns the duration that the cell radio was up for data transfers. 1080 */ 1081 public long getRadioDataUptime() { 1082 if (mRadioDataStart == -1) { 1083 return mRadioDataUptime; 1084 } else { 1085 return getCurrentRadioDataUptime() - mRadioDataStart; 1086 } 1087 } 1088 1089 private int getCurrentBluetoothPingCount() { 1090 if (mBtHeadset != null) { 1091 return mBtHeadset.getBatteryUsageHint(); 1092 } 1093 return -1; 1094 } 1095 1096 public int getBluetoothPingCount() { 1097 if (mBluetoothPingStart == -1) { 1098 return mBluetoothPingCount; 1099 } else if (mBtHeadset != null) { 1100 return getCurrentBluetoothPingCount() - mBluetoothPingStart; 1101 } 1102 return 0; 1103 } 1104 1105 public void setBtHeadset(BluetoothHeadset headset) { 1106 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) { 1107 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1108 } 1109 mBtHeadset = headset; 1110 } 1111 1112 void addHistoryRecordLocked(long curTime) { 1113 if (!mHaveBatteryLevel || !mRecordingHistory) { 1114 return; 1115 } 1116 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 1117 // Once we've reached the maximum number of items, we only 1118 // record changes to the battery level. 1119 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 1120 == mHistoryCur.batteryLevel) { 1121 return; 1122 } 1123 } 1124 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE); 1125 } 1126 1127 void addHistoryRecordLocked(long curTime, byte cmd) { 1128 HistoryItem rec = mHistoryCache; 1129 if (rec != null) { 1130 mHistoryCache = rec.next; 1131 } else { 1132 rec = new HistoryItem(); 1133 } 1134 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); 1135 1136 addHistoryRecordLocked(rec); 1137 } 1138 1139 void addHistoryRecordLocked(HistoryItem rec) { 1140 mNumHistoryItems++; 1141 rec.next = null; 1142 if (mHistoryEnd != null) { 1143 mHistoryEnd.next = rec; 1144 mHistoryEnd = rec; 1145 } else { 1146 mHistory = mHistoryEnd = rec; 1147 } 1148 } 1149 1150 void clearHistoryLocked() { 1151 if (mHistory != null) { 1152 mHistoryEnd.next = mHistoryCache; 1153 mHistoryCache = mHistory; 1154 mHistory = mHistoryEnd = null; 1155 } 1156 mNumHistoryItems = 0; 1157 mHistoryBaseTime = 0; 1158 } 1159 1160 public void doUnplugLocked(long batteryUptime, long batteryRealtime) { 1161 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1162 Uid u = mUidStats.valueAt(iu); 1163 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid); 1164 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid); 1165 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived; 1166 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent; 1167 } 1168 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1169 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime); 1170 } 1171 // Track total mobile data 1172 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1173 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1174 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1175 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1176 // Track radio awake time 1177 mRadioDataStart = getCurrentRadioDataUptime(); 1178 mRadioDataUptime = 0; 1179 // Track bt headset ping count 1180 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1181 mBluetoothPingCount = 0; 1182 } 1183 1184 public void doPlugLocked(long batteryUptime, long batteryRealtime) { 1185 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1186 Uid u = mUidStats.valueAt(iu); 1187 if (u.mStartedTcpBytesReceived >= 0) { 1188 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived(); 1189 u.mStartedTcpBytesReceived = -1; 1190 } 1191 if (u.mStartedTcpBytesSent >= 0) { 1192 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent(); 1193 u.mStartedTcpBytesSent = -1; 1194 } 1195 } 1196 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1197 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime); 1198 } 1199 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1200 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1201 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1202 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1203 // Track radio awake time 1204 mRadioDataUptime = getRadioDataUptime(); 1205 mRadioDataStart = -1; 1206 1207 // Track bt headset ping count 1208 mBluetoothPingCount = getBluetoothPingCount(); 1209 mBluetoothPingStart = -1; 1210 } 1211 1212 int mGpsNesting; 1213 1214 public void noteStartGpsLocked(int uid) { 1215 if (mGpsNesting == 0) { 1216 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 1217 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 1218 + Integer.toHexString(mHistoryCur.states)); 1219 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1220 } 1221 mGpsNesting++; 1222 getUidStatsLocked(uid).noteStartGps(); 1223 } 1224 1225 public void noteStopGpsLocked(int uid) { 1226 mGpsNesting--; 1227 if (mGpsNesting == 0) { 1228 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 1229 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 1230 + Integer.toHexString(mHistoryCur.states)); 1231 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1232 } 1233 getUidStatsLocked(uid).noteStopGps(); 1234 } 1235 1236 public void noteScreenOnLocked() { 1237 if (!mScreenOn) { 1238 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 1239 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 1240 + Integer.toHexString(mHistoryCur.states)); 1241 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1242 mScreenOn = true; 1243 mScreenOnTimer.startRunningLocked(this); 1244 if (mScreenBrightnessBin >= 0) { 1245 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this); 1246 } 1247 } 1248 } 1249 1250 public void noteScreenOffLocked() { 1251 if (mScreenOn) { 1252 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 1253 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 1254 + Integer.toHexString(mHistoryCur.states)); 1255 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1256 mScreenOn = false; 1257 mScreenOnTimer.stopRunningLocked(this); 1258 if (mScreenBrightnessBin >= 0) { 1259 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1260 } 1261 } 1262 } 1263 1264 public void noteScreenBrightnessLocked(int brightness) { 1265 // Bin the brightness. 1266 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 1267 if (bin < 0) bin = 0; 1268 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 1269 if (mScreenBrightnessBin != bin) { 1270 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 1271 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 1272 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 1273 + Integer.toHexString(mHistoryCur.states)); 1274 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1275 if (mScreenOn) { 1276 if (mScreenBrightnessBin >= 0) { 1277 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1278 } 1279 mScreenBrightnessTimer[bin].startRunningLocked(this); 1280 } 1281 mScreenBrightnessBin = bin; 1282 } 1283 } 1284 1285 public void noteInputEventAtomic() { 1286 mInputEventCounter.stepAtomic(); 1287 } 1288 1289 public void noteUserActivityLocked(int uid, int event) { 1290 getUidStatsLocked(uid).noteUserActivityLocked(event); 1291 } 1292 1293 public void notePhoneOnLocked() { 1294 if (!mPhoneOn) { 1295 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG; 1296 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 1297 + Integer.toHexString(mHistoryCur.states)); 1298 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1299 mPhoneOn = true; 1300 mPhoneOnTimer.startRunningLocked(this); 1301 } 1302 } 1303 1304 public void notePhoneOffLocked() { 1305 if (mPhoneOn) { 1306 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG; 1307 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 1308 + Integer.toHexString(mHistoryCur.states)); 1309 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1310 mPhoneOn = false; 1311 mPhoneOnTimer.stopRunningLocked(this); 1312 } 1313 } 1314 1315 void stopAllSignalStrengthTimersLocked(int except) { 1316 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) { 1317 if (i == except) { 1318 continue; 1319 } 1320 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 1321 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); 1322 } 1323 } 1324 } 1325 1326 /** 1327 * Telephony stack updates the phone state. 1328 * @param state phone state from ServiceState.getState() 1329 */ 1330 public void notePhoneStateLocked(int state) { 1331 boolean scanning = false; 1332 1333 int bin = mPhoneSignalStrengthBin; 1334 1335 // If the phone is powered off, stop all timers. 1336 if (state == ServiceState.STATE_POWER_OFF) { 1337 stopAllSignalStrengthTimersLocked(-1); 1338 1339 // If we're back in service or continuing in service, restart the old timer. 1340 } if (state == ServiceState.STATE_IN_SERVICE) { 1341 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1342 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { 1343 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 1344 } 1345 1346 // If we're out of service, we are in the lowest signal strength 1347 // bin and have the scanning bit set. 1348 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 1349 scanning = true; 1350 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1351 stopAllSignalStrengthTimersLocked(mPhoneSignalStrengthBin); 1352 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) { 1353 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this); 1354 } 1355 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 1356 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 1357 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 1358 + Integer.toHexString(mHistoryCur.states)); 1359 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1360 mPhoneSignalScanningTimer.startRunningLocked(this); 1361 } 1362 } 1363 1364 if (!scanning) { 1365 // If we are no longer scanning, then stop the scanning timer. 1366 if (mPhoneSignalScanningTimer.isRunningLocked()) { 1367 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 1368 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 1369 + Integer.toHexString(mHistoryCur.states)); 1370 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1371 mPhoneSignalScanningTimer.stopRunningLocked(this); 1372 } 1373 } 1374 1375 if (mPhoneServiceState != state) { 1376 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 1377 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 1378 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: " 1379 + Integer.toHexString(mHistoryCur.states)); 1380 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1381 mPhoneServiceState = state; 1382 } 1383 } 1384 1385 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 1386 // Bin the strength. 1387 int bin; 1388 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF 1389 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) { 1390 // Ignore any signal strength changes when radio was turned off or out of service. 1391 return; 1392 } 1393 if (!signalStrength.isGsm()) { 1394 int dBm = signalStrength.getCdmaDbm(); 1395 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT; 1396 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD; 1397 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE; 1398 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR; 1399 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1400 } else { 1401 int asu = signalStrength.getGsmSignalStrength(); 1402 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1403 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT; 1404 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD; 1405 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE; 1406 else bin = SIGNAL_STRENGTH_POOR; 1407 } 1408 if (mPhoneSignalStrengthBin != bin) { 1409 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK) 1410 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT); 1411 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: " 1412 + Integer.toHexString(mHistoryCur.states)); 1413 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1414 if (mPhoneSignalStrengthBin >= 0) { 1415 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this); 1416 } 1417 mPhoneSignalStrengthBin = bin; 1418 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 1419 } 1420 } 1421 1422 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 1423 int bin = DATA_CONNECTION_NONE; 1424 if (hasData) { 1425 switch (dataType) { 1426 case TelephonyManager.NETWORK_TYPE_EDGE: 1427 bin = DATA_CONNECTION_EDGE; 1428 break; 1429 case TelephonyManager.NETWORK_TYPE_GPRS: 1430 bin = DATA_CONNECTION_GPRS; 1431 break; 1432 case TelephonyManager.NETWORK_TYPE_UMTS: 1433 bin = DATA_CONNECTION_UMTS; 1434 break; 1435 case TelephonyManager.NETWORK_TYPE_CDMA: 1436 bin = DATA_CONNECTION_CDMA; 1437 break; 1438 case TelephonyManager.NETWORK_TYPE_EVDO_0: 1439 bin = DATA_CONNECTION_EVDO_0; 1440 break; 1441 case TelephonyManager.NETWORK_TYPE_EVDO_A: 1442 bin = DATA_CONNECTION_EVDO_A; 1443 break; 1444 case TelephonyManager.NETWORK_TYPE_1xRTT: 1445 bin = DATA_CONNECTION_1xRTT; 1446 break; 1447 case TelephonyManager.NETWORK_TYPE_HSDPA: 1448 bin = DATA_CONNECTION_HSDPA; 1449 break; 1450 case TelephonyManager.NETWORK_TYPE_HSUPA: 1451 bin = DATA_CONNECTION_HSUPA; 1452 break; 1453 case TelephonyManager.NETWORK_TYPE_HSPA: 1454 bin = DATA_CONNECTION_HSPA; 1455 break; 1456 case TelephonyManager.NETWORK_TYPE_IDEN: 1457 bin = DATA_CONNECTION_IDEN; 1458 break; 1459 case TelephonyManager.NETWORK_TYPE_EVDO_B: 1460 bin = DATA_CONNECTION_EVDO_B; 1461 break; 1462 default: 1463 bin = DATA_CONNECTION_OTHER; 1464 break; 1465 } 1466 } 1467 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 1468 if (mPhoneDataConnectionType != bin) { 1469 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 1470 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 1471 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 1472 + Integer.toHexString(mHistoryCur.states)); 1473 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1474 if (mPhoneDataConnectionType >= 0) { 1475 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this); 1476 } 1477 mPhoneDataConnectionType = bin; 1478 mPhoneDataConnectionsTimer[bin].startRunningLocked(this); 1479 } 1480 } 1481 1482 public void noteWifiOnLocked(int uid) { 1483 if (!mWifiOn) { 1484 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG; 1485 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 1486 + Integer.toHexString(mHistoryCur.states)); 1487 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1488 mWifiOn = true; 1489 mWifiOnTimer.startRunningLocked(this); 1490 } 1491 if (mWifiOnUid != uid) { 1492 if (mWifiOnUid >= 0) { 1493 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked(); 1494 } 1495 mWifiOnUid = uid; 1496 getUidStatsLocked(uid).noteWifiTurnedOnLocked(); 1497 } 1498 } 1499 1500 public void noteWifiOffLocked(int uid) { 1501 if (mWifiOn) { 1502 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG; 1503 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 1504 + Integer.toHexString(mHistoryCur.states)); 1505 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1506 mWifiOn = false; 1507 mWifiOnTimer.stopRunningLocked(this); 1508 } 1509 if (mWifiOnUid >= 0) { 1510 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked(); 1511 mWifiOnUid = -1; 1512 } 1513 } 1514 1515 public void noteAudioOnLocked(int uid) { 1516 if (!mAudioOn) { 1517 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 1518 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 1519 + Integer.toHexString(mHistoryCur.states)); 1520 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1521 mAudioOn = true; 1522 mAudioOnTimer.startRunningLocked(this); 1523 } 1524 getUidStatsLocked(uid).noteAudioTurnedOnLocked(); 1525 } 1526 1527 public void noteAudioOffLocked(int uid) { 1528 if (mAudioOn) { 1529 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 1530 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 1531 + Integer.toHexString(mHistoryCur.states)); 1532 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1533 mAudioOn = false; 1534 mAudioOnTimer.stopRunningLocked(this); 1535 } 1536 getUidStatsLocked(uid).noteAudioTurnedOffLocked(); 1537 } 1538 1539 public void noteVideoOnLocked(int uid) { 1540 if (!mVideoOn) { 1541 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG; 1542 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 1543 + Integer.toHexString(mHistoryCur.states)); 1544 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1545 mVideoOn = true; 1546 mVideoOnTimer.startRunningLocked(this); 1547 } 1548 getUidStatsLocked(uid).noteVideoTurnedOnLocked(); 1549 } 1550 1551 public void noteVideoOffLocked(int uid) { 1552 if (mVideoOn) { 1553 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG; 1554 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 1555 + Integer.toHexString(mHistoryCur.states)); 1556 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1557 mVideoOn = false; 1558 mVideoOnTimer.stopRunningLocked(this); 1559 } 1560 getUidStatsLocked(uid).noteVideoTurnedOffLocked(); 1561 } 1562 1563 public void noteWifiRunningLocked() { 1564 if (!mWifiRunning) { 1565 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG; 1566 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 1567 + Integer.toHexString(mHistoryCur.states)); 1568 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1569 mWifiRunning = true; 1570 mWifiRunningTimer.startRunningLocked(this); 1571 } 1572 } 1573 1574 public void noteWifiStoppedLocked() { 1575 if (mWifiRunning) { 1576 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG; 1577 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 1578 + Integer.toHexString(mHistoryCur.states)); 1579 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1580 mWifiRunning = false; 1581 mWifiRunningTimer.stopRunningLocked(this); 1582 } 1583 } 1584 1585 public void noteBluetoothOnLocked() { 1586 if (!mBluetoothOn) { 1587 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG; 1588 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " 1589 + Integer.toHexString(mHistoryCur.states)); 1590 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1591 mBluetoothOn = true; 1592 mBluetoothOnTimer.startRunningLocked(this); 1593 } 1594 } 1595 1596 public void noteBluetoothOffLocked() { 1597 if (mBluetoothOn) { 1598 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG; 1599 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " 1600 + Integer.toHexString(mHistoryCur.states)); 1601 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1602 mBluetoothOn = false; 1603 mBluetoothOnTimer.stopRunningLocked(this); 1604 } 1605 } 1606 1607 int mWifiFullLockNesting = 0; 1608 1609 public void noteFullWifiLockAcquiredLocked(int uid) { 1610 if (mWifiFullLockNesting == 0) { 1611 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 1612 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 1613 + Integer.toHexString(mHistoryCur.states)); 1614 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1615 } 1616 mWifiFullLockNesting++; 1617 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(); 1618 } 1619 1620 public void noteFullWifiLockReleasedLocked(int uid) { 1621 mWifiFullLockNesting--; 1622 if (mWifiFullLockNesting == 0) { 1623 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 1624 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 1625 + Integer.toHexString(mHistoryCur.states)); 1626 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1627 } 1628 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(); 1629 } 1630 1631 int mWifiScanLockNesting = 0; 1632 1633 public void noteScanWifiLockAcquiredLocked(int uid) { 1634 if (mWifiScanLockNesting == 0) { 1635 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG; 1636 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: " 1637 + Integer.toHexString(mHistoryCur.states)); 1638 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1639 } 1640 mWifiScanLockNesting++; 1641 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked(); 1642 } 1643 1644 public void noteScanWifiLockReleasedLocked(int uid) { 1645 mWifiScanLockNesting--; 1646 if (mWifiScanLockNesting == 0) { 1647 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG; 1648 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: " 1649 + Integer.toHexString(mHistoryCur.states)); 1650 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1651 } 1652 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked(); 1653 } 1654 1655 int mWifiMulticastNesting = 0; 1656 1657 public void noteWifiMulticastEnabledLocked(int uid) { 1658 if (mWifiMulticastNesting == 0) { 1659 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 1660 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 1661 + Integer.toHexString(mHistoryCur.states)); 1662 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1663 } 1664 mWifiMulticastNesting++; 1665 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(); 1666 } 1667 1668 public void noteWifiMulticastDisabledLocked(int uid) { 1669 mWifiMulticastNesting--; 1670 if (mWifiMulticastNesting == 0) { 1671 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 1672 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 1673 + Integer.toHexString(mHistoryCur.states)); 1674 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1675 } 1676 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(); 1677 } 1678 1679 @Override public long getScreenOnTime(long batteryRealtime, int which) { 1680 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which); 1681 } 1682 1683 @Override public long getScreenBrightnessTime(int brightnessBin, 1684 long batteryRealtime, int which) { 1685 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 1686 batteryRealtime, which); 1687 } 1688 1689 @Override public int getInputEventCount(int which) { 1690 return mInputEventCounter.getCountLocked(which); 1691 } 1692 1693 @Override public long getPhoneOnTime(long batteryRealtime, int which) { 1694 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which); 1695 } 1696 1697 @Override public long getPhoneSignalStrengthTime(int strengthBin, 1698 long batteryRealtime, int which) { 1699 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 1700 batteryRealtime, which); 1701 } 1702 1703 @Override public long getPhoneSignalScanningTime( 1704 long batteryRealtime, int which) { 1705 return mPhoneSignalScanningTimer.getTotalTimeLocked( 1706 batteryRealtime, which); 1707 } 1708 1709 @Override public int getPhoneSignalStrengthCount(int dataType, int which) { 1710 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 1711 } 1712 1713 @Override public long getPhoneDataConnectionTime(int dataType, 1714 long batteryRealtime, int which) { 1715 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 1716 batteryRealtime, which); 1717 } 1718 1719 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 1720 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 1721 } 1722 1723 @Override public long getWifiOnTime(long batteryRealtime, int which) { 1724 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which); 1725 } 1726 1727 @Override public long getWifiRunningTime(long batteryRealtime, int which) { 1728 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 1729 } 1730 1731 @Override public long getBluetoothOnTime(long batteryRealtime, int which) { 1732 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); 1733 } 1734 1735 @Override public boolean getIsOnBattery() { 1736 return mOnBattery; 1737 } 1738 1739 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 1740 return mUidStats; 1741 } 1742 1743 /** 1744 * The statistics associated with a particular uid. 1745 */ 1746 public final class Uid extends BatteryStats.Uid { 1747 1748 final int mUid; 1749 long mLoadedTcpBytesReceived; 1750 long mLoadedTcpBytesSent; 1751 long mCurrentTcpBytesReceived; 1752 long mCurrentTcpBytesSent; 1753 long mTcpBytesReceivedAtLastUnplug; 1754 long mTcpBytesSentAtLastUnplug; 1755 1756 // These are not saved/restored when parcelling, since we want 1757 // to return from the parcel with a snapshot of the state. 1758 long mStartedTcpBytesReceived = -1; 1759 long mStartedTcpBytesSent = -1; 1760 1761 boolean mWifiTurnedOn; 1762 StopwatchTimer mWifiTurnedOnTimer; 1763 1764 boolean mFullWifiLockOut; 1765 StopwatchTimer mFullWifiLockTimer; 1766 1767 boolean mScanWifiLockOut; 1768 StopwatchTimer mScanWifiLockTimer; 1769 1770 boolean mWifiMulticastEnabled; 1771 StopwatchTimer mWifiMulticastTimer; 1772 1773 boolean mAudioTurnedOn; 1774 StopwatchTimer mAudioTurnedOnTimer; 1775 1776 boolean mVideoTurnedOn; 1777 StopwatchTimer mVideoTurnedOnTimer; 1778 1779 Counter[] mUserActivityCounters; 1780 1781 /** 1782 * The statistics we have collected for this uid's wake locks. 1783 */ 1784 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>(); 1785 1786 /** 1787 * The statistics we have collected for this uid's sensor activations. 1788 */ 1789 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>(); 1790 1791 /** 1792 * The statistics we have collected for this uid's processes. 1793 */ 1794 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>(); 1795 1796 /** 1797 * The statistics we have collected for this uid's processes. 1798 */ 1799 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>(); 1800 1801 public Uid(int uid) { 1802 mUid = uid; 1803 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables); 1804 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables); 1805 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables); 1806 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, 1807 null, mUnpluggables); 1808 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables); 1809 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables); 1810 } 1811 1812 @Override 1813 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 1814 return mWakelockStats; 1815 } 1816 1817 @Override 1818 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() { 1819 return mSensorStats; 1820 } 1821 1822 @Override 1823 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 1824 return mProcessStats; 1825 } 1826 1827 @Override 1828 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 1829 return mPackageStats; 1830 } 1831 1832 @Override 1833 public int getUid() { 1834 return mUid; 1835 } 1836 1837 @Override 1838 public long getTcpBytesReceived(int which) { 1839 if (which == STATS_LAST) { 1840 return mLoadedTcpBytesReceived; 1841 } else { 1842 long current = computeCurrentTcpBytesReceived(); 1843 if (which == STATS_SINCE_UNPLUGGED) { 1844 current -= mTcpBytesReceivedAtLastUnplug; 1845 } else if (which == STATS_SINCE_CHARGED) { 1846 current += mLoadedTcpBytesReceived; 1847 } 1848 return current; 1849 } 1850 } 1851 1852 public long computeCurrentTcpBytesReceived() { 1853 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0 1854 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0); 1855 } 1856 1857 @Override 1858 public long getTcpBytesSent(int which) { 1859 if (which == STATS_LAST) { 1860 return mLoadedTcpBytesSent; 1861 } else { 1862 long current = computeCurrentTcpBytesSent(); 1863 if (which == STATS_SINCE_UNPLUGGED) { 1864 current -= mTcpBytesSentAtLastUnplug; 1865 } else if (which == STATS_SINCE_CHARGED) { 1866 current += mLoadedTcpBytesSent; 1867 } 1868 return current; 1869 } 1870 } 1871 1872 @Override 1873 public void noteWifiTurnedOnLocked() { 1874 if (!mWifiTurnedOn) { 1875 mWifiTurnedOn = true; 1876 if (mWifiTurnedOnTimer == null) { 1877 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, 1878 null, mUnpluggables); 1879 } 1880 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1881 } 1882 } 1883 1884 @Override 1885 public void noteWifiTurnedOffLocked() { 1886 if (mWifiTurnedOn) { 1887 mWifiTurnedOn = false; 1888 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1889 } 1890 } 1891 1892 @Override 1893 public void noteFullWifiLockAcquiredLocked() { 1894 if (!mFullWifiLockOut) { 1895 mFullWifiLockOut = true; 1896 if (mFullWifiLockTimer == null) { 1897 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, 1898 null, mUnpluggables); 1899 } 1900 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 1901 } 1902 } 1903 1904 @Override 1905 public void noteFullWifiLockReleasedLocked() { 1906 if (mFullWifiLockOut) { 1907 mFullWifiLockOut = false; 1908 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 1909 } 1910 } 1911 1912 @Override 1913 public void noteScanWifiLockAcquiredLocked() { 1914 if (!mScanWifiLockOut) { 1915 mScanWifiLockOut = true; 1916 if (mScanWifiLockTimer == null) { 1917 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, 1918 null, mUnpluggables); 1919 } 1920 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 1921 } 1922 } 1923 1924 @Override 1925 public void noteScanWifiLockReleasedLocked() { 1926 if (mScanWifiLockOut) { 1927 mScanWifiLockOut = false; 1928 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 1929 } 1930 } 1931 1932 @Override 1933 public void noteWifiMulticastEnabledLocked() { 1934 if (!mWifiMulticastEnabled) { 1935 mWifiMulticastEnabled = true; 1936 if (mWifiMulticastTimer == null) { 1937 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, 1938 null, mUnpluggables); 1939 } 1940 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); 1941 } 1942 } 1943 1944 @Override 1945 public void noteWifiMulticastDisabledLocked() { 1946 if (mWifiMulticastEnabled) { 1947 mWifiMulticastEnabled = false; 1948 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this); 1949 } 1950 } 1951 1952 @Override 1953 public void noteAudioTurnedOnLocked() { 1954 if (!mAudioTurnedOn) { 1955 mAudioTurnedOn = true; 1956 if (mAudioTurnedOnTimer == null) { 1957 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, 1958 null, mUnpluggables); 1959 } 1960 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1961 } 1962 } 1963 1964 @Override 1965 public void noteAudioTurnedOffLocked() { 1966 if (mAudioTurnedOn) { 1967 mAudioTurnedOn = false; 1968 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1969 } 1970 } 1971 1972 @Override 1973 public void noteVideoTurnedOnLocked() { 1974 if (!mVideoTurnedOn) { 1975 mVideoTurnedOn = true; 1976 if (mVideoTurnedOnTimer == null) { 1977 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, 1978 null, mUnpluggables); 1979 } 1980 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1981 } 1982 } 1983 1984 @Override 1985 public void noteVideoTurnedOffLocked() { 1986 if (mVideoTurnedOn) { 1987 mVideoTurnedOn = false; 1988 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1989 } 1990 } 1991 1992 @Override 1993 public long getWifiTurnedOnTime(long batteryRealtime, int which) { 1994 if (mWifiTurnedOnTimer == null) { 1995 return 0; 1996 } 1997 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 1998 } 1999 2000 @Override 2001 public long getFullWifiLockTime(long batteryRealtime, int which) { 2002 if (mFullWifiLockTimer == null) { 2003 return 0; 2004 } 2005 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 2006 } 2007 2008 @Override 2009 public long getScanWifiLockTime(long batteryRealtime, int which) { 2010 if (mScanWifiLockTimer == null) { 2011 return 0; 2012 } 2013 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 2014 } 2015 2016 @Override 2017 public long getWifiMulticastTime(long batteryRealtime, int which) { 2018 if (mWifiMulticastTimer == null) { 2019 return 0; 2020 } 2021 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime, 2022 which); 2023 } 2024 2025 @Override 2026 public long getAudioTurnedOnTime(long batteryRealtime, int which) { 2027 if (mAudioTurnedOnTimer == null) { 2028 return 0; 2029 } 2030 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 2031 } 2032 2033 @Override 2034 public long getVideoTurnedOnTime(long batteryRealtime, int which) { 2035 if (mVideoTurnedOnTimer == null) { 2036 return 0; 2037 } 2038 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 2039 } 2040 2041 @Override 2042 public void noteUserActivityLocked(int type) { 2043 if (mUserActivityCounters == null) { 2044 initUserActivityLocked(); 2045 } 2046 if (type < 0) type = 0; 2047 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1; 2048 mUserActivityCounters[type].stepAtomic(); 2049 } 2050 2051 @Override 2052 public boolean hasUserActivity() { 2053 return mUserActivityCounters != null; 2054 } 2055 2056 @Override 2057 public int getUserActivityCount(int type, int which) { 2058 if (mUserActivityCounters == null) { 2059 return 0; 2060 } 2061 return mUserActivityCounters[type].getCountLocked(which); 2062 } 2063 2064 void initUserActivityLocked() { 2065 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 2066 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2067 mUserActivityCounters[i] = new Counter(mUnpluggables); 2068 } 2069 } 2070 2071 public long computeCurrentTcpBytesSent() { 2072 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0 2073 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0); 2074 } 2075 2076 /** 2077 * Clear all stats for this uid. Returns true if the uid is completely 2078 * inactive so can be dropped. 2079 */ 2080 boolean reset() { 2081 boolean active = false; 2082 2083 if (mWifiTurnedOnTimer != null) { 2084 active |= !mWifiTurnedOnTimer.reset(false); 2085 active |= mWifiTurnedOn; 2086 } 2087 if (mFullWifiLockTimer != null) { 2088 active |= !mFullWifiLockTimer.reset(false); 2089 active |= mFullWifiLockOut; 2090 } 2091 if (mScanWifiLockTimer != null) { 2092 active |= !mScanWifiLockTimer.reset(false); 2093 active |= mScanWifiLockOut; 2094 } 2095 if (mWifiMulticastTimer != null) { 2096 active |= !mWifiMulticastTimer.reset(false); 2097 active |= mWifiMulticastEnabled; 2098 } 2099 if (mAudioTurnedOnTimer != null) { 2100 active |= !mAudioTurnedOnTimer.reset(false); 2101 active |= mAudioTurnedOn; 2102 } 2103 if (mVideoTurnedOnTimer != null) { 2104 active |= !mVideoTurnedOnTimer.reset(false); 2105 active |= mVideoTurnedOn; 2106 } 2107 2108 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0; 2109 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0; 2110 2111 if (mUserActivityCounters != null) { 2112 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2113 mUserActivityCounters[i].reset(false); 2114 } 2115 } 2116 2117 if (mWakelockStats.size() > 0) { 2118 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator(); 2119 while (it.hasNext()) { 2120 Map.Entry<String, Wakelock> wakelockEntry = it.next(); 2121 Wakelock wl = wakelockEntry.getValue(); 2122 if (wl.reset()) { 2123 it.remove(); 2124 } else { 2125 active = true; 2126 } 2127 } 2128 } 2129 if (mSensorStats.size() > 0) { 2130 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator(); 2131 while (it.hasNext()) { 2132 Map.Entry<Integer, Sensor> sensorEntry = it.next(); 2133 Sensor s = sensorEntry.getValue(); 2134 if (s.reset()) { 2135 it.remove(); 2136 } else { 2137 active = true; 2138 } 2139 } 2140 } 2141 if (mProcessStats.size() > 0) { 2142 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator(); 2143 while (it.hasNext()) { 2144 Map.Entry<String, Proc> procEntry = it.next(); 2145 procEntry.getValue().detach(); 2146 } 2147 mProcessStats.clear(); 2148 } 2149 if (mPackageStats.size() > 0) { 2150 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 2151 while (it.hasNext()) { 2152 Map.Entry<String, Pkg> pkgEntry = it.next(); 2153 Pkg p = pkgEntry.getValue(); 2154 p.detach(); 2155 if (p.mServiceStats.size() > 0) { 2156 Iterator<Map.Entry<String, Pkg.Serv>> it2 2157 = p.mServiceStats.entrySet().iterator(); 2158 while (it2.hasNext()) { 2159 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 2160 servEntry.getValue().detach(); 2161 } 2162 } 2163 } 2164 mPackageStats.clear(); 2165 } 2166 2167 if (!active) { 2168 if (mWifiTurnedOnTimer != null) { 2169 mWifiTurnedOnTimer.detach(); 2170 } 2171 if (mFullWifiLockTimer != null) { 2172 mFullWifiLockTimer.detach(); 2173 } 2174 if (mScanWifiLockTimer != null) { 2175 mScanWifiLockTimer.detach(); 2176 } 2177 if (mWifiMulticastTimer != null) { 2178 mWifiMulticastTimer.detach(); 2179 } 2180 if (mAudioTurnedOnTimer != null) { 2181 mAudioTurnedOnTimer.detach(); 2182 } 2183 if (mVideoTurnedOnTimer != null) { 2184 mVideoTurnedOnTimer.detach(); 2185 } 2186 if (mUserActivityCounters != null) { 2187 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2188 mUserActivityCounters[i].detach(); 2189 } 2190 } 2191 } 2192 2193 return !active; 2194 } 2195 2196 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2197 out.writeInt(mWakelockStats.size()); 2198 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { 2199 out.writeString(wakelockEntry.getKey()); 2200 Uid.Wakelock wakelock = wakelockEntry.getValue(); 2201 wakelock.writeToParcelLocked(out, batteryRealtime); 2202 } 2203 2204 out.writeInt(mSensorStats.size()); 2205 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { 2206 out.writeInt(sensorEntry.getKey()); 2207 Uid.Sensor sensor = sensorEntry.getValue(); 2208 sensor.writeToParcelLocked(out, batteryRealtime); 2209 } 2210 2211 out.writeInt(mProcessStats.size()); 2212 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) { 2213 out.writeString(procEntry.getKey()); 2214 Uid.Proc proc = procEntry.getValue(); 2215 proc.writeToParcelLocked(out); 2216 } 2217 2218 out.writeInt(mPackageStats.size()); 2219 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 2220 out.writeString(pkgEntry.getKey()); 2221 Uid.Pkg pkg = pkgEntry.getValue(); 2222 pkg.writeToParcelLocked(out); 2223 } 2224 2225 out.writeLong(mLoadedTcpBytesReceived); 2226 out.writeLong(mLoadedTcpBytesSent); 2227 out.writeLong(computeCurrentTcpBytesReceived()); 2228 out.writeLong(computeCurrentTcpBytesSent()); 2229 out.writeLong(mTcpBytesReceivedAtLastUnplug); 2230 out.writeLong(mTcpBytesSentAtLastUnplug); 2231 if (mWifiTurnedOnTimer != null) { 2232 out.writeInt(1); 2233 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime); 2234 } else { 2235 out.writeInt(0); 2236 } 2237 if (mFullWifiLockTimer != null) { 2238 out.writeInt(1); 2239 mFullWifiLockTimer.writeToParcel(out, batteryRealtime); 2240 } else { 2241 out.writeInt(0); 2242 } 2243 if (mScanWifiLockTimer != null) { 2244 out.writeInt(1); 2245 mScanWifiLockTimer.writeToParcel(out, batteryRealtime); 2246 } else { 2247 out.writeInt(0); 2248 } 2249 if (mWifiMulticastTimer != null) { 2250 out.writeInt(1); 2251 mWifiMulticastTimer.writeToParcel(out, batteryRealtime); 2252 } else { 2253 out.writeInt(0); 2254 } 2255 if (mAudioTurnedOnTimer != null) { 2256 out.writeInt(1); 2257 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime); 2258 } else { 2259 out.writeInt(0); 2260 } 2261 if (mVideoTurnedOnTimer != null) { 2262 out.writeInt(1); 2263 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime); 2264 } else { 2265 out.writeInt(0); 2266 } 2267 if (mUserActivityCounters != null) { 2268 out.writeInt(1); 2269 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2270 mUserActivityCounters[i].writeToParcel(out); 2271 } 2272 } else { 2273 out.writeInt(0); 2274 } 2275 } 2276 2277 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2278 int numWakelocks = in.readInt(); 2279 mWakelockStats.clear(); 2280 for (int j = 0; j < numWakelocks; j++) { 2281 String wakelockName = in.readString(); 2282 Uid.Wakelock wakelock = new Wakelock(); 2283 wakelock.readFromParcelLocked(unpluggables, in); 2284 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) { 2285 // We will just drop some random set of wakelocks if 2286 // the previous run of the system was an older version 2287 // that didn't impose a limit. 2288 mWakelockStats.put(wakelockName, wakelock); 2289 } 2290 } 2291 2292 int numSensors = in.readInt(); 2293 mSensorStats.clear(); 2294 for (int k = 0; k < numSensors; k++) { 2295 int sensorNumber = in.readInt(); 2296 Uid.Sensor sensor = new Sensor(sensorNumber); 2297 sensor.readFromParcelLocked(mUnpluggables, in); 2298 mSensorStats.put(sensorNumber, sensor); 2299 } 2300 2301 int numProcs = in.readInt(); 2302 mProcessStats.clear(); 2303 for (int k = 0; k < numProcs; k++) { 2304 String processName = in.readString(); 2305 Uid.Proc proc = new Proc(); 2306 proc.readFromParcelLocked(in); 2307 mProcessStats.put(processName, proc); 2308 } 2309 2310 int numPkgs = in.readInt(); 2311 mPackageStats.clear(); 2312 for (int l = 0; l < numPkgs; l++) { 2313 String packageName = in.readString(); 2314 Uid.Pkg pkg = new Pkg(); 2315 pkg.readFromParcelLocked(in); 2316 mPackageStats.put(packageName, pkg); 2317 } 2318 2319 mLoadedTcpBytesReceived = in.readLong(); 2320 mLoadedTcpBytesSent = in.readLong(); 2321 mCurrentTcpBytesReceived = in.readLong(); 2322 mCurrentTcpBytesSent = in.readLong(); 2323 mTcpBytesReceivedAtLastUnplug = in.readLong(); 2324 mTcpBytesSentAtLastUnplug = in.readLong(); 2325 mWifiTurnedOn = false; 2326 if (in.readInt() != 0) { 2327 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, 2328 null, mUnpluggables, in); 2329 } else { 2330 mWifiTurnedOnTimer = null; 2331 } 2332 mFullWifiLockOut = false; 2333 if (in.readInt() != 0) { 2334 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, 2335 null, mUnpluggables, in); 2336 } else { 2337 mFullWifiLockTimer = null; 2338 } 2339 mScanWifiLockOut = false; 2340 if (in.readInt() != 0) { 2341 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, 2342 null, mUnpluggables, in); 2343 } else { 2344 mScanWifiLockTimer = null; 2345 } 2346 mWifiMulticastEnabled = false; 2347 if (in.readInt() != 0) { 2348 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, 2349 null, mUnpluggables, in); 2350 } else { 2351 mWifiMulticastTimer = null; 2352 } 2353 mAudioTurnedOn = false; 2354 if (in.readInt() != 0) { 2355 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, 2356 null, mUnpluggables, in); 2357 } else { 2358 mAudioTurnedOnTimer = null; 2359 } 2360 mVideoTurnedOn = false; 2361 if (in.readInt() != 0) { 2362 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, 2363 null, mUnpluggables, in); 2364 } else { 2365 mVideoTurnedOnTimer = null; 2366 } 2367 if (in.readInt() != 0) { 2368 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 2369 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2370 mUserActivityCounters[i] = new Counter(mUnpluggables, in); 2371 } 2372 } else { 2373 mUserActivityCounters = null; 2374 } 2375 } 2376 2377 /** 2378 * The statistics associated with a particular wake lock. 2379 */ 2380 public final class Wakelock extends BatteryStats.Uid.Wakelock { 2381 /** 2382 * How long (in ms) this uid has been keeping the device partially awake. 2383 */ 2384 StopwatchTimer mTimerPartial; 2385 2386 /** 2387 * How long (in ms) this uid has been keeping the device fully awake. 2388 */ 2389 StopwatchTimer mTimerFull; 2390 2391 /** 2392 * How long (in ms) this uid has had a window keeping the device awake. 2393 */ 2394 StopwatchTimer mTimerWindow; 2395 2396 /** 2397 * Reads a possibly null Timer from a Parcel. The timer is associated with the 2398 * proper timer pool from the given BatteryStatsImpl object. 2399 * 2400 * @param in the Parcel to be read from. 2401 * return a new Timer, or null. 2402 */ 2403 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 2404 ArrayList<Unpluggable> unpluggables, Parcel in) { 2405 if (in.readInt() == 0) { 2406 return null; 2407 } 2408 2409 return new StopwatchTimer(type, pool, unpluggables, in); 2410 } 2411 2412 boolean reset() { 2413 boolean wlactive = false; 2414 if (mTimerFull != null) { 2415 wlactive |= !mTimerFull.reset(false); 2416 } 2417 if (mTimerPartial != null) { 2418 wlactive |= !mTimerPartial.reset(false); 2419 } 2420 if (mTimerWindow != null) { 2421 wlactive |= !mTimerWindow.reset(false); 2422 } 2423 if (!wlactive) { 2424 if (mTimerFull != null) { 2425 mTimerFull.detach(); 2426 mTimerFull = null; 2427 } 2428 if (mTimerPartial != null) { 2429 mTimerPartial.detach(); 2430 mTimerPartial = null; 2431 } 2432 if (mTimerWindow != null) { 2433 mTimerWindow.detach(); 2434 mTimerWindow = null; 2435 } 2436 } 2437 return !wlactive; 2438 } 2439 2440 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2441 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 2442 mPartialTimers, unpluggables, in); 2443 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, 2444 mFullTimers, unpluggables, in); 2445 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, 2446 mWindowTimers, unpluggables, in); 2447 } 2448 2449 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2450 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime); 2451 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime); 2452 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime); 2453 } 2454 2455 @Override 2456 public Timer getWakeTime(int type) { 2457 switch (type) { 2458 case WAKE_TYPE_FULL: return mTimerFull; 2459 case WAKE_TYPE_PARTIAL: return mTimerPartial; 2460 case WAKE_TYPE_WINDOW: return mTimerWindow; 2461 default: throw new IllegalArgumentException("type = " + type); 2462 } 2463 } 2464 } 2465 2466 public final class Sensor extends BatteryStats.Uid.Sensor { 2467 final int mHandle; 2468 StopwatchTimer mTimer; 2469 2470 public Sensor(int handle) { 2471 mHandle = handle; 2472 } 2473 2474 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables, 2475 Parcel in) { 2476 if (in.readInt() == 0) { 2477 return null; 2478 } 2479 2480 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle); 2481 if (pool == null) { 2482 pool = new ArrayList<StopwatchTimer>(); 2483 mSensorTimers.put(mHandle, pool); 2484 } 2485 return new StopwatchTimer(0, pool, unpluggables, in); 2486 } 2487 2488 boolean reset() { 2489 if (mTimer.reset(true)) { 2490 mTimer = null; 2491 return true; 2492 } 2493 return false; 2494 } 2495 2496 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2497 mTimer = readTimerFromParcel(unpluggables, in); 2498 } 2499 2500 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2501 Timer.writeTimerToParcel(out, mTimer, batteryRealtime); 2502 } 2503 2504 @Override 2505 public Timer getSensorTime() { 2506 return mTimer; 2507 } 2508 2509 @Override 2510 public int getHandle() { 2511 return mHandle; 2512 } 2513 } 2514 2515 /** 2516 * The statistics associated with a particular process. 2517 */ 2518 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable { 2519 /** 2520 * Total time (in 1/100 sec) spent executing in user code. 2521 */ 2522 long mUserTime; 2523 2524 /** 2525 * Total time (in 1/100 sec) spent executing in kernel code. 2526 */ 2527 long mSystemTime; 2528 2529 /** 2530 * Number of times the process has been started. 2531 */ 2532 int mStarts; 2533 2534 /** 2535 * Amount of time the process was running in the foreground. 2536 */ 2537 long mForegroundTime; 2538 2539 /** 2540 * The amount of user time loaded from a previous save. 2541 */ 2542 long mLoadedUserTime; 2543 2544 /** 2545 * The amount of system time loaded from a previous save. 2546 */ 2547 long mLoadedSystemTime; 2548 2549 /** 2550 * The number of times the process has started from a previous save. 2551 */ 2552 int mLoadedStarts; 2553 2554 /** 2555 * The amount of foreground time loaded from a previous save. 2556 */ 2557 long mLoadedForegroundTime; 2558 2559 /** 2560 * The amount of user time loaded from the previous run. 2561 */ 2562 long mLastUserTime; 2563 2564 /** 2565 * The amount of system time loaded from the previous run. 2566 */ 2567 long mLastSystemTime; 2568 2569 /** 2570 * The number of times the process has started from the previous run. 2571 */ 2572 int mLastStarts; 2573 2574 /** 2575 * The amount of foreground time loaded from the previous run 2576 */ 2577 long mLastForegroundTime; 2578 2579 /** 2580 * The amount of user time when last unplugged. 2581 */ 2582 long mUnpluggedUserTime; 2583 2584 /** 2585 * The amount of system time when last unplugged. 2586 */ 2587 long mUnpluggedSystemTime; 2588 2589 /** 2590 * The number of times the process has started before unplugged. 2591 */ 2592 int mUnpluggedStarts; 2593 2594 /** 2595 * The amount of foreground time since unplugged. 2596 */ 2597 long mUnpluggedForegroundTime; 2598 2599 SamplingCounter[] mSpeedBins; 2600 2601 Proc() { 2602 mUnpluggables.add(this); 2603 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; 2604 } 2605 2606 public void unplug(long batteryUptime, long batteryRealtime) { 2607 mUnpluggedUserTime = mUserTime; 2608 mUnpluggedSystemTime = mSystemTime; 2609 mUnpluggedStarts = mStarts; 2610 mUnpluggedForegroundTime = mForegroundTime; 2611 } 2612 2613 public void plug(long batteryUptime, long batteryRealtime) { 2614 } 2615 2616 void detach() { 2617 mUnpluggables.remove(this); 2618 for (int i = 0; i < mSpeedBins.length; i++) { 2619 SamplingCounter c = mSpeedBins[i]; 2620 if (c != null) { 2621 mUnpluggables.remove(c); 2622 mSpeedBins[i] = null; 2623 } 2624 } 2625 } 2626 2627 void writeToParcelLocked(Parcel out) { 2628 out.writeLong(mUserTime); 2629 out.writeLong(mSystemTime); 2630 out.writeLong(mForegroundTime); 2631 out.writeInt(mStarts); 2632 out.writeLong(mLoadedUserTime); 2633 out.writeLong(mLoadedSystemTime); 2634 out.writeLong(mLoadedForegroundTime); 2635 out.writeInt(mLoadedStarts); 2636 out.writeLong(mUnpluggedUserTime); 2637 out.writeLong(mUnpluggedSystemTime); 2638 out.writeLong(mUnpluggedForegroundTime); 2639 out.writeInt(mUnpluggedStarts); 2640 2641 out.writeInt(mSpeedBins.length); 2642 for (int i = 0; i < mSpeedBins.length; i++) { 2643 SamplingCounter c = mSpeedBins[i]; 2644 if (c != null) { 2645 out.writeInt(1); 2646 c.writeToParcel(out); 2647 } else { 2648 out.writeInt(0); 2649 } 2650 } 2651 } 2652 2653 void readFromParcelLocked(Parcel in) { 2654 mUserTime = in.readLong(); 2655 mSystemTime = in.readLong(); 2656 mForegroundTime = in.readLong(); 2657 mStarts = in.readInt(); 2658 mLoadedUserTime = in.readLong(); 2659 mLoadedSystemTime = in.readLong(); 2660 mLoadedForegroundTime = in.readLong(); 2661 mLoadedStarts = in.readInt(); 2662 mLastUserTime = 0; 2663 mLastSystemTime = 0; 2664 mLastForegroundTime = 0; 2665 mLastStarts = 0; 2666 mUnpluggedUserTime = in.readLong(); 2667 mUnpluggedSystemTime = in.readLong(); 2668 mUnpluggedForegroundTime = in.readLong(); 2669 mUnpluggedStarts = in.readInt(); 2670 2671 int bins = in.readInt(); 2672 int steps = getCpuSpeedSteps(); 2673 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps]; 2674 for (int i = 0; i < bins; i++) { 2675 if (in.readInt() != 0) { 2676 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in); 2677 } 2678 } 2679 } 2680 2681 public BatteryStatsImpl getBatteryStats() { 2682 return BatteryStatsImpl.this; 2683 } 2684 2685 public void addCpuTimeLocked(int utime, int stime) { 2686 mUserTime += utime; 2687 mSystemTime += stime; 2688 } 2689 2690 public void addForegroundTimeLocked(long ttime) { 2691 mForegroundTime += ttime; 2692 } 2693 2694 public void incStartsLocked() { 2695 mStarts++; 2696 } 2697 2698 @Override 2699 public long getUserTime(int which) { 2700 long val; 2701 if (which == STATS_LAST) { 2702 val = mLastUserTime; 2703 } else { 2704 val = mUserTime; 2705 if (which == STATS_CURRENT) { 2706 val -= mLoadedUserTime; 2707 } else if (which == STATS_SINCE_UNPLUGGED) { 2708 val -= mUnpluggedUserTime; 2709 } 2710 } 2711 return val; 2712 } 2713 2714 @Override 2715 public long getSystemTime(int which) { 2716 long val; 2717 if (which == STATS_LAST) { 2718 val = mLastSystemTime; 2719 } else { 2720 val = mSystemTime; 2721 if (which == STATS_CURRENT) { 2722 val -= mLoadedSystemTime; 2723 } else if (which == STATS_SINCE_UNPLUGGED) { 2724 val -= mUnpluggedSystemTime; 2725 } 2726 } 2727 return val; 2728 } 2729 2730 @Override 2731 public long getForegroundTime(int which) { 2732 long val; 2733 if (which == STATS_LAST) { 2734 val = mLastForegroundTime; 2735 } else { 2736 val = mForegroundTime; 2737 if (which == STATS_CURRENT) { 2738 val -= mLoadedForegroundTime; 2739 } else if (which == STATS_SINCE_UNPLUGGED) { 2740 val -= mUnpluggedForegroundTime; 2741 } 2742 } 2743 return val; 2744 } 2745 2746 @Override 2747 public int getStarts(int which) { 2748 int val; 2749 if (which == STATS_LAST) { 2750 val = mLastStarts; 2751 } else { 2752 val = mStarts; 2753 if (which == STATS_CURRENT) { 2754 val -= mLoadedStarts; 2755 } else if (which == STATS_SINCE_UNPLUGGED) { 2756 val -= mUnpluggedStarts; 2757 } 2758 } 2759 return val; 2760 } 2761 2762 /* Called by ActivityManagerService when CPU times are updated. */ 2763 public void addSpeedStepTimes(long[] values) { 2764 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { 2765 long amt = values[i]; 2766 if (amt != 0) { 2767 SamplingCounter c = mSpeedBins[i]; 2768 if (c == null) { 2769 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables); 2770 } 2771 c.addCountAtomic(values[i]); 2772 } 2773 } 2774 } 2775 2776 @Override 2777 public long getTimeAtCpuSpeedStep(int speedStep, int which) { 2778 if (speedStep < mSpeedBins.length) { 2779 SamplingCounter c = mSpeedBins[speedStep]; 2780 return c != null ? c.getCountLocked(which) : 0; 2781 } else { 2782 return 0; 2783 } 2784 } 2785 } 2786 2787 /** 2788 * The statistics associated with a particular package. 2789 */ 2790 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable { 2791 /** 2792 * Number of times this package has done something that could wake up the 2793 * device from sleep. 2794 */ 2795 int mWakeups; 2796 2797 /** 2798 * Number of things that could wake up the device loaded from a 2799 * previous save. 2800 */ 2801 int mLoadedWakeups; 2802 2803 /** 2804 * Number of things that could wake up the device as of the 2805 * last run. 2806 */ 2807 int mLastWakeups; 2808 2809 /** 2810 * Number of things that could wake up the device as of the 2811 * last run. 2812 */ 2813 int mUnpluggedWakeups; 2814 2815 /** 2816 * The statics we have collected for this package's services. 2817 */ 2818 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); 2819 2820 Pkg() { 2821 mUnpluggables.add(this); 2822 } 2823 2824 public void unplug(long batteryUptime, long batteryRealtime) { 2825 mUnpluggedWakeups = mWakeups; 2826 } 2827 2828 public void plug(long batteryUptime, long batteryRealtime) { 2829 } 2830 2831 void detach() { 2832 mUnpluggables.remove(this); 2833 } 2834 2835 void readFromParcelLocked(Parcel in) { 2836 mWakeups = in.readInt(); 2837 mLoadedWakeups = in.readInt(); 2838 mLastWakeups = 0; 2839 mUnpluggedWakeups = in.readInt(); 2840 2841 int numServs = in.readInt(); 2842 mServiceStats.clear(); 2843 for (int m = 0; m < numServs; m++) { 2844 String serviceName = in.readString(); 2845 Uid.Pkg.Serv serv = new Serv(); 2846 mServiceStats.put(serviceName, serv); 2847 2848 serv.readFromParcelLocked(in); 2849 } 2850 } 2851 2852 void writeToParcelLocked(Parcel out) { 2853 out.writeInt(mWakeups); 2854 out.writeInt(mLoadedWakeups); 2855 out.writeInt(mUnpluggedWakeups); 2856 2857 out.writeInt(mServiceStats.size()); 2858 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { 2859 out.writeString(servEntry.getKey()); 2860 Uid.Pkg.Serv serv = servEntry.getValue(); 2861 2862 serv.writeToParcelLocked(out); 2863 } 2864 } 2865 2866 @Override 2867 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 2868 return mServiceStats; 2869 } 2870 2871 @Override 2872 public int getWakeups(int which) { 2873 int val; 2874 if (which == STATS_LAST) { 2875 val = mLastWakeups; 2876 } else { 2877 val = mWakeups; 2878 if (which == STATS_CURRENT) { 2879 val -= mLoadedWakeups; 2880 } else if (which == STATS_SINCE_UNPLUGGED) { 2881 val -= mUnpluggedWakeups; 2882 } 2883 } 2884 2885 return val; 2886 } 2887 2888 /** 2889 * The statistics associated with a particular service. 2890 */ 2891 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable { 2892 /** 2893 * Total time (ms in battery uptime) the service has been left started. 2894 */ 2895 long mStartTime; 2896 2897 /** 2898 * If service has been started and not yet stopped, this is 2899 * when it was started. 2900 */ 2901 long mRunningSince; 2902 2903 /** 2904 * True if we are currently running. 2905 */ 2906 boolean mRunning; 2907 2908 /** 2909 * Total number of times startService() has been called. 2910 */ 2911 int mStarts; 2912 2913 /** 2914 * Total time (ms in battery uptime) the service has been left launched. 2915 */ 2916 long mLaunchedTime; 2917 2918 /** 2919 * If service has been launched and not yet exited, this is 2920 * when it was launched (ms in battery uptime). 2921 */ 2922 long mLaunchedSince; 2923 2924 /** 2925 * True if we are currently launched. 2926 */ 2927 boolean mLaunched; 2928 2929 /** 2930 * Total number times the service has been launched. 2931 */ 2932 int mLaunches; 2933 2934 /** 2935 * The amount of time spent started loaded from a previous save 2936 * (ms in battery uptime). 2937 */ 2938 long mLoadedStartTime; 2939 2940 /** 2941 * The number of starts loaded from a previous save. 2942 */ 2943 int mLoadedStarts; 2944 2945 /** 2946 * The number of launches loaded from a previous save. 2947 */ 2948 int mLoadedLaunches; 2949 2950 /** 2951 * The amount of time spent started as of the last run (ms 2952 * in battery uptime). 2953 */ 2954 long mLastStartTime; 2955 2956 /** 2957 * The number of starts as of the last run. 2958 */ 2959 int mLastStarts; 2960 2961 /** 2962 * The number of launches as of the last run. 2963 */ 2964 int mLastLaunches; 2965 2966 /** 2967 * The amount of time spent started when last unplugged (ms 2968 * in battery uptime). 2969 */ 2970 long mUnpluggedStartTime; 2971 2972 /** 2973 * The number of starts when last unplugged. 2974 */ 2975 int mUnpluggedStarts; 2976 2977 /** 2978 * The number of launches when last unplugged. 2979 */ 2980 int mUnpluggedLaunches; 2981 2982 Serv() { 2983 mUnpluggables.add(this); 2984 } 2985 2986 public void unplug(long batteryUptime, long batteryRealtime) { 2987 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime); 2988 mUnpluggedStarts = mStarts; 2989 mUnpluggedLaunches = mLaunches; 2990 } 2991 2992 public void plug(long batteryUptime, long batteryRealtime) { 2993 } 2994 2995 void detach() { 2996 mUnpluggables.remove(this); 2997 } 2998 2999 void readFromParcelLocked(Parcel in) { 3000 mStartTime = in.readLong(); 3001 mRunningSince = in.readLong(); 3002 mRunning = in.readInt() != 0; 3003 mStarts = in.readInt(); 3004 mLaunchedTime = in.readLong(); 3005 mLaunchedSince = in.readLong(); 3006 mLaunched = in.readInt() != 0; 3007 mLaunches = in.readInt(); 3008 mLoadedStartTime = in.readLong(); 3009 mLoadedStarts = in.readInt(); 3010 mLoadedLaunches = in.readInt(); 3011 mLastStartTime = 0; 3012 mLastStarts = 0; 3013 mLastLaunches = 0; 3014 mUnpluggedStartTime = in.readLong(); 3015 mUnpluggedStarts = in.readInt(); 3016 mUnpluggedLaunches = in.readInt(); 3017 } 3018 3019 void writeToParcelLocked(Parcel out) { 3020 out.writeLong(mStartTime); 3021 out.writeLong(mRunningSince); 3022 out.writeInt(mRunning ? 1 : 0); 3023 out.writeInt(mStarts); 3024 out.writeLong(mLaunchedTime); 3025 out.writeLong(mLaunchedSince); 3026 out.writeInt(mLaunched ? 1 : 0); 3027 out.writeInt(mLaunches); 3028 out.writeLong(mLoadedStartTime); 3029 out.writeInt(mLoadedStarts); 3030 out.writeInt(mLoadedLaunches); 3031 out.writeLong(mUnpluggedStartTime); 3032 out.writeInt(mUnpluggedStarts); 3033 out.writeInt(mUnpluggedLaunches); 3034 } 3035 3036 long getLaunchTimeToNowLocked(long batteryUptime) { 3037 if (!mLaunched) return mLaunchedTime; 3038 return mLaunchedTime + batteryUptime - mLaunchedSince; 3039 } 3040 3041 long getStartTimeToNowLocked(long batteryUptime) { 3042 if (!mRunning) return mStartTime; 3043 return mStartTime + batteryUptime - mRunningSince; 3044 } 3045 3046 public void startLaunchedLocked() { 3047 if (!mLaunched) { 3048 mLaunches++; 3049 mLaunchedSince = getBatteryUptimeLocked(); 3050 mLaunched = true; 3051 } 3052 } 3053 3054 public void stopLaunchedLocked() { 3055 if (mLaunched) { 3056 long time = getBatteryUptimeLocked() - mLaunchedSince; 3057 if (time > 0) { 3058 mLaunchedTime += time; 3059 } else { 3060 mLaunches--; 3061 } 3062 mLaunched = false; 3063 } 3064 } 3065 3066 public void startRunningLocked() { 3067 if (!mRunning) { 3068 mStarts++; 3069 mRunningSince = getBatteryUptimeLocked(); 3070 mRunning = true; 3071 } 3072 } 3073 3074 public void stopRunningLocked() { 3075 if (mRunning) { 3076 long time = getBatteryUptimeLocked() - mRunningSince; 3077 if (time > 0) { 3078 mStartTime += time; 3079 } else { 3080 mStarts--; 3081 } 3082 mRunning = false; 3083 } 3084 } 3085 3086 public BatteryStatsImpl getBatteryStats() { 3087 return BatteryStatsImpl.this; 3088 } 3089 3090 @Override 3091 public int getLaunches(int which) { 3092 int val; 3093 3094 if (which == STATS_LAST) { 3095 val = mLastLaunches; 3096 } else { 3097 val = mLaunches; 3098 if (which == STATS_CURRENT) { 3099 val -= mLoadedLaunches; 3100 } else if (which == STATS_SINCE_UNPLUGGED) { 3101 val -= mUnpluggedLaunches; 3102 } 3103 } 3104 3105 return val; 3106 } 3107 3108 @Override 3109 public long getStartTime(long now, int which) { 3110 long val; 3111 if (which == STATS_LAST) { 3112 val = mLastStartTime; 3113 } else { 3114 val = getStartTimeToNowLocked(now); 3115 if (which == STATS_CURRENT) { 3116 val -= mLoadedStartTime; 3117 } else if (which == STATS_SINCE_UNPLUGGED) { 3118 val -= mUnpluggedStartTime; 3119 } 3120 } 3121 3122 return val; 3123 } 3124 3125 @Override 3126 public int getStarts(int which) { 3127 int val; 3128 if (which == STATS_LAST) { 3129 val = mLastStarts; 3130 } else { 3131 val = mStarts; 3132 if (which == STATS_CURRENT) { 3133 val -= mLoadedStarts; 3134 } else if (which == STATS_SINCE_UNPLUGGED) { 3135 val -= mUnpluggedStarts; 3136 } 3137 } 3138 3139 return val; 3140 } 3141 } 3142 3143 public BatteryStatsImpl getBatteryStats() { 3144 return BatteryStatsImpl.this; 3145 } 3146 3147 public void incWakeupsLocked() { 3148 mWakeups++; 3149 } 3150 3151 final Serv newServiceStatsLocked() { 3152 return new Serv(); 3153 } 3154 } 3155 3156 /** 3157 * Retrieve the statistics object for a particular process, creating 3158 * if needed. 3159 */ 3160 public Proc getProcessStatsLocked(String name) { 3161 Proc ps = mProcessStats.get(name); 3162 if (ps == null) { 3163 ps = new Proc(); 3164 mProcessStats.put(name, ps); 3165 } 3166 3167 return ps; 3168 } 3169 3170 /** 3171 * Retrieve the statistics object for a particular service, creating 3172 * if needed. 3173 */ 3174 public Pkg getPackageStatsLocked(String name) { 3175 Pkg ps = mPackageStats.get(name); 3176 if (ps == null) { 3177 ps = new Pkg(); 3178 mPackageStats.put(name, ps); 3179 } 3180 3181 return ps; 3182 } 3183 3184 /** 3185 * Retrieve the statistics object for a particular service, creating 3186 * if needed. 3187 */ 3188 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 3189 Pkg ps = getPackageStatsLocked(pkg); 3190 Pkg.Serv ss = ps.mServiceStats.get(serv); 3191 if (ss == null) { 3192 ss = ps.newServiceStatsLocked(); 3193 ps.mServiceStats.put(serv, ss); 3194 } 3195 3196 return ss; 3197 } 3198 3199 public StopwatchTimer getWakeTimerLocked(String name, int type) { 3200 Wakelock wl = mWakelockStats.get(name); 3201 if (wl == null) { 3202 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) { 3203 name = BATCHED_WAKELOCK_NAME; 3204 wl = mWakelockStats.get(name); 3205 } 3206 if (wl == null) { 3207 wl = new Wakelock(); 3208 mWakelockStats.put(name, wl); 3209 } 3210 } 3211 StopwatchTimer t = null; 3212 switch (type) { 3213 case WAKE_TYPE_PARTIAL: 3214 t = wl.mTimerPartial; 3215 if (t == null) { 3216 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); 3217 wl.mTimerPartial = t; 3218 } 3219 return t; 3220 case WAKE_TYPE_FULL: 3221 t = wl.mTimerFull; 3222 if (t == null) { 3223 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); 3224 wl.mTimerFull = t; 3225 } 3226 return t; 3227 case WAKE_TYPE_WINDOW: 3228 t = wl.mTimerWindow; 3229 if (t == null) { 3230 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); 3231 wl.mTimerWindow = t; 3232 } 3233 return t; 3234 default: 3235 throw new IllegalArgumentException("type=" + type); 3236 } 3237 } 3238 3239 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 3240 Sensor se = mSensorStats.get(sensor); 3241 if (se == null) { 3242 if (!create) { 3243 return null; 3244 } 3245 se = new Sensor(sensor); 3246 mSensorStats.put(sensor, se); 3247 } 3248 StopwatchTimer t = se.mTimer; 3249 if (t != null) { 3250 return t; 3251 } 3252 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor); 3253 if (timers == null) { 3254 timers = new ArrayList<StopwatchTimer>(); 3255 mSensorTimers.put(sensor, timers); 3256 } 3257 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables); 3258 se.mTimer = t; 3259 return t; 3260 } 3261 3262 public void noteStartWakeLocked(String name, int type) { 3263 StopwatchTimer t = getWakeTimerLocked(name, type); 3264 if (t != null) { 3265 t.startRunningLocked(BatteryStatsImpl.this); 3266 } 3267 } 3268 3269 public void noteStopWakeLocked(String name, int type) { 3270 StopwatchTimer t = getWakeTimerLocked(name, type); 3271 if (t != null) { 3272 t.stopRunningLocked(BatteryStatsImpl.this); 3273 } 3274 } 3275 3276 public void noteStartSensor(int sensor) { 3277 StopwatchTimer t = getSensorTimerLocked(sensor, true); 3278 if (t != null) { 3279 t.startRunningLocked(BatteryStatsImpl.this); 3280 } 3281 } 3282 3283 public void noteStopSensor(int sensor) { 3284 // Don't create a timer if one doesn't already exist 3285 StopwatchTimer t = getSensorTimerLocked(sensor, false); 3286 if (t != null) { 3287 t.stopRunningLocked(BatteryStatsImpl.this); 3288 } 3289 } 3290 3291 public void noteStartGps() { 3292 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 3293 if (t != null) { 3294 t.startRunningLocked(BatteryStatsImpl.this); 3295 } 3296 } 3297 3298 public void noteStopGps() { 3299 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 3300 if (t != null) { 3301 t.stopRunningLocked(BatteryStatsImpl.this); 3302 } 3303 } 3304 3305 public BatteryStatsImpl getBatteryStats() { 3306 return BatteryStatsImpl.this; 3307 } 3308 } 3309 3310 public BatteryStatsImpl(String filename) { 3311 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); 3312 mStartCount++; 3313 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables); 3314 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3315 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables); 3316 } 3317 mInputEventCounter = new Counter(mUnpluggables); 3318 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables); 3319 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3320 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables); 3321 } 3322 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables); 3323 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3324 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables); 3325 } 3326 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables); 3327 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables); 3328 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables); 3329 mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables); 3330 mVideoOnTimer = new StopwatchTimer(-7, null, mUnpluggables); 3331 mOnBattery = mOnBatteryInternal = false; 3332 initTimes(); 3333 mTrackBatteryPastUptime = 0; 3334 mTrackBatteryPastRealtime = 0; 3335 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 3336 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 3337 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 3338 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 3339 mDischargeStartLevel = 0; 3340 mDischargeUnplugLevel = 0; 3341 mDischargeCurrentLevel = 0; 3342 mLowDischargeAmountSinceCharge = 0; 3343 mHighDischargeAmountSinceCharge = 0; 3344 } 3345 3346 public BatteryStatsImpl(Parcel p) { 3347 mFile = null; 3348 readFromParcel(p); 3349 } 3350 3351 public void setNumSpeedSteps(int steps) { 3352 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; 3353 } 3354 3355 public void setRadioScanningTimeout(long timeout) { 3356 if (mPhoneSignalScanningTimer != null) { 3357 mPhoneSignalScanningTimer.setTimeout(timeout); 3358 } 3359 } 3360 3361 @Override 3362 public HistoryItem getHistory() { 3363 return mHistory; 3364 } 3365 3366 @Override 3367 public int getStartCount() { 3368 return mStartCount; 3369 } 3370 3371 public boolean isOnBattery() { 3372 return mOnBattery; 3373 } 3374 3375 void initTimes() { 3376 mBatteryRealtime = mTrackBatteryPastUptime = 0; 3377 mBatteryUptime = mTrackBatteryPastRealtime = 0; 3378 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 3379 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 3380 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 3381 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 3382 } 3383 3384 public void resetAllStatsLocked() { 3385 mStartCount = 0; 3386 initTimes(); 3387 mScreenOnTimer.reset(false); 3388 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3389 mScreenBrightnessTimer[i].reset(false); 3390 } 3391 mInputEventCounter.reset(false); 3392 mPhoneOnTimer.reset(false); 3393 mAudioOnTimer.reset(false); 3394 mVideoOnTimer.reset(false); 3395 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3396 mPhoneSignalStrengthsTimer[i].reset(false); 3397 } 3398 mPhoneSignalScanningTimer.reset(false); 3399 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3400 mPhoneDataConnectionsTimer[i].reset(false); 3401 } 3402 mWifiOnTimer.reset(false); 3403 mWifiRunningTimer.reset(false); 3404 mBluetoothOnTimer.reset(false); 3405 3406 for (int i=0; i<mUidStats.size(); i++) { 3407 if (mUidStats.valueAt(i).reset()) { 3408 mUidStats.remove(mUidStats.keyAt(i)); 3409 i--; 3410 } 3411 } 3412 3413 if (mKernelWakelockStats.size() > 0) { 3414 for (SamplingTimer timer : mKernelWakelockStats.values()) { 3415 mUnpluggables.remove(timer); 3416 } 3417 mKernelWakelockStats.clear(); 3418 } 3419 3420 clearHistoryLocked(); 3421 } 3422 3423 void setOnBattery(boolean onBattery, int oldStatus, int level) { 3424 synchronized(this) { 3425 boolean doWrite = false; 3426 mOnBattery = mOnBatteryInternal = onBattery; 3427 3428 long uptime = SystemClock.uptimeMillis() * 1000; 3429 long mSecRealtime = SystemClock.elapsedRealtime(); 3430 long realtime = mSecRealtime * 1000; 3431 if (onBattery) { 3432 // We will reset our status if we are unplugging after the 3433 // battery was last full, or the level is at 100, or 3434 // we have gone through a significant charge (from a very low 3435 // level to a now very high level). 3436 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL 3437 || level >= 100 3438 || (mDischargeCurrentLevel < 20 && level > 90)) { 3439 doWrite = true; 3440 resetAllStatsLocked(); 3441 mDischargeStartLevel = level; 3442 mLowDischargeAmountSinceCharge = 0; 3443 mHighDischargeAmountSinceCharge = 0; 3444 } 3445 updateKernelWakelocksLocked(); 3446 mHistoryCur.batteryLevel = (byte)level; 3447 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 3448 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 3449 + Integer.toHexString(mHistoryCur.states)); 3450 addHistoryRecordLocked(mSecRealtime); 3451 mTrackBatteryUptimeStart = uptime; 3452 mTrackBatteryRealtimeStart = realtime; 3453 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); 3454 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); 3455 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 3456 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); 3457 } else { 3458 updateKernelWakelocksLocked(); 3459 mHistoryCur.batteryLevel = (byte)level; 3460 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 3461 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 3462 + Integer.toHexString(mHistoryCur.states)); 3463 addHistoryRecordLocked(mSecRealtime); 3464 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; 3465 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; 3466 mDischargeCurrentLevel = level; 3467 if (level < mDischargeUnplugLevel) { 3468 mLowDischargeAmountSinceCharge = mDischargeUnplugLevel-level-1; 3469 mHighDischargeAmountSinceCharge = mDischargeUnplugLevel-level; 3470 } 3471 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime)); 3472 } 3473 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 3474 if (mFile != null) { 3475 writeLocked(); 3476 } 3477 } 3478 } 3479 } 3480 3481 // This should probably be exposed in the API, though it's not critical 3482 private static final int BATTERY_PLUGGED_NONE = 0; 3483 3484 public void setBatteryState(int status, int health, int plugType, int level, 3485 int temp, int volt) { 3486 boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 3487 int oldStatus = mHistoryCur.batteryStatus; 3488 if (!mHaveBatteryLevel) { 3489 mHaveBatteryLevel = true; 3490 // We start out assuming that the device is plugged in (not 3491 // on battery). If our first report is now that we are indeed 3492 // plugged in, then twiddle our state to correctly reflect that 3493 // since we won't be going through the full setOnBattery(). 3494 if (onBattery == mOnBattery) { 3495 if (onBattery) { 3496 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 3497 } else { 3498 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 3499 } 3500 } 3501 oldStatus = status; 3502 } 3503 if (onBattery) { 3504 mDischargeCurrentLevel = level; 3505 mRecordingHistory = true; 3506 } 3507 if (onBattery != mOnBattery) { 3508 mHistoryCur.batteryLevel = (byte)level; 3509 mHistoryCur.batteryStatus = (byte)status; 3510 mHistoryCur.batteryHealth = (byte)health; 3511 mHistoryCur.batteryPlugType = (byte)plugType; 3512 mHistoryCur.batteryTemperature = (char)temp; 3513 mHistoryCur.batteryVoltage = (char)volt; 3514 setOnBattery(onBattery, oldStatus, level); 3515 } else { 3516 boolean changed = false; 3517 if (mHistoryCur.batteryLevel != level) { 3518 mHistoryCur.batteryLevel = (byte)level; 3519 changed = true; 3520 } 3521 if (mHistoryCur.batteryStatus != status) { 3522 mHistoryCur.batteryStatus = (byte)status; 3523 changed = true; 3524 } 3525 if (mHistoryCur.batteryHealth != health) { 3526 mHistoryCur.batteryHealth = (byte)health; 3527 changed = true; 3528 } 3529 if (mHistoryCur.batteryPlugType != plugType) { 3530 mHistoryCur.batteryPlugType = (byte)plugType; 3531 changed = true; 3532 } 3533 if (mHistoryCur.batteryTemperature != temp) { 3534 mHistoryCur.batteryTemperature = (char)temp; 3535 changed = true; 3536 } 3537 if (mHistoryCur.batteryVoltage != volt) { 3538 mHistoryCur.batteryVoltage = (char)volt; 3539 changed = true; 3540 } 3541 if (changed) { 3542 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 3543 } 3544 } 3545 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 3546 // We don't record history while we are plugged in and fully charged. 3547 // The next time we are unplugged, history will be cleared. 3548 mRecordingHistory = false; 3549 } 3550 } 3551 3552 public void updateKernelWakelocksLocked() { 3553 Map<String, KernelWakelockStats> m = readKernelWakelockStats(); 3554 3555 if (m == null) { 3556 // Not crashing might make board bringup easier. 3557 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 3558 return; 3559 } 3560 3561 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) { 3562 String name = ent.getKey(); 3563 KernelWakelockStats kws = ent.getValue(); 3564 3565 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3566 if (kwlt == null) { 3567 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 3568 true /* track reported values */); 3569 mKernelWakelockStats.put(name, kwlt); 3570 } 3571 kwlt.updateCurrentReportedCount(kws.mCount); 3572 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); 3573 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion); 3574 } 3575 3576 if (m.size() != mKernelWakelockStats.size()) { 3577 // Set timers to stale if they didn't appear in /proc/wakelocks this time. 3578 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 3579 SamplingTimer st = ent.getValue(); 3580 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) { 3581 st.setStale(); 3582 } 3583 } 3584 } 3585 } 3586 3587 public long getAwakeTimeBattery() { 3588 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 3589 } 3590 3591 public long getAwakeTimePlugged() { 3592 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 3593 } 3594 3595 @Override 3596 public long computeUptime(long curTime, int which) { 3597 switch (which) { 3598 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 3599 case STATS_LAST: return mLastUptime; 3600 case STATS_CURRENT: return (curTime-mUptimeStart); 3601 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart); 3602 } 3603 return 0; 3604 } 3605 3606 @Override 3607 public long computeRealtime(long curTime, int which) { 3608 switch (which) { 3609 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 3610 case STATS_LAST: return mLastRealtime; 3611 case STATS_CURRENT: return (curTime-mRealtimeStart); 3612 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart); 3613 } 3614 return 0; 3615 } 3616 3617 @Override 3618 public long computeBatteryUptime(long curTime, int which) { 3619 switch (which) { 3620 case STATS_SINCE_CHARGED: 3621 return mBatteryUptime + getBatteryUptime(curTime); 3622 case STATS_LAST: 3623 return mBatteryLastUptime; 3624 case STATS_CURRENT: 3625 return getBatteryUptime(curTime); 3626 case STATS_SINCE_UNPLUGGED: 3627 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; 3628 } 3629 return 0; 3630 } 3631 3632 @Override 3633 public long computeBatteryRealtime(long curTime, int which) { 3634 switch (which) { 3635 case STATS_SINCE_CHARGED: 3636 return mBatteryRealtime + getBatteryRealtimeLocked(curTime); 3637 case STATS_LAST: 3638 return mBatteryLastRealtime; 3639 case STATS_CURRENT: 3640 return getBatteryRealtimeLocked(curTime); 3641 case STATS_SINCE_UNPLUGGED: 3642 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime; 3643 } 3644 return 0; 3645 } 3646 3647 long getBatteryUptimeLocked(long curTime) { 3648 long time = mTrackBatteryPastUptime; 3649 if (mOnBatteryInternal) { 3650 time += curTime - mTrackBatteryUptimeStart; 3651 } 3652 return time; 3653 } 3654 3655 long getBatteryUptimeLocked() { 3656 return getBatteryUptime(SystemClock.uptimeMillis() * 1000); 3657 } 3658 3659 @Override 3660 public long getBatteryUptime(long curTime) { 3661 return getBatteryUptimeLocked(curTime); 3662 } 3663 3664 long getBatteryRealtimeLocked(long curTime) { 3665 long time = mTrackBatteryPastRealtime; 3666 if (mOnBatteryInternal) { 3667 time += curTime - mTrackBatteryRealtimeStart; 3668 } 3669 return time; 3670 } 3671 3672 @Override 3673 public long getBatteryRealtime(long curTime) { 3674 return getBatteryRealtimeLocked(curTime); 3675 } 3676 3677 private long getTcpBytes(long current, long[] dataBytes, int which) { 3678 if (which == STATS_LAST) { 3679 return dataBytes[STATS_LAST]; 3680 } else { 3681 if (which == STATS_SINCE_UNPLUGGED) { 3682 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) { 3683 return dataBytes[STATS_LAST]; 3684 } else { 3685 return current - dataBytes[STATS_SINCE_UNPLUGGED]; 3686 } 3687 } else if (which == STATS_SINCE_CHARGED) { 3688 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED]; 3689 } 3690 return current - dataBytes[STATS_CURRENT]; 3691 } 3692 } 3693 3694 /** Only STATS_UNPLUGGED works properly */ 3695 public long getMobileTcpBytesSent(int which) { 3696 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which); 3697 } 3698 3699 /** Only STATS_UNPLUGGED works properly */ 3700 public long getMobileTcpBytesReceived(int which) { 3701 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which); 3702 } 3703 3704 /** Only STATS_UNPLUGGED works properly */ 3705 public long getTotalTcpBytesSent(int which) { 3706 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which); 3707 } 3708 3709 /** Only STATS_UNPLUGGED works properly */ 3710 public long getTotalTcpBytesReceived(int which) { 3711 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which); 3712 } 3713 3714 @Override 3715 public int getDischargeStartLevel() { 3716 synchronized(this) { 3717 return getDischargeStartLevelLocked(); 3718 } 3719 } 3720 3721 public int getDischargeStartLevelLocked() { 3722 return mDischargeUnplugLevel; 3723 } 3724 3725 @Override 3726 public int getDischargeCurrentLevel() { 3727 synchronized(this) { 3728 return getDischargeCurrentLevelLocked(); 3729 } 3730 } 3731 3732 public int getDischargeCurrentLevelLocked() { 3733 return mDischargeCurrentLevel; 3734 } 3735 3736 @Override 3737 public int getLowDischargeAmountSinceCharge() { 3738 synchronized(this) { 3739 return mLowDischargeAmountSinceCharge; 3740 } 3741 } 3742 3743 @Override 3744 public int getHighDischargeAmountSinceCharge() { 3745 synchronized(this) { 3746 return mHighDischargeAmountSinceCharge; 3747 } 3748 } 3749 3750 @Override 3751 public int getCpuSpeedSteps() { 3752 return sNumSpeedSteps; 3753 } 3754 3755 /** 3756 * Retrieve the statistics object for a particular uid, creating if needed. 3757 */ 3758 public Uid getUidStatsLocked(int uid) { 3759 Uid u = mUidStats.get(uid); 3760 if (u == null) { 3761 u = new Uid(uid); 3762 mUidStats.put(uid, u); 3763 } 3764 return u; 3765 } 3766 3767 /** 3768 * Remove the statistics object for a particular uid. 3769 */ 3770 public void removeUidStatsLocked(int uid) { 3771 mUidStats.remove(uid); 3772 } 3773 3774 /** 3775 * Retrieve the statistics object for a particular process, creating 3776 * if needed. 3777 */ 3778 public Uid.Proc getProcessStatsLocked(int uid, String name) { 3779 Uid u = getUidStatsLocked(uid); 3780 return u.getProcessStatsLocked(name); 3781 } 3782 3783 /** 3784 * Retrieve the statistics object for a particular process, given 3785 * the name of the process. 3786 * @param name process name 3787 * @return the statistics object for the process 3788 */ 3789 public Uid.Proc getProcessStatsLocked(String name, int pid) { 3790 int uid; 3791 if (mUidCache.containsKey(name)) { 3792 uid = mUidCache.get(name); 3793 } else { 3794 uid = Process.getUidForPid(pid); 3795 mUidCache.put(name, uid); 3796 } 3797 Uid u = getUidStatsLocked(uid); 3798 return u.getProcessStatsLocked(name); 3799 } 3800 3801 /** 3802 * Retrieve the statistics object for a particular process, creating 3803 * if needed. 3804 */ 3805 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 3806 Uid u = getUidStatsLocked(uid); 3807 return u.getPackageStatsLocked(pkg); 3808 } 3809 3810 /** 3811 * Retrieve the statistics object for a particular service, creating 3812 * if needed. 3813 */ 3814 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 3815 Uid u = getUidStatsLocked(uid); 3816 return u.getServiceStatsLocked(pkg, name); 3817 } 3818 3819 public void shutdownLocked() { 3820 writeLocked(); 3821 mShuttingDown = true; 3822 } 3823 3824 public void writeLocked() { 3825 if (mFile == null) { 3826 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 3827 return; 3828 } 3829 3830 if (mShuttingDown) { 3831 return; 3832 } 3833 3834 try { 3835 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 3836 Parcel out = Parcel.obtain(); 3837 writeSummaryToParcel(out); 3838 stream.write(out.marshall()); 3839 out.recycle(); 3840 3841 stream.flush(); 3842 stream.close(); 3843 mFile.commit(); 3844 3845 mLastWriteTime = SystemClock.elapsedRealtime(); 3846 return; 3847 } catch (IOException e) { 3848 Slog.w("BatteryStats", "Error writing battery statistics", e); 3849 } 3850 mFile.rollback(); 3851 } 3852 3853 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 3854 int pos = 0; 3855 int avail = stream.available(); 3856 byte[] data = new byte[avail]; 3857 while (true) { 3858 int amt = stream.read(data, pos, data.length-pos); 3859 //Log.i("foo", "Read " + amt + " bytes at " + pos 3860 // + " of avail " + data.length); 3861 if (amt <= 0) { 3862 //Log.i("foo", "**** FINISHED READING: pos=" + pos 3863 // + " len=" + data.length); 3864 return data; 3865 } 3866 pos += amt; 3867 avail = stream.available(); 3868 if (avail > data.length-pos) { 3869 byte[] newData = new byte[pos+avail]; 3870 System.arraycopy(data, 0, newData, 0, pos); 3871 data = newData; 3872 } 3873 } 3874 } 3875 3876 public void readLocked() { 3877 if (mFile == null) { 3878 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 3879 return; 3880 } 3881 3882 mUidStats.clear(); 3883 3884 try { 3885 File file = mFile.chooseForRead(); 3886 if (!file.exists()) { 3887 return; 3888 } 3889 FileInputStream stream = new FileInputStream(file); 3890 3891 byte[] raw = readFully(stream); 3892 Parcel in = Parcel.obtain(); 3893 in.unmarshall(raw, 0, raw.length); 3894 in.setDataPosition(0); 3895 stream.close(); 3896 3897 readSummaryFromParcel(in); 3898 } catch(java.io.IOException e) { 3899 Slog.e("BatteryStats", "Error reading battery statistics", e); 3900 } 3901 3902 addHistoryRecordLocked(SystemClock.elapsedRealtime(), HistoryItem.CMD_START); 3903 } 3904 3905 public int describeContents() { 3906 return 0; 3907 } 3908 3909 void readHistory(Parcel in) { 3910 mHistory = mHistoryEnd = mHistoryCache = null; 3911 mHistoryBaseTime = 0; 3912 long time; 3913 while ((time=in.readLong()) >= 0) { 3914 HistoryItem rec = new HistoryItem(time, in); 3915 addHistoryRecordLocked(rec); 3916 if (rec.time > mHistoryBaseTime) { 3917 mHistoryBaseTime = rec.time; 3918 } 3919 } 3920 3921 long oldnow = SystemClock.elapsedRealtime() - (5*60*100); 3922 if (oldnow > 0) { 3923 // If the system process has restarted, but not the entire 3924 // system, then the mHistoryBaseTime already accounts for 3925 // much of the elapsed time. We thus want to adjust it back, 3926 // to avoid large gaps in the data. We determine we are 3927 // in this case by arbitrarily saying it is so if at this 3928 // point in boot the elapsed time is already more than 5 seconds. 3929 mHistoryBaseTime -= oldnow; 3930 } 3931 } 3932 3933 void writeHistory(Parcel out) { 3934 HistoryItem rec = mHistory; 3935 while (rec != null) { 3936 if (rec.time >= 0) rec.writeToParcel(out, 0); 3937 rec = rec.next; 3938 } 3939 out.writeLong(-1); 3940 } 3941 3942 private void readSummaryFromParcel(Parcel in) { 3943 final int version = in.readInt(); 3944 if (version != VERSION) { 3945 Slog.w("BatteryStats", "readFromParcel: version got " + version 3946 + ", expected " + VERSION + "; erasing old stats"); 3947 return; 3948 } 3949 3950 readHistory(in); 3951 3952 mStartCount = in.readInt(); 3953 mBatteryUptime = in.readLong(); 3954 mBatteryRealtime = in.readLong(); 3955 mUptime = in.readLong(); 3956 mRealtime = in.readLong(); 3957 mDischargeUnplugLevel = in.readInt(); 3958 mDischargeCurrentLevel = in.readInt(); 3959 mLowDischargeAmountSinceCharge = in.readInt(); 3960 mHighDischargeAmountSinceCharge = in.readInt(); 3961 3962 mStartCount++; 3963 3964 mScreenOn = false; 3965 mScreenOnTimer.readSummaryFromParcelLocked(in); 3966 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3967 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 3968 } 3969 mInputEventCounter.readSummaryFromParcelLocked(in); 3970 mPhoneOn = false; 3971 mPhoneOnTimer.readSummaryFromParcelLocked(in); 3972 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3973 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 3974 } 3975 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 3976 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3977 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 3978 } 3979 mWifiOn = false; 3980 mWifiOnTimer.readSummaryFromParcelLocked(in); 3981 mWifiRunning = false; 3982 mWifiRunningTimer.readSummaryFromParcelLocked(in); 3983 mBluetoothOn = false; 3984 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 3985 3986 int NKW = in.readInt(); 3987 if (NKW > 10000) { 3988 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW); 3989 return; 3990 } 3991 for (int ikw = 0; ikw < NKW; ikw++) { 3992 if (in.readInt() != 0) { 3993 String kwltName = in.readString(); 3994 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 3995 } 3996 } 3997 3998 sNumSpeedSteps = in.readInt(); 3999 4000 final int NU = in.readInt(); 4001 if (NU > 10000) { 4002 Slog.w(TAG, "File corrupt: too many uids " + NU); 4003 return; 4004 } 4005 for (int iu = 0; iu < NU; iu++) { 4006 int uid = in.readInt(); 4007 Uid u = new Uid(uid); 4008 mUidStats.put(uid, u); 4009 4010 u.mWifiTurnedOn = false; 4011 if (in.readInt() != 0) { 4012 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in); 4013 } 4014 u.mFullWifiLockOut = false; 4015 if (in.readInt() != 0) { 4016 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 4017 } 4018 u.mScanWifiLockOut = false; 4019 if (in.readInt() != 0) { 4020 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in); 4021 } 4022 u.mWifiMulticastEnabled = false; 4023 if (in.readInt() != 0) { 4024 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 4025 } 4026 u.mAudioTurnedOn = false; 4027 if (in.readInt() != 0) { 4028 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in); 4029 } 4030 u.mVideoTurnedOn = false; 4031 if (in.readInt() != 0) { 4032 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in); 4033 } 4034 4035 if (in.readInt() != 0) { 4036 if (u.mUserActivityCounters == null) { 4037 u.initUserActivityLocked(); 4038 } 4039 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 4040 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 4041 } 4042 } 4043 4044 int NW = in.readInt(); 4045 if (NW > 10000) { 4046 Slog.w(TAG, "File corrupt: too many wake locks " + NW); 4047 return; 4048 } 4049 for (int iw = 0; iw < NW; iw++) { 4050 String wlName = in.readString(); 4051 if (in.readInt() != 0) { 4052 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 4053 } 4054 if (in.readInt() != 0) { 4055 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 4056 } 4057 if (in.readInt() != 0) { 4058 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 4059 } 4060 } 4061 4062 int NP = in.readInt(); 4063 if (NP > 10000) { 4064 Slog.w(TAG, "File corrupt: too many sensors " + NP); 4065 return; 4066 } 4067 for (int is = 0; is < NP; is++) { 4068 int seNumber = in.readInt(); 4069 if (in.readInt() != 0) { 4070 u.getSensorTimerLocked(seNumber, true) 4071 .readSummaryFromParcelLocked(in); 4072 } 4073 } 4074 4075 NP = in.readInt(); 4076 if (NP > 10000) { 4077 Slog.w(TAG, "File corrupt: too many processes " + NP); 4078 return; 4079 } 4080 for (int ip = 0; ip < NP; ip++) { 4081 String procName = in.readString(); 4082 Uid.Proc p = u.getProcessStatsLocked(procName); 4083 p.mUserTime = p.mLoadedUserTime = in.readLong(); 4084 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 4085 p.mStarts = p.mLoadedStarts = in.readInt(); 4086 } 4087 4088 NP = in.readInt(); 4089 if (NP > 10000) { 4090 Slog.w(TAG, "File corrupt: too many packages " + NP); 4091 return; 4092 } 4093 for (int ip = 0; ip < NP; ip++) { 4094 String pkgName = in.readString(); 4095 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 4096 p.mWakeups = p.mLoadedWakeups = in.readInt(); 4097 final int NS = in.readInt(); 4098 for (int is = 0; is < NS; is++) { 4099 String servName = in.readString(); 4100 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 4101 s.mStartTime = s.mLoadedStartTime = in.readLong(); 4102 s.mStarts = s.mLoadedStarts = in.readInt(); 4103 s.mLaunches = s.mLoadedLaunches = in.readInt(); 4104 } 4105 } 4106 4107 u.mLoadedTcpBytesReceived = in.readLong(); 4108 u.mLoadedTcpBytesSent = in.readLong(); 4109 } 4110 } 4111 4112 /** 4113 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 4114 * disk. This format does not allow a lossless round-trip. 4115 * 4116 * @param out the Parcel to be written to. 4117 */ 4118 public void writeSummaryToParcel(Parcel out) { 4119 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 4120 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 4121 final long NOW = getBatteryUptimeLocked(NOW_SYS); 4122 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS); 4123 4124 out.writeInt(VERSION); 4125 4126 writeHistory(out); 4127 4128 out.writeInt(mStartCount); 4129 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED)); 4130 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 4131 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 4132 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 4133 out.writeInt(mDischargeUnplugLevel); 4134 out.writeInt(mDischargeCurrentLevel); 4135 out.writeInt(mLowDischargeAmountSinceCharge); 4136 out.writeInt(mHighDischargeAmountSinceCharge); 4137 4138 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4139 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4140 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 4141 } 4142 mInputEventCounter.writeSummaryFromParcelLocked(out); 4143 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4144 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 4145 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 4146 } 4147 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4148 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4149 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 4150 } 4151 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4152 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4153 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4154 4155 out.writeInt(mKernelWakelockStats.size()); 4156 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 4157 Timer kwlt = ent.getValue(); 4158 if (kwlt != null) { 4159 out.writeInt(1); 4160 out.writeString(ent.getKey()); 4161 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL); 4162 } else { 4163 out.writeInt(0); 4164 } 4165 } 4166 4167 out.writeInt(sNumSpeedSteps); 4168 final int NU = mUidStats.size(); 4169 out.writeInt(NU); 4170 for (int iu = 0; iu < NU; iu++) { 4171 out.writeInt(mUidStats.keyAt(iu)); 4172 Uid u = mUidStats.valueAt(iu); 4173 4174 if (u.mWifiTurnedOnTimer != null) { 4175 out.writeInt(1); 4176 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4177 } else { 4178 out.writeInt(0); 4179 } 4180 if (u.mFullWifiLockTimer != null) { 4181 out.writeInt(1); 4182 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4183 } else { 4184 out.writeInt(0); 4185 } 4186 if (u.mScanWifiLockTimer != null) { 4187 out.writeInt(1); 4188 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4189 } else { 4190 out.writeInt(0); 4191 } 4192 if (u.mWifiMulticastTimer != null) { 4193 out.writeInt(1); 4194 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4195 } else { 4196 out.writeInt(0); 4197 } 4198 if (u.mAudioTurnedOnTimer != null) { 4199 out.writeInt(1); 4200 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4201 } else { 4202 out.writeInt(0); 4203 } 4204 if (u.mVideoTurnedOnTimer != null) { 4205 out.writeInt(1); 4206 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4207 } else { 4208 out.writeInt(0); 4209 } 4210 4211 if (u.mUserActivityCounters == null) { 4212 out.writeInt(0); 4213 } else { 4214 out.writeInt(1); 4215 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 4216 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 4217 } 4218 } 4219 4220 int NW = u.mWakelockStats.size(); 4221 out.writeInt(NW); 4222 if (NW > 0) { 4223 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent 4224 : u.mWakelockStats.entrySet()) { 4225 out.writeString(ent.getKey()); 4226 Uid.Wakelock wl = ent.getValue(); 4227 if (wl.mTimerFull != null) { 4228 out.writeInt(1); 4229 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL); 4230 } else { 4231 out.writeInt(0); 4232 } 4233 if (wl.mTimerPartial != null) { 4234 out.writeInt(1); 4235 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL); 4236 } else { 4237 out.writeInt(0); 4238 } 4239 if (wl.mTimerWindow != null) { 4240 out.writeInt(1); 4241 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL); 4242 } else { 4243 out.writeInt(0); 4244 } 4245 } 4246 } 4247 4248 int NSE = u.mSensorStats.size(); 4249 out.writeInt(NSE); 4250 if (NSE > 0) { 4251 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent 4252 : u.mSensorStats.entrySet()) { 4253 out.writeInt(ent.getKey()); 4254 Uid.Sensor se = ent.getValue(); 4255 if (se.mTimer != null) { 4256 out.writeInt(1); 4257 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL); 4258 } else { 4259 out.writeInt(0); 4260 } 4261 } 4262 } 4263 4264 int NP = u.mProcessStats.size(); 4265 out.writeInt(NP); 4266 if (NP > 0) { 4267 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent 4268 : u.mProcessStats.entrySet()) { 4269 out.writeString(ent.getKey()); 4270 Uid.Proc ps = ent.getValue(); 4271 out.writeLong(ps.mUserTime); 4272 out.writeLong(ps.mSystemTime); 4273 out.writeInt(ps.mStarts); 4274 } 4275 } 4276 4277 NP = u.mPackageStats.size(); 4278 out.writeInt(NP); 4279 if (NP > 0) { 4280 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 4281 : u.mPackageStats.entrySet()) { 4282 out.writeString(ent.getKey()); 4283 Uid.Pkg ps = ent.getValue(); 4284 out.writeInt(ps.mWakeups); 4285 final int NS = ps.mServiceStats.size(); 4286 out.writeInt(NS); 4287 if (NS > 0) { 4288 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 4289 : ps.mServiceStats.entrySet()) { 4290 out.writeString(sent.getKey()); 4291 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 4292 long time = ss.getStartTimeToNowLocked(NOW); 4293 out.writeLong(time); 4294 out.writeInt(ss.mStarts); 4295 out.writeInt(ss.mLaunches); 4296 } 4297 } 4298 } 4299 } 4300 4301 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED)); 4302 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED)); 4303 } 4304 } 4305 4306 public void readFromParcel(Parcel in) { 4307 readFromParcelLocked(in); 4308 } 4309 4310 void readFromParcelLocked(Parcel in) { 4311 int magic = in.readInt(); 4312 if (magic != MAGIC) { 4313 throw new ParcelFormatException("Bad magic number"); 4314 } 4315 4316 readHistory(in); 4317 4318 mStartCount = in.readInt(); 4319 mBatteryUptime = in.readLong(); 4320 mBatteryLastUptime = 0; 4321 mBatteryRealtime = in.readLong(); 4322 mBatteryLastRealtime = 0; 4323 mScreenOn = false; 4324 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in); 4325 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4326 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in); 4327 } 4328 mInputEventCounter = new Counter(mUnpluggables, in); 4329 mPhoneOn = false; 4330 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 4331 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 4332 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in); 4333 } 4334 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in); 4335 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4336 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in); 4337 } 4338 mWifiOn = false; 4339 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 4340 mWifiRunning = false; 4341 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 4342 mBluetoothOn = false; 4343 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 4344 mUptime = in.readLong(); 4345 mUptimeStart = in.readLong(); 4346 mLastUptime = 0; 4347 mRealtime = in.readLong(); 4348 mRealtimeStart = in.readLong(); 4349 mLastRealtime = 0; 4350 mOnBattery = in.readInt() != 0; 4351 mOnBatteryInternal = false; // we are no longer really running. 4352 mTrackBatteryPastUptime = in.readLong(); 4353 mTrackBatteryUptimeStart = in.readLong(); 4354 mTrackBatteryPastRealtime = in.readLong(); 4355 mTrackBatteryRealtimeStart = in.readLong(); 4356 mUnpluggedBatteryUptime = in.readLong(); 4357 mUnpluggedBatteryRealtime = in.readLong(); 4358 mDischargeUnplugLevel = in.readInt(); 4359 mDischargeCurrentLevel = in.readInt(); 4360 mLowDischargeAmountSinceCharge = in.readInt(); 4361 mHighDischargeAmountSinceCharge = in.readInt(); 4362 mLastWriteTime = in.readLong(); 4363 4364 mMobileDataRx[STATS_LAST] = in.readLong(); 4365 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1; 4366 mMobileDataTx[STATS_LAST] = in.readLong(); 4367 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1; 4368 mTotalDataRx[STATS_LAST] = in.readLong(); 4369 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1; 4370 mTotalDataTx[STATS_LAST] = in.readLong(); 4371 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1; 4372 4373 mRadioDataUptime = in.readLong(); 4374 mRadioDataStart = -1; 4375 4376 mBluetoothPingCount = in.readInt(); 4377 mBluetoothPingStart = -1; 4378 4379 mKernelWakelockStats.clear(); 4380 int NKW = in.readInt(); 4381 for (int ikw = 0; ikw < NKW; ikw++) { 4382 if (in.readInt() != 0) { 4383 String wakelockName = in.readString(); 4384 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel 4385 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in); 4386 mKernelWakelockStats.put(wakelockName, kwlt); 4387 } 4388 } 4389 4390 mPartialTimers.clear(); 4391 mFullTimers.clear(); 4392 mWindowTimers.clear(); 4393 4394 sNumSpeedSteps = in.readInt(); 4395 4396 int numUids = in.readInt(); 4397 mUidStats.clear(); 4398 for (int i = 0; i < numUids; i++) { 4399 int uid = in.readInt(); 4400 Uid u = new Uid(uid); 4401 u.readFromParcelLocked(mUnpluggables, in); 4402 mUidStats.append(uid, u); 4403 } 4404 } 4405 4406 public void writeToParcel(Parcel out, int flags) { 4407 writeToParcelLocked(out, true, flags); 4408 } 4409 4410 public void writeToParcelWithoutUids(Parcel out, int flags) { 4411 writeToParcelLocked(out, false, flags); 4412 } 4413 4414 @SuppressWarnings("unused") 4415 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 4416 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 4417 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 4418 final long batteryUptime = getBatteryUptimeLocked(uSecUptime); 4419 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 4420 4421 out.writeInt(MAGIC); 4422 4423 writeHistory(out); 4424 4425 out.writeInt(mStartCount); 4426 out.writeLong(mBatteryUptime); 4427 out.writeLong(mBatteryRealtime); 4428 mScreenOnTimer.writeToParcel(out, batteryRealtime); 4429 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4430 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime); 4431 } 4432 mInputEventCounter.writeToParcel(out); 4433 mPhoneOnTimer.writeToParcel(out, batteryRealtime); 4434 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 4435 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime); 4436 } 4437 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime); 4438 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4439 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); 4440 } 4441 mWifiOnTimer.writeToParcel(out, batteryRealtime); 4442 mWifiRunningTimer.writeToParcel(out, batteryRealtime); 4443 mBluetoothOnTimer.writeToParcel(out, batteryRealtime); 4444 out.writeLong(mUptime); 4445 out.writeLong(mUptimeStart); 4446 out.writeLong(mRealtime); 4447 out.writeLong(mRealtimeStart); 4448 out.writeInt(mOnBattery ? 1 : 0); 4449 out.writeLong(batteryUptime); 4450 out.writeLong(mTrackBatteryUptimeStart); 4451 out.writeLong(batteryRealtime); 4452 out.writeLong(mTrackBatteryRealtimeStart); 4453 out.writeLong(mUnpluggedBatteryUptime); 4454 out.writeLong(mUnpluggedBatteryRealtime); 4455 out.writeInt(mDischargeUnplugLevel); 4456 out.writeInt(mDischargeCurrentLevel); 4457 out.writeInt(mLowDischargeAmountSinceCharge); 4458 out.writeInt(mHighDischargeAmountSinceCharge); 4459 out.writeLong(mLastWriteTime); 4460 4461 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED)); 4462 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED)); 4463 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED)); 4464 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED)); 4465 4466 // Write radio uptime for data 4467 out.writeLong(getRadioDataUptime()); 4468 4469 out.writeInt(getBluetoothPingCount()); 4470 4471 if (inclUids) { 4472 out.writeInt(mKernelWakelockStats.size()); 4473 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 4474 SamplingTimer kwlt = ent.getValue(); 4475 if (kwlt != null) { 4476 out.writeInt(1); 4477 out.writeString(ent.getKey()); 4478 Timer.writeTimerToParcel(out, kwlt, batteryRealtime); 4479 } else { 4480 out.writeInt(0); 4481 } 4482 } 4483 } else { 4484 out.writeInt(0); 4485 } 4486 4487 out.writeInt(sNumSpeedSteps); 4488 4489 if (inclUids) { 4490 int size = mUidStats.size(); 4491 out.writeInt(size); 4492 for (int i = 0; i < size; i++) { 4493 out.writeInt(mUidStats.keyAt(i)); 4494 Uid uid = mUidStats.valueAt(i); 4495 4496 uid.writeToParcelLocked(out, batteryRealtime); 4497 } 4498 } else { 4499 out.writeInt(0); 4500 } 4501 } 4502 4503 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 4504 new Parcelable.Creator<BatteryStatsImpl>() { 4505 public BatteryStatsImpl createFromParcel(Parcel in) { 4506 return new BatteryStatsImpl(in); 4507 } 4508 4509 public BatteryStatsImpl[] newArray(int size) { 4510 return new BatteryStatsImpl[size]; 4511 } 4512 }; 4513 4514 public void dumpLocked(PrintWriter pw) { 4515 if (DEBUG) { 4516 Printer pr = new PrintWriterPrinter(pw); 4517 pr.println("*** Screen timer:"); 4518 mScreenOnTimer.logState(pr, " "); 4519 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4520 pr.println("*** Screen brightness #" + i + ":"); 4521 mScreenBrightnessTimer[i].logState(pr, " "); 4522 } 4523 pr.println("*** Input event counter:"); 4524 mInputEventCounter.logState(pr, " "); 4525 pr.println("*** Phone timer:"); 4526 mPhoneOnTimer.logState(pr, " "); 4527 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 4528 pr.println("*** Signal strength #" + i + ":"); 4529 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 4530 } 4531 pr.println("*** Signal scanning :"); 4532 mPhoneSignalScanningTimer.logState(pr, " "); 4533 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4534 pr.println("*** Data connection type #" + i + ":"); 4535 mPhoneDataConnectionsTimer[i].logState(pr, " "); 4536 } 4537 pr.println("*** Wifi timer:"); 4538 mWifiOnTimer.logState(pr, " "); 4539 pr.println("*** WifiRunning timer:"); 4540 mWifiRunningTimer.logState(pr, " "); 4541 pr.println("*** Bluetooth timer:"); 4542 mBluetoothOnTimer.logState(pr, " "); 4543 } 4544 super.dumpLocked(pw); 4545 } 4546} 4547