将system_server进程配置成Android Application进程

这篇blog主要是介绍Android是怎样将system_server这个系统进程配置成android的application的运行环境的。
其中会涉及到framework-res.apk , SettingsProvider.apk

注: 该篇代码是基本 Android M 6.0.1

这篇文章最早发表于我的个人主页github,现在只是将它移到上。
转载请标注来处: http://www.jianshu.com/p/4378ebb1847f

一、framework-res.apk

framework-res.apk是android framework相关的资源文件apk, 里面保存了framework使用到的layout、图片、string等资源, 同时也会声明一些系统级的Activity.
代码地址: frameworks/base/core/res

1.1 Android.mk

LOCAL_PACKAGE_NAME := framework-res
LOCAL_CERTIFICATE := platform
LOCAL_EXPORT_PACKAGE_RESOURCES := true  

LOCAL_EXPORT_PACKAGE_RESOURCES 为true, 表示允许framework-res.apk里的资源可以被其它app使用.

1.2 AndroidManifest.mk

  • 配置成system sharedUserId

    android:sharedUserLabel="@string/android_system_label"
>

从AndroidManifest里可以看出framework-res.apk的package name为 “android”, 且要运行在system进程中.

  • 定义protected-broadcast


pretected-broadcast广播只能由系统级应用发出, 它是由PackageManagerService解析.
在Android系统运作起来之后,如果某个不具有系统权限的APP试图发送系统中的“保护性广播”,那么AMS的broadcastIntentLocked()会拦截,AMS会抛出异常

java.lang.SecurityException: Permission Denial: not allowed to send broadcast
android.intent.action.SCREEN_OFF from pid=3225, uid=10068
  • 定义permission与permission-group



    

permission-element用来作为安全权限限制访问一些特殊的模块或者features或者其它应用程序。
若APP要使用,必须要声明

    
  • 定义主application


    
    

默认所有的components都运行在system进程, 当然前提是有相同的shared User ID, 和相同的签名(Android.mk里定义了platform)

二、SettingsProvider.apk

SettingsProvider.apk 是一个ContentProvider, 主要用来提供系统的Settings的值,它是运行
在system进程中的,因为system进程里面有很多service, 这些service都可能需要访问到SettingsProvider里的值。
因此将SettingsProvider.apk跑在system进程中可以避免不必要的跨进程间消耗.
参见邓凡平的android 系统2

2.1 Android.mk

LOCAL_MODULE_TAGS := optional  
LOCAL_SRC_FILES := $(call all-subdir-java-files) \
        src/com/android/providers/settings/EventLogTags.logtags
LOCAL_JAVA_LIBRARIES := telephony-common ims-common
LOCAL_PACKAGE_NAME := SettingsProvider
LOCAL_CERTIFICATE := platform   //platform签名
LOCAL_PRIVILEGED_MODULE := true //privileged的apk

从上面可以看出, SettingsProvider.apk也是platform签名

2.2 AndroidManifest.xml

 

    

        android:backupAgent="SettingsBackupAgent"
        android:killAfterRestore="false"
        android:icon="@mipmap/ic_launcher_settings">

        

        
            android:singleUser="true"
            android:initOrder="100" />
    

从AndroidManifest.xml中定义来看,SettingsProvider.apk里所有的组件默认也是运行在system进程,且SettingsProvider.apk这个进程是system权限。

三、配置 SystemServer为Android application的环境

接下来这节主要来介绍如何将SystemServer配置成android应用程序的运行环境
整个简化的流程如下所示:

public static void main(String[] args) {
    new SystemServer().run();
}

private void run() {
    …
    // Initialize the system context.
    createSystemContext();
    //初始化系统上下文

    // Set up the Application instance for the system process and get started.
    mActivityManagerService.setSystemProcess();
    //通过AMS,将当前进程设置成android的应用程序的环境,安装framework-res.apk,生成进程相关的ProcessRecord

    //安装系统Providers
    mActivityManagerService.installSystemProviders();

}

3.1 createSystemContext

每个android 应用程序在进行初始化的时候首先都会生成一个全局的Applicaton实例(不管App代码有没有去实现这样一个application).
而createSystemContext创建的系统上下文就是去生成这样一个Application实例。

private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    //创建与线程相关的AcivityThread, 并且创建系统context
    mSystemContext = activityThread.getSystemContext();
    …
}
public static ActivityThread systemMain() {
     …
    ActivityThread thread = new ActivityThread();
    //将当前system_server运行的主线程关联一个AcivityThread.
    thread.attach(true);
    return thread;
}

// attach 系统进程
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        …
    } else {
     // Don't set application object here -- if the system crashes,
     // we can't display an alert, we just want to die die die.
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        //将Systemserver进程在DDM里设置名称为 system_process,这样就可以在DDMS里看到
        // system server进程了
        try {
            mInstrumentation = new Instrumentation();
            //生成一个Instrumentation,这是一个工具类
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            //这个context完全没用,只是临时使用LoadedApk, “android/system”
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            //生成应用程序对应的全局的Application
            mInitialApplication.onCreate();
            //进入Application的生命周期 onCreate()
        } catch (Exception e) {
            …
        }
    }

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
        //强制初始化"android.app.Application"
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            initializeJavaContextClassLoader();
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        //这个创建出来的Context是真正的Systemserver的Application里对应的那个Context
        //原来的application实例仅是一个壳
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
        //生成Application, Application是继承于ContextWrapper,类似于proxy模式,
        // ContextImpl与Application通过mOuterContext, mBase互相引用
    } catch (Exception e) {
    …
    }
    mActivityThread.mAllApplications.add(app);
    //将当前生成的Application加入到mAllApplications里,
    //可以看出,一个线程是可以跑多个apk的,(一个apk对应一个Application)

    mApplication = app;  //用mApplication表示最初始化的Application

    return app;
}

3.2 setSystemProcess

createSystemContext 仅仅是将应用程序的环境准备好,如ActivityThread, Application, context等等。
里面还没有一些真正意义上的程序、资源,仅仅是一个进程空壳。

AMS setSystemProcess()
//安装framework-res.apk, 生成systemserver对应的ProcessRecord, 并与ActivityThread进行绑定

public void setSystemProcess() {
    ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
        "android", STOCK_PM_FLAGS);
    //注意,这里的mContext是 mSystemContext, 即系统级的上下文, 查找package name为 “android”
    //的ApplicationInfo,从以上可知package name为 “android”的 apk是 framework-res.apk,
    //即framework的资源文件apk, ApplicationInfo是通过解析framework-res.apk里的AndroidManifest.xml获得的

    mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
    //开始为ActivityThread 安装 system application相关信息,将framework-res.apk对应的
    //ApplicationInfo安装到LoadedApk中的mApplicationInfo

    //为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息
    synchronized (this) {
        //从framework-res.apk里可以知道info.processName为 “system”进程,即framework-res.apk是要跑在system进程中的。
        ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
        app.persistent = true;
        app.pid = MY_PID;  //为ProcessRecord赋值当前进程ID,即system_server进程ID
        app.maxAdj = ProcessList.SYSTEM_ADJ;  //这个值跟OOM killer有关,值越小,越不容易被kill来释放内存
        app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
        //将ProcessRecord与ActivityThread进行关联
        synchronized (mPidsSelfLocked) {
            mPidsSelfLocked.put(app.pid, app);
            //将ProcessRecord放到mPidSelfLocked里统一管理
        }
        updateLruProcessLocked(app, false, null);
        updateOomAdjLocked();  //更新oom adj, 没看
    }
}

//生成 ProcessRecord对象
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
        boolean isolated, int isolatedUid) {
    String proc = customProcess != null ? customProcess : info.processName;
    final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
    if (!mBooted && !mBooting
            && userId == UserHandle.USER_OWNER
            && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
        r.persistent = true; //persistent
    }
    addProcessNameLocked(r);
    return r;
}

3.3 installSystemProviders

为系统安装settings provider

AMS installSystemProviders() //安装系统级的Providers

public final void installSystemProviders() {
    List providers;
    synchronized (this) {
        ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
        //这里是查找system进程的ProcessRecord,即 3.2节 生成的
        providers = generateApplicationProvidersLocked(app);
        //根据app.processName “system” 来查看Providers, 在这里是SettingsProvider
        if (providers != null) {
            for (int i=providers.size()-1; i>=0; i--) {
                ProviderInfo pi = (ProviderInfo)providers.get(i);
                if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                    Slog.w(TAG, "Not installing system proc provider " + pi.name
                            + ": not system .apk");
                    //这里只安装系统级的Providers
                    providers.remove(i);
                }
            }
        }
    }
    if (providers != null) {
        mSystemThread.installSystemProviders(providers);
    }

    mCoreSettingsObserver = new CoreSettingsObserver(this);

    //mUsageStatsService.monitorPackages();
}

//往ActivityThread里安装SystemProviders, mInitialApplication即是systemserver进程的Application, 前面有讲
mSystemThread.installSystemProviders(providers);
installContentProviders(mInitialApplication, providers);

private void installContentProviders(
        Context context, List providers) {
    final ArrayList results =
        new ArrayList();

    for (ProviderInfo cpi : providers) {
        if (DEBUG_PROVIDER) {
            StringBuilder buf = new StringBuilder(128);
            buf.append("Pub ");
            buf.append(cpi.authority);
            buf.append(": ");
            buf.append(cpi.name);
            Log.i(TAG, buf.toString());
        }
        //具体安装到 ActivityThread里的mProviderMap

        IActivityManager.ContentProviderHolder cph = installProvider(context, null,
                cpi,  false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
        if (cph != null) {
            cph.noReleaseNeeded = true;
            results.add(cph);
        }
    }

    try {
        ActivityManagerNative.getDefault().publishContentProviders(
            getApplicationThread(), results);
    } catch (RemoteException ex) {
    }
}

四、 SystemServer的ActivityThread安装图

将system_server进程配置成Android Application进程_第1张图片
图1 SystemServer的ActivityThread的安装图

你可能感兴趣的:(将system_server进程配置成Android Application进程)