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

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

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

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

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;

}

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

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也不难弄。/*****************************************************************************************************/声明:本博内容均由http://blog.csdn.net/sundesheng125原创,转载请注明出处,谢谢!/*****************************************************************************************************/

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

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还会弹出一个进度的对话框,代码如下:

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),看你是重启还是关机了。

/**

* Low-level function turn the device off immediately, without trying

* to be clean. Most people should use

* [email protected] android.internal.app.ShutdownThread} for a clean shutdown.

*

* @deprecated

* @hide

*/

@Deprecated

public static native void shutdown();

/**

* 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

{

rebootNative(reason);

}

private static native void rebootNative(String reason) throws IOException ;

再往下跟,

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);

}

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

原文:http://blog.csdn.net/edsam49/article/details/25000539

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值