打印
[资料分享]

【转】Android 长按电源键关机整个流程小学习

[复制链接]
637|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

Android 长按电源键关机整个流程小学习

           最近研究了一下android关机跟重新启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程。

首先还是来看看这个长按电源键都干了些什么吧?一般来说,电源键都是接到PMU上的,PMU来判断是长按还短按,当有按键消息产生的时候,系统会有中断,然后去读PMU的状态就可以知道是什么了。笔者以全志平台的AXP209小议一下,先贴上关键代码:


[cpp] view plain copy


  • static int axp_battery_event(struct notifier_block *nb, unsigned long event,  
  •         void *data)  
  • {  
  •     struct axp_charger *charger =  
  •     container_of(nb, struct axp_charger, nb);  
  •     uint8_t w[9];  
  •     w[0] = (uint8_t) ((event) & 0xFF);  
  •     w[1] = POWER20_INTSTS2;  
  •     w[2] = (uint8_t) ((event >> 8) & 0xFF);  
  •     w[3] = POWER20_INTSTS3;  
  •     w[4] = (uint8_t) ((event >> 16) & 0xFF);  
  •     w[5] = POWER20_INTSTS4;  
  •     w[6] = (uint8_t) ((event >> 24) & 0xFF);  
  •     w[7] = POWER20_INTSTS5;  
  •     w[8] = (uint8_t) (((uint64_t) event >> 32) & 0xFF);  
  •   
  •     if(event & (AXP20_IRQ_BATIN|AXP20_IRQ_BATRE)) {  
  •         axp_capchange(charger);  
  •     }  
  •   
  •     if(event & (AXP20_IRQ_ACIN|AXP20_IRQ_USBIN|AXP20_IRQ_ACOV|AXP20_IRQ_USBOV|AXP20_IRQ_CHAOV  
  •                 |AXP20_IRQ_CHAST|AXP20_IRQ_TEMOV|AXP20_IRQ_TEMLO)) {  
  •         axp_change(charger);  
  •     }  
  •   
  •     if(event & (AXP20_IRQ_ACRE|AXP20_IRQ_USBRE)) {  
  •         axp_change(charger);  
  •     }  
  •   
  •     if(event & AXP20_IRQ_PEKLO) {  
  •         axp_presslong(charger);  
  •     }  
  •   
  •     if(event & AXP20_IRQ_PEKSH) {  
  •         axp_pressshort(charger);  
  •     }  
  •   
  •     DBG_PSY_MSG("event = 0x%x\n",(int) event);  
  •     axp_writes(charger->master,POWER20_INTSTS1,9,w);  
  •   
  •     return 0;  
  • }  


短按跟长按具体也就是上报的延时区别,如下:


[cpp] view plain copy


  • static void axp_presslong(struct axp_charger *charger)  
  • {  
  •     DBG_PSY_MSG("press long\n");  
  •     input_report_key(powerkeydev, KEY_POWER, 1);  
  •     input_sync(powerkeydev);  
  •     ssleep(2);  
  •     DBG_PSY_MSG("press long up\n");  
  •     input_report_key(powerkeydev, KEY_POWER, 0);  
  •     input_sync(powerkeydev);  
  • }  
  •   
  • static void axp_pressshort(struct axp_charger *charger)  
  • {  
  •     DBG_PSY_MSG("press short\n");  
  •     input_report_key(powerkeydev, KEY_POWER, 1);  
  •     input_sync(powerkeydev);  
  •     msleep(100);  
  •     input_report_key(powerkeydev, KEY_POWER, 0);  
  •     input_sync(powerkeydev);  
  • }  


     在inputmanager里面再解析出是长按还是短按,来做相应处理。如果是长按,就弹出对话框,在弹出对话框之前,有几次传递,还是activitymanger跟Windowsmanagerservice做宏观调控,最终把消息传到苦逼的ShutdownThread,不过ShutdownThread也不难弄。


相关帖子

沙发
俺是村长他爹|  楼主 | 2016-9-13 00:52 | 只看该作者

首先来看一下,在ShutdownThread里面有一个CloseDialogReceiver来关注Intent.ACTION_CLOSE_SYSTEM_DIALOGS,它收到这个消息就会关闭这个对话框。对话框怎么起来的呢?请看下面的源码:

[java] view plain copy


  • if (confirm) {  
  •     final CloseDialogReceiver closer = new CloseDialogReceiver(context);  
  •     final AlertDialog dialog = new AlertDialog.Builder(context)  
  •             .setTitle(com.android.internal.R.string.power_off)  
  •             .setMessage(resourceId)  
  •             .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {  
  •                 public void onClick(DialogInterface dialog, int which) {  
  •                     beginShutdownSequence(context);  
  •                 }  
  •             })  
  •             .setNegativeButton(com.android.internal.R.string.no, null)  
  •             .create();  
  •     closer.dialog = dialog;  
  •     dialog.setOnDismissListener(closer);  
  •     dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);  
  •     dialog.show();  
  • } else {  
  •     beginShutdownSequence(context);  
  • }  


    其实就是一个AlertDialog,也没什么新鲜的,只是在setPositiveButton的时候注册了clicklistener来监听你是否按下了,按下了就直接执行beginShutdownSequence。在beginShutdownSequence还会弹出一个进度的对话框,代码如下:

[java] view plain copy


  • ProgressDialog pd = new ProgressDialog(context);  
  • pd.setTitle(context.getText(com.android.internal.R.string.power_off));  
  • pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));  
  • pd.setIndeterminate(true);  
  • pd.setCancelable(false);  
  • pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);  
  •   
  • pd.show();  


      在里面还会调用两个非常重要的Power.shutdown()跟Power.reboot(reason),看你是重启还是关机了。

[cpp] view plain copy


  • /**
  • * Low-level function turn the device off immediately, without trying
  • * to be clean.  Most people should use
  • * {@link android.internal.app.ShutdownThread} for a clean shutdown.
  • *
  • * @deprecated
  • * @hide
  • */  
  • @Deprecated  
  • public static native void <span style="color:#ff0000;">shutdown</span>();  
  •   
  • /**
  • * Reboot the device.
  • * @param reason code to pass to the kernel (e.g. "recovery"), or null.
  • *
  • * @throws IOException if reboot fails for some reason (eg, lack of
  • *         permission)
  • */  
  • public static void reboot(String reason) throws IOException  
  • {  
  •     <span style="color:#ff0000;">rebootNative</span>(reason);  
  • }  
  •   
  • private static native void rebootNative(String reason) throws IOException ;  

      再往下跟,


[cpp] view plain copy


  • static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)  
  • {  
  •     android_reboot(ANDROID_RB_POWEROFF, 0, 0);  
  • }  
  •   
  • extern int go_recovery(void);  
  •   
  • static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)  
  • {  
  •     if (reason == NULL) {  
  •         android_reboot(ANDROID_RB_RESTART, 0, 0);  
  •     } else {  
  •         const char *chars = env->GetStringUTFChars(reason, NULL);  
  •         //android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);  
  •         go_recovery();  
  •         android_reboot(ANDROID_RB_RESTART, 0, 0);  
  •         env->ReleaseStringUTFChars(reason, chars);  // In case it fails.  
  •     }  
  •     jniThrowIOException(env, errno);  
  • }  


所以,整个流程都是好的,学习理了一下流程,大部分都是源码,把它搞清楚也是有好处的。


使用特权

评论回复
板凳
沉默的风筝| | 2016-11-21 21:40 | 只看该作者
谢谢楼主分享。这属于开关机流程啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

168

帖子

2

粉丝