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

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



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

  • 相关阅读:
    java io系列23之 BufferedReader(字符缓冲输入流)
    java io系列22之 FileReader和FileWriter
    java io系列21之 InputStreamReader和OutputStreamWriter
    java io系列20之 PipedReader和PipedWriter
    java io系列19之 CharArrayWriter(字符数组输出流)
    java io系列18之 CharArrayReader(字符数组输入流)
    java io系列17之 System.out.println("hello world")原理
    java io系列16之 PrintStream(打印输出流)详解
    java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例
    java io系列14之 DataInputStream(数据输入流)的认知、源码和示例
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4746101.html
Copyright © 2011-2022 走看看