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

安卓关机和重启源码流程

// 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, &current_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  }

相关文章:

  • 【HDFS入门】Hadoop 2.0+ HDFS核心架构深度解析:高可用设计揭秘
  • C. Good Subarrays
  • 操作系统基础:07 我们的任务
  • MySQL-锁
  • leetcode 3508 设计路由器 模拟 深拷贝 二分 bound
  • (即插即用模块-特征处理部分) 三十二、(TGRS 2024) MDAF 多尺度双表示对齐过滤器
  • 深入解析TCP拥塞控制机制:从原理到现代算法优化
  • 如何在Agent中设置Memory
  • 【数学建模】佳点集(Good Point Set)在智能优化算法中的应用与实现
  • ChatGPT-如何让AI写作不那么生硬!
  • 学习笔记九——Rust所有权机制
  • 探索 MCP 和 A2A 协议: 本质上新协议都基于 HTTP的
  • 【Spring底层分析】Spring IoC
  • RocketMQ 安装时启动一闪而过 start mqnamesrv.cmd
  • 插值算法 - 最近邻插值实现
  • 用python写一个简单的射击游戏
  • skynet.socket 完整通信流程
  • Mysql8配置文件
  • 【贪心之摆动序列】
  • 三、Virtual Device Manager
  • 4月22城新房价格上涨:上海一二手房价环比均上涨,核心城市土地热带动市场热度提升
  • 历史缝隙里的人︱觑功名如画饼:盛世“做题家”的攀爬与坠落
  • 美官方将使用华为芯片视作违反美出口管制行为,外交部回应
  • 多地举办演唱会等吸引游客刺激消费,经济日报:引导粉丝经济理性健康发展
  • 上海率先推进生物制品分段生产试点,这款国产1类创新药获批上市
  • 创同期历史新高!1至4月全国铁路发送旅客14.6亿人次