Android version 2.3.5

首先查看Settings里控制开关




​01​

​// 获取当前状态​


​02​

​boolean​​​​ipoSettingEnabled = Settings.System.getInt(getContentResolver(),​


​03​

​            ​​​​Settings.System.IPO_SETTING,​​​​1​​​​) == ​​​​1​​​​;​


​04​

​if​​​​(mIpoSetting!=​​​​null​​​​){​


​05​

​    ​​​​mIpoSetting.setChecked(ipoSettingEnabled);​


​06​

​}​


​07​

​//设置新状态​


​08​

​boolean​​​​isChecked = ((CheckBoxPreference) preference).isChecked();​


​09​

​Settings.System.putInt(getContentResolver(), Settings.System.IPO_SETTING,​


​10​

​                ​​​​isChecked ? ​​​​1​​​​:​​​​0​​​​);​


全局搜索 Settings.System.IPO_SETTING ,发现在关机系统里调用了该状态(ShutdownThread.java)

ShutdownThread 里的 checkShutdownFlow 方法




​01​

​// 判断是否不支持该功能 是否需要重启​


​02​

​if​​​​(FeatureOption.MTK_IPO_SUPPORT == ​​​​false​​​​|| mReboot == ​​​​true​​​​) {​


​03​

​    ​​​​mShutdownFlow = NORMAL_SHUTDOWN_FLOW;    ​​​​// 更改状态     ​


​04​

​    ​​​​return​​​​;​


​05​

​}​


​06​

​boolean​​​​isIPOEnabled;​


​07​

​try​​​​{​


​08​

​    ​​​​// 获取当前状态​


​09​

​    ​​​​isIPOEnabled = Settings.System.getInt(sInstance.mContext.getContentResolver(),​


​10​

​        ​​​​Settings.System.IPO_SETTING, ​​​​1​​​​) == ​​​​1​​​​;​


​11​

​} ​​​​catch​​​​(NullPointerException ex) {​


​12​

​    ​​​​mShutdownFlow = NORMAL_SHUTDOWN_FLOW;​


​13​

​    ​​​​return​​​​;​


​14​

​}​


​15​

​if​​​​(isIPOEnabled == ​​​​true​​​​) {​


​16​

​    ​​​​// 判断系统参数​


​17​

​    ​​​​if​​​​(​​​​"1"​​​​.equals(SystemProperties.get(​​​​"sys.ipo.battlow"​​​​)))​


​18​

​        ​​​​mShutdownFlow = NORMAL_SHUTDOWN_FLOW;​


​19​

​    ​​​​else​


​20​

​        ​​​​mShutdownFlow = IPO_SHUTDOWN_FLOW;​


​21​

​} ​​​​else​​​​{​


​22​

​        ​​​​mShutdownFlow = NORMAL_SHUTDOWN_FLOW;​


​23​

​}​


​24​

​return​​​​;​


以上函数如果正常进入快速关机模式 

mShutdownFlow = IPO_SHUTDOWN_FLOW

关机流程会调用 ShutdownThread.shutdown(mContext, true);

ShutdownThread 里的 shutdown 方法




​01​

​bConfirmForAnimation = confirm;​


​02​

​if​​​​(confirm) {​


​03​

​    ​​​​if​​​​(mDialog == ​​​​null​​​​) {​


​04​

​        ​​​​mDialog = ​​​​new​​​​AlertDialog.Builder(context)​


​05​

​        ​​​​.setIcon(android.R.drawable.ic_dialog_alert)​


​06​

​        ​​​​.setTitle(com.android.internal.R.string.power_off)​


​07​

​        ​​​​.setMessage(com.android.internal.R.string.shutdown_confirm)​


​08​

​        ​​​​.setPositiveButton(com.android.internal.R.string.yes, ​​​​new​​​​DialogInterface.OnClickListener() {​


​09​

​            ​​​​public​​​​void​​​​onClick(DialogInterface dialog, ​​​​int​​​​which) {​


​10​

​                ​​​​//确认关机 检查状态​


​11​

​                ​​​​beginShutdownSequence(context);​


​12​

​                ​​​​if​​​​(mDialog != ​​​​null​​​​) {​


​13​

​                    ​​​​mDialog = ​​​​null​​​​;​


​14​

​                ​​​​}​


​15​

​            ​​​​}​


​16​

​        ​​​​})​


​17​

​        ​​​​.setNegativeButton(com.android.internal.R.string.no, ​​​​new​​​​DialogInterface.OnClickListener() {​


​18​

​            ​​​​public​​​​void​​​​onClick(DialogInterface dialog, ​​​​int​​​​which) {​


​19​

​                ​​​​synchronized​​​​(sIsStartedGuard) {​


​20​

​                    ​​​​sIsStarted = ​​​​false​​​​;​


​21​

​                ​​​​}​


​22​

​                ​​​​if​​​​(mDialog != ​​​​null​​​​) {​


​23​

​                    ​​​​mDialog = ​​​​null​​​​;​


​24​

​                ​​​​}​


​25​

​            ​​​​}​


​26​

​        ​​​​})​


​27​

​        ​​​​.create();​


​28​

​        ​​​​mDialog.setCancelable(​​​​false​​​​);​


​29​

​        ​​​​mDialog.getWindow().setType(​


​30​

​             ​​​​WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);​


​31​

​        ​​​​mDialog.getWindow().addFlags(​


​32​

​             ​​​​WindowManager.LayoutParams.FLAG_DIM_BEHIND);​


​33​

​    ​​​​}​


​34​

​    ​​​​if​​​​(!mDialog.isShowing()) {​


​35​

​        ​​​​mDialog.show();​


​36​

​    ​​​​}​


​37​

​} ​​​​else​​​​{​


​38​

​    ​​​​beginShutdownSequence(context);​


​39​

​}​


ShutdownThread 里的 beginShutdownSequence 方法




​1​

​if​​​​(mShutdownFlow == IPO_SHUTDOWN_FLOW) {​


​2​

​     ​​​​checkShutdownFlow();​


​3​

​     ​​​​synchronized​​​​(mShutdownThreadSync) {​


​4​

​         ​​​​mShutdownThreadSync.notify();​


​5​

​     ​​​​}​


​6​

​ ​​​​}​


ShutdownThread 里的 run 方法




​01​

​public​​​​void​​​​run() {​


​02​

​    ​​​​checkShutdownFlow();​


​03​

​    ​​​​while​​​​(mShutdownFlow == IPO_SHUTDOWN_FLOW) {​


​04​

​        ​​​​stMgr.saveStates(mContext);​


​05​

​        ​​​​running();​


​06​

​    ​​​​}​


​07​

​    ​​​​if​​​​(mShutdownFlow != IPO_SHUTDOWN_FLOW) {​


​08​

​        ​​​​running();​


​09​

​    ​​​​}​


​10​

​}​


adb logcat -s “ShutdownThread”




​01​

​--------- beginning of /dev/log/system​


​02​

​--------- beginning of /dev/log/main​


​03​

​D/ShutdownThread(  ​​​​189​​​​): !!! Request to shutdown !!!​


​04​

​D/ShutdownThread(  ​​​​189​​​​): Notifying thread to start radio shutdown​


​05​

​D/ShutdownThread(  ​​​​189​​​​): PowerOff dialog doesn't exist. Create it first​


​06​

​D/ShutdownThread(  ​​​​189​​​​): ShutdownThread exists already​


​07​

​D/ShutdownThread(  ​​​​189​​​​): checkShutdownFlow: IPO_Support=​​​​true​​​​mReboot=​​​​false​


​08​

​D/ShutdownThread(  ​​​​189​​​​): checkShutdownFlow: isIPOEnabled=​​​​true​​​​mShutdownFlow=​​​​1​


​09​

​D/ShutdownThread(  ​​​​189​​​​): shutdown acquire partial WakeLock ​​​​2​


​10​

​I/ShutdownThread(  ​​​​189​​​​): Sending shutdown broadcast...​


​11​

​I/ShutdownThread(  ​​​​189​​​​): Waiting ​​​​for​​​​Bluetooth and Radio...​


​12​

​I/ShutdownThread(  ​​​​189​​​​): Radio and Bluetooth shutdown complete.​


​13​

​I/ShutdownThread(  ​​​​189​​​​): Shutting down MountService​


​14​

​W/ShutdownThread(  ​​​​189​​​​): Result code ​​​​0​​​​from MountService.shutdown​


​15​

​I/ShutdownThread(  ​​​​189​​​​): Performing ipo low-level shutdown...​


ShutdownManager 里的 saveStates 方法




​1​

​//保存wifi状态​


ShutdownThread 里的 running 方法




​1​

​//广播全局事件 android.intent.action.ACTION_SHUTDOWN_IPO​


​2​

​//关闭蓝牙​


​3​

​//关闭Radio​


​4​

​//关闭MountService​


​5​

​stMgr.shutdown(mContext);​


ShutdownManager 里的 shutdown 方法




​1​

​mPowerManager = (PowerManager)context.getSystemService(​​​​"power"​​​​);​


​2​

​mPowerManager.goToSleep(SystemClock.uptimeMillis());​


​3​

​......​


​4​

​SystemProperties.set(​​​​"ctl.start"​​​​, ​​​​"ipod"​​​​);​


​5​

​Intent intent = ​​​​new​​​​Intent(​​​​"android.intent.action.black.mode"​​​​);​


​6​

​intent.putExtra(​​​​"_black_mode"​​​​, ​​​​true​​​​);​


​7​

​context.sendBroadcast(intent);​


adb logcat -s “ShutdownManager”




​01​

​--------- beginning of /dev/log/system​


​02​

​--------- beginning of /dev/log/main​


​03​

​I/ShutdownManager(  ​​​​189​​​​): btState: ​​​​false​


​04​

​I/ShutdownManager(  ​​​​189​​​​): saveStates: wifi:​​​​0​​​​, airplaneModeState: ​​​​0​


​05​

​V/ShutdownManager(  ​​​​189​​​​): Current Wallpaper = ​​​​null​


​06​

​V/ShutdownManager(  ​​​​189​​​​): Current IME: com.android.inputmethod.pinyin​


​07​

​I/ShutdownManager(  ​​​​189​​​​): accessibility is disabled​


​08​

​I/ShutdownManager(  ​​​​189​​​​): killProcess (IME): com.android.inputmethod.pinyin​


​09​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.cooliris.media​


​10​

​V/ShutdownManager(  ​​​​189​​​​): process = com.android.settings​


​11​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.android.settings​


​12​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.mediatek.launcherplus​


​13​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.android.mms​


​14​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: android.process.media​


​15​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: android.process.media​


​16​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: android.process.media​


​17​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.mediatek.moreapp​


​18​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.mediatek.omacp​


​19​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.android.email​


​20​

​V/ShutdownManager(  ​​​​189​​​​): uid-process = com.mediatek.mdlogger​


​21​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.android.providers.calendar​


​22​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.android.deskclock​


​23​

​V/ShutdownManager(  ​​​​189​​​​): uid-process = com.android.ActivityNetwork​


​24​

​I/ShutdownManager(  ​​​​189​​​​): forceStopPackage: com.mediatek.weather​


ActivityManagerPlus 接收到关机广播

adb logcat -s “ActivityManagerPlus”




​1​

​--------- beginning of /dev/log/system​


​2​

​--------- beginning of /dev/log/main​


​3​

​I/ActivityManagerPlus(  ​​​​189​​​​): Receive:​


​4​

​Intent { act=android.intent.action.ACTION_SHUTDOWN_IPO }​


​5​

​I/ActivityManagerPlus(  ​​​​189​​​​): finished​


​6​

​I/ActivityManagerPlus(  ​​​​189​​​​): Receive:​


​7​

​Intent { act=android.intent.action.black.mode (has  extras) }​


​8​

​I/ActivityManagerPlus(  ​​​​189​​​​): createIPOWin​


ActivityManagerPlus 里的 createIPOWin 方法 关机调用




​01​

​Window win = PolicyManager.makeNewWindow(context);​


​02​

​win.setType(​​​​2016​​​​);​


​03​

​win.setFlags(​​​​1024​​​​, ​​​​1024​​​​);​


​04​

​win.setLayout(-​​​​1​​​​, -​​​​1​​​​);​


​05​

​win.requestFeature(​​​​1​​​​);​


​06​

​android.view.WindowManager.LayoutParams params = win.getAttributes();​


​07​

​params.setTitle(​​​​"IPOWindow"​​​​);​


​08​

​params.flags = ​​​​24​​​​;​


​09​

​WindowManagerImpl wm = (WindowManagerImpl)context.getSystemService(​​​​"window"​​​​);​


​10​

​view = win.getDecorView();​


​11​

​wm.addView(view, params);​


ActivityManagerPlus 里的 removeIPOWin 方法 开机调用




​1​

​WindowManagerImpl wm = (WindowManagerImpl)context.getSystemService(​​​​"window"​​​​);​


​2​

​wm.removeView(view);​


底层实现 

mediatek/source/external/ipod/