Android8 SystemServer 启动源码分析笔记(三)

前文回顾:

Android8 SystemServer启动源码分析(二)-CSDN博客文章浏览阅读508次,点赞11次,收藏7次。本文分析了Android系统SystemServer启动的核心流程,重点包括:1)SystemServer.main()方法创建实例并调用run();2)run()方法中初始化系统环境,包括设置时钟、时区、加载JNI库等;3)创建主Looper循环和系统上下文;4)分阶段启动系统服务:a) 引导服务(AMS、PMS等)b) 核心服务(电池、使用统计等)。文章详细解析了SystemServiceManager如何通过反射机制创建和启动各类系统服务,并强调了服务间的依赖关系决定了启动顺序。最后指出startOt https://blog.csdn.net/g_i_a_o_giao/article/details/150918252?spm=1001.2014.3001.5502

安卓8 SystemServer启动源码分析笔记(一)-CSDN博客文章浏览阅读823次,点赞15次,收藏6次。本文分析了Android系统中Zygote进程孵化SystemServer的过程。关键流程包括:1)Zygote通过forkSystemServer创建SystemServer进程;2)子进程调用handleSystemServerProcess方法返回Runnable对象;3)通过zygoteInit方法执行通用初始化,包括启动Binder线程池;4)使用findStaticMain方法反射获取SystemServer等类的main方法;5)通过MethodAndArgsCaller这个"跳板类 https://blog.csdn.net/g_i_a_o_giao/article/details/150863370?spm=1011.2124.3001.6209

根据上文分析,AMS和PMS等核心服务已通过startBootstrapServicesstartCoreServices方法完成初始化。那么WMS作为另一个关键服务,其创建时机是什么?此外,系统服务初始化后又是如何通过context提供给应用使用的?本文将逐步深入探讨这些问题。

首先来看看之前startBootstrapManager方法中创建AMS的代码:

mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();

.....
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
// installer守护线程不进行分析了
mActivityManagerService.setInstaller(installer);
.....
​​​​​​​mActivityManagerService.setSystemProcess();

那我们来看看AMS中的代码中这几个方法的作用:setSystemServiceManager是一个简单的set方法就不进行分析了。主要是核心方法setSystemProcess,在这个方法中,调用ServiceManager的addService将核心系统服务AMS注册到ServiceManager中。这里我们看到了熟悉的Context.ACTIVITY_SERVICE这个常量。

// 简单的set方法
public void setSystemServiceManager(SystemServiceManager mgr) {
        mSystemServiceManager = mgr;
    }

// 核心方法
public void setSystemProcess() {
    try {
        // 1. 注册核心系统服务到 ServiceManager
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this));
        ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
        ServiceManager.addService("dbinfo", new DbBinder(this));
        
        // 2. 根据条件注册 CPU 使用情况监视服务
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(this));
        }
        
        // 3. 注册权限和进程信息服务
        ServiceManager.addService("permission", new PermissionController(this));
        ServiceManager.addService("processinfo", new ProcessInfoService(this));

        // 4. 获取 Android 系统包的应用信息
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
        
        // 5. 为系统线程安装系统应用信息
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

        // 6. 创建并配置系统进程记录
        synchronized (this) {
            // 创建新的进程记录
            ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
            
            // 标记为持久化进程(不会被轻易杀死)
            app.persistent = true;
            
            // 设置进程 ID 为当前进程 ID
            app.pid = MY_PID;
            
            // 设置最大调整值(adj)为系统级别
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            
            // 激活进程记录,关联应用线程和进程统计信息
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            
            // 7. 将进程记录添加到进程映射表中
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
            }
            
            // 8. 更新 LRU(最近最少使用)进程列表
            updateLruProcessLocked(app, false, null);
            
            // 9. 更新进程的 OOM(内存不足)调整值
            updateOomAdjLocked();
        }
    } catch (PackageManager.NameNotFoundException e) {
        // 10. 异常处理:如果找不到 Android 系统包则抛出运行时异常
        throw new RuntimeException(
                "Unable to find android system package", e);
    }
}

继续分析ServiceManager的addService方法,主要是调用getIServiceManager中的addService方法,再来看看getIServiceManager方法,主要是返回一个ServiceManagerProxy内部类。然后调用这个内部类的addService()方法,在这个方法中,构建了一个Parcel数据包对象然后调用mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);方法将数据和操作发送给了binder,然后将服务添加到system_server中。其实当每一个系统服务创建以后,都会调用ServiceManager的addService方法。

/**
 * 将名为 @a name 的新服务 @a service 添加到服务管理器
 * 
 * @param name 新服务的名称
 * @param service 服务对象
 * @param allowIsolated 设置为true以允许隔离的沙盒进程访问此服务
 */
public static void addService(String name, IBinder service, boolean allowIsolated) {
    try {
        // 获取服务管理器接口并调用其addService方法
        getIServiceManager().addService(name, service, allowIsolated);
    } catch (RemoteException e) {
        // 处理远程调用异常,记录错误日志
        Log.e(TAG, "error in addService", e);
    }
}

/**
 * 获取服务管理器接口的单例实例
 * 使用双重检查锁定模式确保线程安全
 * 
 * @return IServiceManager 服务管理器接口实例
 */
private static IServiceManager getIServiceManager() {
    // 第一次检查:如果实例已存在,直接返回
    if (sServiceManager != null) {
        return sServiceManager;
    }
    
    // 同步块,确保线程安全
    synchronized (ServiceManager.class) {
        // 第二次检查:防止多个线程同时进入同步块时重复创建实例
        if (sServiceManager == null) {
            // 获取Binder上下文对象(通常是Binder代理对象)
            IBinder binder = BinderInternal.getContextObject();
            // 允许阻塞调用
            IBinder blockingBinder = Binder.allowBlocking(binder);
            // 将Binder对象转换为IServiceManager接口
            sServiceManager = ServiceManagerNative.asInterface(blockingBinder);
        }
    }
    return sServiceManager;
}

ServiceManagerNative.java中的asInterface

/**
 * 将Binder对象转换为服务管理器接口,必要时生成代理
 * 
 * @param obj 要转换的Binder对象
 * @return IServiceManager 服务管理器接口实例
 */
static public IServiceManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    
    // 首先查询本地接口(检查是否在同一进程)
    IServiceManager in = (IServiceManager) obj.queryLocalInterface(descriptor);
    if (in != null) {
        // 如果是本地接口(在同一进程),直接返回
        return in;
    }
    
    // 如果是远程接口(在不同进程),创建代理对象处理跨进程通信
    return new ServiceManagerProxy(obj);
}

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
    
    public IBinder asBinder() {
        return mRemote;
    }
   
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        // 核心方法
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }
    

那我们再来看看另一个核心系统服务WMS是什么时候启动的。查找之后发现WMS在startOtherServices方法中,不过可以看到,WMS是直接调用了自身的静态main方法,然后同AMS一样调用ServiceManager.addService方法的将服务添加到注册表中。

 private void startOtherServices() {
    
    final Context context = mSystemContext;
        VibratorService vibrator = null;
        IStorageManager storageManager = null;
        NetworkManagementService networkManagement = null;
        NetworkStatsService networkStats = null;
        NetworkPolicyManagerService networkPolicy = null;
        ConnectivityService connectivity = null;
        NetworkScoreService networkScore = null;
        NsdService serviceDiscovery= null;
        WindowManagerService wm = null;

        ............
        traceBeginAndSlog("StartWindowManagerService");
            // WMS needs sensor service ready
            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
            mSensorServiceStart = null;
            wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore, new PhoneWindowManager());
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
        ............
}

综上,启动SystemService有两种方式:
1.调用SystemServiceManager的startService方法调用目标服务的onstart生命周期方法。
2.直接创建目标服务的对象或者直接调用目标对象的main函数。

继续分析startOtherServices方法。根据注释可以看出来在所有系统服务启动以后,会调用各个服务的systemReady方法。

(代码太长了只展示部分)
// It is now time to start up the app processes...
        // 启动应用程序
        traceBeginAndSlog("MakeVibratorServiceReady");
        try {
            vibrator.systemReady();
        } catch (Throwable e) {
            reportWtf("making Vibrator Service ready", e);
        }
        traceEnd();

        traceBeginAndSlog("MakeLockSettingsServiceReady");
        if (lockSettings != null) {
            try {
                lockSettings.systemReady();
            } catch (Throwable e) {
                reportWtf("making Lock Settings Service ready", e);
            }
        }
        traceEnd();

        // Needed by DevicePolicyManager for initialization
        traceBeginAndSlog("StartBootPhaseLockSettingsReady");
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        traceEnd();

        traceBeginAndSlog("StartBootPhaseSystemServicesReady");
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        traceEnd();

        traceBeginAndSlog("MakeWindowManagerServiceReady");
        try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
        traceEnd();

        if (safeMode) {
            mActivityManagerService.showSafeModeOverlay();
        }

        // Update the configuration for this context by hand, because we're going
        // to start using it before the config change done in wm.systemReady() will
        // propagate to it.
        final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        w.getDefaultDisplay().getMetrics(metrics);
        context.getResources().updateConfiguration(config, metrics);

        // The system context's theme may be configuration-dependent.
        final Theme systemTheme = context.getTheme();
        if (systemTheme.getChangingConfigurations() != 0) {
            systemTheme.rebase();
        }

        traceBeginAndSlog("MakePowerManagerServiceReady");
        try {
            // TODO: use boot phase
            mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
        } catch (Throwable e) {
            reportWtf("making Power Manager Service ready", e);
        }
        traceEnd();

        traceBeginAndSlog("MakePackageManagerServiceReady");
        try {
            mPackageManagerService.systemReady();
        } catch (Throwable e) {
            reportWtf("making Package Manager Service ready", e);
        }
        traceEnd();

下面以AMS的systemReady方法为例进行分析。当系统准备就绪以后会进行一系列初始化操作,并通知其它关联方系统已就绪,然后找到HomeActivity并启动,然后发送广播。AMS的systemReady方法的源码分析部分将在后续笔记中详细展开。

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    // 开始记录"ActivityManagerReady"阶段的性能轨迹,用于分析启动时间
    traceLog.traceBegin("PhaseActivityManagerReady");
    synchronized(this) {
        // 检查系统是否已经准备就绪,避免重复初始化
        if (mSystemReady) {
            // 如果已经就绪,并且传入了回调,则直接执行回调并返回
            if (goingCallback != null) {
                goingCallback.run();
            }
            return;
        }

        // 获取设备空闲控制器服务,用于管理设备空闲状态(如Doze模式)
        mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
        // 初始化辅助功能工具类(用于实现Google Now on Tap等功能)
        mAssistUtils = new AssistUtils(mContext);
        // 通知VR控制器系统已就绪
        mVrController.onSystemReady();
        // 确保获取当前用户配置文件信息,因为安全检查需要它
        mUserController.onSystemReady();
        // 通知最近任务列表系统就绪
        mRecentTasks.onSystemReadyLocked();
        // 通知AppOpsService(应用操作权限服务)系统就绪
        mAppOpsService.systemReady();
        // 标记ActivityManagerService本身已准备就绪
        mSystemReady = true;
    }

    // 尝试获取设备的真实序列号(用于标识设备)
    try {
        sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
                .getSerial();
    } catch (RemoteException e) {} // 忽略获取序列号时的远程异常

    // 创建一个列表,用于存储在系统更新期间不允许运行、需要杀死的进程
    ArrayList<ProcessRecord> procsToKill = null;
    synchronized(mPidsSelfLocked) {
        // 遍历所有当前运行的进程
        for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
            ProcessRecord proc = mPidsSelfLocked.valueAt(i);
            // 检查进程是否允许在启动过程中运行
            if (!isAllowedWhileBooting(proc.info)){
                if (procsToKill == null) {
                    procsToKill = new ArrayList<ProcessRecord>();
                }
                procsToKill.add(proc); // 将不允许的进程添加到待杀死列表
            }
        }
    }

    synchronized(this) {
        // 如果有需要杀死的进程,则逐个移除它们
        if (procsToKill != null) {
            for (int i=procsToKill.size()-1; i>=0; i--) {
                ProcessRecord proc = procsToKill.get(i);
                Slog.i(TAG, "Removing system update proc: " + proc);
                removeProcessLocked(proc, true, false, "system update done");
            }
        }

        // 现在我们已经清理了所有更新进程,准备启动真正的应用进程
        // 并确保不会再有进程冲突
        mProcessesReady = true; // 标记进程系统已准备就绪
    }

    // 记录系统就绪的日志
    Slog.i(TAG, "System now ready");
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());

    synchronized(this) {
        // 确保没有预就绪的进程残留(在工厂测试模式下)

        // 处理低级工厂测试模式
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            ResolveInfo ri = mContext.getPackageManager()
                    .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
            CharSequence errorMsg = null;
            if (ri != null) {
                ActivityInfo ai = ri.activityInfo;
                ApplicationInfo app = ai.applicationInfo;
                // 检查工厂测试Activity是否是系统应用
                if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                    // 设置顶部动作为工厂测试
                    mTopAction = Intent.ACTION_FACTORY_TEST;
                    mTopData = null;
                    mTopComponent = new ComponentName(app.packageName, ai.name);
                } else {
                    // 非系统应用,获取错误消息
                    errorMsg = mContext.getResources().getText(
                            com.android.internal.R.string.factorytest_not_system);
                }
            } else {
                // 没有找到工厂测试Activity,获取错误消息
                errorMsg = mContext.getResources().getText(
                        com.android.internal.R.string.factorytest_no_action);
            }
            if (errorMsg != null) {
                // 清除顶部组件设置并发送错误消息到UI线程
                mTopAction = null;
                mTopData = null;
                mTopComponent = null;
                Message msg = Message.obtain();
                msg.what = SHOW_FACTORY_ERROR_UI_MSG;
                msg.getData().putCharSequence("msg", errorMsg);
                mUiHandler.sendMessage(msg);
            }
        }
    }

    // 检索系统设置
    retrieveSettings();
    final int currentUserId;
    synchronized (this) {
        // 获取当前用户ID
        currentUserId = mUserController.getCurrentUserIdLocked();
        // 读取已授权的URI权限
        readGrantedUriPermissionsLocked();
    }

    // 执行传入的回调函数(通常用于通知SystemServer AMS已准备就绪)
    if (goingCallback != null) goingCallback.run();
    
    // 开始记录"启动应用"阶段的性能轨迹
    traceLog.traceBegin("ActivityManagerStartApps");
    
    // 向电池统计服务记录用户开始运行和切换到前台的事件
    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
            Integer.toString(currentUserId), currentUserId);
    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
            Integer.toString(currentUserId), currentUserId);
    
    // 通知系统服务管理器用户已启动
    mSystemServiceManager.startUser(currentUserId);

    synchronized (this) {
        // 只启动支持加密的持久化应用(直接启动感知应用)
        // 当用户解锁后,我们会回来启动非感知应用
        startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);

        // 启动初始Activity(Launcher)
        mBooting = true; // 标记系统正在启动中
        
        // 为系统用户启用Home Activity,确保系统总能启动
        // 如果系统用户未完成设置,我们不这样做,因为设置向导应该处理Home Activity
        if (UserManager.isSplitSystemUser() &&
                Settings.Secure.getInt(mContext.getContentResolver(),
                     Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
            ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
            try {
                AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
                        UserHandle.USER_SYSTEM);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
        }
        
        // 启动Home Activity(Launcher) - 这是用户看到的第一个界面
        startHomeActivityLocked(currentUserId, "systemReady");

        // 检查系统UID是否存在不一致
        try {
            if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
                        + " data partition or your device will be unstable.");
                mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
            }
        } catch (RemoteException e) {
        }

        // 检查构建指纹是否一致
        if (!Build.isBuildConsistent()) {
            Slog.e(TAG, "Build fingerprint is not consistent, warning user");
            mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
        }

        // 清除调用身份以便以系统权限执行操作
        long ident = Binder.clearCallingIdentity();
        try {
            // 广播用户已启动 intent
            Intent intent = new Intent(Intent.ACTION_USER_STARTED);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
            intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 
                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, currentUserId);
            
            // 广播用户正在启动 intent
            intent = new Intent(Intent.ACTION_USER_STARTING);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
            broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() {
                @Override
                public void performReceive(Intent intent, int resultCode, String data,
                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
                        throws RemoteException {
                }
            }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
                    null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
        } catch (Throwable t) {
            Slog.wtf(TAG, "Failed sending first user broadcasts", t);
        } finally {
            // 恢复调用身份
            Binder.restoreCallingIdentity(ident);
        }
        
        // 恢复焦点栈的顶部Activity
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
        // 发送用户切换广播
        mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
        
        // 结束性能轨迹记录
        traceLog.traceEnd(); // ActivityManagerStartApps
        traceLog.traceEnd(); // PhaseActivityManagerReady
    }
}

总结,当ZygoteInit调用handleSystemServerProcess返回的runnable对象的run方法以后会找到SystemServer.java的静态main函数,在这个main方法中又会去调用startService、addService、systemReady等方法来告知系统服务已经成功启动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值