zoukankan      html  css  js  c++  java
  • 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
    ",(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
    ");
    	input_report_key(powerkeydev, KEY_POWER, 1);
    	input_sync(powerkeydev);
    	ssleep(2);
    	DBG_PSY_MSG("press long up
    ");
    	input_report_key(powerkeydev, KEY_POWER, 0);
    	input_sync(powerkeydev);
    }
    
    static void axp_pressshort(struct axp_charger *charger)
    {
    	DBG_PSY_MSG("press short
    ");
    	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
         * {@link 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);
    }

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



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Android native CursorWindow数据保存原理
    王立平--EditText实现单行显示,左側图标,提示信息
    Cocos2d-x 3.4 之 消灭星星 > 第三篇(终) <
    关于Segmentation fault错误
    python 2.x 与3.x的区别
    σ 代数与测度(measures)
    中文的表达 —— 句式、段落、结构(逻辑)
    中文的表达 —— 句式、段落、结构(逻辑)
    matlab 快捷键
    matlab 快捷键
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4746101.html
Copyright © 2011-2022 走看看