博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SP91的待机功耗大到42mA(com.android.deskclock.ON_QUARTER_HOUR)
阅读量:4147 次
发布时间:2019-05-25

本文共 12505 字,大约阅读时间需要 41 分钟。

CPU 休眠偶尔平均电流 42 mA

  • 现象如下

    这里写图片描述

  • 发生时刻:PC时间 11:06 ,PowerMonitor 1026~1032秒

  • MtkLog 时间点
11-28 11:05:45.118827   950  1112 E ActivityManager: Sending non-protected broadcast com.android.deskclock.ON_QUARTER_HOUR from system uid 1000 pkg com.android.deskclock11-28 11:05:45.118827   950  1112 E ActivityManager: java.lang.Throwable11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:19338)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:19942)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.ActivityManagerService.broadcastIntentInPackage(ActivityManagerService.java:20130)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:325)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:222)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:8169)11-28 11:05:45.118827   950  1112 E ActivityManager:    at android.app.PendingIntent.send(PendingIntent.java:836)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.AlarmManagerService$DeliveryTracker.deliverLocked(AlarmManagerService.java:3565)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.AlarmManagerService.deliverAlarmsLocked(AlarmManagerService.java:2938)11-28 11:05:45.118827   950  1112 E ActivityManager:    at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:3086)11-28 11:05:45.129578   950   978 D AppOps  : startOperation: allowing code 40 uid 1000 package android11-28 11:05:45.130176   950  1112 D AES     : onEndOfErrorDumpThread: system_server_wtf Process: system_server11-28 11:05:45.130176   950  1112 D AES     : Subject: ActivityManager11-28 11:05:45.130176   950  1112 D AES     : Build: LAVA/Z91/Z91:7.1.1/N6F26Q/1514365452:user/release-keys11-28 11:05:45.130176   950  1112 D AES     : 11-28 11:05:45.130176   950  1112 D AES     : android.util.Log$TerribleFailure: Sending non-protected broadcast com.android.deskclock.ON_QUARTER_HOUR from system uid 1000 pkg com.android.deskclock11-28 11:05:45.130176   950  1112 D AES     :   at android.util.Log.wtf(Log.java:295)11-28 11:05:45.130176   950  1112 D AES     :   at android.util.Log.wtf(Log.java:290)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:19335)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:19942)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.ActivityManagerService.broadcastIntentInPackage(ActivityManagerService.java:20130)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:325)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:222)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:8169)11-28 11:05:45.130176   950  1112 D AES     :   at android.app.PendingIntent.send(PendingIntent.java:836)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.AlarmManagerService$DeliveryTracker.deliverLocked(AlarmManagerService.java:3565)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.AlarmManagerService.deliverAlarmsLocked(AlarmManagerService.java:2938)11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:3086)11-28 11:05:45.130176   950  1112 D AES     : Caused by: java.lang.Throwable11-28 11:05:45.130176   950  1112 D AES     :   at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:19338)11-28 11:05:45.130176   950  1112 D AES     :   ... 9 more11-28 11:05:45.130176   950  1112 D AES     :  95011-28 11:05:45.130366   950  1112 W AES     : Exception Log handling...11-28 11:05:45.130829   950  1169 D AppOps  : startOperation: allowing code 40 uid 1000 package android11-28 11:05:45.137684  1223  1223 D KeyguardUpdateMonitor: received broadcast android.intent.action.TIME_TICK11-28 11:05:45.138396  1223  1223 D KeyguardUpdateMonitor: handleTimeUpdate11-28 11:05:45.272902  1223  1223 V Clock   : onReceive: Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }11-28 11:05:45.293306   950  1472 D AES     : AEEIOCTL_GET/SET_SF_STATE IOCTL,cmd= 1074294797, lParam=0. 11-28 11:05:45.294011   950  1472 D AES     : AEEIOCTL_RT_MON_Kick IOCTL,cmd= 2147774474, lParam=300. 11-28 11:05:45.294107  1223  1223 V Clock   : onReceive: Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }

分析

首先查看系统唤醒

如果是 RTC 唤醒,要找上层的 alarm 也很简单,在 main log 或者 sys log 里面搜索下面的关键字即可
关键字 AlarmManager: sending alarm Alarm

查询结果如下:

11-28 11:05:45.134589   950  1112 V AlarmManager: sending alarm Alarm{b982fb4 type 1 when 1480302001000 com.android.deskclock} success具体细节:4,381: 11-28 11:05:45.134589   950  1112 V AlarmManager: sending alarm Alarm{b982fb4 type 1 when 1480302001000 com.android.deskclock} success 4,399: 11-28 11:05:45.389511   950  1783 V AlarmManager: APP set(PendingIntent{
9e1ef52: PendingIntentRecord{
78a1223 com.android.deskclock broadcastIntent}}) : type=1 triggerAtTime=1480302901000 win=0 tElapsed=4190256 maxElapsed=4190256 interval=0 flags=0x9 由于该AlarmManager.RTC 没有实际唤醒CPU,故kenalLog不显示11-28 11:05:45.426971 0 0 I [ 1084.519376]-(1)[0:swapper/1]: [SPM] wake up by R12_APXGPT1_EVENT_B, timer_out = 375, r13 = 0xe860200, debug_flag = 0x200110ff 0x0, r12 = 0x10, r12_ext = 0x100, raw_sta = 0x0, idle_sta = 0xfb, req_sta = 0x1800, event_reg = 0x90100000, isr = 0x0, raw_ext_sta = 0x4402a3aa, wake_misc = 0x0, pcm_flag = 0x180 0x0, req = 0x0

上述确定 com.android.deskclock 设置定时进行广播com.android.deskclock.ON_QUARTER_HOUR唤醒 type 1 表示AlarmManager.RTC

AlarmManager.RTC,硬件闹钟,不唤醒手机(也可能是其它设备)休眠;当手机休眠时不发射闹钟。

xref: /frameworks/base/core/java/android/app/AlarmManager.java83public class AlarmManager {92    /**93     * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}94     * (wall clock time in UTC).  This alarm does not wake the95     * device up; if it goes off while the device is asleep, it will not be96     * delivered until the next time the device wakes up.97     */98    public static final int RTC = 1;

分析结果

com.android.deskclock 休眠下执行的com.android.deskclock.ON_QUARTER_HOUR导致平均电流被拉高

查看 com.android.deskclock 相关源码

AndroidManifest.xml

package com.android.alarmclock;public class MultiColckWidgetProvider extends AppWidgetProvider {
/** * Intent to be used for checking if a world clock's date has changed. Must be every fifteen * minutes because not all time zones are hour-locked. **/ public static final String ACTION_ON_QUARTER_HOUR = "com.android.deskclock.ON_QUARTER_HOUR"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "onReceive: " + action); super.onReceive(context, intent); if (ACTION_ON_QUARTER_HOUR.equals(action) || Intent.ACTION_DATE_CHANGED.equals(action) || Intent.ACTION_TIMEZONE_CHANGED.equals(action) || Intent.ACTION_TIME_CHANGED.equals(action) || Intent.ACTION_LOCALE_CHANGED.equals(action) || Cities.WORLDCLOCK_UPDATE_INTENT.equals(action)) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); if (appWidgetManager != null) { int[] appWidgetIds = appWidgetManager.getAppWidgetIds(getComponentName(context)); for (int appWidgetId : appWidgetIds) { updateClock(context, appWidgetManager, appWidgetId); } if(!ACTION_ON_QUARTER_HOUR.equals(action)) { cancelAlarmOnQuarterHour(context); } startAlarmOnQuarterHour(context); } } } /** * Start an alarm that fires on the next quarter hour to update the world clock city * day when the local time or the world city crosses midnight. * * @param context The context in which the PendingIntent should perform the broadcast. */ private void startAlarmOnQuarterHour(Context context) { if (context != null) { final long onQuarterHour = Utils.getAlarmOnQuarterHour(); final PendingIntent quarterlyIntent = getOnQuarterHourPendingIntent(context); final AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); am.setExact(AlarmManager.RTC, onQuarterHour, quarterlyIntent); Log.v(TAG, "startAlarmOnQuarterHour " + context.toString()); } }

上述确认无误了

写一个Demo 验证

定时器进行AlarmManager.RTC休眠下唤醒

代码如下

调用===============================================================================package com.android.wakeupdemo;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity {
private Intent mIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIntent = new Intent(this, MyBroadcast.class); mIntent.setAction(MyBroadcast.ACITON); AlarmTaskUtil.starRepeatAlarmTaskBroadcast(this, 5 * 1000 /* 5秒钟 */, mIntent); Log.d("suhuazhi", "starRepeatAlarmTaskBroadcast " + MyBroadcast.ACITON); } @Override protected void onDestroy() { super.onDestroy(); AlarmTaskUtil.stopAlarmTaskByBroadcast(this, mIntent); Log.d("suhuazhi", "onDestroy"); }}定时器===============================================================================package com.android.wakeupdemo;import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;public class AlarmTaskUtil {
public static void starRepeatAlarmTaskBroadcast(Context context, long intervalMillis, Intent intent) { AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent operation = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), intervalMillis, operation); } public static void stopAlarmTaskByBroadcast(Context context, Intent intent) { AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent operation = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); mAlarmManager.cancel(operation); }}广播===============================================================================package com.android.wakeupdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class MyBroadcast extends BroadcastReceiver {
public final static String ACITON = "com.su.wakeupdemo.ON_QUARTER_HOUR"; @Override public void onReceive(Context context, Intent intent) { if (ACITON.equals(intent.getAction())) { Log.d("suhuazhi", "I am here " + ACITON); } }}

捕获台阶电流

这里写图片描述

Log关键字

sending alarm Alarm

3,687: 11-28 15:46:40.163016   920  1090 V AlarmManager: sending alarm Alarm{
92ddf3e type 1 when 1511855198951 com.android.wakeupdemo} success 3,681: 11-28 15:46:40.122116 920 1090 V AlarmManager: sending alarm Alarm{e4b4fd type 1 when 1511854898951 com.android.wakeupdemo} success

解决方案

本测试是在飞行模式下测试,要求平均待机电流在 4mA 下,该广播的主要作用是刷新时间控件,解决思路,没有联网的情况下,不进行定时设置或者延迟更新时间,不要太频繁。如果影响不大,甚至可以去除自定义广播

你可能感兴趣的文章
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
IPS开发手记【一】
查看>>
Java通用字符处理类
查看>>
文件上传时生成“日期+随机数”式文件名前缀的Java代码
查看>>
Java代码检查工具Checkstyle常见输出结果
查看>>
北京十大情人分手圣地
查看>>
Android自动关机代码
查看>>
Android中启动其他Activity并返回结果
查看>>
2009年33所高校被暂停或被限制招生
查看>>
GlassFish 部署及应用入门
查看>>
X-code7 beta error: warning: Is a directory
查看>>
Error: An App ID with identifier "*****" is not avaliable. Please enter a different string.
查看>>
3.5 YOLO9000: Better,Faster,Stronger(YOLO9000:更好,更快,更强)
查看>>
iOS菜鸟学习--如何避免两个按钮同时响应
查看>>
iOS菜鸟学习—— NSSortDescriptor的使用
查看>>
C语言8
查看>>
Qt实现简单延时
查看>>
qml有关矩形说明
查看>>
在qt中使用QSplitter设置初始比例setStretchFactor失效的解决方法
查看>>