frameworks/base
修訂 | bd243e8ff63a36f905f2c0b5a463e8b62e37ebc2 (tree) |
---|---|
時間 | 2013-09-25 11:45:43 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
BatteryService: improve battery status support for x86
Only set charge level if data is read correctly.
In some cases the battery path may just disappear a while.
Do not set 0 in such cases to avoid shutdown suddenly.
Update the battery status every 30 seconds.
Add more messages for debugging.
@@ -44,7 +44,8 @@ import java.io.FileDescriptor; | ||
44 | 44 | import java.io.FileOutputStream; |
45 | 45 | import java.io.IOException; |
46 | 46 | import java.io.PrintWriter; |
47 | - | |
47 | +import java.util.Timer; | |
48 | +import java.util.TimerTask; | |
48 | 49 | |
49 | 50 | /** |
50 | 51 | * <p>BatteryService monitors the charging status, and charge level of the device |
@@ -150,6 +151,7 @@ public final class BatteryService extends Binder { | ||
150 | 151 | mHandler = new Handler(true /*async*/); |
151 | 152 | mLed = new Led(context, lights); |
152 | 153 | mBatteryStats = BatteryStatsService.getService(); |
154 | + mBatteryLevel = -1; // initialize to an invalid value | |
153 | 155 | |
154 | 156 | mCriticalBatteryLevel = mContext.getResources().getInteger( |
155 | 157 | com.android.internal.R.integer.config_criticalBatteryWarningLevel); |
@@ -168,10 +170,16 @@ public final class BatteryService extends Binder { | ||
168 | 170 | "DEVPATH=/devices/virtual/switch/invalid_charger"); |
169 | 171 | } |
170 | 172 | |
171 | - // set initial status | |
172 | - synchronized (mLock) { | |
173 | - updateLocked(); | |
174 | - } | |
173 | + // Some boards have buggy power_supply uevents | |
174 | + // Start a timer to update battery level periodically | |
175 | + new Timer("BatteryUpdateTimer").schedule(new TimerTask() { | |
176 | + @Override | |
177 | + public void run() { | |
178 | + synchronized (mLock) { | |
179 | + updateLocked(); | |
180 | + } | |
181 | + } | |
182 | + }, 0, 30000); | |
175 | 183 | } |
176 | 184 | |
177 | 185 | void systemReady() { |
@@ -249,6 +257,7 @@ public final class BatteryService extends Binder { | ||
249 | 257 | // shut down gracefully if our battery is critically low and we are not powered. |
250 | 258 | // wait until the system has booted before attempting to display the shutdown dialog. |
251 | 259 | if (mBatteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) { |
260 | + Slog.w(TAG, "shutdownIfNoPower!!!"); | |
252 | 261 | mHandler.post(new Runnable() { |
253 | 262 | @Override |
254 | 263 | public void run() { |
@@ -268,6 +277,7 @@ public final class BatteryService extends Binder { | ||
268 | 277 | // wait until the system has booted before attempting to display the |
269 | 278 | // shutdown dialog. |
270 | 279 | if (mBatteryTemperature > mShutdownBatteryTemperature) { |
280 | + Slog.w(TAG, "shutdownIfOverTemp!!!"); | |
271 | 281 | mHandler.post(new Runnable() { |
272 | 282 | @Override |
273 | 283 | public void run() { |
@@ -289,6 +299,7 @@ public final class BatteryService extends Binder { | ||
289 | 299 | |
290 | 300 | // Process the new values. |
291 | 301 | processValuesLocked(); |
302 | + if (DEBUG) Slog.v(TAG, "update battery level = " + mBatteryLevel); | |
292 | 303 | } |
293 | 304 | } |
294 | 305 |
@@ -588,7 +599,9 @@ public final class BatteryService extends Binder { | ||
588 | 599 | return com.android.internal.R.drawable.stat_sys_battery; |
589 | 600 | } |
590 | 601 | } else { |
591 | - return com.android.internal.R.drawable.stat_sys_battery_unknown; | |
602 | + return mBatteryPresent ? | |
603 | + com.android.internal.R.drawable.stat_sys_battery_unknown : | |
604 | + com.android.internal.R.drawable.stat_sys_battery_charge; | |
592 | 605 | } |
593 | 606 | } |
594 | 607 |
@@ -76,6 +76,8 @@ struct PowerSupplyPaths { | ||
76 | 76 | String8 batteryHealthPath; |
77 | 77 | String8 batteryPresentPath; |
78 | 78 | String8 batteryCapacityPath; |
79 | + String8 batteryChargeNowPath; | |
80 | + String8 batteryChargeFullPath; | |
79 | 81 | String8 batteryVoltagePath; |
80 | 82 | String8 batteryTemperaturePath; |
81 | 83 | String8 batteryTechnologyPath; |
@@ -204,6 +206,21 @@ static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfiel | ||
204 | 206 | env->SetIntField(obj, fieldID, value); |
205 | 207 | } |
206 | 208 | |
209 | +static void setChargeLevel(JNIEnv* env, jobject obj, jfieldID fieldID) { | |
210 | + char buf1[128], buf2[128]; | |
211 | + | |
212 | + if (readFromFile(gPaths.batteryChargeNowPath, buf1, 128) > 0 && | |
213 | + readFromFile(gPaths.batteryChargeFullPath, buf2, 128) > 0) { | |
214 | + jint value = atoi(buf1) * 100 / atoi(buf2); | |
215 | + env->SetIntField(obj, fieldID, value); | |
216 | + ALOGV("setChargeLevel value=%d", value); | |
217 | + } | |
218 | + /* | |
219 | + * In some cases the battery path may just disappear a while. | |
220 | + * Do not set 0 in such cases to avoid shutdown suddenly. | |
221 | + */ | |
222 | +} | |
223 | + | |
207 | 224 | static PowerSupplyType readPowerSupplyType(const String8& path) { |
208 | 225 | const int SIZE = 128; |
209 | 226 | char buf[SIZE]; |
@@ -230,7 +247,15 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj) | ||
230 | 247 | { |
231 | 248 | setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent); |
232 | 249 | |
233 | - setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); | |
250 | + if (gPaths.batteryPresentPath.isEmpty()) { | |
251 | + env->SetIntField(obj, gFieldIds.mBatteryLevel, 100); | |
252 | + } else { | |
253 | + if (gPaths.batteryCapacityPath.isEmpty()) { | |
254 | + setChargeLevel(env, obj, gFieldIds.mBatteryLevel); | |
255 | + } else { | |
256 | + setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); | |
257 | + } | |
258 | + } | |
234 | 259 | setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage); |
235 | 260 | setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature); |
236 | 261 |
@@ -278,10 +303,15 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj) | ||
278 | 303 | default: |
279 | 304 | ALOGW("%s: Unknown power supply type", |
280 | 305 | gChargerNames[i].string()); |
306 | + break; | |
281 | 307 | } |
282 | 308 | } |
283 | 309 | } |
284 | 310 | } |
311 | + if (i == 0) { | |
312 | + /* most likely, we have a PC here */ | |
313 | + acOnline = true; | |
314 | + } | |
285 | 315 | |
286 | 316 | env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline); |
287 | 317 | env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline); |
@@ -339,9 +369,31 @@ int register_android_server_BatteryService(JNIEnv* env) | ||
339 | 369 | gPaths.batteryPresentPath = path; |
340 | 370 | path.clear(); |
341 | 371 | path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name); |
342 | - if (access(path, R_OK) == 0) | |
372 | + if (access(path, R_OK) == 0) { | |
343 | 373 | gPaths.batteryCapacityPath = path; |
344 | - | |
374 | + } else { | |
375 | + path.clear(); | |
376 | + path.appendFormat("%s/%s/charge_now", POWER_SUPPLY_PATH, name); | |
377 | + if (access(path, R_OK) == 0) { | |
378 | + gPaths.batteryChargeNowPath = path; | |
379 | + path.clear(); | |
380 | + path.appendFormat("%s/%s/charge_full", POWER_SUPPLY_PATH, name); | |
381 | + if (access(path, R_OK) == 0) { | |
382 | + gPaths.batteryChargeFullPath = path; | |
383 | + } | |
384 | + } else { | |
385 | + path.clear(); | |
386 | + path.appendFormat("%s/%s/energy_now", POWER_SUPPLY_PATH, name); | |
387 | + if (access(path, R_OK) == 0) { | |
388 | + gPaths.batteryChargeNowPath = path; | |
389 | + path.clear(); | |
390 | + path.appendFormat("%s/%s/energy_full", POWER_SUPPLY_PATH, name); | |
391 | + if (access(path, R_OK) == 0) { | |
392 | + gPaths.batteryChargeFullPath = path; | |
393 | + } | |
394 | + } | |
395 | + } | |
396 | + } | |
345 | 397 | path.clear(); |
346 | 398 | path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name); |
347 | 399 | if (access(path, R_OK) == 0) { |
@@ -371,6 +423,9 @@ int register_android_server_BatteryService(JNIEnv* env) | ||
371 | 423 | if (access(path, R_OK) == 0) |
372 | 424 | gPaths.batteryTechnologyPath = path; |
373 | 425 | break; |
426 | + default: | |
427 | + ALOGW("%s/%s/type is ANDROID_POWER_SUPPLY_TYPE_UNKNOWN?", POWER_SUPPLY_PATH, name); | |
428 | + break; | |
374 | 429 | } |
375 | 430 | } |
376 | 431 | closedir(dir); |
@@ -380,7 +435,7 @@ int register_android_server_BatteryService(JNIEnv* env) | ||
380 | 435 | ALOGE_IF(gPaths.batteryStatusPath.isEmpty(), "batteryStatusPath not found"); |
381 | 436 | ALOGE_IF(gPaths.batteryHealthPath.isEmpty(), "batteryHealthPath not found"); |
382 | 437 | ALOGE_IF(gPaths.batteryPresentPath.isEmpty(), "batteryPresentPath not found"); |
383 | - ALOGE_IF(gPaths.batteryCapacityPath.isEmpty(), "batteryCapacityPath not found"); | |
438 | + ALOGE_IF(gPaths.batteryCapacityPath.isEmpty() && (gPaths.batteryChargeNowPath.isEmpty() || gPaths.batteryChargeFullPath.isEmpty()), "batteryCapacityPath not found"); | |
384 | 439 | ALOGE_IF(gPaths.batteryVoltagePath.isEmpty(), "batteryVoltagePath not found"); |
385 | 440 | ALOGE_IF(gPaths.batteryTemperaturePath.isEmpty(), "batteryTemperaturePath not found"); |
386 | 441 | ALOGE_IF(gPaths.batteryTechnologyPath.isEmpty(), "batteryTechnologyPath not found"); |