非常にお勧めの記事:ようこそお気に入り
のAndroidドライシェア
5分、毎日10時、あなたと生涯学習を読んで、ここでのAndroidのプログラマです
この資料に記載されているAndroid
この記事を読んで知識の開発の一部を、次のことを刈り取ります。
1.ShutdownThread概要
2.shutdownシャットダウン方法を
達成するための3.shutdownInnerの方法
4.CloseDialogReceiverは、放送シャットダウン]ダイアログボックス登録
シャットダウン]ダイアログボックスを表示5.new sConfirmDialog
シャットダウンプロセスを開始6.beginShutdownSequenceを
進捗ダイアログを披露7.showShutdownDialog
SystemUIRebootかどうかを判断8.
9.、スレッドを始めるRunメソッド実行
10.shutdownRadios閉じるラジオが実装
11.rebootOrShutdownの初期化をシャットダウンまたは再起動することを決定し
、シャットダウンログ分析を12
1.ShutdownThread概要
シャットダウンスレッドの実装クラス
Android
シャットダウンスレッドの実装クラスframeworks/base/services/core/java/com/android/server/power/ShutdownThread.java
ShutdownThread一般的なプロセス
次のように静的変数の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;
... ...
}
引数なしのコンストラクタShutdownThread
private ShutdownThread() {
}
2.シャットダウンシャットダウン方法
・パワー・キーを押して呼び出すための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
}
3.shutdownInner達成する方法
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
4.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);
}
}
5.新しい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() {
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();
6.シャットダウンプロセスを開始beginShutdownSequence
beginShutdownSequence
次のように一連の処理をオフに起動し、主な機能は以下のとおりです
。1.表示シャットダウンプログレスバーダイアログ。
2. [スタート] ShutdownThead
スレッド。
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
Log.d(TAG, "Shutdown sequence already running, returning.");
return;
}
sIsStarted = true;
}
// 显示关机进度对话框 详见 7
sInstance.mProgressDialog = showShutdownDialog(context);
sInstance.mContext = context;
sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
// make sure we never fall asleep again
sInstance.mCpuWakeLock = null;
try {
sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu");
sInstance.mCpuWakeLock.setReferenceCounted(false);
sInstance.mCpuWakeLock.acquire();
} catch (SecurityException e) {
Log.w(TAG, "No permission to acquire wake lock", e);
sInstance.mCpuWakeLock = null;
}
// also make sure the screen stays on for better user experience
sInstance.mScreenWakeLock = null;
if (sInstance.mPowerManager.isScreenOn()) {
try {
sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(
PowerManager.FULL_WAKE_LOCK, TAG + "-screen");
sInstance.mScreenWakeLock.setReferenceCounted(false);
sInstance.mScreenWakeLock.acquire();
} catch (SecurityException e) {
Log.w(TAG, "No permission to acquire wake lock", e);
sInstance.mScreenWakeLock = null;
}
}
if (SecurityLog.isLoggingEnabled()) {
SecurityLog.writeEvent(SecurityLog.TAG_OS_SHUTDOWN);
}
// 启动 关机线程 ,执行 Run 方法,详见 9
sInstance.mHandler = new Handler() {
};
sInstance.start();
}
進捗ダイアログを披露7.showShutdownDialog
showShutdownDialog
主に進捗ダイアログを誇示するために使用
private static ProgressDialog showShutdownDialog(Context context) {
// Throw up a system dialog to indicate the device is rebooting / shutting down.
ProgressDialog pd = new ProgressDialog(context);
// Path 1: Reboot to recovery for update
// Condition: mReason startswith REBOOT_RECOVERY_UPDATE
//
// Path 1a: uncrypt needed
// Condition: if /cache/recovery/uncrypt_file exists but
// /cache/recovery/block.map doesn't.
// UI: determinate progress bar (mRebootHasProgressBar == True)
//
// * Path 1a is expected to be removed once the GmsCore shipped on
// device always calls uncrypt prior to reboot.
//
// Path 1b: uncrypt already done
// UI: spinning circle only (no progress bar)
//
// Path 2: Reboot to recovery for factory reset
// Condition: mReason == REBOOT_RECOVERY
// UI: spinning circle only (no progress bar)
//
// Path 3: Regular reboot / shutdown
// Condition: Otherwise
// UI: spinning circle only (no progress bar)
// mReason could be "recovery-update" or "recovery-update,quiescent".
if (mReason != null && mReason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
// We need the progress bar if uncrypt will be invoked during the
// reboot, which might be time-consuming.
mRebootHasProgressBar = RecoverySystem.UNCRYPT_PACKAGE_FILE.exists()
&& !(RecoverySystem.BLOCK_MAP_FILE.exists());
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_update_title));
if (mRebootHasProgressBar) {
pd.setMax(100);
pd.setProgress(0);
pd.setIndeterminate(false);
pd.setProgressNumberFormat(null);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage(context.getText(
com.android.internal.R.string.reboot_to_update_prepare));
} else {
if (showSysuiReboot()) {
return null;
}
pd.setIndeterminate(true);
pd.setMessage(context.getText(
com.android.internal.R.string.reboot_to_update_reboot));
}
} else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
if (RescueParty.isAttemptingFactoryReset()) {
// We're not actually doing a factory reset yet; we're rebooting
// to ask the user if they'd like to reset, so give them a less
// scary dialog message.
pd.setTitle(context.getText(com.android.internal.R.string.power_off));
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
} else {
// Factory reset path. Set the dialog message accordingly.
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
pd.setMessage(context.getText(
com.android.internal.R.string.reboot_to_reset_message));
pd.setIndeterminate(true);
}
} else {
// 判断是否显示SystemUIReboot 详见 8
if (showSysuiReboot()) {
return null;
}
// 显示关机 进度对话框 详见 8
pd.setTitle(context.getText(com.android.internal.R.string.power_off));
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
}
pd.setCancelable(false);
pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
pd.show();
return pd;
}
シャットダウン進行状況ダイアログを達成
8. SystemUIRebootか否かを判断します
showSysuiReboot
主に表示するかどうかを示すために使用しますSystemUIReboot
。
private static boolean showSysuiReboot() {
Log.d(TAG, "Attempting to use SysUI shutdown UI");
try {
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
if (service.showShutdownUi(mReboot, mReason)) {
// Sysui will handle shutdown UI.
Log.d(TAG, "SysUI handling shutdown UI");
return true;
}
} catch (Exception e) {
// If anything went wrong, ignore it and use fallback ui
}
Log.d(TAG, "SysUI is unavailable");
return false;
}
9. Runメソッドを実行し、スレッドをオフに起動します
beginShutdownSequence
スレッド方法を発進。
private static void beginShutdownSequence(Context context) {
... ...
// static instance of this thread
private static final ShutdownThread sInstance = new ShutdownThread();
// start the thread that initiates shutdown
sInstance.mHandler = new Handler() {
};
sInstance.start();
... ...
}
ShutdownThreadラン実現
ShutdownThread
主な機能:
1.通常のシャットダウンブロードキャストを送信します。
2.いくつかのプロジェクトの終了時間を測定します。
3.閉じますActivityManager
。
4.閉じますPackageManager
。
5.閉じますRadios
。
6.完全にSystem Server
閉鎖。
7.初期化およびシャットダウンや再起動を決定
/**
* Makes sure we handle the shutdown gracefully.
* Shuts off power regardless of radio state if the allotted time has passed.
*/
public void run() {
TimingsTraceLog shutdownTimingLog = newTimingsLog();
shutdownTimingLog.traceBegin("SystemServerShutdown");
metricShutdownStart();
metricStarted(METRIC_SYSTEM_SERVER);
BroadcastReceiver br = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
// We don't allow apps to cancel this, so ignore the result.
actionDone();
}
};
/*
* 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") + (mReason != null ? mReason : "");
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
}
/*
* If we are rebooting into safe mode, write a system property
* indicating so.
*/
if (mRebootSafeMode) {
SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
}
metricStarted(METRIC_SEND_BROADCAST);
shutdownTimingLog.traceBegin("SendShutdownBroadcast");
Log.i(TAG, "Sending shutdown broadcast...");
// First send the high-level shut down broadcast.
mActionDone = false;
Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
// 发送 有序的 关机广播
mContext.sendOrderedBroadcastAsUser(intent,
UserHandle.ALL, null, br, mHandler, 0, null, null);
final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
synchronized (mActionDoneSync) {
while (!mActionDone) {
long delay = endTime - SystemClock.elapsedRealtime();
if (delay <= 0) {
Log.w(TAG, "Shutdown broadcast timed out");
break;
} else if (mRebootHasProgressBar) {
int status = (int)((MAX_BROADCAST_TIME - delay) * 1.0 *
BROADCAST_STOP_PERCENT / MAX_BROADCAST_TIME);
sInstance.setRebootProgress(status, null);
}
try {
mActionDoneSync.wait(Math.min(delay, ACTION_DONE_POLL_WAIT_MS));
} catch (InterruptedException e) {
}
}
}
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(BROADCAST_STOP_PERCENT, null);
}
// 测量 发送有序 关机广播所用的时间
shutdownTimingLog.traceEnd(); // SendShutdownBroadcast
metricEnded(METRIC_SEND_BROADCAST);
Log.i(TAG, "Shutting down activity manager...");
shutdownTimingLog.traceBegin("ShutdownActivityManager");
metricStarted(METRIC_AM);
// 关闭 Activity Manager
final IActivityManager am =
IActivityManager.Stub.asInterface(ServiceManager.checkService("activity"));
if (am != null) {
try {
am.shutdown(MAX_BROADCAST_TIME);
} catch (RemoteException e) {
}
}
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(ACTIVITY_MANAGER_STOP_PERCENT, null);
}
shutdownTimingLog.traceEnd();// ShutdownActivityManager
metricEnded(METRIC_AM);
Log.i(TAG, "Shutting down package manager...");
shutdownTimingLog.traceBegin("ShutdownPackageManager");
metricStarted(METRIC_PM);
// 关闭 Package Manager
final PackageManagerService pm = (PackageManagerService)
ServiceManager.getService("package");
if (pm != null) {
pm.shutdown();
}
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(PACKAGE_MANAGER_STOP_PERCENT, null);
}
shutdownTimingLog.traceEnd(); // ShutdownPackageManager
metricEnded(METRIC_PM);
// Shutdown radios.
shutdownTimingLog.traceBegin("ShutdownRadios");
metricStarted(METRIC_RADIOS);
//关闭 Radios shutdownRadios 详细 请看 10
shutdownRadios(MAX_RADIO_WAIT_TIME);
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);
}
shutdownTimingLog.traceEnd(); // ShutdownRadios
metricEnded(METRIC_RADIOS);
// 关闭 System Server
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(MOUNT_SERVICE_STOP_PERCENT, null);
// If it's to reboot to install an update and uncrypt hasn't been
// done yet, trigger it now.
uncrypt();
}
shutdownTimingLog.traceEnd(); // SystemServerShutdown
metricEnded(METRIC_SYSTEM_SERVER);
saveMetrics(mReboot, mReason);
//初始化 并判断是关机还是重启 详见 11
rebootOrShutdown(mContext, mReboot, mReason);
}
10.shutdownRadios閉じるラジオ実現
shutdownRadios
近くにphone Radio
主に以下を達成するために、関連コンテンツ:
private void shutdownRadios(final int timeout) {
// If a radio is wedged, disabling it may hang so we do this work in another thread,
// just in case.
final long endTime = SystemClock.elapsedRealtime() + timeout;
final boolean[] done = new boolean[1];
//另起线程 异步关闭 Radios
Thread t = new Thread() {
public void run() {
TimingsTraceLog shutdownTimingsTraceLog = newTimingsLog();
boolean radioOff;
final ITelephony phone =
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
try {
radioOff = phone == null || !phone.needMobileRadioShutdown();
if (!radioOff) {
Log.w(TAG, "Turning off cellular radios...");
metricStarted(METRIC_RADIO);
phone.shutdownMobileRadios();
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during radio shutdown", ex);
radioOff = true;
}
Log.i(TAG, "Waiting for Radio...");
long delay = endTime - SystemClock.elapsedRealtime();
while (delay > 0) {
if (mRebootHasProgressBar) {
int status = (int)((timeout - delay) * 1.0 *
(RADIO_STOP_PERCENT - PACKAGE_MANAGER_STOP_PERCENT) / timeout);
status += PACKAGE_MANAGER_STOP_PERCENT;
sInstance.setRebootProgress(status, null);
}
if (!radioOff) {
try {
radioOff = !phone.needMobileRadioShutdown();
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during radio shutdown", ex);
radioOff = true;
}
if (radioOff) {
Log.i(TAG, "Radio turned off.");
metricEnded(METRIC_RADIO);
shutdownTimingsTraceLog
.logDuration("ShutdownRadio", TRON_METRICS.get(METRIC_RADIO));
}
}
if (radioOff) {
Log.i(TAG, "Radio shutdown complete.");
done[0] = true;
break;
}
SystemClock.sleep(RADIOS_STATE_POLL_SLEEP_MS);
delay = endTime - SystemClock.elapsedRealtime();
}
}
};
//另起线程 异步关闭 Radios
t.start();
try {
t.join(timeout);
} catch (InterruptedException ex) {
}
if (!done[0]) {
Log.w(TAG, "Timed out waiting for Radio shutdown.");
}
}
11.rebootOrShutdownの初期化およびシャットダウンまたは再起動することを決定しました
rebootOrShutdown
主に初期化するために使用され、シャットダウンまたは再起動することを決めました。
/**
* Do not call this directly. Use {@link #reboot(Context, String, boolean)}
* or {@link #shutdown(Context, String, boolean)} instead.
*
* @param context Context used to vibrate or null without vibration
* @param reboot true to reboot or false to shutdown
* @param reason reason for reboot/shutdown
*/
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
String subsysProp;
subsysProp = SystemProperties.get("vendor.peripheral.shutdown_critical_list",
"ERROR");
//If we don't have the shutdown critical subsystem list we can't
//really do anything. Proceed with full system shutdown.
if (!subsysProp.equals("ERROR")) {
Log.i(TAG, "Shutdown critical subsyslist is :"+subsysProp+": ");
Log.i(TAG, "Waiting for a maximum of " +
(VENDOR_SUBSYS_MAX_WAIT_MS) + "ms");
String[] subsysList = subsysProp.split(" ");
int wait_count = 0;
boolean okToShutdown = true;
String subsysState;
int subsysListLength = subsysList.length;
do {
okToShutdown = true;
for (int i = 0; i < subsysListLength; i++) {
subsysState =
SystemProperties.get(
"vendor.peripheral." +
subsysList[i] +
".state",
"ERROR");
if(subsysState.equals("ONLINE")) {
//We only want to delay shutdown while
//one of the shutdown critical
//subsystems still shows as 'ONLINE'.
okToShutdown = false;
}
}
if (okToShutdown == false) {
SystemClock.sleep(VENDOR_SUBSYS_STATE_CHECK_INTERVAL_MS);
wait_count++;
}
} while (okToShutdown != true &&
wait_count < (VENDOR_SUBSYS_MAX_WAIT_MS/VENDOR_SUBSYS_STATE_CHECK_INTERVAL_MS));
if (okToShutdown != true) {
for (int i = 0; i < subsysList.length; i++) {
subsysState =
SystemProperties.get(
"vendor.peripheral." +
subsysList[i] +
".state",
"ERROR");
if(subsysState.equals("ONLINE")) {
Log.w(TAG, "Subsystem " + subsysList[i]+
"did not shut down within timeout");
}
}
} else {
Log.i(TAG, "Vendor subsystem(s) shutdown successful");
}
}
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 down
Vibrator 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) {
}
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown(reason);
}
12.シャットダウンログ解析
リンクすることでadb
、我々はシャットダウンをつかむことができるLog
、の一部Log
は次のような情報は以下のとおりです。
Line 96: 07-26 01:02:26.205 2510 3766 I AudioController: internalShutdown
Line 540: 07-26 01:02:30.968 790 790 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
Line 540: 07-26 01:02:30.968 790 790 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
Line 541: 07-26 01:02:30.970 790 790 D ShutdownThread: Attempting to use SysUI shutdown UI
Line 541: 07-26 01:02:30.970 790 790 D ShutdownThread: Attempting to use SysUI shutdown UI
Line 542: 07-26 01:02:30.971 790 790 D ShutdownThread: SysUI handling shutdown UI
Line 542: 07-26 01:02:30.971 790 790 D ShutdownThread: SysUI handling shutdown UI
Line 555: 07-26 01:02:30.997 790 3902 I ShutdownThread: Sending shutdown broadcast...
Line 555: 07-26 01:02:30.997 790 3902 I ShutdownThread: Sending shutdown broadcast...
Line 561: 07-26 01:02:31.014 790 790 W SyncManager: Writing sync state before shutdown...
Line 666: 07-26 01:02:31.436 2510 3766 I AudioController: internalShutdown
Line 669: 07-26 01:02:31.443 790 790 I StatsCompanionService: StatsCompanionService noticed a shutdown.
Line 708: 07-26 01:02:31.671 790 3902 D ShutdownTiming: SendShutdownBroadcast took to complete: 675ms
Line 708: 07-26 01:02:31.671 790 3902 D ShutdownTiming: SendShutdownBroadcast took to complete: 675ms
Line 711: 07-26 01:02:31.671 790 3902 I ShutdownThread: Shutting down activity manager...
Line 740: 07-26 01:02:31.954 790 3902 W AppOps : Writing app ops before shutdown...
Line 771: 07-26 01:02:32.152 790 3902 W BatteryStats: Writing battery stats before shutdown...
Line 806: 07-26 01:02:32.386 790 1015 W system_server: Long monitor contention with owner Thread-29 (3902) at void com.android.server.am.BatteryStatsService.shutdown()(BatteryStatsService.java:249) waiters=0 in void com.android.server.am.BatteryStatsService.noteProcessStart(java.lang.String, int) for 132ms
Line 840: 07-26 01:02:32.507 790 3902 W ProcessStatsService: Writing process stats before shutdown...
Line 850: 07-26 01:02:32.563 790 3902 D ShutdownTiming: ShutdownActivityManager took to complete: 891ms
Line 850: 07-26 01:02:32.563 790 3902 D ShutdownTiming: ShutdownActivityManager took to complete: 891ms
Line 853: 07-26 01:02:32.563 790 3902 I ShutdownThread: Shutting down package manager...
Line 872: 07-26 01:02:32.656 790 3902 D ShutdownTiming: ShutdownPackageManager took to complete: 93ms
Line 872: 07-26 01:02:32.656 790 3902 D ShutdownTiming: ShutdownPackageManager took to complete: 93ms
Line 879: 07-26 01:02:32.677 1804 1976 V PhoneInterfaceManager: [PhoneIntfMgr] 1 Phones are shutdown.
Line 882: 07-26 01:02:32.678 790 3951 I ShutdownThread: Waiting for Radio...
Line 883: 07-26 01:02:32.679 790 3951 I ShutdownThread: Radio shutdown complete.
Line 883: 07-26 01:02:32.679 790 3951 I ShutdownThread: Radio shutdown complete.
Line 884: 07-26 01:02:32.681 790 3902 D ShutdownTiming: ShutdownRadios took to complete: 25ms
Line 884: 07-26 01:02:32.681 790 3902 D ShutdownTiming: ShutdownRadios took to complete: 25ms
Line 885: 07-26 01:02:32.681 790 3902 D ShutdownTiming: SystemServerShutdown took to complete: 1705ms
Line 885: 07-26 01:02:32.681 790 3902 D ShutdownTiming: SystemServerShutdown took to complete: 1705ms
Line 886: 07-26 01:02:32.684 790 3902 I ShutdownThread: Shutdown critical subsyslist is :modem :
Line 886: 07-26 01:02:32.684 790 3902 I ShutdownThread: Shutdown critical subsyslist is :modem :
Line 887: 07-26 01:02:32.684 790 3902 I ShutdownThread: Waiting for a maximum of 10000ms
Line 888: 07-26 01:02:32.684 790 3902 I ShutdownThread: Vendor subsystem(s) shutdown successful
Line 888: 07-26 01:02:32.684 790 3902 I ShutdownThread: Vendor subsystem(s) shutdown successful
Line 931: 07-26 01:02:33.192 790 3902 I ShutdownThread: Performing low-level shutdown...
Line 931: 07-26 01:02:33.192 790 3902 I ShutdownThread: Performing low-level shutdown...
Line 1003: 07-26 01:02:33.543 565 585 E Dpps : ProcessAlMsg():471 Shutdown event recieved quit -108
Line 1005: 07-26 01:02:33.543 565 585 I Dpps : ProcessNextEvent():142 Shutdown notification quit processing
Line 1009: 07-26 01:02:33.562 565 583 E Dpps : ProcessAbaMsg():579 Shutdown event recieved quit -108
間違った場所、あなたの提案や修正を歓迎している場合これまでのところ、本明細書に、これは、終了しました。同時に、あなたの注意を楽しみにして、お読みいただきありがとうございました、ありがとうございました!