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
相关文章:
MTK平台关机流程和原因(二)
(1)ShutdownThread 从上一篇可以看到,最终会调用此类的shutdown以及reboot等函数,我们来看一下这些函数的实现。 (A)被调用函数 //frameworks/base/services/core/java/com/android/server/power/Shutdo…...
【Python】pyqt6入门到入土系列,非常详细...
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 一、什么是PyQt6? 简单介绍一下PyQt6 1、基础简介 PyQt6 Digia 公司的 Qt 程序的 Python 中间件。Qt库是最强大的GUI库之一。 PyQt6的官网:www.riverbankcomputing.co.uk/news。 PyQt6是由Riverbank Co…...
TCP socket编程
一、服务端代码 #encoding utf -8 #导入socket库 from socket import * #等待客户端来连接,主机地址为0.0.0.0表示绑定本机所有网络接口ip地址 IP 0.0.0.0 #端口号 PORT 50000 #定义一次从socket缓存区最多读入512个字节数据 BUFLEN 512 #实例化一个socket编程…...
HTTP——一、了解Web及网络基础
HTTP 一、使用HTTP协议访问Web二、HTTP的诞生1、为知识共享而规划Web2、Web成长时代3、驻足不前的HTTP 三、网络基础TCP/IP1、TCP/IP协议族2、TCP/IP的分层管理3、TCP/IP 通信传输流 四、与HTTP关系密切的协议:IP、TCP和DNS1、负责传输的 IP 协议2、确保可靠性的TCP…...
[论文笔记] chatgpt系列 2.6 DeepSpeed-chat 数据集
一、FT数据集 & Reward model数据集 Deepspeed-chat 源代码的数据集: Dahoas/rm-static: 这是一个用于强化学习的静态环境数据集,包含了一个机器人在一个固定环境中的运动轨迹。该数据集旨在用于评估强化学习算法在静态环境下的表现。 Dahoas/full-hh-rlhf: 这是一个用于…...
探究SAM和眼球追踪技术在自动医学图像分割的应用(2023+GazeSAM: What You See is What You Segment)
摘要: 本研究探讨眼动追踪技术与SAM的潜力,以设计一个协同的人机交互系统,自动化医学图像分割。提出了GazeSAM系统,使放射科医生能够在图像诊断过程中通过简单地查看感兴趣的区域来收集分割掩模。该系统跟踪放射科医生的眼球运动…...
excle中的条件求和SUMIF
问题:将每一行中红色文字的前一个值累计求和到境外总数这一列 使用的公式 自制单元格的格式计算公式:ctrlf3打开格式管理,创建如下公式,其中24是表示获取文字颜色 由于sumif只能直接与第二参数条件比较,所以先使用IF(公…...
python-网络爬虫.Request
Request python中requests库使用方法详解: 一简介: Requests 是Python语言编写,基于urllib, 采用Apache2 Licensed开源协议的 HTTP 库。 与urllib相比,Requests更加方便,处理URL资源特别流畅。 可以节约我…...
时序预测 | MATLAB实现GRNN广义回归神经网络时间序列预测(多指标,多图)
时序预测 | MATLAB实现GRNN广义回归神经网络时间序列预测(多指标,多图) 目录 时序预测 | MATLAB实现GRNN广义回归神经网络时间序列预测(多指标,多图)效果一览基本介绍程序设计参考资料效果一览 基本介绍 1.MATLAB实现GRNN广义回归神经网络时间序列预测(完整源码和数据) …...
如何看待低级爬虫与高级爬虫?
爬虫之所以分为高级和低级,主要是基于其功能、复杂性和灵活性的差异。根据我总结大概有下面几点原因: 功能和复杂性:高级爬虫通常提供更多功能和扩展性,包括处理复杂页面结构、模拟用户操作、解析和清洗数据等。它们解决了开发者…...
3.分支与循环
一、分支结构 1.概念 一个 CPP 程序默认是按照代码书写顺序,从上到下依次执行下来的。但是,有时我们需要选择性的执行某些语句,来实现更加复杂的逻辑,这时候就需要分支结构语句的功能来实现。选择合适的分支语句可以显著提高程序…...
面试之多线程案例(四)
1.单例模式 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。…...
抄写Linux源码(Day1:获取并运行 Linux0.11)
Day1:获取并运行 Linux0.11 参考资料:https://zhuanlan.zhihu.com/p/438577225 这是我参考的一个别人写的 Linux0.11 解读:https://github.com/dibingfa/flash-linux0.11-talk 我获取 Linux-0.11 源码的链接:https://github.com/…...
大数据_Hadoop_Parquet数据格式详解
之前有面试官问到了parquet的数据格式,下面对这种格式做一个详细的解读。 参考链接 : 列存储格式Parquet浅析 - 简书 Parquet 文件结构与优势_parquet文件_KK架构的博客-CSDN博客 Parquet文件格式解析_parquet.block.size_davidfantasy的博客-CSDN博…...
Docker的安装和部署
目录 一、Docker的安装部署 (1)关闭防火墙 (2)关闭selinux (3)安装docker引擎 (4)启动docker (5)设置docker自启动 (6)测试doc…...
FPGA项目实现:秒表设计
文章目录 项目要求项目设计 项目要求 设计一个时钟秒表,共六个数码管,前两位显示分钟,中间两位显示时间秒,后两位显示毫秒的高两位,可以通过按键来开始、暂停以及重新开始秒表的计数。 项目设计 为完成此项目共设计…...
Postgresql源码(109)并行框架实例与分析
1 PostgreSQL并行参数 系统参数 系统总worker限制:max_worker_processes 默认8 系统总并发限制:max_parallel_workers 默认8 单Query限制:max_parallel_workers_per_gather 默认2 表参数限制:parallel_workers alter table tbl …...
ES派生类的prototype方法中,不能访问super的解决方案
1 下面的B.prototype.compile方法中,无法访问super class A {compile() {console.log(A)} }class B extends A {compile() {super.compile()console.log(B)} }B.prototype.compile function() {super.compile() // 报错,不可以在此处使用superconsole.…...
使用adb通过电脑给安卓设备安装apk文件
最近碰到要在开发板上安装软件的问题,由于是开发板上的安卓系统没有解析apk文件的工具,所以无法通过直接打开apk文件来安装软件。因此查询各种资料后发现可以使用adb工具,这样一来可以在电脑上给安卓设备安装软件。 ADB 就是连接 Android 手…...
113、单例Bean是单例模式吗?
单例Bean是单例模式吗? 通常来说,单例模式是指在一个JVM中,一个类只能构造出来一个对象,有很多方法来实现单例模式,比如懒汉模式,但是我们通常讲的单例模式有一个前提条件就是规定在一个JVM中,那如果要在两个JVM中保证单例呢?那可能就要用分布式锁这些技术,这里的重点…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
