Android4.0关机流程

1. 长摁电源键关机
ANDROID_ROOT/frameworks/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
private void interceptPowerKeyDown(boolean handled) {
		mPowerKeyHandled = handled;
		if (!handled) {
			mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
		}
	}
	
	private final Runnable mPowerLongPress = new Runnable() {
        public void run() {
            // The context isn't read
            if (mLongPressOnPowerBehavior < 0) {
                mLongPressOnPowerBehavior = mContext.getResources().getInteger(
                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
            }
            switch (mLongPressOnPowerBehavior) {
            case LONG_PRESS_POWER_NOTHING:
                break;
            case LONG_PRESS_POWER_GLOBAL_ACTIONS:
                mPowerKeyHandled = true;
                performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                showGlobalActionsDialog();
                break;
            case LONG_PRESS_POWER_SHUT_OFF:
                mPowerKeyHandled = true;
                performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                ShutdownThread.shutdown(mContext, true);	//启动关机线程去关机
                break;
            }
        }
    };
    
2. 启动线程去关机
ANDROID_ROOT/frameworks/base/core/java/com/android/internal/app/ShutdownThread.java
public static void shutdown(final Context context, boolean confirm) {
		mReboot = false;
		shutdownInner(context, confirm);
	}
	
	    public static void shutdownInner(final Context context, boolean confirm) {  //samsung yujing modify for reboot
        // ensure that only one thread is trying to power down.
        // any additional calls are just returned
        synchronized (sIsStartedGuard) {
            if (sIsStarted) {
                Log.d(TAG, "Request to shutdown already running, returning.");
                return;
            }
        }
				if (confirm) {
            final CloseDialogReceiver closer = new CloseDialogReceiver(context);            
                      final AlertDialog dialog = new AlertDialog.Builder(context)
                              .setTitle(mReboot?com.android.internal.R.string.global_action_reboot: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);	//不管如何,总会调到这个函数去关机
        }
    }
    
    private static void beginShutdownSequence(Context context) {
        SystemProperties.set("ctl.start","shutdownanim");
        ...
        // start the thread that initiates shutdown
        sInstance.mHandler = new Handler() {
        };
        sInstance.start();
        
    }
    
    //sInstance.run(){}
    /**
     * Makes sure we handle the shutdown gracefully.
     * Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
     */
    public void run() {
				...
        /*
         * Write a system property in case the system_server reboots before we
         * get to the actual hardware restart. If that happens, we'll retry at
         * the beginning of the SystemServer startup.
         */
        {
            String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
            SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
        }


        Log.i(TAG, "Sending shutdown broadcast...");
        
        // First send the high-level shut down broadcast.
        mActionDone = false;
        mContext.sendOrderedBroadcast(new Intent(Intent.ACTION_SHUTDOWN), null,
                br, mHandler, 0, null, null);


        rebootOrShutdown(mReboot, mRebootReason);
    }
    
    /**
     * Do not call this directly. Use {@link #reboot(Context, String, boolean)}
     * or {@link #shutdown(Context, boolean)} instead.
     *
     * @param reboot true to reboot or false to shutdown
     * @param reason reason for reboot
     */
    public static void rebootOrShutdown(boolean reboot, String reason) {
        if (reboot) {
            Log.i(TAG, "Rebooting, reason: " + reason);
            try {
                Power.reboot(reason);
            } catch (Exception e) {
                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
            }
        } else if (SHUTDOWN_VIBRATE_MS > 0) {
            // vibrate before shutting down
            Vibrator vibrator = new Vibrator();
            try {
                vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
            } catch (Exception e) {
                // Failure to vibrate shouldn't interrupt shutdown.  Just log it.
                Log.w(TAG, "Failed to vibrate during shutdown.", e);
            }


            // vibrator is asynchronous so we need to wait to avoid shutting down too soon.
            try {
                Thread.sleep(SHUTDOWN_VIBRATE_MS);
            } catch (InterruptedException unused) {
            }
        }


        // Shutdown power
        Log.i(TAG, "Performing low-level shutdown...");
        Power.shutdown();	//关机
    }

3. 关机的实现,有的是用PowerManager来实现的,这里看到的是三星的代码
ANDROID_ROOT/base/core/java/android/os/Power.java    
 /**
     * 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();
    
4. 找JNI看看是如何实现的
ANDROID_ROOT\frameworks\base\core\jni\android_os_Power.cpp
static JNINativeMethod method_table[] = {
	    { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
	    { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
	    { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
	    { "setScreenState", "(Z)I", (void*)setScreenState },
	    { "shutdown", "()V", (void*)android_os_Power_shutdown },
	    { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
	};
	
	static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
	{
	    android_reboot(ANDROID_RB_POWEROFF, 0, 0);
	}

5. 看看android_reboot的引用
ANDROID_ROOT\system\core\include\cutils\android_reboot.h
#ifndef __CUTILS_ANDROID_REBOOT_H__
	#define __CUTILS_ANDROID_REBOOT_H__
	
	__BEGIN_DECLS
	
	/* Commands */
	#define ANDROID_RB_RESTART  0xDEAD0001
	#define ANDROID_RB_POWEROFF 0xDEAD0002
	#define ANDROID_RB_RESTART2 0xDEAD0003
	
	/* Flags */
	#define ANDROID_RB_FLAG_NO_SYNC       0x1
	#define ANDROID_RB_FLAG_NO_REMOUNT_RO 0x2
	
	int android_reboot(int cmd, int flags, char *arg);
	
	__END_DECLS
	
	#endif /* __CUTILS_ANDROID_REBOOT_H__ */

6. 看看android_reboot的实现,详细的请看源码
ANDROID_ROOT\system\core\libcutils\android_reboot.c
int android_reboot(int cmd, int flags, char *arg)
	{
	    int ret;
	
	    if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
	        sync();
	
	    if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
	        remount_ro();
	
	    switch (cmd) {
	        case ANDROID_RB_RESTART:
	            ret = reboot(RB_AUTOBOOT);
	            break;
	
	        case ANDROID_RB_POWEROFF:
	            ret = reboot(RB_POWER_OFF);	//系统调用,下一步就是去kernel查看了
	            break;
	
	        case ANDROID_RB_RESTART2:
	            ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
	                           LINUX_REBOOT_CMD_RESTART2, arg);
	            break;
	
	        default:
	            ret = -1;
	    }
	
	    return ret;
	}

7. 查看kernel关机接口
//暂时还是盲区

你可能感兴趣的:(Android4.0关机流程)