private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
private static final String ENCRYPTED_STATE = "1";
- ContentResolver mContentResolver;
+ private static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
- void reportWtf(String msg, Throwable e) {
- Slog.w(TAG, "***********************************************");
- Log.wtf(TAG, "BOOT FAILURE " + msg, e);
+ // The earliest supported time. We pick one day into 1970, to
+ // give any timezone code room without going into negative time.
+ private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
+
+ /*
+ * Implementation class names. TODO: Move them to a codegen class or load
+ * them from the build system somehow.
+ */
+ private static final String BACKUP_MANAGER_SERVICE_CLASS =
+ "com.android.server.backup.BackupManagerService$Lifecycle";
+ private static final String APPWIDGET_SERVICE_CLASS =
+ "com.android.server.appwidget.AppWidgetService";
+ private static final String PRINT_MANAGER_SERVICE_CLASS =
+ "com.android.server.print.PrintManagerService";
+ private static final String USB_SERVICE_CLASS =
+ "com.android.server.usb.UsbService$Lifecycle";
+ private static final String HDMI_CEC_SERVICE_CLASS =
+ "com.android.server.hdmi.HdmiCecService";
+
+ private final int mFactoryTestMode;
+ private Timer mProfilerSnapshotTimer;
+
+ private Context mSystemContext;
+ private SystemServiceManager mSystemServiceManager;
+
+ // TODO: remove all of these references by improving dependency resolution and boot phases
+ private Installer mInstaller;
+ private PowerManagerService mPowerManagerService;
+ private ActivityManagerService mActivityManagerService;
+ private DisplayManagerService mDisplayManagerService;
+ private ContentResolver mContentResolver;
+
+ /**
+ * Called to initialize native system services.
+ */
+ private static native void nativeInit();
+
+ /**
+ * The main entry point from zygote.
+ */
+ public static void main(String[] args) {
+ new SystemServer().run();
}
- public void initAndLoop() {
- EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
- SystemClock.uptimeMillis());
+ public SystemServer() {
+ mFactoryTestMode = FactoryTest.getMode();
+ }
- Looper.prepareMainLooper();
+ private void run() {
+ // If a device's clock is before 1970 (before 0), a lot of
+ // APIs crash dealing with negative numbers, notably
+ // java.io.File#setLastModified, so instead we fake it and
+ // hope that time from cell towers or NTP fixes it shortly.
+ if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
+ Slog.w(TAG, "System clock is before 1970; setting to 1970.");
+ SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
+ }
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ // Here we go!
+ Slog.i(TAG, "Entered the Android system server!");
+ EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
+
+ // In case the runtime switched since last boot (such as when
+ // the old runtime was removed in an OTA), set the system
+ // property so that it is in sync. We can't do this in
+ // libnativehelper's JniInvocation::Init code where we already
+ // had to fallback to a different runtime because it is
+ // running as root and we need to be the system user to set
+ // the property. http://b/11463182
- SystemProperties.set("persist.sys.dalvik.vm.lib.1", VMRuntime.getRuntime().vmLibrary());
++ SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
+
+ // Enable the sampling profiler.
+ if (SamplingProfilerIntegration.isEnabled()) {
+ SamplingProfilerIntegration.start();
+ mProfilerSnapshotTimer = new Timer();
+ mProfilerSnapshotTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ SamplingProfilerIntegration.writeSnapshot("system_server", null);
+ }
+ }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
+ }
+ // Mmmmmm... more memory!
+ VMRuntime.getRuntime().clearGrowthLimit();
+
+ // The system server has to run all of the time, so it needs to be
+ // as efficient as possible with its memory usage.
+ VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
+
+ // Within the system server, it is an error to access Environment paths without
+ // explicitly specifying a user.
+ Environment.setUserRequired(true);
+
+ // Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);
+
+ // Prepare the main looper thread (this thread).
+ android.os.Process.setThreadPriority(
+ android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
+ Looper.prepareMainLooper();
+
+ // Initialize native services.
+ System.loadLibrary("android_servers");
+ nativeInit();
// Check whether we failed to shut down last time we tried.
- {
- final String shutdownAction = SystemProperties.get(
- ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
- if (shutdownAction != null && shutdownAction.length() > 0) {
- boolean reboot = (shutdownAction.charAt(0) == '1');
-
- final String reason;
- if (shutdownAction.length() > 1) {
- reason = shutdownAction.substring(1, shutdownAction.length());
- } else {
- reason = null;
- }
+ // This call may not return.
+ performPendingShutdown();
- ShutdownThread.rebootOrShutdown(reboot, reason);
+ // Initialize the system context.
+ createSystemContext();
+
+ // Create the system service manager.
+ mSystemServiceManager = new SystemServiceManager(mSystemContext);
+ LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
+
+ // Start services.
+ try {
+ startBootstrapServices();
+ startCoreServices();
+ startOtherServices();
+ } catch (RuntimeException ex) {
+ Slog.e("System", "******************************************");
+ Slog.e("System", "************ Failure starting system services", ex);
+ throw ex;
+ }
+
+ // For debug builds, log event loop stalls to dropbox for analysis.
+ if (StrictMode.conditionallyEnableDebugLogging()) {
+ Slog.i(TAG, "Enabled StrictMode for system server main thread.");
+ }
+
+ // Loop forever.
+ Looper.loop();
+ throw new RuntimeException("Main thread loop unexpectedly exited");
+ }
+
+ private void reportWtf(String msg, Throwable e) {
+ Slog.w(TAG, "***********************************************");
+ Log.wtf(TAG, "BOOT FAILURE " + msg, e);
+ }
+
+ private void performPendingShutdown() {
+ final String shutdownAction = SystemProperties.get(
+ ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
+ if (shutdownAction != null && shutdownAction.length() > 0) {
+ boolean reboot = (shutdownAction.charAt(0) == '1');
+
+ final String reason;
+ if (shutdownAction.length() > 1) {
+ reason = shutdownAction.substring(1, shutdownAction.length());
+ } else {
+ reason = null;
}
+
+ ShutdownThread.rebootOrShutdown(reboot, reason);
}
+ }
- String factoryTestStr = SystemProperties.get("ro.factorytest");
- int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
- : Integer.parseInt(factoryTestStr);
- final boolean headless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
+ private void createSystemContext() {
+ ActivityThread activityThread = ActivityThread.systemMain();
+ mSystemContext = activityThread.getSystemContext();
+ mSystemContext.setTheme(android.R.style.Theme_Holo);
+ }
- Installer installer = null;
+ private void startBootstrapServices() {
+ // Wait for installd to finish starting up so that it has a chance to
+ // create critical directories such as /data/user with the appropriate
+ // permissions. We need this to complete before we initialize other services.
+ mInstaller = mSystemServiceManager.startService(Installer.class);
+
+ // Power manager needs to be started early because other services need it.
+ // TODO: The conversion to the new pattern is incomplete. We need to switch
+ // the power manager's dependencies over then we can use boot phases to arrange
+ // initialization order and remove the mPowerManagerService field.
+ mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
+
+ // Activity manager runs the show.
+ mActivityManagerService = mSystemServiceManager.startService(
+ ActivityManagerService.Lifecycle.class).getService();
+ }
+
+ private void startCoreServices() {
+ // Display manager is needed to provide display metrics before package manager
+ // starts up.
+ mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
+ }
+
+ private void startOtherServices() {
+ final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
- LightsService lights = null;
- PowerManagerService power = null;
- DisplayManagerService display = null;
+ LightsManager lights = null;
BatteryService battery = null;
VibratorService vibrator = null;
- AlarmManagerService alarm = null;
+ IAlarmManager alarm = null;
MountService mountService = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;