Android 9.0 自动关机流程解析

一、ShutdownThread 概述

1.关机线程实现类
Android关机线程实现类frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java

2.ShutdownThread 大致流程
关机线程大致流程
在这里插入图片描述

3.ShutdownThread 部分静态变量如下:
public final class ShutdownThread extends Thread {
   
    // constants
    private static final String TAG = "ShutdownThread";
    private static final int ACTION_DONE_POLL_WAIT_MS = 500;
    private static final int RADIOS_STATE_POLL_SLEEP_MS = 100;
    // maximum time we wait for the shutdown broadcast before going on.
    private static final int MAX_BROADCAST_TIME = 10*1000;
    private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
    private static final int MAX_RADIO_WAIT_TIME = 12*1000;
    private static final int MAX_UNCRYPT_WAIT_TIME = 15*60*1000;
    // constants for progress bar. the values are roughly estimated based on timeout.
    private static final int BROADCAST_STOP_PERCENT = 2;
    private static final int ACTIVITY_MANAGER_STOP_PERCENT = 4;
    private static final int PACKAGE_MANAGER_STOP_PERCENT = 6;
    private static final int RADIO_STOP_PERCENT = 18;
    private static final int MOUNT_SERVICE_STOP_PERCENT = 20;
    // Time we should wait for vendor subsystem shutdown
    // Sleep times(ms) between checks of the vendor subsystem state
    private static final int VENDOR_SUBSYS_STATE_CHECK_INTERVAL_MS = 100;
    // Max time we wait for vendor subsystems to shut down before resuming
    // with full system shutdown
    private static final int VENDOR_SUBSYS_MAX_WAIT_MS = 10000;

    // length of vibration before shutting down
    private static final int SHUTDOWN_VIBRATE_MS = 500;

    ... ...
}
4.ShutdownThread 无参构造方法
  private ShutdownThread() {
   
    }

二、 shutdown 关机实现

长按 ·Power· 键调用 shutdown方法,通过调用内部shutdownInner方法,实现 弹出 关机 、重启对话框,供用户选择关机 或者重启。

 /**
     * Request a clean shutdown, waiting for subsystems to clean up their
     * state etc.  Must be called from a Looper thread in which its UI
     * is shown.
     *
     * @param context Context used to display the shutdown progress dialog. This must be a context
     *                suitable for displaying UI (aka Themable).
     * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
     * @param confirm true if user confirmation is needed before shutting down.
     */
    public static void shutdown(final Context context, String reason, boolean confirm) {
   
        mReboot = false;
        mRebootSafeMode = false;
        mReason = reason;
        shutdownInner(context, confirm); // 详见分析3
    }

三、shutdownInner 方法实现

1.shutdownInner 主要作用是
1.获取用户关机 Behavior。
2.注册关机广播,详见4.
3.创建关机Dialog。
4.执行一系列关机流程。

   private static void shutdownInner(final Context context, boolean confirm) {
   
        // ShutdownThread is called from many places, so best to verify here that the context passed
        // in is themed.
        context.assertRuntimeOverlayThemable();

        // 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;
            }
        }
        // 获取用户长按Power键的处理行为
        final int longPressBehavior = context.getResources().getInteger(
                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
        final int resourceId = mRebootSafeMode
                ? com.android.internal.R.string.reboot_safemode_confirm
                : (longPressBehavior == 2
                        ? com.android.internal.R.string.shutdown_confirm_question
                        : com.android.internal.R.string.shutdown_confirm);

        Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);

        if (confirm) {
   
           //注册关机对话框广播  详细实现见 4
            final CloseDialogReceiver closer = new CloseDialogReceiver(context);
            if (sConfirmDialog != null) {
   
                sConfirmDialog.dismiss();
            }
            // 创建关机Dialg 详见 实现5
            sConfirmDialog = new AlertDialog.Builder(context)
                    .setTitle(mRebootSafeMode
                            ? com.android.internal.R.string.reboot_safemode_title
                            : 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) {
   
                             // 开始一系列的关机流程,详见 6
                            beginShutdownSequence(context);
                        }
                    })
                    .setNegativeButton(com.android.internal.R.string.no, null)
                    .create();
            closer.dialog = sConfirmDialog;
            sConfirmDialog.setOnDismissListener(closer);
            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
            sConfirmDialog.show();
        } else {
   
            beginShutdownSequence(context);
        }
    }
其中 config_longPressOnPowerBehavior 用来控制用户长按Power键触发的行为。
主要行为如下:

 <!-- Control the behavior when the user long presses the power button.
            0 - Nothing
            1 - Global actions menu
            2 - Power off (with confirmation)
            3 - Power off (without confirmation)
            4 - Go to voice assist
    -->
    <integer name="config_longPressOnPowerBehavior">1</integer>
此源码 可以在 config.xml中查看,代码目录如下:frameworks\base\core\res\res\values\config.xml

四、CloseDialogReceiver 注册关机对话框广播

注册action 为ACTION_CLOSE_SYSTEM_DIALOGS广播接收器。

    private static class CloseDialogReceiver extends BroadcastReceiver
            implements DialogInterface.OnDismissListener {
   
        private Context mContext;
        public Dialog dialog;

        CloseDialogReceiver(Context context) {
   
            mContext = context;
            IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            context.registerReceiver(this, filter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
   
            dialog.cancel();
        }

        public void onDismiss(DialogInterface unused) {
   
            mContext.unregisterReceiver(this);
        }
    }

五、new sConfirmDialog 显示关机对话框

Android原生关机对话框如下:
关机对话框创建
            // 创建关机Dialg 详见 实现5
            sConfirmDialog = new AlertDialog.Builder(context)
                    .setTitle(mRebootSafeMode
                            ? com.android.internal.R.string.reboot_safemode_title
                            : com.android.internal.R.string.power_off)
                    .setMessage(resourceId)
                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener(
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安卓兼职framework应用工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值