zoukankan      html  css  js  c++  java
  • Android 源码分析(六) SystemServer 进程

        一.前言:

        init进程 –> Zygote进程 –> SystemServer进程 –> Launcher桌面程序 -> 我们的App应用

        init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;

        Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;

        SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
        
        Launcher桌面程序:就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序.
       

      二. SystemService进程

            ZygoteInit类的main方法调用了StartSystemService() 启动SystemService.
            SystemServer进程主要的作用是启动各种系统服务,比如ActivityManagerService,PackageManagerService,WindowManagerService等服务.

    //ZygoteInit.java
         /**
         * Prepare the arguments and fork for the system server process.
         */
        private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
                throws Zygote.MethodAndArgsCaller, RuntimeException {
            long capabilities = posixCapabilitiesAsBits(
                OsConstants.CAP_IPC_LOCK,
                OsConstants.CAP_KILL,
                OsConstants.CAP_NET_ADMIN,
                OsConstants.CAP_NET_BIND_SERVICE,
                OsConstants.CAP_NET_BROADCAST,
                OsConstants.CAP_NET_RAW,
                OsConstants.CAP_SYS_MODULE,
                OsConstants.CAP_SYS_NICE,
                OsConstants.CAP_SYS_PTRACE,
                OsConstants.CAP_SYS_TIME,
                OsConstants.CAP_SYS_TTY_CONFIG,
                OsConstants.CAP_WAKE_ALARM
            );
            /* Containers run without this capability, so avoid setting it in that case */
            if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
                capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
            }
            /* Hardcoded command line to start the system server */
            String args[] = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "com.android.server.SystemServer",
            };
            ZygoteConnection.Arguments parsedArgs = null;
    
            int pid;
    
            try {
                parsedArgs = new ZygoteConnection.Arguments(args);
                ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
                ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
    
                /* Request to fork the system server process */
                pid = Zygote.forkSystemServer(
                        parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids,
                        parsedArgs.debugFlags,
                        null,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    
            /* For child process */
            if (pid == 0) {
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
    
                zygoteServer.closeServerSocket();
                handleSystemServerProcess(parsedArgs);
            }
    
            return true;
        }

      接上篇文章继续看看SystemServer在源码中做了什么.

    //SystemServer.java
        
        /**
         * The main entry point from zygote.
         */
        public static void main(String[] args) {
            new SystemServer().run();
        }
        
        private void run() {
            try {
                traceBeginAndSlog("InitBeforeStartServices");
                // 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);
                }
    
                //
                // Default the timezone property to GMT if not set.
                //
                String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
                if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                    Slog.w(TAG, "Timezone not set; setting to GMT.");
                    SystemProperties.set("persist.sys.timezone", "GMT");
                }
    
                // If the system has "persist.sys.language" and friends set, replace them with
                // "persist.sys.locale". Note that the default locale at this point is calculated
                // using the "-Duser.locale" command line flag. That flag is usually populated by
                // AndroidRuntime using the same set of system properties, but only the system_server
                // and system apps are allowed to set them.
                //
                // NOTE: Most changes made here will need an equivalent change to
                // core/jni/AndroidRuntime.cpp
                if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                    final String languageTag = Locale.getDefault().toLanguageTag();
    
                    SystemProperties.set("persist.sys.locale", languageTag);
                    SystemProperties.set("persist.sys.language", "");
                    SystemProperties.set("persist.sys.country", "");
                    SystemProperties.set("persist.sys.localevar", "");
                }
    
                // The system server should never make non-oneway calls
                Binder.setWarnOnBlocking(true);
    
                // Here we go!
                Slog.i(TAG, "Entered the Android system server!");
                int uptimeMillis = (int) SystemClock.elapsedRealtime();
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
                if (!mRuntimeRestart) {
                    MetricsLogger.histogram(null, "boot_system_server_init", 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 | xq oqi'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.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);
    
                // Some devices rely on runtime fingerprint generation, so make sure
                // we've defined it before booting further.
                Build.ensureFingerprintProperty();
    
                // Within the system server, it is an error to access Environment paths without
                // explicitly specifying a user.
                Environment.setUserRequired(true);
    
                // Within the system server, any incoming Bundles should be defused
                // to avoid throwing BadParcelableException.
                BaseBundle.setShouldDefuse(true);
    
                // Ensure binder calls into the system always run at foreground priority.
                BinderInternal.disableBackgroundScheduling(true);
    
                // Increase the number of binder threads in system_server
                BinderInternal.setMaxThreads(sMaxBinderThreads);
    
                // 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");
    
                // Check whether we failed to shut down last time we tried.
                // This call may not return.
                performPendingShutdown();
    
                // Initialize the system context.
                createSystemContext();
    
                // Create the system service manager.
                mSystemServiceManager = new SystemServiceManager(mSystemContext);
                mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
                LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
                // Prepare the thread pool for init tasks that can be parallelized
                SystemServerInitThreadPool.get();
            } finally {
                traceEnd();  // InitBeforeStartServices
            }
    
            // Start services. 启动各种需要的服务
            try {
                traceBeginAndSlog("StartServices");
                //启动系统Boot级服务 
                startBootstrapServices();
                //启动系统核心的服务 
                startCoreServices();
                //启动非核心的服务 
                startOtherServices();
                SystemServerInitThreadPool.shutdown();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            } finally {
                traceEnd();
            }
    
            // For debug builds, log event loop stalls to dropbox for analysis.
            if (StrictMode.conditionallyEnableDebugLogging()) {
                Slog.i(TAG, "Enabled StrictMode for system server main thread.");
            }
            if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
                int uptimeMillis = (int) SystemClock.elapsedRealtime();
                MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
                final int MAX_UPTIME_MILLIS = 60 * 1000;
                if (uptimeMillis > MAX_UPTIME_MILLIS) {
                    Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                            "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
                }
            }
    
            // Loop forever.
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    
        /**
         * Starts the small tangle of critical services that are needed to get
         * the system off the ground.  These services have complex mutual dependencies
         * which is why we initialize them all in one place here.  Unless your service
         * is also entwined in these dependencies, it should be initialized in one of
         * the other functions.
         */
        private void startBootstrapServices() {
            Slog.i(TAG, "Reading configuration...");
            final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
            traceBeginAndSlog(TAG_SYSTEM_CONFIG);
            SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
            traceEnd();
    
            // 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.
            traceBeginAndSlog("StartInstaller");
            Installer installer = mSystemServiceManager.startService(Installer.class);
            traceEnd();
    
            // In some cases after launching an app we need to access device identifiers,
            // therefore register the device identifier policy before the activity manager.
            traceBeginAndSlog("DeviceIdentifiersPolicyService");
            mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
            traceEnd();
    
            // Activity manager runs the show.
            traceBeginAndSlog("StartActivityManager");
            mActivityManagerService = mSystemServiceManager.startService(
                    ActivityManagerService.Lifecycle.class).getService();
            mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
            mActivityManagerService.setInstaller(installer);
            traceEnd();
    
            // Power manager needs to be started early because other services need it.
            // Native daemons may be watching for it to be registered so it must be ready
            // to handle incoming binder calls immediately (including being able to verify
            // the permissions for those calls).
            traceBeginAndSlog("StartPowerManager");
            mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
            traceEnd();
    
            // Now that the power manager has been started, let the activity manager
            // initialize power management features.
            traceBeginAndSlog("InitPowerManagement");
            mActivityManagerService.initPowerManagement();
            traceEnd();
    
            // Bring up recovery system in case a rescue party needs a reboot
            if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
                traceBeginAndSlog("StartRecoverySystemService");
                mSystemServiceManager.startService(RecoverySystemService.class);
                traceEnd();
            }
    
            // Now that we have the bare essentials of the OS up and running, take
            // note that we just booted, which might send out a rescue party if
            // we're stuck in a runtime restart loop.
            RescueParty.noteBoot(mSystemContext);
    
            // Manages LEDs and display backlight so we need it to bring up the display.
            traceBeginAndSlog("StartLightsService");
            mSystemServiceManager.startService(LightsService.class);
            traceEnd();
    
            // Display manager is needed to provide display metrics before package manager
            // starts up.
            traceBeginAndSlog("StartDisplayManager");
            mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
            traceEnd();
    
            // We need the default display before we can initialize the package manager.
            traceBeginAndSlog("WaitForDisplay");
            mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
            traceEnd();
    
            // Only run "core" apps if we're encrypting the device.
            String cryptState = SystemProperties.get("vold.decrypt");
            if (ENCRYPTING_STATE.equals(cryptState)) {
                Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
                mOnlyCore = true;
            } else if (ENCRYPTED_STATE.equals(cryptState)) {
                Slog.w(TAG, "Device encrypted - only parsing core apps");
                mOnlyCore = true;
            }
    
            // Start the package manager.
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_package_manager_init_start",
                        (int) SystemClock.elapsedRealtime());
            }
            traceBeginAndSlog("StartPackageManagerService");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
            mFirstBoot = mPackageManagerService.isFirstBoot();
            mPackageManager = mSystemContext.getPackageManager();
            traceEnd();
            if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
                MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                        (int) SystemClock.elapsedRealtime());
            }
            // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
            // A/B artifacts after boot, before anything else might touch/need them.
            // Note: this isn't needed during decryption (we don't have /data anyways).
            if (!mOnlyCore) {
                boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                        false);
                if (!disableOtaDexopt) {
                    traceBeginAndSlog("StartOtaDexOptService");
                    try {
                        OtaDexoptService.main(mSystemContext, mPackageManagerService);
                    } catch (Throwable e) {
                        reportWtf("starting OtaDexOptService", e);
                    } finally {
                        traceEnd();
                    }
                }
            }
    
            traceBeginAndSlog("StartUserManagerService");
            mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
            traceEnd();
    
            // Initialize attribute cache used to cache resources from packages.
            traceBeginAndSlog("InitAttributerCache");
            AttributeCache.init(mSystemContext);
            traceEnd();
    
            // Set up the Application instance for the system process and get started.
            traceBeginAndSlog("SetSystemProcess");
            mActivityManagerService.setSystemProcess();
            traceEnd();
    
            // DisplayManagerService needs to setup android.display scheduling related policies
            // since setSystemProcess() would have overridden policies due to setProcessGroup
            mDisplayManagerService.setupSchedulerPolicies();
    
            // Manages Overlay packages
            traceBeginAndSlog("StartOverlayManagerService");
            mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
            traceEnd();
    
            // The sensor service needs access to package manager service, app ops
            // service, and permissions service, therefore we start it after them.
            // Start sensor service in a separate thread. Completion should be checked
            // before using it.
            mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
                BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
                        SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
                traceLog.traceBegin(START_SENSOR_SERVICE);
                startSensorService();
                traceLog.traceEnd();
            }, START_SENSOR_SERVICE);
        }
    
        
        /**
         * Starts some essential services that are not tangled up in the bootstrap process.
         */
        private void startCoreServices() {
            // Records errors and logs, for example wtf()
            traceBeginAndSlog("StartDropBoxManager");
            mSystemServiceManager.startService(DropBoxManagerService.class);
            traceEnd();
    
            traceBeginAndSlog("StartBatteryService");
            // Tracks the battery level.  Requires LightService.
            mSystemServiceManager.startService(BatteryService.class);
            traceEnd();
    
            // Tracks application usage stats.
            traceBeginAndSlog("StartUsageService");
            mSystemServiceManager.startService(UsageStatsService.class);
            mActivityManagerService.setUsageStatsManager(
                    LocalServices.getService(UsageStatsManagerInternal.class));
            traceEnd();
    
            // Tracks whether the updatable WebView is in a ready state and watches for update installs.
            traceBeginAndSlog("StartWebViewUpdateService");
            mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
            traceEnd();
        }
        
    // mSystemServiceManager是系统服务管理对象.在run()方法已经创建 mSystemServiceManager = new SystemServiceManager(mSystemContext);
        // 进入mSystemServiceManager.startService() 分析下. 进入具体实现的方法
        
        //SystemServiceManager.java
        /**
         * Creates and starts a system service. The class must be a subclass of
         * {@link com.android.server.SystemService}.
         *
         * @param serviceClass A Java class that implements the SystemService interface.
         * @return The service instance, never null.
         * @throws RuntimeException if the service fails to start.
         */
        @SuppressWarnings("unchecked")
        public <T extends SystemService> T startService(Class<T> serviceClass) {
            try {
                final String name = serviceClass.getName();
                Slog.i(TAG, "Starting " + name);
                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
    
                // Create the service.
                if (!SystemService.class.isAssignableFrom(serviceClass)) {
                    throw new RuntimeException("Failed to create " + name
                            + ": service must extend " + SystemService.class.getName());
                }
                final T service;
                try {
                    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                    service = constructor.newInstance(mContext);
                } catch (InstantiationException ex) {
                    throw new RuntimeException("Failed to create service " + name
                            + ": service could not be instantiated", ex);
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException("Failed to create service " + name
                            + ": service must have a public constructor with a Context argument", ex);
                } catch (NoSuchMethodException ex) {
                    throw new RuntimeException("Failed to create service " + name
                            + ": service must have a public constructor with a Context argument", ex);
                } catch (InvocationTargetException ex) {
                    throw new RuntimeException("Failed to create service " + name
                            + ": service constructor threw an exception", ex);
                }
    
                startService(service);
                return service;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        }
        
          /**
         * Starts a service by class name.
         *
         * @return The service instance.
         */
        @SuppressWarnings("unchecked")
        public SystemService startService(String className) {
            final Class<SystemService> serviceClass;
            try {
                serviceClass = (Class<SystemService>)Class.forName(className);
            } catch (ClassNotFoundException ex) {
                Slog.i(TAG, "Starting " + className);
                throw new RuntimeException("Failed to create service " + className
                        + ": service class not found, usually indicates that the caller should "
                        + "have called PackageManager.hasSystemFeature() to check whether the "
                        + "feature is available on this device before trying to start the "
                        + "services that implement it", ex);
            }
            return startService(serviceClass);
        }
        
        //通过反射器构造方法创建出服务类,然后返回SystemService.启动对应的服务.
  • 相关阅读:
    LVDS汇总
    smtp模块+Gmail搭建邮件发送功能
    网站建立(杂)
    xampp部署elgg
    转xampp 访问出现New XAMPP security concept
    FPGA参考电源
    android开发环境搭建问题
    cadence仿真前电路板设置(转)
    cadence串扰仿真 (转)
    cadence约束管理器总体设置 (转)
  • 原文地址:https://www.cnblogs.com/bugzone/p/SystemServer.html
Copyright © 2011-2022 走看看