安卓关机和重启源码流程
// systemui关机
frameworks/base/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@Override
public void shutdown() {
try {
mBarService.shutdown();
} catch (RemoteException e) {
}
}
frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@Override
public void shutdown() {
enforceStatusBarService();
// 原因为:userrequested
String reason = PowerManager.SHUTDOWN_USER_REQUESTED;
ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
final long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.prepareForPossibleShutdown();
// ShutdownThread displays UI, so give it a UI context.
// 调用ShutdownThread.shutdown,传入参数为 false
mHandler.post(() ->
ShutdownThread.shutdown(getUiContext(), reason, false));
} finally {
Binder.restoreCallingIdentity(identity);
}
}
// 调用ShutdownThread.shutdown,传入参数为 false
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
public static void shutdown(final Context context, String reason, boolean confirm) {
mReboot = false;
mRebootSafeMode = false;
mReason = reason;
// confirm 为false
shutdownInner(context, confirm);
}
// 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();
// ensure that only one thread is trying to power down.
// any additional calls are just returned
synchronized (sIsStartedGuard) {
if (sIsStarted) {
if (DEBUG) {
Log.d(TAG, "Request to shutdown already running, returning.");
}
return;
}
}
// Add checkpoint for this shutdown attempt. The user might still cancel the dialog, but
// this point preserves the system trace of the trigger point of the ShutdownThread.
// 会记录是哪个进程调用shutdown 关机的
ShutdownCheckPoints.recordCheckPoint(/* reason= */ null);
// 关于关机重启的dialog
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);
if (DEBUG) {
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
}
// confirm 为false,不启动dialog
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();
closer.dialog = sConfirmDialog;
sConfirmDialog.setOnDismissListener(closer);
sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
sConfirmDialog.show();
} else {
// 调用 beginShutdownSequence
beginShutdownSequence(context);
}
}
// 调用 beginShutdownSequence
private static final ShutdownThread sInstance = new ShutdownThread();
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
if (DEBUG) {
Log.d(TAG, "Shutdown sequence already running, returning.");
}
return;
}
sIsStarted = true;
}
// sInstance 是 ShutdownThread
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 {
// 让cpu 不睡眠,亮屏
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);
}
// start the thread that initiates shutdown
sInstance.mHandler = new Handler() {
};
// 启动 ShutdownThread 线程
sInstance.start();
}
// 启动 ShutdownThread 线程
public void run() {
TimingsTraceLog shutdownTimingLog = newTimingsLog();
shutdownTimingLog.traceBegin("SystemServerShutdown");
metricShutdownStart();
metricStarted(METRIC_SYSTEM_SERVER);
// 保存关机的信息,前面调用了 recordCheckPoint,保存关机的调用栈
// Start dumping check points for this shutdown in a separate thread.
Thread dumpCheckPointsThread = ShutdownCheckPoints.newDumpThread(
new File(CHECK_POINTS_FILE_BASENAME));
dumpCheckPointsThread.start();
/*
* 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");
}
shutdownTimingLog.traceBegin("DumpPreRebootInfo");
try {
Slog.i(TAG, "Logging pre-reboot information...");
PreRebootLogger.log(mContext);
} catch (Exception e) {
Slog.e(TAG, "Failed to log pre-reboot information", e);
}
shutdownTimingLog.traceEnd(); // DumpPreRebootInfo
metricStarted(METRIC_SEND_BROADCAST);
shutdownTimingLog.traceBegin("SendShutdownBroadcast");
Log.i(TAG, "Sending shutdown broadcast...");
// First send the high-level shut down broadcast.
mActionDone = false;
// 发送关机广播,只能是前台receiver和注册广播类型
Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
final Bundle opts = BroadcastOptions.makeBasic()
.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
.toBundle();
final ActivityManagerInternal activityManagerInternal = LocalServices.getService(
ActivityManagerInternal.class);
// 设置广播 回调 this::actionDone
activityManagerInternal.broadcastIntentWithCallback(intent,
new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
mHandler.post(ShutdownThread.this::actionDone);
}
}, null, UserHandle.USER_ALL, null, null, opts);
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 {
// 等待处理完关机广播,等待 500ms
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);
final IActivityManager am =
IActivityManager.Stub.asInterface(ServiceManager.checkService("activity"));
if (am != null) {
try {
// 1)调用AMS 的 shutdown 方法
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);
final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
if (pm != null) {
// 关闭 packagemanagerservice
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);
// 2)关闭radio:shutdownRadios
shutdownRadios(MAX_RADIO_WAIT_TIME);
if (mRebootHasProgressBar) {
sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);
}
shutdownTimingLog.traceEnd(); // ShutdownRadios
metricEnded(METRIC_RADIOS);
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();
}
// Wait for the check points dump thread to finish, or kill it if not finished in time.
shutdownTimingLog.traceBegin("ShutdownCheckPointsDumpWait");
try {
dumpCheckPointsThread.join(MAX_CHECK_POINTS_DUMP_WAIT_TIME);
} catch (InterruptedException ex) {
}
shutdownTimingLog.traceEnd(); // ShutdownCheckPointsDumpWait
shutdownTimingLog.traceEnd(); // SystemServerShutdown
metricEnded(METRIC_SYSTEM_SERVER);
saveMetrics(mReboot, mReason);
// Remaining work will be done by init, including vold shutdown
// 3)调用 rebootOrShutdown 方法
rebootOrShutdown(mContext, mReboot, mReason);
}
// 1)调用AMS 的 shutdown 方法
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
7150 @Override
7151 public boolean shutdown(int timeout) {
7152 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7153 != PackageManager.PERMISSION_GRANTED) {
7154 throw new SecurityException("Requires permission "
7155 + android.Manifest.permission.SHUTDOWN);
7156 }
7157
/// 主要调用了 ActivityTaskManagerService 的 shuttingDown,去保存最近的任务状态
7158 final boolean timedout = mAtmInternal.shuttingDown(mBooted, timeout);
7159
7160 mAppOpsService.shutdown();
7161 if (mUsageStatsService != null) {
7162 mUsageStatsService.prepareShutdown();
7163 }
7164 mBatteryStatsService.shutdown();
7165 mProcessStats.shutdown();
7166
7167 return timedout;
7168 }
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
6045 @Override
6046 public boolean shuttingDown(boolean booted, int timeout) {
6047 mShuttingDown = true;
6048 synchronized (mGlobalLock) {
6049 mRootWindowContainer.prepareForShutdown();
// 设置不接受input
6050 updateEventDispatchingLocked(booted);
// 关于最近任务持久化
6051 notifyTaskPersisterLocked(null, true);
// 设置activity走pause流程
6052 return mTaskSupervisor.shutdownLocked(timeout);
6053 }
6054 }
// 2)关闭radio:shutdownRadios
625 private void shutdownRadios(final int timeout) {
626 // If a radio is wedged, disabling it may hang so we do this work in another thread,
627 // just in case.
628 final long endTime = SystemClock.elapsedRealtime() + timeout;
629 final boolean[] done = new boolean[1];
630 Thread t = new Thread() {
631 public void run() {
632 TimingsTraceLog shutdownTimingsTraceLog = newTimingsLog();
633 boolean radioOff;
634
635 TelephonyManager telephonyManager = mContext.getSystemService(
636 TelephonyManager.class);
637
638 radioOff = telephonyManager == null
639 || !telephonyManager.isAnyRadioPoweredOn();
640 if (!radioOff) {
641 Log.w(TAG, "Turning off cellular radios...");
642 metricStarted(METRIC_RADIO);
// 调用 TelephonyManager 的 shutdownAllRadios 方法
643 telephonyManager.shutdownAllRadios();
644 }
645
646 Log.i(TAG, "Waiting for Radio...");
647
648 long delay = endTime - SystemClock.elapsedRealtime();
649 while (delay > 0) {
650 if (mRebootHasProgressBar) {
651 int status = (int)((timeout - delay) * 1.0 *
652 (RADIO_STOP_PERCENT - PACKAGE_MANAGER_STOP_PERCENT) / timeout);
653 status += PACKAGE_MANAGER_STOP_PERCENT;
654 sInstance.setRebootProgress(status, null);
655 }
656
657 if (!radioOff) {
// 需要满足 isAnyRadioPoweredOn
658 radioOff = !telephonyManager.isAnyRadioPoweredOn();
659 if (radioOff) {
660 Log.i(TAG, "Radio turned off.");
661 metricEnded(METRIC_RADIO);
662 shutdownTimingsTraceLog
663 .logDuration("ShutdownRadio", TRON_METRICS.get(METRIC_RADIO));
664 }
665 }
666
667 if (radioOff) {
668 Log.i(TAG, "Radio shutdown complete.");
669 done[0] = true;
670 break;
671 }
672 SystemClock.sleep(RADIOS_STATE_POLL_SLEEP_MS);
673 delay = endTime - SystemClock.elapsedRealtime();
674 }
675 }
676 };
677
678 t.start();
679 try {
680 t.join(timeout);
681 } catch (InterruptedException ex) {
682 }
683 if (!done[0]) {
684 Log.w(TAG, "Timed out waiting for Radio shutdown.");
685 }
686 }
// 3)调用 rebootOrShutdown 方法
696 public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
// 如果是重启,则会打印下列的log Rebooting, reason
697 if (reboot) {
698 Log.i(TAG, "Rebooting, reason: " + reason);
699 PowerManagerService.lowLevelReboot(reason);
700 Log.e(TAG, "Reboot failed, will attempt shutdown instead");
701 reason = null;
// 振动为 500毫秒,这里先振动
702 } else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
703 // vibrate before shutting down
704 Vibrator vibrator = new SystemVibrator(context);
705 try {
706 if (vibrator.hasVibrator()) {
707 vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES);
708 // vibrator is asynchronous so we need to wait to avoid shutting down too soon.
709 try {
710 Thread.sleep(SHUTDOWN_VIBRATE_MS);
711 } catch (InterruptedException unused) {
712 // this is not critical and does not require logging
713 }
714 }
715 } catch (Exception e) {
716 // Failure to vibrate shouldn't interrupt shutdown. Just log it.
717 Log.w(TAG, "Failed to vibrate during shutdown.", e);
718 }
719
720 }
721 // Shutdown power
// 关机会打印下列delog
722 Log.i(TAG, "Performing low-level shutdown...");
// 关机调用下列的方法
723 PowerManagerService.lowLevelShutdown(reason);
724 }
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
4468 public static void lowLevelShutdown(String reason) {
4469 if (reason == null) {
4470 reason = "";
4471 }
/// sprd这里增加了判断是否在充电,charging
// 这里直接去设置个属性,设置关机,reason为 userrequest,会设置到init 进程
4472 SystemProperties.set("sys.powerctl", "shutdown," + reason);
4473 }
//reboot重启的流程为:
4482 public static void lowLevelReboot(String reason) {
4483 if (reason == null) {
4484 reason = "";
4485 }
4486
4487 // If the reason is "quiescent", it means that the boot process should proceed
4488 // without turning on the screen/lights.
4489 // The "quiescent" property is sticky, meaning that any number
4490 // of subsequent reboots should honor the property until it is reset.
4491 if (reason.equals(PowerManager.REBOOT_QUIESCENT)) {
4492 sQuiescent = true;
4493 reason = "";
4494 } else if (reason.endsWith("," + PowerManager.REBOOT_QUIESCENT)) {
4495 sQuiescent = true;
4496 reason = reason.substring(0,
4497 reason.length() - PowerManager.REBOOT_QUIESCENT.length() - 1);
4498 }
4499
4500 if (reason.equals(PowerManager.REBOOT_RECOVERY)
4501 || reason.equals(PowerManager.REBOOT_RECOVERY_UPDATE)) {
4502 reason = "recovery";
4503 }
4504
4505 if (sQuiescent) {
4506 // Pass the optional "quiescent" argument to the bootloader to let it know
4507 // that it should not turn the screen/lights on.
4508 if (!"".equals(reason)) {
4509 reason += ",";
4510 }
4511 reason = reason + "quiescent";
4512 }
4513
// 重启发送的是:"sys.powerctl", "reboot,"
4514 SystemProperties.set("sys.powerctl", "reboot," + reason);
4515 try {
4516 Thread.sleep(20 * 1000L);
4517 } catch (InterruptedException e) {
4518 Thread.currentThread().interrupt();
4519 }
4520 Slog.wtf(TAG, "Unexpected return from lowLevelReboot!");
4521 }
// 系统进程是通过 system_property_set 提供的接口,与 property_service socket 通信
/xref/bionic/libc/bionic/system_property_set.cpp
247 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
248 int __system_property_set(const char* key, const char* value) {
249 if (key == nullptr) return -1;
250 if (value == nullptr) value = "";
251
252 if (g_propservice_protocol_version == 0) {
253 detect_protocol_version();
254 }
。。。
256 if (g_propservice_protocol_version == kProtocolVersion1) {
。。。。
266
267 return send_prop_msg(&msg);
268 } else {
// 使用的是新的版本
// 版本是通过 getprop获取到const char* kServiceVersionPropertyName = "ro.property_service.version";
269 // New protocol only allows long values for ro. properties only.
270 if (strlen(value) >= PROP_VALUE_MAX && strncmp(key, "ro.", 3) != 0) return -1;
271 // Use proper protocol
// 创建 PropertyServiceConnection 对象,进行socket 通信
272 PropertyServiceConnection connection;
273 if (!connection.IsValid()) {
274 errno = connection.GetLastError();
275 async_safe_format_log(
276 ANDROID_LOG_WARN, "libc",
277 "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", key, value,
278 errno, strerror(errno));
279 return -1;
280 }
281
282 SocketWriter writer(&connection);
// 通过socket 去发送消息
283 if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
284 errno = connection.GetLastError();
285 async_safe_format_log(ANDROID_LOG_WARN, "libc",
286 "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
287 key, value, errno, strerror(errno));
288 return -1;
289 }
290
291 int result = -1;
292 if (!connection.RecvInt32(&result)) {
293 errno = connection.GetLastError();
294 async_safe_format_log(ANDROID_LOG_WARN, "libc",
295 "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
296 key, value, errno, strerror(errno));
297 return -1;
298 }
299
300 if (result != PROP_SUCCESS) {
301 async_safe_format_log(ANDROID_LOG_WARN, "libc",
302 "Unable to set property \"%s\" to \"%s\": error code: 0x%x", key, value,
303 result);
304 return -1;
305 }
// 创建 PropertyServiceConnection 对象,进行socket 通信
51 static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
52 static const char* kServiceVersionPropertyName = "ro.property_service.version";
53
54 class PropertyServiceConnection {
55 public:
56 PropertyServiceConnection() : last_error_(0) {
57 socket_.reset(::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0));
58 if (socket_.get() == -1) {
59 last_error_ = errno;
60 return;
61 }
62
63 const size_t namelen = strlen(property_service_socket);
64 sockaddr_un addr;
65 memset(&addr, 0, sizeof(addr));
// 构造方法中会去socket 通信:property_service_socket为 "/dev/socket/" PROP_SERVICE_NAME
66 strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path));
67 addr.sun_family = AF_LOCAL;
68 socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
69
70 if (TEMP_FAILURE_RETRY(connect(socket_.get(),
71 reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
72 last_error_ = errno;
73 socket_.reset();
74 }
75 }
// property_service 的启动
/android-14.0.0_r21/xref/system/core/init/property_service.cpp
// 在init 初始化的时候,在第二个阶段会StartPropertyService
1485 void StartPropertyService(int* epoll_socket) {
// 初始化 "ro.property_service.version" 的值为 2,前面 system_property_set 会去获取
1486 InitPropertySet("ro.property_service.version", "2");
1487
1488 int sockets[2];
// 创建socket,这里是和init 通信
1489 if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) {
1490 PLOG(FATAL) << "Failed to socketpair() between property_service and init";
1491 }
1492 *epoll_socket = from_init_socket = sockets[0];
1493 init_socket = sockets[1];
1494 StartSendingMessages();
1495
// 创建与 PROP_SERVICE 的socket通信
1496 if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1497 /*passcred=*/false, /*should_listen=*/false, 0666, /*uid=*/0,
1498 /*gid=*/0, /*socketcon=*/{});
1499 result.ok()) {
// 保存fd 值
1500 property_set_fd = *result;
1501 } else {
1502 LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
1503 }
1504
1505 listen(property_set_fd, 8);
1506
// 创建 PropertyServiceThread 线程
1507 auto new_thread = std::thread{PropertyServiceThread};
1508 property_service_thread.swap(new_thread);
1509
1510 auto async_persist_writes =
1511 android::base::GetBoolProperty("ro.property_service.async_persist_writes", false);
1512
1513 if (async_persist_writes) {
1514 persist_write_thread = std::make_unique<PersistWriteThread>();
1515 }
1516 }
// PropertyServiceThread 线程
1422 static void PropertyServiceThread() {
1423 Epoll epoll;
1424 if (auto result = epoll.Open(); !result.ok()) {
1425 LOG(FATAL) << result.error();
1426 }
1427
// 监听 与 PROP_SERVICE的socket 通信,会回调 handle_property_set_fd
1428 if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);
1429 !result.ok()) {
1430 LOG(FATAL) << result.error();
1431 }
1432
// 监听与init 的socket 通信
1433 if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
1434 LOG(FATAL) << result.error();
1435 }
1436
1437 while (true) {
1438 auto epoll_result = epoll.Wait(std::nullopt);
1439 if (!epoll_result.ok()) {
1440 LOG(ERROR) << epoll_result.error();
1441 }
1442 }
1443 }
// property的设置有变化,则回调 handle_property_set_fd
SystemProperties.set(“sys.powerctl”, “shutdown,” + reason);
SystemProperties.set(“sys.powerctl”, “reboot,” + reason);
582 static void handle_property_set_fd() {
583 static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */
584
585 int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);
586 if (s == -1) {
587 return;
588 }
589
590 ucred cr;
591 socklen_t cr_size = sizeof(cr);
592 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
593 close(s);
594 PLOG(ERROR) << "sys_prop: unable to get SO_PEERCRED";
595 return;
596 }
597
598 SocketConnection socket(s, cr);
// 超时时间为 2 秒
599 uint32_t timeout_ms = kDefaultSocketTimeout;
600
601 uint32_t cmd = 0;
602 if (!socket.RecvUint32(&cmd, &timeout_ms)) {
603 PLOG(ERROR) << "sys_prop: error while reading command from the socket";
604 socket.SendUint32(PROP_ERROR_READ_CMD);
605 return;
606 }
608 switch (cmd) {
。。。
639 case PROP_MSG_SETPROP2: {
640 std::string name;
641 std::string value;
// 获取到name 和value
642 if (!socket.RecvString(&name, &timeout_ms) ||
643 !socket.RecvString(&value, &timeout_ms)) {
644 PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP2): error while reading name/value from the socket";
645 socket.SendUint32(PROP_ERROR_READ_DATA);
646 return;
647 }
648
649 std::string source_context;
650 if (!socket.GetSourceContext(&source_context)) {
651 PLOG(ERROR) << "Unable to set property '" << name << "': getpeercon() failed";
652 socket.SendUint32(PROP_ERROR_PERMISSION_DENIED);
653 return;
654 }
655
656 // HandlePropertySet takes ownership of the socket if the set is handled asynchronously.
657 const auto& cr = socket.cred();
658 std::string error;
// 处理 name 和value:HandlePropertySet
659 auto result = HandlePropertySet(name, value, source_context, cr, &socket, &error);
660 if (!result) {
661 // Result will be sent after completion.
662 return;
663 }
664 if (*result != PROP_SUCCESS) {
665 LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid
666 << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
667 }
668 socket.SendUint32(*result);
669 break;
670 }
// 处理 name 和value:HandlePropertySet
529 std::optional<uint32_t> HandlePropertySet(const std::string& name, const std::string& value,
530 const std::string& source_context, const ucred& cr,
531 SocketConnection* socket, std::string* error) {
532 if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {
533 return {ret};
534 }
535
// 如果是 ctl. 开头,则执行 SendControlMessage
536 if (StartsWith(name, "ctl.")) {
537 return {SendControlMessage(name.c_str() + 4, value, cr.pid, socket, error)};
538 }
539
540 // sys.powerctl is a special property that is used to make the device reboot. We want to log
541 // any process that sets this property to be able to accurately blame the cause of a shutdown.
// 满足下列条件:"sys.powerctl"
542 if (name == "sys.powerctl") {
// cr.pid 获取的是调用端的pid,cmdline_path 获取到对应pid进程的进程名
// todo: 待追踪 cr.pid的赋值
543 std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);
544 std::string process_cmdline;
545 std::string process_log_string;
546 if (ReadFileToString(cmdline_path, &process_cmdline)) {
547 // Since cmdline is null deliminated, .c_str() conveniently gives us just the process
548 // path.
549 process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());
550 }
// 会打印下列的log:
551 LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
552 << process_log_string;
553 if (value == "reboot,userspace" && !is_userspace_reboot_supported().value_or(false)) {
554 *error = "Userspace reboot is not supported by this device";
555 return {PROP_ERROR_INVALID_VALUE};
556 }
557 }
558
// 不满足name 为 kRestoreconProperty
563 if (name == kRestoreconProperty && cr.pid != 1 && !value.empty()) {
564 static AsyncRestorecon async_restorecon;
565 async_restorecon.TriggerRestorecon(value);
566 return {PROP_SUCCESS};
567 }
568
// 调用 PropertySet 方法
569 return PropertySet(name, value, socket, error);
570 }
// 调用 PropertySet 方法
383 static std::optional<uint32_t> PropertySet(const std::string& name, const std::string& value,
384 SocketConnection* socket, std::string* error) {
385 size_t valuelen = value.size();
386
// 判断name 和value 是否合法
387 if (!IsLegalPropertyName(name)) {
388 *error = "Illegal property name";
389 return {PROP_ERROR_INVALID_NAME};
390 }
391
392 if (auto result = IsLegalPropertyValue(name, value); !result.ok()) {
393 *error = result.error().message();
394 return {PROP_ERROR_INVALID_VALUE};
395 }
396
// 保存到 __system_property
397 prop_info* pi = (prop_info*)__system_property_find(name.c_str());
398 if (pi != nullptr) {
399 // ro.* properties are actually "write-once".
400 if (StartsWith(name, "ro.")) {
401 *error = "Read-only property was already set";
402 return {PROP_ERROR_READ_ONLY_PROPERTY};
403 }
404
405 __system_property_update(pi, value.c_str(), valuelen);
406 } else {
407 int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
408 if (rc < 0) {
409 *error = "__system_property_add failed";
410 return {PROP_ERROR_SET_FAILED};
411 }
412 }
413
414 // Don't write properties to disk until after we have read all default
415 // properties to prevent them from being overwritten by default values.
// 如果是persist 属性,则缓存到 "/data/property/persistent_properties"
416 if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
417 if (persist_write_thread) {
418 persist_write_thread->Write(name, value, std::move(*socket));
419 return {};
420 }
421 WritePersistentProperty(name, value);
422 }
423
// 通知到属性变化
424 NotifyPropertyChange(name, value);
425 return {PROP_SUCCESS};
426 }
185 void NotifyPropertyChange(const std::string& name, const std::string& value) {
186 // If init hasn't started its main loop, then it won't be handling property changed messages
187 // anyway, so there's no need to try to send them.
188 auto lock = std::lock_guard{accept_messages_lock};
// 在执行reboot 重启或者关机,StopSendingMessages 会设置 accept_messages为false
189 if (accept_messages) {
190 PropertyChanged(name, value);
191 }
192 }
/system/core/init/init.cpp
363 void PropertyChanged(const std::string& name, const std::string& value) {
364 // If the property is sys.powerctl, we bypass the event queue and immediately handle it.
365 // This is to ensure that init will always and immediately shutdown/reboot, regardless of
366 // if there are other pending events to process or if init is waiting on an exec service or
367 // waiting on a property.
368 // In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific
369 // commands to be executed.
// 满足下列条件,"sys.powerctl",回调 trigger_shutdown 方法
370 if (name == "sys.powerctl") {
371 trigger_shutdown(value);
372 }
373
374 if (property_triggers_enabled) {
// 去增加属性变化
375 ActionManager::GetInstance().QueuePropertyChange(name, value);
376 WakeMainInitThread();
377 }
378
379 prop_waiter_state.CheckAndResetWait(name, value);
380 }
// 回调 trigger_shutdown 方法,传入参数是value,为shutdown或者reboot
trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); };
236 static class ShutdownState {
237 public:
238 void TriggerShutdown(const std::string& command) {
239 // We can't call HandlePowerctlMessage() directly in this function,
240 // because it modifies the contents of the action queue, which can cause the action queue
241 // to get into a bad state if this function is called from a command being executed by the
242 // action queue. Instead we set this flag and ensure that shutdown happens before the next
243 // command is run in the main init loop.
244 auto lock = std::lock_guard{shutdown_command_lock_};
// 缓存value 的值
245 shutdown_command_ = command;
// 设置 do_shutdown_ = true
246 do_shutdown_ = true;
// 唤醒init 主线程
247 WakeMainInitThread();
248 }
// 通过 CheckShutdown 可以获取到 shutdown_command_ 值
250 std::optional<std::string> CheckShutdown() __attribute__((warn_unused_result)) {
251 auto lock = std::lock_guard{shutdown_command_lock_};
252 if (do_shutdown_ && !IsShuttingDown()) {
253 do_shutdown_ = false;
254 return shutdown_command_;
255 }
256 return {};
257 }
153 static void WakeMainInitThread() {
154 uint64_t counter = 1;
155 TEMP_FAILURE_RETRY(write(wake_main_thread_fd, &counter, sizeof(counter)));
156 }
// 唤醒init 主线程
912 int SecondStageMain(int argc, char** argv) {
913 if (REBOOT_BOOTLOADER_ON_PANIC) {
914 InstallRebootSignalHandlers();
915 }
916
917 // No threads should be spin up until signalfd
918 // is registered. If the threads are indeed required,
919 // each of these threads _should_ make sure SIGCHLD signal
920 // is blocked. See b/223076262
921 boot_clock::time_point start_time = boot_clock::now();
922
923 trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); };
。。
// 下列方法监听了 wake_main_thread_fd
1005 InstallInitNotifier(&epoll);
。。。
1090 while (true) {
1091 // By default, sleep until something happens. Do not convert far_future into
1092 // std::chrono::milliseconds because that would trigger an overflow. The unit of boot_clock
1093 // is 1ns.
1094 const boot_clock::time_point far_future = boot_clock::time_point::max();
1095 boot_clock::time_point next_action_time = far_future;
1096
// 获取到 shutdown_command
1097 auto shutdown_command = shutdown_state.CheckShutdown();
// 会打印下列log
1098 if (shutdown_command) {
1099 LOG(INFO) << "Got shutdown_command '" << *shutdown_command
1100 << "' Calling HandlePowerctlMessage()";
// 3-1)执行 HandlePowerctlMessage 方法
1101 HandlePowerctlMessage(*shutdown_command);
1102 }
1103
// 前面分析调用了 ResetWaitForPropLocked设置 MightBeWaiting为false;UnSetExec也设置了 is_exec_service_running为false
// 3-2)执行 action命令:ExecuteOneCommand
1104 if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
1105 am.ExecuteOneCommand();
1106 // If there's more work to do, wake up again immediately.
1107 if (am.HasMoreCommands()) {
1108 next_action_time = boot_clock::now();
1109 }
1110 }
1111 // Since the above code examined pending actions, no new actions must be
1112 // queued by the code between this line and the Epoll::Wait() call below
1113 // without calling WakeMainInitThread().
1114 if (!IsShuttingDown()) {
1115 auto next_process_action_time = HandleProcessActions();
1116
1117 // If there's a process that needs restarting, wake up in time for that.
1118 if (next_process_action_time) {
1119 next_action_time = std::min(next_action_time, *next_process_action_time);
1120 }
1121 }
1122
1123 std::optional<std::chrono::milliseconds> epoll_timeout;
1124 if (next_action_time != far_future) {
1125 epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
1126 std::max(next_action_time - boot_clock::now(), 0ns));
1127 }
// epoll 机制在这里wait,前面会唤醒int 主线程;执行while 循环
1128 auto epoll_result = epoll.Wait(epoll_timeout);
1129 if (!epoll_result.ok()) {
1130 LOG(ERROR) << epoll_result.error();
1131 }
1132 if (!IsShuttingDown()) {
1133 HandleControlMessages();
1134 SetUsbController();
1135 }
1136 }
1137
1138 return 0;
1139 }
// 3-1)执行 HandlePowerctlMessage 方法
/android-14.0.0_r21/xref/system/core/init/reboot.cpp
1027 void HandlePowerctlMessage(const std::string& command) {
1028 unsigned int cmd = 0;
1029 std::vector<std::string> cmd_params = Split(command, ",");
1030 std::string reboot_target = "";
1031 bool run_fsck = false;
1032 bool command_invalid = false;
1033 bool userspace_reboot = false;
1034
// 处理关机流程,设置 cmd = ANDROID_RB_POWEROFF
1035 if (cmd_params[0] == "shutdown") {
1036 cmd = ANDROID_RB_POWEROFF;
1037 if (cmd_params.size() >= 2) {
1038 if (cmd_params[1] == "userrequested") {
1039 // The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
1040 // Run fsck once the file system is remounted in read-only mode.
// 也满足下列条件
1041 run_fsck = true;
1042 } else if (cmd_params[1] == "thermal") {
1043 // Turn off sources of heat immediately.
1044 TurnOffBacklight();
1045 // run_fsck is false to avoid delay
1046 cmd = ANDROID_RB_THERMOFF;
1047 }
1048 }
// 处理重启逻辑
1049 } else if (cmd_params[0] == "reboot") {
1050 cmd = ANDROID_RB_RESTART2;
1051 if (cmd_params.size() >= 2) {
1052 reboot_target = cmd_params[1];
1053 if (reboot_target == "userspace") {
1054 LOG(INFO) << "Userspace reboot requested";
1055 userspace_reboot = true;
1056 }
1057 // adb reboot fastboot should boot into bootloader for devices not
1058 // supporting logical partitions.
1059 if (reboot_target == "fastboot" &&
1060 !android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
1061 reboot_target = "bootloader";
1062 }
1063 // When rebooting to the bootloader notify the bootloader writing
1064 // also the BCB.
1065 if (reboot_target == "bootloader") {
1066 std::string err;
1067 if (!write_reboot_bootloader(&err)) {
1068 LOG(ERROR) << "reboot-bootloader: Error writing "
1069 "bootloader_message: "
1070 << err;
1071 }
1072 } else if (reboot_target == "recovery") {
1073 bootloader_message boot = {};
1074 if (std::string err; !read_bootloader_message(&boot, &err)) {
1075 LOG(ERROR) << "Failed to read bootloader message: " << err;
1076 }
1077 // Update the boot command field if it's empty, and preserve
1078 // the other arguments in the bootloader message.
1079 if (!CommandIsPresent(&boot)) {
1080 strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
1081 if (std::string err; !write_bootloader_message(boot, &err)) {
1082 LOG(ERROR) << "Failed to set bootloader message: " << err;
1083 return;
1084 }
1085 }
1086 } else if (reboot_target == "quiescent") {
1087 bootloader_message boot = {};
1088 if (std::string err; !read_bootloader_message(&boot, &err)) {
1089 LOG(ERROR) << "Failed to read bootloader message: " << err;
1090 }
1091 // Update the boot command field if it's empty, and preserve
1092 // the other arguments in the bootloader message.
1093 if (!CommandIsPresent(&boot)) {
1094 strlcpy(boot.command, "boot-quiescent", sizeof(boot.command));
1095 if (std::string err; !write_bootloader_message(boot, &err)) {
1096 LOG(ERROR) << "Failed to set bootloader message: " << err;
1097 return;
1098 }
1099 }
1100 } else if (reboot_target == "sideload" || reboot_target == "sideload-auto-reboot" ||
1101 reboot_target == "fastboot") {
1102 std::string arg = reboot_target == "sideload-auto-reboot" ? "sideload_auto_reboot"
1103 : reboot_target;
1104 const std::vector<std::string> options = {
1105 "--" + arg,
1106 };
1107 std::string err;
1108 if (!write_bootloader_message(options, &err)) {
1109 LOG(ERROR) << "Failed to set bootloader message: " << err;
1110 return;
1111 }
1112 reboot_target = "recovery";
1113 }
1114
1115 // If there are additional parameter, pass them along
1116 for (size_t i = 2; (cmd_params.size() > i) && cmd_params[i].size(); ++i) {
1117 reboot_target += "," + cmd_params[i];
1118 }
1119 }
1120 } else {
1121 command_invalid = true;
1122 }
1123 if (command_invalid) {
1124 LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";
1125 return;
1126 }
1127
1128 // We do not want to process any messages (queue'ing triggers, shutdown messages, control
1129 // messages, etc) from properties during reboot.
// 设置accept_messages = false,init不会处理设置属性了
1130 StopSendingMessages();
1131
1132 if (userspace_reboot) {
1133 HandleUserspaceReboot();
1134 return;
1135 }
1136
// 会打印下列的log
1137 LOG(INFO) << "Clear action queue and start shutdown trigger";
// 先清除所有的event
1138 ActionManager::GetInstance().ClearQueue();
1139 // Queue shutdown trigger first
// 增加shutdown 事件
1140 ActionManager::GetInstance().QueueEventTrigger("shutdown");
1141 // Queue built-in shutdown_done
// 设置 关机方法作为回调方法 DoReboot
1142 auto shutdown_handler = [cmd, command, reboot_target, run_fsck](const BuiltinArguments&) {
// cmd= ANDROID_RB_POWEROFF;command为shutdown,userrequest; reboot_target为空,run_fsck为true
1143 DoReboot(cmd, command, reboot_target, run_fsck);
1144 return Result<void>{};
1145 };
// 给 ActionManager 增加action 事件
1146 ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");
1147
// 进入到关机模式
1148 EnterShutdown();
1149 }
// 进入到关机模式EnterShutdown
802 static void EnterShutdown() {
// 会打印下列的log
803 LOG(INFO) << "Entering shutdown mode";
// 设置 shutting_down = true,可以通过 IsShuttingDown() 获取到
804 shutting_down = true;
805 // Skip wait for prop if it is in progress
806 ResetWaitForProp();
807 // Clear EXEC flag if there is one pending
// 遍历所有的service
808 for (const auto& s : ServiceList::GetInstance()) {
809 s->UnSetExec();
810 }
811 }
/system/core/init/service.h
// 遍历所有的service,设置 is_exec_service_running_ = false
99 void UnSetExec() {
100 is_exec_service_running_ = false;
101 flags_ &= ~SVC_EXEC;
102 }
110 static bool is_exec_service_running() { return is_exec_service_running_; }
// 给 ActionManager 增加action 事件
/system/core/init/action_manager.cpp
57 void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) {
58 auto lock = std::lock_guard{event_queue_lock_};
// 创建 Action 对象,设置 oneshot 为true
59 auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0, name,
60 std::map<std::string, std::string>{});
// 增加命令AddCommand
61 action->AddCommand(std::move(func), {name}, 0);
62
// 将 action 保存到 event_queue_ 和 actions_
63 event_queue_.emplace(action.get());
64 actions_.emplace_back(std::move(action));
65 }
// 创建 Action 对象
99 Action::Action(bool oneshot, Subcontext* subcontext, const std::string& filename, int line,
100 const std::string& event_trigger,
101 const std::map<std::string, std::string>& property_triggers)
102 : property_triggers_(property_triggers),
103 event_trigger_(event_trigger),
104 oneshot_(oneshot),
105 subcontext_(subcontext),
106 filename_(filename),
107 line_(line) {}
// 增加命令AddCommand
126 void Action::AddCommand(BuiltinFunction f, std::vector<std::string>&& args, int line) {
// 将回调函数保存到 commands_
127 commands_.emplace_back(std::move(f), false, std::move(args), line);
128 }
// 前面分析调用了 ResetWaitForPropLocked设置 MightBeWaiting为false;UnSetExec也设置了 is_exec_service_running为false
// 3-2)执行 action命令:ExecuteOneCommand
/system/core/init/action_manager.cpp
67 void ActionManager::ExecuteOneCommand() {
68 {
69 auto lock = std::lock_guard{event_queue_lock_};
70 // Loop through the event queue until we have an action to execute
71 while (current_executing_actions_.empty() && !event_queue_.empty()) {
// 遍历所有的 actions_,这里只有一个
// event_queue_.front() 为 event 参数:CheckEvent调用的是:Action::CheckEvent(const BuiltinAction& builtin_action)
72 for (const auto& action : actions_) {
73 if (std::visit([&action](const auto& event) { return action->CheckEvent(event); },
74 event_queue_.front())) {
// 将 action 保存到 current_executing_actions_
75 current_executing_actions_.emplace(action.get());
76 }
77 }
78 event_queue_.pop();
79 }
80 }
81
82 if (current_executing_actions_.empty()) {
83 return;
84 }
85
86 auto action = current_executing_actions_.front();
87
88 if (current_command_ == 0) {
// 会打印下列log
89 std::string trigger_name = action->BuildTriggersString();
90 LOG(INFO) << "processing action (" << trigger_name << ") from (" << action->filename()
91 << ":" << action->line() << ")";
92 }
93
// 执行 ExecuteOneCommand 方法
94 action->ExecuteOneCommand(current_command_);
95
96 // If this was the last command in the current action, then remove
97 // the action from the executing list.
98 // If this action was oneshot, then also remove it from actions_.
99 ++current_command_;
100 if (current_command_ == action->NumCommands()) {
101 current_executing_actions_.pop();
102 current_command_ = 0;
// action 是 oneshot,执行完去移除它;重新设置 current_command_ = 0
103 if (action->oneshot()) {
104 auto eraser = [&action](std::unique_ptr<Action>& a) { return a.get() == action; };
105 actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser),
106 actions_.end());
107 }
108 }
109 }
// 执行 ExecuteOneCommand 方法
/system/core/init/action.cpp
146 void Action::ExecuteOneCommand(std::size_t command) const {
147 // We need a copy here since some Command execution may result in
148 // changing commands_ vector by importing .rc files through parser
149 Command cmd = commands_[command];
// 获取到第一个 command
150 ExecuteCommand(cmd);
151 }
159 void Action::ExecuteCommand(const Command& command) const {
160 android::base::Timer t;
// 回调 do_reboot 方法
161 auto result = command.InvokeFunc(subcontext_);
162 auto duration = t.duration();
163
164 // Any action longer than 50ms will be warned to user as slow operation
165 if (!result.has_value() || duration > 50ms ||
166 android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
167 std::string trigger_name = BuildTriggersString();
168 std::string cmd_str = command.BuildCommandString();
169
170 LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
171 << ":" << command.line() << ") took " << duration.count() << "ms and "
172 << (result.ok() ? "succeeded" : "failed: " + result.error().message());
173 }
174 }
// InvokeFunc 具体实现
31 Result<void> RunBuiltinFunction(const BuiltinFunction& function,
32 const std::vector<std::string>& args, const std::string& context) {
33 BuiltinArguments builtin_arguments{.context = context};
34
35 builtin_arguments.args.resize(args.size());
36 builtin_arguments.args[0] = args[0];
37 for (std::size_t i = 1; i < args.size(); ++i) {
38 auto expanded_arg = ExpandProps(args[i]);
39 if (!expanded_arg.ok()) {
40 return expanded_arg.error();
41 }
42 builtin_arguments.args[i] = std::move(*expanded_arg);
43 }
44
45 return function(builtin_arguments);
46 }
47
48 Command::Command(BuiltinFunction f, bool execute_in_subcontext, std::vector<std::string>&& args,
49 int line)
50 : func_(std::move(f)),
51 execute_in_subcontext_(execute_in_subcontext),
52 args_(std::move(args)),
53 line_(line) {}
54
55 Result<void> Command::InvokeFunc(Subcontext* subcontext) const {
// subcontext 为空
56 if (subcontext) {
57 if (execute_in_subcontext_) {
58 return subcontext->Execute(args_);
59 }
60
61 auto expanded_args = subcontext->ExpandArgs(args_);
62 if (!expanded_args.ok()) {
63 return expanded_args.error();
64 }
65 return RunBuiltinFunction(func_, *expanded_args, subcontext->context());
66 }
67
68 return RunBuiltinFunction(func_, args_, kInitContext);
69 }
// 执行 DoReboot 方法
// cmd= ANDROID_RB_POWEROFF;command为shutdown,userrequest; reboot_target为空,run_fsck为true
1143 DoReboot(cmd, command, reboot_target, run_fsck);
/system/core/init/reboot.cpp
613 static void DoReboot(unsigned int cmd, const std::string& reason, const std::string& reboot_target,
614 bool run_fsck) {
615 Timer t;
// 会打印下列的log
616 LOG(INFO) << "Reboot start, reason: " << reason << ", reboot_target: " << reboot_target;
617
//cmd 是ANDROID_RB_POWEROFF
618 bool is_thermal_shutdown = cmd == ANDROID_RB_THERMOFF;
619
620 auto shutdown_timeout = 0ms;
621 if (!SHUTDOWN_ZERO_TIMEOUT) {
// 默认的超时时间为 6 秒
622 constexpr unsigned int shutdown_timeout_default = 6;
623 constexpr unsigned int max_thermal_shutdown_timeout = 3;
// 没有
624 auto shutdown_timeout_final = android::base::GetUintProperty("ro.build.shutdown_timeout",
625 shutdown_timeout_default);
626 if (is_thermal_shutdown && shutdown_timeout_final > max_thermal_shutdown_timeout) {
627 shutdown_timeout_final = max_thermal_shutdown_timeout;
628 }
629 shutdown_timeout = std::chrono::seconds(shutdown_timeout_final);
630 }
// 会打印下列的log
631 LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
632
633 sem_t reboot_semaphore;
634 if (sem_init(&reboot_semaphore, false, 0) == -1) {
635 // These should never fail, but if they do, skip the graceful reboot and reboot immediately.
636 LOG(ERROR) << "sem_init() fail and RebootSystem() return!";
637 RebootSystem(cmd, reboot_target, reason);
638 }
639
640 // Start a thread to monitor init shutdown process
641 LOG(INFO) << "Create reboot monitor thread.";
642 bool reboot_monitor_run = true;
// 3-2-1)创建reboot 的监控的线程 RebootMonitorThread
643 std::thread reboot_monitor_thread(&RebootMonitorThread, cmd, reboot_target, &reboot_semaphore,
644 shutdown_timeout, &reboot_monitor_run);
645 reboot_monitor_thread.detach();
646
647 // Start reboot monitor thread
648 sem_post(&reboot_semaphore);
649
650 // Ensure last reboot reason is reduced to canonical
651 // alias reported in bootloader or system boot reason.
652 size_t skip = 0;
653 std::vector<std::string> reasons = Split(reason, ",");
654 if (reasons.size() >= 2 && reasons[0] == "reboot" &&
655 (reasons[1] == "recovery" || reasons[1] == "bootloader" || reasons[1] == "cold" ||
656 reasons[1] == "hard" || reasons[1] == "warm")) {
657 skip = strlen("reboot,");
658 }
// 3-2-2)序列化关机或者重启的原因:PersistRebootReason
659 PersistRebootReason(reason.c_str() + skip, true);
660
661 // If /data isn't mounted then we can skip the extra reboot steps below, since we don't need to
662 // worry about unmounting it.
663 if (!IsDataMounted("*")) {
664 sync();
665 RebootSystem(cmd, reboot_target, reason);
666 abort();
667 }
668
// 是否显示关机动画,这里不去显示
669 bool do_shutdown_animation = GetBoolProperty("ro.init.shutdown_animation", false);
670 // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
671 const std::set<std::string> to_starts{"watchdogd"};
672 std::set<std::string> stop_first;
// 遍历所有的service
673 for (const auto& s : ServiceList::GetInstance()) {
// kDebuggingServices为 {"tombstoned", "logd", "adbd", "console"}
674 if (kDebuggingServices.count(s->name())) {
675 // keep debugging tools until non critical ones are all gone.
676 s->SetShutdownCritical();
// to_starts为 watchdogd,走启动 watchdogd进程的
677 } else if (to_starts.count(s->name())) {
678 if (auto result = s->Start(); !result.ok()) {
679 LOG(ERROR) << "Could not start shutdown 'to_start' service '" << s->name()
680 << "': " << result.error();
681 }
682 s->SetShutdownCritical();
683 } else if (do_shutdown_animation) {
684 continue;
685 } else if (s->IsShutdownCritical()) {
686 // Start shutdown critical service if not started.
687 if (auto result = s->Start(); !result.ok()) {
688 LOG(ERROR) << "Could not start shutdown critical service '" << s->name()
689 << "': " << result.error();
690 }
691 } else {
// 将不是上述的service,增加到 stop_first
692 stop_first.insert(s->name());
693 }
694 }
695
// 如果没有关机动画,则取关闭背光
697 if (!do_shutdown_animation && (cmd == ANDROID_RB_POWEROFF || is_thermal_shutdown)) {
// 3-2-3)关闭背光:TurnOffBacklight
698 TurnOffBacklight();
699 }
700
701 Service* boot_anim = ServiceList::GetInstance().FindService("bootanim");
702 Service* surface_flinger = ServiceList::GetInstance().FindService("surfaceflinger");
703 if (boot_anim != nullptr && surface_flinger != nullptr && surface_flinger->IsRunning()) {
704
// 不启动bootanim
705 if (do_shutdown_animation) {
。。。
730 }
731
732 // optional shutdown step
733 // 1. terminate all services except shutdown critical ones. wait for delay to finish
734 if (shutdown_timeout > 0ms) {
// 3-2-4)发送signal15去中止进程StopServicesAndLogViolations
735 StopServicesAndLogViolations(stop_first, shutdown_timeout / 2, true /* SIGTERM */);
736 }
737 // Send SIGKILL to ones that didn't terminate cleanly.
// 发送sigkill ,kill没有被terminate 的进程
738 StopServicesAndLogViolations(stop_first, 0ms, false /* SIGKILL */);
739 SubcontextTerminate();
740 // Reap subcontext pids.
741 ReapAnyOutstandingChildren();
742
743 // 3. send volume abort_fuse and volume shutdown to vold
// 对vold 进程的处理
744 Service* vold_service = ServiceList::GetInstance().FindService("vold");
745 if (vold_service != nullptr && vold_service->IsRunning()) {
746 // Manually abort FUSE connections, since the FUSE daemon is already dead
747 // at this point, and unmounting it might hang.
748 CallVdc("volume", "abort_fuse");
749 CallVdc("volume", "shutdown");
750 vold_service->Stop();
751 } else {
752 LOG(INFO) << "vold not running, skipping vold shutdown";
753 }
754 // logcat stopped here
// 杀掉 {"tombstoned", "logd", "adbd", "console"} 进程
755 StopServices(kDebuggingServices, 0ms, false /* SIGKILL */);
756 // 4. sync, try umount, and optionally run fsck for user shutdown
757 {
758 Timer sync_timer;
759 LOG(INFO) << "sync() before umount...";
//sync 用于强制被改变的内容立刻写入磁盘,更新超块信息。
760 sync();
761 LOG(INFO) << "sync() before umount took" << sync_timer;
762 }
763 // 5. drop caches and disable zram backing device, if exist
// 处理zram
764 KillZramBackingDevice();
765
// 会打印处理了多久
766 LOG(INFO) << "Ready to unmount apexes. So far shutdown sequence took " << t;
767 // 6. unmount active apexes, otherwise they might prevent clean unmount of /data.
768 if (auto ret = UnmountAllApexes(); !ret.ok()) {
769 LOG(ERROR) << ret.error();
770 }
771 UmountStat stat =
772 TryUmountAndFsck(cmd, run_fsck, shutdown_timeout - t.duration(), &reboot_semaphore);
773 // Follow what linux shutdown is doing: one more sync with little bit delay
774 {
775 Timer sync_timer;
776 LOG(INFO) << "sync() after umount...";
777 sync();
778 LOG(INFO) << "sync() after umount took" << sync_timer;
779 }
780 if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
// 会打印init从收到关机命令到现在的时间powerctl_shutdown_time_ms:11559:0
781 LogShutdownTime(stat, &t);
782
783 // Send signal to terminate reboot monitor thread.
784 reboot_monitor_run = false;
785 sem_post(&reboot_semaphore);
786
787 // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
788 if (IsDataMounted("f2fs")) {
789 uint32_t flag = F2FS_GOING_DOWN_FULLSYNC;
790 unique_fd fd(TEMP_FAILURE_RETRY(open("/data", O_RDONLY)));
791 int ret = ioctl(fd.get(), F2FS_IOC_SHUTDOWN, &flag);
792 if (ret) {
793 PLOG(ERROR) << "Shutdown /data: ";
794 } else {
795 LOG(INFO) << "Shutdown /data";
796 }
797 }
// 3-2-5)重启系统:RebootSystem
798 RebootSystem(cmd, reboot_target, reason);
// 主动退出init进程
799 abort();
800 }
// 3-2-1)创建reboot 的监控的线程 RebootMonitorThread
322 // Create reboot/shutdwon monitor thread
323 void RebootMonitorThread(unsigned int cmd, const std::string& reboot_target,
324 sem_t* reboot_semaphore, std::chrono::milliseconds shutdown_timeout,
325 bool* reboot_monitor_run) {
326 unsigned int remaining_shutdown_time = 0;
327
328 // 300 seconds more than the timeout passed to the thread as there is a final Umount pass
329 // after the timeout is reached.
330 constexpr unsigned int shutdown_watchdog_timeout_default = 300;
331 auto shutdown_watchdog_timeout = android::base::GetUintProperty(
332 "ro.build.shutdown.watchdog.timeout", shutdown_watchdog_timeout_default);
// 为 306 秒,给关机的超时时间为 306秒
333 remaining_shutdown_time = shutdown_watchdog_timeout + shutdown_timeout.count() / 1000;
334
335 while (*reboot_monitor_run == true) {
336 if (TEMP_FAILURE_RETRY(sem_wait(reboot_semaphore)) == -1) {
337 LOG(ERROR) << "sem_wait failed and exit RebootMonitorThread()";
338 return;
339 }
340
341 timespec shutdown_timeout_timespec;
342 if (clock_gettime(CLOCK_MONOTONIC, &shutdown_timeout_timespec) == -1) {
343 LOG(ERROR) << "clock_gettime() fail! exit RebootMonitorThread()";
344 return;
345 }
346
347 // If there are some remaining shutdown time left from previous round, we use
348 // remaining time here.
349 shutdown_timeout_timespec.tv_sec += remaining_shutdown_time;
350
// 会 打印 超时的kernel 时间
351 LOG(INFO) << "shutdown_timeout_timespec.tv_sec: " << shutdown_timeout_timespec.tv_sec;
352
353 int sem_return = 0;
354 while ((sem_return = sem_timedwait_monotonic_np(reboot_semaphore,
355 &shutdown_timeout_timespec)) == -1 &&
356 errno == EINTR) {
357 }
358
// 为-1 则是超时了
359 if (sem_return == -1) {
360 LOG(ERROR) << "Reboot thread timed out";
361
362 if (android::base::GetBoolProperty("ro.debuggable", false) == true) {
363 if (false) {
364 // SEPolicy will block debuggerd from running and this is intentional.
365 // But these lines are left to be enabled during debugging.
366 LOG(INFO) << "Try to dump init process call trace:";
367 const char* vdc_argv[] = {"/system/bin/debuggerd", "-b", "1"};
368 int status;
369 logwrap_fork_execvp(arraysize(vdc_argv), vdc_argv, &status, false, LOG_KLOG,
370 true, nullptr);
371 }
// 收集 CPU 等信息
372 LOG(INFO) << "Show stack for all active CPU:";
373 WriteStringToFile("l", PROC_SYSRQ);
374
375 LOG(INFO) << "Show tasks that are in disk sleep(uninterruptable sleep), which are "
376 "like "
377 "blocked in mutex or hardware register access:";
378 WriteStringToFile("w", PROC_SYSRQ);
379 }
380
381 // In shutdown case,notify kernel to sync and umount fs to read-only before shutdown.
382 if (cmd == ANDROID_RB_POWEROFF || cmd == ANDROID_RB_THERMOFF) {
383 WriteStringToFile("s", PROC_SYSRQ);
384
385 WriteStringToFile("u", PROC_SYSRQ);
386
387 RebootSystem(cmd, reboot_target);
388 }
389
390 LOG(ERROR) << "Trigger crash at last!";
391 WriteStringToFile("c", PROC_SYSRQ);
392 } else {
393 timespec current_time_timespec;
394
395 if (clock_gettime(CLOCK_MONOTONIC, ¤t_time_timespec) == -1) {
396 LOG(ERROR) << "clock_gettime() fail! exit RebootMonitorThread()";
397 return;
398 }
399
// 还有多少时间剩余
400 remaining_shutdown_time =
401 shutdown_timeout_timespec.tv_sec - current_time_timespec.tv_sec;
402
403 LOG(INFO) << "remaining_shutdown_time: " << remaining_shutdown_time;
404 }
405 }
406 }
// 3-2-2)序列化关机或者重启的原因:PersistRebootReason
100 static void PersistRebootReason(const char* reason, bool write_to_property) {
101 if (write_to_property) {
102 SetProperty(LAST_REBOOT_REASON_PROPERTY, reason);
103 }
// "/metadata/bootstat/"
104 auto fd = unique_fd(TEMP_FAILURE_RETRY(open(
105 LAST_REBOOT_REASON_FILE, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, 0666)));
106 if (!fd.ok()) {
107 PLOG(ERROR) << "Could not open '" << LAST_REBOOT_REASON_FILE
108 << "' to persist reboot reason";
109 return;
110 }
111 WriteStringToFd(reason, fd);
112 fsync(fd.get());
113 }
// 3-2-3)关闭背光:TurnOffBacklight
192 // Turn off backlight while we are performing power down cleanup activities.
193 static void TurnOffBacklight() {
194 Service* service = ServiceList::GetInstance().FindService("blank_screen");
195 if (service == nullptr) {
196 LOG(WARNING) << "cannot find blank_screen in TurnOffBacklight";
197 return;
198 }
199 if (auto result = service->Start(); !result.ok()) {
200 LOG(WARNING) << "Could not start blank_screen service: " << result.error();
201 }
202 }
// 3-2-4)发送signal15去中止进程StopServicesAndLogViolations
575 int StopServicesAndLogViolations(const std::set<std::string>& services,
576 std::chrono::milliseconds timeout, bool terminate) {
577 StopServices(services, timeout, terminate);
578 int still_running = 0;
579 for (const auto& s : ServiceList::GetInstance()) {
580 if (s->IsRunning() && services.count(s->name())) {
581 LOG(ERROR) << "[service-misbehaving] : service '" << s->name() << "' is still running "
582 << timeout.count() << "ms after receiving "
583 << (terminate ? "SIGTERM" : "SIGKILL");
584 still_running++;
585 }
586 }
587 return still_running;
588 }
546 static void StopServices(const std::set<std::string>& services, std::chrono::milliseconds timeout,
547 bool terminate) {
// 会打印下列log
548 LOG(INFO) << "Stopping " << services.size() << " services by sending "
549 << (terminate ? "SIGTERM" : "SIGKILL");
550 std::vector<pid_t> pids;
551 pids.reserve(services.size());
552 for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
553 if (services.count(s->name()) == 0) {
554 continue;
555 }
556 if (s->pid() > 0) {
557 pids.push_back(s->pid());
558 }
559 if (terminate) {
// 调用 Terminate 方法
560 s->Terminate();
561 } else {
562 s->Stop();
563 }
564 }
565 if (timeout > 0ms) {
566 WaitToBeReaped(pids, timeout);
567 } else {
568 // Even if we don't to wait for services to stop, we still optimistically reap zombies.
569 ReapAnyOutstandingChildren();
570 }
571 }
572
// 3-2-5)重启系统:RebootSystem
/system/core/init/reboot_utils.cpp
109 void __attribute__((noreturn))
110 RebootSystem(unsigned int cmd, const std::string& rebootTarget, const std::string& reboot_reason) {
// 会打印下列的log
111 LOG(INFO) << "Reboot ending, jumping to kernel";
112
113 if (!IsRebootCapable()) {
114 // On systems where init does not have the capability of rebooting the
115 // device, just exit cleanly.
116 exit(0);
117 }
118
119 switch (cmd) {
// 关机会走reboot(RB_POWER_OFF)
120 case ANDROID_RB_POWEROFF:
121 reboot(RB_POWER_OFF);
122 break;
123
// 重启
124 case ANDROID_RB_RESTART2:
125 syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
126 LINUX_REBOOT_CMD_RESTART2, rebootTarget.c_str());
127 break;
128
129 case ANDROID_RB_THERMOFF:
130 if (android::base::GetBoolProperty("ro.thermal_warmreset", false)) {
131 std::string reason = "shutdown,thermal";
132 if (!reboot_reason.empty()) reason = reboot_reason;
133
134 LOG(INFO) << "Try to trigger a warm reset for thermal shutdown";
135 syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
136 LINUX_REBOOT_CMD_RESTART2, reason.c_str());
137 } else {
138 reboot(RB_POWER_OFF);
139 }
140 break;
141 }
142 // In normal case, reboot should not return.
143 PLOG(ERROR) << "reboot call returned";
144 abort();
145 }