当前位置: 首页 > news >正文

MTK平台关机流程和原因(二)

(1)ShutdownThread

从上一篇可以看到,最终会调用此类的shutdown以及reboot等函数,我们来看一下这些函数的实现。

(A)被调用函数

//frameworks/base/services/core/java/com/android/server/power/ShutdownThread.javapublic static void shutdown(final Context context, String reason, boolean confirm) {mReboot = false;mRebootSafeMode = false;mReason = reason;shutdownInner(context, confirm);}public static void reboot(final Context context, String reason, boolean confirm) {mReboot = true;mRebootSafeMode = false;mRebootHasProgressBar = false;mReason = reason;shutdownInner(context, confirm);}public static void rebootSafeMode(final Context context, boolean confirm) {UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);if (um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {return;}mReboot = true;mRebootSafeMode = true;mRebootHasProgressBar = false;mReason = null;shutdownInner(context, confirm);}public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {if (reboot) {Log.i(TAG, "Rebooting, reason: " + reason);PowerManagerService.lowLevelReboot(reason);Log.e(TAG, "Reboot failed, will attempt shutdown instead");reason = null;} else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {// vibrate before shutting downVibrator vibrator = new SystemVibrator(context);try {vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES);} 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) {}}///M: added for shutdown Enhancement@{sInstance.mLowLevelShutdownSeq(context);/// @}// Shutdown powerLog.i(TAG, "Performing low-level shutdown...");PowerManagerService.lowLevelShutdown(reason);}

(B)shutdownInner函数实现

接下来看一下shutdownInner内部实现。

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();//xinghui add.avoid shutdown when monkey test.if (ActivityManager.isUserAMonkey()) {Log.d(TAG, "Cannot request to shutdown when Monkey is running, returning.");return;}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) {final CloseDialogReceiver closer = new CloseDialogReceiver(context);if (sConfirmDialog != null) {sConfirmDialog.dismiss();}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) {beginShutdownSequence(context);}}).setNegativeButton(com.android.internal.R.string.no, null).create();if (mReboot && !mRebootSafeMode) {sConfirmDialog.setTitle(com.android.internal.R.string.global_action_restart);sConfirmDialog.setMessage(context.getText(com.android.internal.R.string.reboot_confirm_question));}closer.dialog = sConfirmDialog;sConfirmDialog.setOnDismissListener(closer);sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);sConfirmDialog.show();} else {beginShutdownSequence(context);}}

由于这段代码融合了phone,TV,tablet等平台,所以字符串有不同的区分。

<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"您的平板电脑会关闭。"</string>
<string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"您的 Android TV 设备将关闭。"</string>
<string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"您的手表即将关机。"</string>
<string name="shutdown_confirm" product="default" msgid="136816458966692315">"您的手机将会关机。"</string>
<string name="shutdown_confirm_question" msgid="796151167261608447">"您要关机吗?"</string>

而具体是如何区分phone,TV,tablet等平台的,因为会根据系统的如下属性。

PRODUCT_CHARACTERISTICS := nosdcard
PRODUCT_CHARACTERISTICS := tvifndef PRODUCT_CHARACTERISTICSTARGET_AAPT_CHARACTERISTICS := defaultelseTARGET_AAPT_CHARACTERISTICS := $(PRODUCT_CHARACTERISTICS)endifADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)

将TARGET_AAPT_CHARACTERISTICS的值赋予ro.build.characteristics,而这个属性在Android编译完成后最终写入到/system目录下的build.prop文件。

(C)MTK重载的部分关机流程函数

这里要提一下,MTK平台有自定义部分关机流程函数,我们可以同步了解一下。

public class ShutdownThread extends Thread {protected boolean mIsShowShutdownSysui() {return true;}protected boolean mIsShowShutdownDialog(Context c) {return true;}//add by fenghuan for 开关机动画 endprotected boolean mStartShutdownSeq(Context c, boolean IsReboot) {return true;}protected void mShutdownSeqFinish(Context c) {return;}protected void mLowLevelShutdownSeq(Context c) {return;}
}

(D)beginShutdownSequence函数实现

private static void beginShutdownSequence(Context context) {synchronized (sIsStartedGuard) {if (sIsStarted) {Log.d(TAG, "Shutdown sequence already running, returning.");return;}sIsStarted = true;}sInstance.mProgressDialog = showShutdownDialog(context);sInstance.mContext = context;sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);//...// start the thread that initiates shutdownsInstance.mHandler = new Handler() {};///M: added for Shutdown Enhancement @{if(sInstance.mStartShutdownSeq(context, mReboot)) {sInstance.start();}}

(2)MtkShutdownThread

//vendor/mediatek/proprietary/frameworks/base/services/core/java/com/mediatek/server/MtkShutdownThread.javapublic class MtkShutdownThread extends ShutdownThread {@Overrideprotected boolean mIsShowShutdownSysui() {//...return true;}@Overrideprotected boolean mIsShowShutdownDialog(Context context) {//...return true;}@Overrideprotected boolean mStartShutdownSeq(Context context, boolean isReboot) {//...return true;}@Overrideprotected void mShutdownSeqFinish(Context context) {//...}@Overrideprotected void mLowLevelShutdownSeq(Context context) {//...}
}

(3)关机Log分析

大致关机Log如下:

03-30 07:48:25.865  1342  1342 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
03-30 07:48:27.303  1342  1342 D ShutdownThread: Attempting to use SysUI shutdown UI
03-30 07:48:27.303  1342  1342 D ShutdownThread: SysUI handling shutdown UI03-30 07:48:27.311  1342  1342 I MtkShutdownThread: hct screen turn off time shutdown_animation_play_time =6000
03-30 07:48:27.312  1342  1342 I MtkShutdownThread: screen turn off time screenTurnOffTime =600003-30 07:48:27.321  1342  7625 I ShutdownThread: Sending shutdown broadcast...
03-30 07:48:27.554  1342  7625 I ShutdownThread: Shutting down activity manager...
03-30 07:48:27.842  1342  7625 I ShutdownThread: Shutting down package manager...
03-30 07:48:27.888  1342  7630 W ShutdownThread: Turning off cellular radios...
03-30 07:48:27.902  1342  7630 I ShutdownThread: Waiting for Radio...
03-30 07:48:28.413  1342  7630 I ShutdownThread: Radio turned off.
03-30 07:48:28.414  1342  7630 I ShutdownThread: Radio shutdown complete.03-30 07:48:28.415  1342  7625 I MtkShutdownThread: mShutOffAnimation: 103-30 07:48:28.418  1342  7625 I ShutdownThread: rebootOrShutdown:goToSleep
03-30 07:48:28.918  1342  7625 I ShutdownThread: Rebooting, reason: user requested

在boot_normal中可以看到开机原因。

//adb reboot
bootstat: Canonical boot reason: reboot,shell
bootstat: Last reboot reason read from /metadata/bootstat/persist.sys.boot.reason : reboot,shell. Last reboot reason read from persist.sys.boot.reason : reboot,shell
bootstat: Normalized last reboot reason : reboot,shell//adb reboot -p
bootstat: Canonical boot reason: cold,powerkey
bootstat: Last reboot reason read from /metadata/bootstat/persist.sys.boot.reason : shutdown,shell. Last reboot reason read from persist.sys.boot.reason : shutdown,shell
bootstat: Normalized last reboot reason : shutdown,shell//power键关机
bootstat: Canonical boot reason: cold,powerkey
bootstat: Last reboot reason read from /metadata/bootstat/persist.sys.boot.reason : shutdown,userrequested. Last reboot reason read from persist.sys.boot.reason : shutdown,userrequested
bootstat: Normalized last reboot reason : shutdown,userrequested//power键重启
bootstat: Canonical boot reason: reboot,userrequested
bootstat: Last reboot reason read from /metadata/bootstat/persist.sys.boot.reason : reboot,userrequested. Last reboot reason read from persist.sys.boot.reason : reboot,userrequested
bootstat: Normalized last reboot reason : reboot,userrequested
http://www.lryc.cn/news/104433.html

相关文章:

  • 【Python】pyqt6入门到入土系列,非常详细...
  • TCP socket编程
  • HTTP——一、了解Web及网络基础
  • [论文笔记] chatgpt系列 2.6 DeepSpeed-chat 数据集
  • 探究SAM和眼球追踪技术在自动医学图像分割的应用(2023+GazeSAM: What You See is What You Segment)
  • excle中的条件求和SUMIF
  • python-网络爬虫.Request
  • 时序预测 | MATLAB实现GRNN广义回归神经网络时间序列预测(多指标,多图)
  • 如何看待低级爬虫与高级爬虫?
  • 3.分支与循环
  • 面试之多线程案例(四)
  • 抄写Linux源码(Day1:获取并运行 Linux0.11)
  • 大数据_Hadoop_Parquet数据格式详解
  • Docker的安装和部署
  • FPGA项目实现:秒表设计
  • Postgresql源码(109)并行框架实例与分析
  • ES派生类的prototype方法中,不能访问super的解决方案
  • 使用adb通过电脑给安卓设备安装apk文件
  • 113、单例Bean是单例模式吗?
  • RabbitMQ 集群部署
  • 2023年【零声教育】13代C/C++Linux服务器开发高级架构师课程体系分析
  • iOS开发-实现热门话题标签tag显示控件
  • linux系统磁盘性能监视工具iostat
  • BT#蓝牙 - Link Policy Settings
  • c++ | 动态链接库 | 小结
  • 如何使用Flask-SQLAlchemy来管理数据库连接和操作数据?
  • 麒麟-飞腾Kylin-V4桌面arm64系统静态编译QT
  • CentOS 项目发出一篇奇怪的博文
  • 【Mybatis-Plus】or拼接
  • SpringBoot项目部署在Windows与Centos上