当前位置:   article > 正文

android 程序启动 罗升阳,Android 系统的启动过程(3)

tracebeginandslog

上一篇说到,Zygote启动之后,最终会启动SystemServer进程,调用SystemServer.java的mian()方法。接下来看一下这个mian()方法。

/**

* The main entry point from zygote.

*/

public static void main(String[] args) {

new SystemServer().run();

}

这个main方法直接调用了SystemServer的run()方法。从这个main方法也可以看出,SystemServer进程是从zygote进程而来。

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);

// The system server should always load safe labels

PackageItemInfo.setForceSafeLabels(true);

// Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized

SQLiteCompatibilityWalFlags.init(null);

// 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());

// 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);

// Within the system server, when parceling exceptions, include the stack trace

Parcel.setStackTraceParceling(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();

Looper.getMainLooper().setSlowLogThresholdMs(

SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

// 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.setStartInfo(mRuntimeRestart,

mRuntimeStartElapsedTime, mRuntimeStartUptime);

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");

startBootstrapServices();

startCoreServices();

startOtherServices();

SystemServerInitThreadPool.shutdown();

} catch (Throwable ex) {

Slog.e("System", "******************************************");

Slog.e("System", "************ Failure starting system services", ex);

throw ex;

} finally {

traceEnd();

}

StrictMode.initVmDefaults(null);

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");

}

run()方法比较长,前部分初始化一些属性,设置之类的,包括初始化mainLooper,开启looper循环。重点关注

startBootstrapServices();

startCoreServices();

startOtherServices();

这个三个方法就是启动服务的地方。SystemServer要启动的服务很多,跟我们关系紧密的,首先就是ActivityManangerService(AMS),看一下AMS的启动。

mActivityManagerService = mSystemServiceManager.startService(

ActivityManagerService.Lifecycle.class).getService();

mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

mActivityManagerService.setInstaller(installer);

代码比较简单,先启动AMS,再把AMS设置为系统级服务,最后给ASM传入一个installer对象。这个installer对象是用来标记系统启动完成的。重点看startService方法。

public T startService(Class 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 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);

}

}

通过Class的getConstructor方法,获取AMS类的对象,然后嗲用startService()方法

public void startService(@NonNull final SystemService service) {

// Register it.

mServices.add(service);

// Start it.

long time = SystemClock.elapsedRealtime();

try {

service.onStart();

} catch (RuntimeException ex) {

throw new RuntimeException("Failed to start service " + service.getClass().getName()

+ ": onStart threw an exception", ex);

}

warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");

}

将service添加mServices列表中,调用SystemService的onStar()方法。从这里可以看出,AMS是SystemService的一个子类,而SystemService是一个抽象类,那么我们直接看AMS的onStart()方法。

public class ActivityManagerService extends IActivityManager.Stub

implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback{

//省略

}

但是看AMS并没有实现SystemService,那么onStart()方法在哪里呢?

其实,在AMS中有一个Lifecycle的内部类,这个内部类继承了SystemService,并且持有AMS的实例

public static final class Lifecycle extends SystemService {

private final ActivityManagerService mService;

public Lifecycle(Context context) {

super(context);

mService = new ActivityManagerService(context);

}

@Override

public void onStart() {

mService.start();

}

@Override

public void onBootPhase(int phase) {

mService.mBootPhase = phase;

if (phase == PHASE_SYSTEM_SERVICES_READY) {

mService.mBatteryStatsService.systemServicesReady();

mService.mServices.systemServicesReady();

}

}

@Override

public void onCleanupUser(int userId) {

mService.mBatteryStatsService.onCleanupUser(userId);

}

public ActivityManagerService getService() {

return mService;

}

}

这样,最终调用的是AMS的start()方法。

private void start() {

removeAllProcessGroups();

mProcessCpuThread.start();

mBatteryStatsService.publish();

mAppOpsService.publish(mContext);

Slog.d("AppOps", "AppOpsService published");

LocalServices.addService(ActivityManagerInternal.class, new LocalService());

// Wait for the synchronized block started in mProcessCpuThread,

// so that any other acccess to mProcessCpuTracker from main thread

// will be blocked during mProcessCpuTracker initialization.

try {

mProcessCpuInitLatch.await();

} catch (InterruptedException e) {

Slog.wtf(TAG, "Interrupted wait during start", e);

Thread.currentThread().interrupt();

throw new IllegalStateException("Interrupted wait during start");

}

}

我们知道,所有的服务都需要向ServiceManager注册之后才能够使用。但是,AMS的start()方法中并没有看到ServiceManager的addService方法,哪去了呢?

回过头来重新看startBootstrapServices方法, 其中

// Set up the Application instance for the system process and get started.

traceBeginAndSlog("SetSystemProcess");

mActivityManagerService.setSystemProcess();

traceEnd();

AMS的实例调用了setSystemProcess()方法

public void setSystemProcess() {

try {

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,

DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);

ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);

ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,

DUMP_FLAG_PRIORITY_HIGH);

ServiceManager.addService("gfxinfo", new GraphicsBinder(this));

ServiceManager.addService("dbinfo", new DbBinder(this));

if (MONITOR_CPU_USAGE) {

ServiceManager.addService("cpuinfo", new CpuBinder(this),

/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);

}

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);

}

// Start watching app ops after we and the package manager are up and running.

mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,

new IAppOpsCallback.Stub() {

@Override public void opChanged(int op, int uid, String packageName) {

if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {

if (mAppOpsService.checkOperation(op, uid, packageName)

!= AppOpsManager.MODE_ALLOWED) {

runInBackgroundDisabled(uid);

}

}

}

});

}

终于,在第3行看到我们期望的,AMS将自身注册到ServiceManager中。这样,ASM就可以正常使用了。

AMS启动之后,对于用户来说,还早着呢!

Android设备在每次开机之后,都会将之前安装的应用重新安装一遍,这就需要PackageManagerService(PMS)的支持。PMS的启动也是在startBootstrapServices方法中

mPackageManagerService = PackageManagerService.main(mSystemContext, installer,

mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

PMS的main方法

public static PackageManagerService main(Context context, Installer installer,

boolean factoryTest, boolean onlyCore) {

// Self-check for initial settings.

PackageManagerServiceCompilerMapping.checkProperties();

PackageManagerService m = new PackageManagerService(context, installer,

factoryTest, onlyCore);

m.enableSystemUserPackages();

ServiceManager.addService("package", m);

final PackageManagerNative pmn = m.new PackageManagerNative();

ServiceManager.addService("package_native", pmn);

return m;

}

这个方法看起来比较简单,创建一个PMS的对象m和一个PMS的本地对象,并注册到ServiceManager中,我们重点关注一下PMS的构造函数。

public PackageManagerService(Context context, Installer installer,

boolean factoryTest, boolean onlyCore) {

//省略

}

这个构造方法比较长,我们只看其中跟流程相关的重点部分。

...

mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.log", LOG_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.se", SE_UID,

ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

...

mSetting是用来保存上一次安装应用的信息,在下一次安装的时候能够保证信息的一致性,特别是用户Id跟用户组Id等重要信息。

scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_VENDOR,

0);

scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_PRODUCT,

0);

mParallelPackageParserCallback.findStaticOverlayPackages();

// Find base frameworks (resource packages without code).

scanDirTracedLI(frameworkDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_NO_DEX

| SCAN_AS_SYSTEM

| SCAN_AS_PRIVILEGED,

0);

// Collect privileged system packages.

final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");

scanDirTracedLI(privilegedAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_PRIVILEGED,

0);

// Collect ordinary system packages.

final File systemAppDir = new File(Environment.getRootDirectory(), "app");

scanDirTracedLI(systemAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM,

0);

// Collect privileged vendor packages.

File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");

try {

privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(privilegedVendorAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_VENDOR

| SCAN_AS_PRIVILEGED,

0);

// Collect ordinary vendor packages.

File vendorAppDir = new File(Environment.getVendorDirectory(), "app");

try {

vendorAppDir = vendorAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(vendorAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_VENDOR,

0);

// Collect privileged odm packages. /odm is another vendor partition

// other than /vendor.

File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),

"priv-app");

try {

privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(privilegedOdmAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_VENDOR

| SCAN_AS_PRIVILEGED,

0);

// Collect ordinary odm packages. /odm is another vendor partition

// other than /vendor.

File odmAppDir = new File(Environment.getOdmDirectory(), "app");

try {

odmAppDir = odmAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(odmAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_VENDOR,

0);

// Collect all OEM packages.

final File oemAppDir = new File(Environment.getOemDirectory(), "app");

scanDirTracedLI(oemAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_OEM,

0);

// Collected privileged product packages.

File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");

try {

privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(privilegedProductAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_PRODUCT

| SCAN_AS_PRIVILEGED,

0);

// Collect ordinary product packages.

File productAppDir = new File(Environment.getProductDirectory(), "app");

try {

productAppDir = productAppDir.getCanonicalFile();

} catch (IOException e) {

// failed to look up canonical path, continue with original one

}

scanDirTracedLI(productAppDir,

mDefParseFlags

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanFlags

| SCAN_AS_SYSTEM

| SCAN_AS_PRODUCT,

0);

这部分代码主要扫描特定路径下的文件,来安装保存在其中的程序。

我们随便看一个列子

private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {

Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");

try {

scanDirLI(scanDir, parseFlags, scanFlags, currentTime);

} finally {

Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

}

}

private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {

final File[] files = scanDir.listFiles();

if (ArrayUtils.isEmpty(files)) {

Log.d(TAG, "No files in app dir " + scanDir);

return;

}

if (DEBUG_PACKAGE_SCANNING) {

Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags

+ " flags=0x" + Integer.toHexString(parseFlags));

}

try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(

mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,

mParallelPackageParserCallback)) {

// Submit files for parsing in parallel

int fileCount = 0;

for (File file : files) {

final boolean isPackage = (isApkFile(file) || file.isDirectory())

&& !PackageInstallerService.isStageName(file.getName());

if (!isPackage) {

// Ignore entries which are not packages

continue;

}

parallelPackageParser.submit(file, parseFlags);

fileCount++;

}

// Process results one by one

for (; fileCount > 0; fileCount--) {

ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();

Throwable throwable = parseResult.throwable;

int errorCode = PackageManager.INSTALL_SUCCEEDED;

if (throwable == null) {

// TODO(toddke): move lower in the scan chain

// Static shared libraries have synthetic package names

if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {

renameStaticSharedLibraryPackage(parseResult.pkg);

}

try {

if (errorCode == PackageManager.INSTALL_SUCCEEDED) {

scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,

currentTime, null);

}

} catch (PackageManagerException e) {

errorCode = e.error;

Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());

}

} else if (throwable instanceof PackageParser.PackageParserException) {

PackageParser.PackageParserException e = (PackageParser.PackageParserException)

throwable;

errorCode = e.error;

Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());

} else {

throw new IllegalStateException("Unexpected exception occurred while parsing "

+ parseResult.scanFile, throwable);

}

// Delete invalid userdata apps

if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&

errorCode != PackageManager.INSTALL_SUCCEEDED) {

logCriticalInfo(Log.WARN,

"Deleting invalid package at " + parseResult.scanFile);

removeCodePathLI(parseResult.scanFile);

}

}

}

}

整个安装过程就是两个for循环,第一个是遍历文件夹下的安装包,第二个是循环解析安装包安装。这里只看流程,不做具体分析(也没有能力),具体的分析请查看源码或者参考罗升阳的《Android系统源代码情景分析》。

AMS启动了,PMS也把该安装的应用安装了,该启动Launcher进程让用户看到了吧?不要急,除了AMS,PMS之外,跟应用开发者,跟用户息息相关的服务还有WindowManagerService(WSM)跟InputManagerService(IMS),这些都准备好了,才能启动Launcher进程,用户与设备才是可见、可交互的。

下面我们在来看一下WMS的启动流程。WSM是在SystemServer中的startOtherServices()方法中启动的。

traceBeginAndSlog("StartInputManagerService");

inputManager = new InputManagerService(context);

traceEnd();

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, /* allowIsolated= */ false,

DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);

ServiceManager.addService(Context.INPUT_SERVICE, inputManager,

/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);

traceEnd();

traceBeginAndSlog("SetWindowManagerService");

mActivityManagerService.setWindowManager(wm);

traceEnd();

这里先创建一个IMS的对象,再创建一个WMS对象,并且注册到SM中。

IMS的构造函数

public InputManagerService(Context context) {

this.mContext = context;

this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());

mUseDevInputEventForAudioJack =

context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);

Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="

+ mUseDevInputEventForAudioJack);

mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

String doubleTouchGestureEnablePath = context.getResources().getString(

R.string.config_doubleTouchGestureEnableFile);

mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :

new File(doubleTouchGestureEnablePath);

LocalServices.addService(InputManagerInternal.class, new LocalService());

}

实例化一个InputManagerHandler对象,作为参数做本地初始化,不做深入分析。看一下WMS的main()方法

public static WindowManagerService main(final Context context, final InputManagerService im,

final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,

WindowManagerPolicy policy) {

DisplayThread.getHandler().runWithScissors(() ->

sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,

onlyCore, policy), 0);

return sInstance;

}

继续WMS的构造方法

private WindowManagerService(Context context, InputManagerService inputManager,

boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,

WindowManagerPolicy policy) {

installLock(this, INDEX_WINDOW);

mContext = context;

mHaveInputMethods = haveInputMethods;

mAllowBootMessages = showBootMsgs;

mOnlyCore = onlyCore;

mLimitedAlphaCompositing = context.getResources().getBoolean(

com.android.internal.R.bool.config_sf_limitedAlpha);

mHasPermanentDpad = context.getResources().getBoolean(

com.android.internal.R.bool.config_hasPermanentDpad);

mInTouchMode = context.getResources().getBoolean(

com.android.internal.R.bool.config_defaultInTouchMode);

mDrawLockTimeoutMillis = context.getResources().getInteger(

com.android.internal.R.integer.config_drawLockTimeoutMillis);

mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(

com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);

mMaxUiWidth = context.getResources().getInteger(

com.android.internal.R.integer.config_maxUiWidth);

mDisableTransitionAnimation = context.getResources().getBoolean(

com.android.internal.R.bool.config_disableTransitionAnimation);

mInputManager = inputManager; // Must be before createDisplayContentLocked.

mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

mDisplaySettings = new DisplaySettings();

mDisplaySettings.readSettingsLocked();

mPolicy = policy;

mAnimator = new WindowAnimator(this);

mRoot = new RootWindowContainer(this);

mWindowPlacerLocked = new WindowSurfacePlacer(this);

mTaskSnapshotController = new TaskSnapshotController(this);

mWindowTracing = WindowTracing.createDefaultAndStartLooper(context);

LocalServices.addService(WindowManagerPolicy.class, mPolicy);

if(mInputManager != null) {

final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);

mPointerEventDispatcher = inputChannel != null

? new PointerEventDispatcher(inputChannel) : null;

} else {

mPointerEventDispatcher = null;

}

mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);

mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);

if (mPowerManagerInternal != null) {

mPowerManagerInternal.registerLowPowerModeObserver(

new PowerManagerInternal.LowPowerModeListener() {

@Override

public int getServiceType() {

return ServiceType.ANIMATION;

}

@Override

public void onLowPowerModeChanged(PowerSaveState result) {

synchronized (mWindowMap) {

final boolean enabled = result.batterySaverEnabled;

if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {

mAnimationsDisabled = enabled;

dispatchNewAnimatorScaleLocked(null);

}

}

}

});

mAnimationsDisabled = mPowerManagerInternal

.getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;

}

mScreenFrozenLock = mPowerManager.newWakeLock(

PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");

mScreenFrozenLock.setReferenceCounted(false);

mAppTransition = new AppTransition(context, this);

mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);

final AnimationHandler animationHandler = new AnimationHandler();

animationHandler.setProvider(new SfVsyncFrameCallbackProvider());

mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,

AnimationThread.getHandler(), animationHandler);

mActivityManager = ActivityManager.getService();

mAmInternal = LocalServices.getService(ActivityManagerInternal.class);

mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);

AppOpsManager.OnOpChangedInternalListener opListener =

new AppOpsManager.OnOpChangedInternalListener() {

@Override public void onOpChanged(int op, String packageName) {

updateAppOpsState();

}

};

mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);

mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);

mPmInternal = LocalServices.getService(PackageManagerInternal.class);

final IntentFilter suspendPackagesFilter = new IntentFilter();

suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);

suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);

context.registerReceiverAsUser(new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

final String[] affectedPackages =

intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);

final boolean suspended =

Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());

updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)),

suspended);

}

}, UserHandle.ALL, suspendPackagesFilter, null, null);

// Get persisted window scale setting

mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),

Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);

mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),

Settings.Global.TRANSITION_ANIMATION_SCALE,

context.getResources().getFloat(

R.dimen.config_appTransitionAnimationDurationScaleDefault));

setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),

Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));

IntentFilter filter = new IntentFilter();

// Track changes to DevicePolicyManager state so we can enable/disable keyguard.

filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);

mContext.registerReceiver(mBroadcastReceiver, filter);

mLatencyTracker = LatencyTracker.getInstance(context);

mSettingsObserver = new SettingsObserver();

mHoldingScreenWakeLock = mPowerManager.newWakeLock(

PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);

mHoldingScreenWakeLock.setReferenceCounted(false);

mSurfaceAnimationRunner = new SurfaceAnimationRunner();

mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(

com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);

mTaskPositioningController = new TaskPositioningController(

this, mInputManager, mInputMonitor, mActivityManager, mH.getLooper());

mDragDropController = new DragDropController(this, mH.getLooper());

LocalServices.addService(WindowManagerInternal.class, new LocalService());

}

WMS的构造方法做了很多系统级别的参数设置,我们关注的IMS的实例也是在这里赋值给了WMS,这样WMS就持有了IMS的引用。而在前面的代码中

mActivityManagerService.setWindowManager(wm);

又将WMS的实例赋值给AMS,这样AMS就持有了WMS的引用,三者之间就相互关联起来了。

我们需要的服务都启动了,这下总该Launcher进程启动了吧?Launcher进程又是在哪里启动的呢?看SystemServer的startOtherService方法最后

mActivityManagerService.systemReady

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {

...

startHomeActivityLocked(currentUserId, "systemReady");

...

}

在systemReady之后,调用startHomeActivityLocked方法,就是启动Launcher进程。

boolean startHomeActivityLocked(int userId, String reason) {

if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL

&& mTopAction == null) {

// We are running in factory test mode, but unable to find

// the factory test app, so just sit around displaying the

// error message and don't try to start anything.

return false;

}

Intent intent = getHomeIntent();

ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);

if (aInfo != null) {

intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));

// Don't do this if the home app is currently being

// instrumented.

aInfo = new ActivityInfo(aInfo);

aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);

ProcessRecord app = getProcessRecordLocked(aInfo.processName,

aInfo.applicationInfo.uid, true);

if (app == null || app.instr == null) {

intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);

final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);

// For ANR debugging to verify if the user activity is the one that actually

// launched.

final String myReason = reason + ":" + userId + ":" + resolvedUserId;

mActivityStartController.startHomeActivity(intent, aInfo, myReason);

}

} else {

Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());

}

return true;

}

其中涉及到应用的启动过程,进程间的binder通信,后续再分析。这样Launcher终于启动了,用户终于可以看到桌面,点击应用了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/227823
推荐阅读
相关标签
  

闽ICP备14008679号