1/*
2 * Copyright (C) 2006 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.settings;
18
19import android.app.Activity;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.os.BatteryManager;
25import android.os.Bundle;
26import android.os.Handler;
27import android.os.IPowerManager;
28import android.os.Message;
29import android.os.ServiceManager;
30import android.os.SystemClock;
31import android.text.format.DateUtils;
32import android.widget.TextView;
33
34import com.android.internal.app.IBatteryStats;
35
36public class BatteryInfo extends Activity {
37    private TextView mStatus;
38    private TextView mPower;
39    private TextView mLevel;
40    private TextView mScale;
41    private TextView mHealth;
42    private TextView mVoltage;
43    private TextView mTemperature;
44    private TextView mTechnology;
45    private TextView mUptime;
46    private IBatteryStats mBatteryStats;
47    private IPowerManager mScreenStats;
48
49    private static final int EVENT_TICK = 1;
50
51    private Handler mHandler = new Handler() {
52        @Override
53        public void handleMessage(Message msg) {
54            switch (msg.what) {
55                case EVENT_TICK:
56                    updateBatteryStats();
57                    sendEmptyMessageDelayed(EVENT_TICK, 1000);
58
59                    break;
60            }
61        }
62    };
63
64    /**
65     * Format a number of tenths-units as a decimal string without using a
66     * conversion to float.  E.g. 347 -> "34.7"
67     */
68    private final String tenthsToFixedString(int x) {
69        int tens = x / 10;
70        return Integer.toString(tens) + "." + (x - 10 * tens);
71    }
72
73   /**
74    *Listens for intent broadcasts
75    */
76    private IntentFilter   mIntentFilter;
77
78    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
79        @Override
80        public void onReceive(Context context, Intent intent) {
81            String action = intent.getAction();
82            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
83                int plugType = intent.getIntExtra("plugged", 0);
84
85                mLevel.setText("" + intent.getIntExtra("level", 0));
86                mScale.setText("" + intent.getIntExtra("scale", 0));
87                mVoltage.setText("" + intent.getIntExtra("voltage", 0) + " "
88                        + getString(R.string.battery_info_voltage_units));
89                mTemperature.setText("" + tenthsToFixedString(intent.getIntExtra("temperature", 0))
90                        + getString(R.string.battery_info_temperature_units));
91                mTechnology.setText("" + intent.getStringExtra("technology"));
92
93                mStatus.setText(Utils.getBatteryStatus(getResources(), intent));
94
95                switch (plugType) {
96                    case 0:
97                        mPower.setText(getString(R.string.battery_info_power_unplugged));
98                        break;
99                    case BatteryManager.BATTERY_PLUGGED_AC:
100                        mPower.setText(getString(R.string.battery_info_power_ac));
101                        break;
102                    case BatteryManager.BATTERY_PLUGGED_USB:
103                        mPower.setText(getString(R.string.battery_info_power_usb));
104                        break;
105                    case BatteryManager.BATTERY_PLUGGED_WIRELESS:
106                        mPower.setText(getString(R.string.battery_info_power_wireless));
107                        break;
108                    case (BatteryManager.BATTERY_PLUGGED_AC|BatteryManager.BATTERY_PLUGGED_USB):
109                        mPower.setText(getString(R.string.battery_info_power_ac_usb));
110                        break;
111                    default:
112                        mPower.setText(getString(R.string.battery_info_power_unknown));
113                        break;
114                }
115
116                int health = intent.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN);
117                String healthString;
118                if (health == BatteryManager.BATTERY_HEALTH_GOOD) {
119                    healthString = getString(R.string.battery_info_health_good);
120                } else if (health == BatteryManager.BATTERY_HEALTH_OVERHEAT) {
121                    healthString = getString(R.string.battery_info_health_overheat);
122                } else if (health == BatteryManager.BATTERY_HEALTH_DEAD) {
123                    healthString = getString(R.string.battery_info_health_dead);
124                } else if (health == BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE) {
125                    healthString = getString(R.string.battery_info_health_over_voltage);
126                } else if (health == BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE) {
127                    healthString = getString(R.string.battery_info_health_unspecified_failure);
128                } else if (health == BatteryManager.BATTERY_HEALTH_COLD) {
129                    healthString = getString(R.string.battery_info_health_cold);
130                } else {
131                    healthString = getString(R.string.battery_info_health_unknown);
132                }
133                mHealth.setText(healthString);
134            }
135        }
136    };
137
138    @Override
139    public void onCreate(Bundle icicle) {
140        super.onCreate(icicle);
141
142        setContentView(R.layout.battery_info);
143
144        // create the IntentFilter that will be used to listen
145        // to battery status broadcasts
146        mIntentFilter = new IntentFilter();
147        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
148    }
149
150    @Override
151    public void onResume() {
152        super.onResume();
153
154        mStatus = (TextView)findViewById(R.id.status);
155        mPower = (TextView)findViewById(R.id.power);
156        mLevel = (TextView)findViewById(R.id.level);
157        mScale = (TextView)findViewById(R.id.scale);
158        mHealth = (TextView)findViewById(R.id.health);
159        mTechnology = (TextView)findViewById(R.id.technology);
160        mVoltage = (TextView)findViewById(R.id.voltage);
161        mTemperature = (TextView)findViewById(R.id.temperature);
162        mUptime = (TextView) findViewById(R.id.uptime);
163
164        // Get awake time plugged in and on battery
165        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
166        mScreenStats = IPowerManager.Stub.asInterface(ServiceManager.getService(POWER_SERVICE));
167        mHandler.sendEmptyMessageDelayed(EVENT_TICK, 1000);
168
169        registerReceiver(mIntentReceiver, mIntentFilter);
170    }
171
172    @Override
173    public void onPause() {
174        super.onPause();
175        mHandler.removeMessages(EVENT_TICK);
176
177        // we are no longer on the screen stop the observers
178        unregisterReceiver(mIntentReceiver);
179    }
180
181    private void updateBatteryStats() {
182        long uptime = SystemClock.elapsedRealtime();
183        mUptime.setText(DateUtils.formatElapsedTime(uptime / 1000));
184    }
185
186}
187