(N)Telephony分析(三)之PhoneApp启动

时间:2022-01-09 19:47:13

此前,分析过,SystemServer的启动,那么接着上篇,继续分析PhoneApp的启动

首先,SystemServer启动时,进入其的main函数

SystemServer.java文件

public static void main(String[] args) {
new SystemServer().run();
}
private void run() {......    // Start services.    try {        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");        startBootstrapServices();        startCoreServices();        startOtherServices();    } catch (Throwable ex) {        ......    }    ......}
private void startBootstrapServices() {    ......    // Activity manager runs the show.    mActivityManagerService = mSystemServiceManager.startService(            ActivityManagerService.Lifecycle.class).getService();    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);    mActivityManagerService.setInstaller(installer);    ......
 
    // Set up the Application instance for the system process and get started.    // Leo,调用ActivityManagerService对象爱那个的setSystemProcess方法    mActivityManagerService.setSystemProcess();
    ......}
从这个地方来看,好像是创建了一个ActivityManagerService对象,OK,我们先来看下SystemServiceManager对象的startService方法

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 {
                // Leo, 原来是之调用了serviceClass的构造函数                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                // Leo,得到serviceClass的对象                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);            }            // Register it.            mServices.add(service);            // Start it.            try {
                // Leo, 调用其onStart方法                service.onStart();            } catch (RuntimeException ex) {                throw new RuntimeException("Failed to start service " + name                        + ": onStart threw an exception", ex);            }            return service;        } finally {            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);        }    }
原来是调用了serviceClass类的构造函数,然后再调用其onStart方法,传入的参数为ActivityManagerService.Lifecycle.class,因此,我们查看Lifecycle内部类的实现

public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;

// Leo, 构造函数中,新建了一个ActivityManagerService的对象
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}

@Override
// Leo,onStart方法中,其实就是调用了ActivityManagerService对象的start方法
public void onStart() {
mService.start();
}

// Leo,返回ActivityManagerService对象
public ActivityManagerService getService() {
return mService;
}
}
从这个内部类,我们可以看出,实际上,在调用SystemServiceManager的startService方法,是新建了一个ActivityManagerService的对象,然后调用其start方法,最后使用getService方法,返回该对象,由此,我们启动ActivityManagerService,这个是Android的核心进程,掌控了四大组件的启动,转换,调度等工作

接下来调用了ActivityManagerService对象的setSystemProcess方法

public void setSystemProcess() {
try {
// Leo, 将Service加入到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));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));

ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
其将service加入到ServiceManager中进行管理,后续我们再研究分析ServiceManager的addService和getService方法,暂时不提

接下来,查看ServiceServer的run方法中的其他方法,startOtherService

private void startOtherServices() {
......
// Leo, 调用ActivityManagerService的systemReady方法
mActivityManagerService.systemReady(......);
}
调用ActivityManagerService的systemReady方法

public void systemReady(final Runnable goingCallback) {
......
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
.....
}
private void startPersistentApps(int matchFlags) {    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;    synchronized (this) {        try {            final List<ApplicationInfo> apps = AppGlobals.getPackageManager()                    .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();            for (ApplicationInfo app : apps) {                if (!"android".equals(app.packageName)) {                    addAppLocked(app, false, null /* ABI override */);                }            }        } catch (RemoteException ex) {        }    }}
从这边可以看到,ActivityManagerService将persistent和directbootaware属性的应用通过addAppLocked方法,做了一些操作,那么先来看看PhoneApp的AndroidManifest.xml文件中是否具有该两个属性

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.phone"
coreApp="true"
android:sharedUserId="android.uid.phone"
android:sharedUserLabel="@string/phoneAppLabel"
>
......
<application android:name="PhoneApp"
android:persistent="true"
android:label="@string/phoneAppLabel"
android:icon="@mipmap/ic_launcher_phone"
android:allowBackup="false"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
......
</application>
</manifest>
可以看到,PhoneApp具有这两个属性,那么PhoneApp应用,会被addAppLocked处理,而针对于PhoneApp应用来说,ApplicationInfo指的是其应用信息,第二个参数为false,第三个参数为null

// Leo, info is app, isolated is false, abiOverride is null
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
String abiOverride) {
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(info.processName, info.uid, true);
} else {
app = null;
}

if (app == null) {
// Leo, 通过ApplicationInfo获取ProcessRecord
app = newProcessRecordLocked(info, null, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}

// This package really, really can not be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
info.packageName, false, UserHandle.getUserId(app.uid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ info.packageName + ": " + e);
}

if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
app.persistent = true;
app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
// Leo,调用startProcessLocked,看这个方法的名称,应该是启动该应用
startProcessLocked(app, "added application", app.processName, abiOverride,
null /* entryPoint */, null /* entryPointArgs */);
}

return app;
}
调用startProcessLocked方法,启动该应用

// Leo, hosting Type is "added application", addAppLocked is null, entryPoint is null, entryPointArgs is null
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
// Leo, 配置启动进程的一些必要参数
......
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        // Leo, 调用Process的start方法,看样子,是在这边启动进程,注意这边的entryPoint参数是"android.app.ActivityThread"        Process.ProcessStartResult startResult = Process.start(entryPoint,                app.processName, uid, uid, gids, debugFlags, mountExternal,                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,                app.info.dataDir, entryPointArgs);        ......    }
public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] zygoteArgs) {        ......
// Leo, 注意,此处的processClass为"android.app.ActivityThread"        return startViaZygote(processClass, niceName, uid, gid, gids,                debugFlags, mountExternal, targetSdkVersion, seInfo,                abi, instructionSet, appDataDir, zygoteArgs);        ......    }
继续,注意此处的processClass为"android.app.ActivityThread",而其他的参数均是和PhoneApp相关,之后,通过和zygote的通信,fork一个进程,调用ActivityThread的main函数,过程以后再分析研究

public static void main(String[] args) {
......
ActivityThread thread = new ActivityThread();
thread.attach(false);
......
}
private void attach(boolean system) {// Leo, 调用IActivityManager的attachApplication    final IActivityManager mgr = ActivityManagerNative.getDefault();    try {        mgr.attachApplication(mAppThread);    } catch (RemoteException ex) {        throw ex.rethrowFromSystemServer();    }}
调用ActivityManagerNative的getDefault方法后,返回IActivityManager,并调用其attachApplication方法

static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {    protected IActivityManager create() {        IBinder b = ServiceManager.getService("activity");        if (false) {            Log.v("ActivityManager", "default service binder = " + b);        }        IActivityManager am = asInterface(b);        if (false) {            Log.v("ActivityManager", "default service = " + am);        }        return am;    }};
在此前ActivityManagerService的setSystemProcess方法中,有ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);,因此,此时使用ServiceManager.getService("activity");取出的就是ActivityManagerService对象,然后通过asInterface方法,将ActivityManagerService和ActivityManagerProxy建立连接关系

我们继续查看ActivityManagerProxy的attachApplication,此后通过一系列的Binder通信,调用的是ActivityManagerService的attachApplication方法,因此

public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
// Leo,调用attachApplicationLocked方法
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,    int pid) {......    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,            app.instrumentationUiAutomationConnection, testMode,            mBinderTransactionTrackingEnabled, enableTrackAllocation,            isRestrictedBackupMode || !normalMode, app.persistent,            new Configuration(mConfiguration), app.compat,            getCommonServicesLocked(app.isolated),            mCoreSettingsObserver.getCoreSettingsLocked());......}

而IApplicationThread是什么呢?此地就不多说了,依旧是通过Binder通信来连接的IBinder,一个为ApplicationThreadProxy,另一个是ApplicationThread

因此最终调用的是ApplicationThread的bindApplication方法

ActivityThread.java

public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {

if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}

setCoreSettings(coreSettings);

AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
public void handleMessage(Message msg) {    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));    switch (msg.what) {    ......        case BIND_APPLICATION:            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");            AppBindData data = (AppBindData)msg.obj;            // Leo, 调用handleBindApplication方法            handleBindApplication(data);            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);            break;        ......    }}
调用handleBindApplication方法

private void handleBindApplication(AppBindData data) {
......
// Continue loading instrumentation.
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}

final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

if (mProfiler.profileFile != null && !ii.handleProfiling
&& mProfiler.profileFd == null) {
mProfiler.handlingProfiling = true;
final File file = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
mInstrumentation = new Instrumentation();
}
......
try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
......
}
最红调用到Instrumentation的callApplicationOnCreate方法中

public void callApplicationOnCreate(Application app) {
app.onCreate();
}
而我们知道,此处的Application代表的是PhoneApp应用信息,因此直接进入PhoneApp的oncreate方法,此时PhoneApp即已经启动