1/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import android.content.Context;
20import android.os.Binder;
21import android.os.IBinder;
22import android.os.Parcel;
23import android.os.Process;
24import android.os.ServiceManager;
25import android.telephony.SignalStrength;
26import android.telephony.TelephonyManager;
27import android.util.Log;
28
29import com.android.internal.app.IBatteryStats;
30import com.android.internal.os.BatteryStatsImpl;
31
32import java.io.FileDescriptor;
33import java.io.PrintWriter;
34
35/**
36 * All information we are collecting about things that can happen that impact
37 * battery life.
38 */
39public final class BatteryStatsService extends IBatteryStats.Stub {
40    static IBatteryStats sService;
41
42    final BatteryStatsImpl mStats;
43    Context mContext;
44
45    BatteryStatsService(String filename) {
46        mStats = new BatteryStatsImpl(filename);
47    }
48
49    public void publish(Context context) {
50        mContext = context;
51        ServiceManager.addService("batteryinfo", asBinder());
52    }
53
54    public void shutdown() {
55        Log.w("BatteryStats", "Writing battery stats before shutdown...");
56        synchronized (mStats) {
57            mStats.writeLocked();
58        }
59    }
60
61    public static IBatteryStats getService() {
62        if (sService != null) {
63            return sService;
64        }
65        IBinder b = ServiceManager.getService("batteryinfo");
66        sService = asInterface(b);
67        return sService;
68    }
69
70    /**
71     * @return the current statistics object, which may be modified
72     * to reflect events that affect battery usage.  You must lock the
73     * stats object before doing anything with it.
74     */
75    public BatteryStatsImpl getActiveStatistics() {
76        return mStats;
77    }
78
79    public byte[] getStatistics() {
80        mContext.enforceCallingPermission(
81                android.Manifest.permission.BATTERY_STATS, null);
82        //Log.i("foo", "SENDING BATTERY INFO:");
83        //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo"));
84        Parcel out = Parcel.obtain();
85        mStats.writeToParcel(out, 0);
86        byte[] data = out.marshall();
87        out.recycle();
88        return data;
89    }
90
91    public void noteStartWakelock(int uid, String name, int type) {
92        enforceCallingPermission();
93        synchronized (mStats) {
94            mStats.getUidStatsLocked(uid).noteStartWakeLocked(name, type);
95        }
96    }
97
98    public void noteStopWakelock(int uid, String name, int type) {
99        enforceCallingPermission();
100        synchronized (mStats) {
101            mStats.getUidStatsLocked(uid).noteStopWakeLocked(name, type);
102        }
103    }
104
105    public void noteStartSensor(int uid, int sensor) {
106        enforceCallingPermission();
107        synchronized (mStats) {
108            mStats.getUidStatsLocked(uid).noteStartSensor(sensor);
109        }
110    }
111
112    public void noteStopSensor(int uid, int sensor) {
113        enforceCallingPermission();
114        synchronized (mStats) {
115            mStats.getUidStatsLocked(uid).noteStopSensor(sensor);
116        }
117    }
118
119    public void noteStartGps(int uid) {
120        enforceCallingPermission();
121        synchronized (mStats) {
122            mStats.noteStartGps(uid);
123        }
124    }
125
126    public void noteStopGps(int uid) {
127        enforceCallingPermission();
128        synchronized (mStats) {
129            mStats.noteStopGps(uid);
130        }
131    }
132
133    public void noteScreenOn() {
134        enforceCallingPermission();
135        synchronized (mStats) {
136            mStats.noteScreenOnLocked();
137        }
138    }
139
140    public void noteScreenBrightness(int brightness) {
141        enforceCallingPermission();
142        synchronized (mStats) {
143            mStats.noteScreenBrightnessLocked(brightness);
144        }
145    }
146
147    public void noteScreenOff() {
148        enforceCallingPermission();
149        synchronized (mStats) {
150            mStats.noteScreenOffLocked();
151        }
152    }
153
154    public void noteInputEvent() {
155        enforceCallingPermission();
156        synchronized (mStats) {
157            mStats.noteInputEventLocked();
158        }
159    }
160
161    public void noteUserActivity(int uid, int event) {
162        enforceCallingPermission();
163        synchronized (mStats) {
164            mStats.noteUserActivityLocked(uid, event);
165        }
166    }
167
168    public void notePhoneOn() {
169        enforceCallingPermission();
170        synchronized (mStats) {
171            mStats.notePhoneOnLocked();
172        }
173    }
174
175    public void notePhoneOff() {
176        enforceCallingPermission();
177        synchronized (mStats) {
178            mStats.notePhoneOffLocked();
179        }
180    }
181
182    public void notePhoneSignalStrength(SignalStrength signalStrength) {
183        enforceCallingPermission();
184        synchronized (mStats) {
185            mStats.notePhoneSignalStrengthLocked(signalStrength);
186        }
187    }
188
189    public void notePhoneDataConnectionState(int dataType, boolean hasData) {
190        enforceCallingPermission();
191        synchronized (mStats) {
192            mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
193        }
194    }
195
196    public void noteAirplaneMode(boolean airplaneMode) {
197        enforceCallingPermission();
198        synchronized (mStats) {
199            mStats.noteAirplaneModeLocked(airplaneMode);
200        }
201    }
202
203    public void noteWifiOn(int uid) {
204        enforceCallingPermission();
205        synchronized (mStats) {
206            mStats.noteWifiOnLocked(uid);
207        }
208    }
209
210    public void noteWifiOff(int uid) {
211        enforceCallingPermission();
212        synchronized (mStats) {
213            mStats.noteWifiOffLocked(uid);
214        }
215    }
216
217    public void noteStartAudio(int uid) {
218        enforceCallingPermission();
219        synchronized (mStats) {
220            mStats.noteAudioOnLocked(uid);
221        }
222    }
223
224    public void noteStopAudio(int uid) {
225        enforceCallingPermission();
226        synchronized (mStats) {
227            mStats.noteAudioOffLocked(uid);
228        }
229    }
230
231    public void noteStartVideo(int uid) {
232        enforceCallingPermission();
233        synchronized (mStats) {
234            mStats.noteVideoOnLocked(uid);
235        }
236    }
237
238    public void noteStopVideo(int uid) {
239        enforceCallingPermission();
240        synchronized (mStats) {
241            mStats.noteVideoOffLocked(uid);
242        }
243    }
244
245    public void noteWifiRunning() {
246        enforceCallingPermission();
247        synchronized (mStats) {
248            mStats.noteWifiRunningLocked();
249        }
250    }
251
252    public void noteWifiStopped() {
253        enforceCallingPermission();
254        synchronized (mStats) {
255            mStats.noteWifiStoppedLocked();
256        }
257    }
258
259    public void noteBluetoothOn() {
260        enforceCallingPermission();
261        synchronized (mStats) {
262            mStats.noteBluetoothOnLocked();
263        }
264    }
265
266    public void noteBluetoothOff() {
267        enforceCallingPermission();
268        synchronized (mStats) {
269            mStats.noteBluetoothOffLocked();
270        }
271    }
272
273    public void noteFullWifiLockAcquired(int uid) {
274        enforceCallingPermission();
275        synchronized (mStats) {
276            mStats.noteFullWifiLockAcquiredLocked(uid);
277        }
278    }
279
280    public void noteFullWifiLockReleased(int uid) {
281        enforceCallingPermission();
282        synchronized (mStats) {
283            mStats.noteFullWifiLockReleasedLocked(uid);
284        }
285    }
286
287    public void noteScanWifiLockAcquired(int uid) {
288        enforceCallingPermission();
289        synchronized (mStats) {
290            mStats.noteScanWifiLockAcquiredLocked(uid);
291        }
292    }
293
294    public void noteScanWifiLockReleased(int uid) {
295        enforceCallingPermission();
296        synchronized (mStats) {
297            mStats.noteScanWifiLockReleasedLocked(uid);
298        }
299    }
300
301    public void noteWifiMulticastEnabled(int uid) {
302        enforceCallingPermission();
303        synchronized (mStats) {
304            mStats.noteWifiMulticastEnabledLocked(uid);
305        }
306    }
307
308    public void noteWifiMulticastDisabled(int uid) {
309        enforceCallingPermission();
310        synchronized (mStats) {
311            mStats.noteWifiMulticastDisabledLocked(uid);
312        }
313    }
314
315    public boolean isOnBattery() {
316        return mStats.isOnBattery();
317    }
318
319    public void setOnBattery(boolean onBattery, int level) {
320        enforceCallingPermission();
321        mStats.setOnBattery(onBattery, level);
322    }
323
324    public void recordCurrentLevel(int level) {
325        enforceCallingPermission();
326        mStats.recordCurrentLevel(level);
327    }
328
329    public long getAwakeTimeBattery() {
330        mContext.enforceCallingOrSelfPermission(
331                android.Manifest.permission.BATTERY_STATS, null);
332        return mStats.getAwakeTimeBattery();
333    }
334
335    public long getAwakeTimePlugged() {
336        mContext.enforceCallingOrSelfPermission(
337                android.Manifest.permission.BATTERY_STATS, null);
338        return mStats.getAwakeTimePlugged();
339    }
340
341    public void enforceCallingPermission() {
342        if (Binder.getCallingPid() == Process.myPid()) {
343            return;
344        }
345        mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
346                Binder.getCallingPid(), Binder.getCallingUid(), null);
347    }
348
349    @Override
350    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
351        synchronized (mStats) {
352            boolean isCheckin = false;
353            if (args != null) {
354                for (String arg : args) {
355                    if ("--checkin".equals(arg)) {
356                        isCheckin = true;
357                        break;
358                    }
359                }
360            }
361            if (isCheckin) mStats.dumpCheckinLocked(pw, args);
362            else mStats.dumpLocked(pw);
363        }
364    }
365}
366