Installer启动分析
本篇继续解析pms前置installer服务的启动
系统启动之后init进程会解析各种.rc文件最后以service形式拉起zygote,zygote会fork各种系统服务,比如SystemServer,SystemServer会启动多种关键服务。
这里不再赘述init进程启动及zygote、SystemServer是如何启动
- Installer服务
- 总结
SystemServer是如何启动installer的
入口是在main函数
/frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
...
public static void main(String[] args) {
new SystemServer().run();
}
...
private void run() {
...
Looper.prepareMainLooper();
...
startBootstrapServices();
startCoreServices();
startOtherServices();
...
Looper.loop();
...
}
private void startBootstrapServices() {
...
Installer installer = mSystemServiceManager.startService(Installer.class);
...
}
...
}
略去部分细节,run主要启动各种服务,开启主线程Looper开启消息分发
Installer服务是在startBootstrapServices中启动的
Installer启动
接下来看SystemServiceManager#startService实现
/frameworks/base/services/java/com/android/server/SystemServiceManager.java
public class SystemServiceManager {
...
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
...
}
return startService(serviceClass);
}
...
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
...
//如果不是SystemService子类说明要启动的不是个系统服务
if (!SystemService.class.isAssignableFrom(serviceClass)) {
...
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
...
} catch (IllegalAccessException ex) {
..
} catch (NoSuchMethodException ex) {
...
} catch (InvocationTargetException ex) {
...
}
startService(service);
return service;
} finally {
...
}
}
...
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
...
try {
service.onStart();
} catch (RuntimeException ex) {
...
}
...
}
...
}
看到整个调用流程就是拿到Installer.class然后调用构造函数初始化一个Installer
最后先cache要启动的Installer,然后调用service.onStart()去启动服务,先看Installer的实现
/frameworks/base/services/java/com/android/server/pm/Installer.java
public class Installer extends SystemService {
...
private final boolean mIsolated;
...
public Installer(Context context) {
this(context, false);
}
public Installer(Context context, boolean isolated) {
super(context);
mIsolated = isolated;
}
...
@Override
public void onStart() {
if (mIsolated) {
...
} else {
connect();
}
}
private void connect() {
//获取installd的proxy贼复杂
IBinder binder = ServiceManager.getService("installd");
if (binder != null) {
try {
//死亡通知重连
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
...
connect();
}
}, 0);
} catch (RemoteException e) {
binder = null;
}
}
if (binder != null) {
mInstalld = IInstalld.Stub.asInterface(binder);
try {
invalidateMounts();
} catch (InstallerException ignored) {
...
}
} else {
...
}
}
...
}
这里三件件事,获取installd守护进程,设置binder的死亡通知,然后去调用invalidateMounts判断sdcard状态
接下来分析调用流程,前方车速较快,乘客请做好
ServiceManager.getService(“installd”)
/frameworks/base/core/java/android/os/ServiceManager.java
public final class ServiceManager {
...
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
//BinderInternal.getContextObject() 拿到bpBinder(0)
//之后对bpBinder(0)做一层封装返回BinderProxy
sServiceManager = ServiceManagerNative
.asInterface(Binder
.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
...
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
...
}
return null;
}
...
private static IBinder rawGetService(String name) throws RemoteException {
...
final IBinder binder = getIServiceManager().getService(name);
...
return binder;
}
}
- 首次调用sCache中如果没有缓存的server就通过rawGetService()去查找对应的服务
getIServiceManager()
getIServiceManager()调用比较复杂,我们先来看BinderInternal.getContextObject()实现
BinderInternal.getContextObject()
/frameworks/base/core/java/com/android/internal/os/BinderInternal.java
public class BinderInternal {
...
public static final native IBinder getContextObject();
...
}
这个是个native方法,对应jni实现在/frameworks/base/core/jni/android_util_Binder.cpp
...
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
...
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
...
};
...
jni中getContextObject对应的函数是android_os_BinderInternal_getContextObject,其中主要通过ProcessState::getContextObject(NULL)拿到bpBinder(0)也就是service_manager的代理对象,然后经过一层包装,最后返还给java层
ProcessState::getContextObject
/frameworks/native/libs/binder/ProcessState.cpp
...
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
//这里传入的handle为0
return getStrongProxyForHandle(0);
}
...
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
...
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
...
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
...
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
...
}
}
return result;
}
...
- 可以看到实际上拿到的就是个BpBinder(0),具体流程可以参考笔者Binder分析那篇,这里不再赘述
javaObjectForIBinder
分析javaObjectForIBinder()实现之前,我们先来看一些jni初始化相关的java层引用
/frameworks/base/core/jni/android_util_Binder.cpp
...
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mGetInstance;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;
...
int register_android_os_Binder(JNIEnv* env)
{
....
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
...
}
...
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
//BinderProxy
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//BinderProxy#getInstance
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env,
clazz, "getInstance", "(JJ)Landroid/os/BinderProxy;");
...
//BinderProxy#mNativeData
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz,
"mNativeData", "J");
//Class
clazz = FindClassOrDie(env, "java/lang/Class");
//Class#getName
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz,
"getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
...
- jni文件初始化时候会去解析拿到BinderProxy的class、getInstance、mNativeData等信息并存到gBinderProxyOffsets这个struct中
接下来看javaObjectForIBinder()的实现
/frameworks/base/core/jni/android_util_Binder.cpp
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
}
...
struct BinderProxyNativeData {
// The native IBinder proxied by this BinderProxy.
sp<IBinder> mObject;
sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
};
...
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
//一系列校验
...
//封装BinderProxyNativeData
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
//调用BinderProxy#getInstance(nativeData,val.get())
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
...
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
...
return object;
}
- 这里val指向的是bpBinder(0),这里构造了BinderProxyNativeData结构体用来存bpBinder(0)与死亡通知队列DeathRecipientList,之后通过调用BinderProxy#getInstance()将nativeData的地址及bpBinder(0)地址传入,最后经过数据初始化然后返回一个BinderProxy对象
/frameworks/base/core/java/android/os/BinderProxy.java
public final class BinderProxy implements IBinder {
...
private static BinderProxy getInstance(long nativeData, long iBinder) {
BinderProxy result;
synchronized (sProxyMap) {
try {
result = sProxyMap.get(iBinder);
if (result != null) {
return result;
}
result = new BinderProxy(nativeData);
} catch (Throwable e) {
...
}
...
sProxyMap.set(iBinder, result);
}
return result;
}
...
}
BinderProxy#getInstance实际上就是cache了bpBinder(0)与BinderProxy对象的map,方便后续多次使用
ServiceManagerNative#asInterface
回到getIServiceManager(),Binder.allowBlocking只是将BinderProxy的mWarnOnBlocking置位false
public static IBinder allowBlocking(IBinder binder) {
try {
if (binder instanceof BinderProxy) {
((BinderProxy) binder).mWarnOnBlocking = false;
}else if(...){
...
}
} catch (RemoteException ignored) {
}
return binder;
}
最终ServiceManagerNative#asInterface拿到返回一个ServiceManagerProxy并赋值给sServiceManager
/frameworks/base/core/java/android/os/ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
...
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
//obj就是持有BpBinder(0)的BinderProxy对象
return new ServiceManagerProxy(obj);
}
...
}
ServiceManagerProxy#getService
接下来我们看ServiceManagerProxy#getService
/frameworks/base/core/java/android/os/ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
...
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
...
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
//service_manager返回的installd对象
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
...
}
...
}
ServiceManagerProxy是一个内部类,mRemote就是前文中提到的持有BpBinder(0)的BinderProxy对象,最终是一个跨进程通信,这里name是installd
BinderProxy#transact
BinderProxy最终会调用到transactNative,直接来看jni
/frameworks/base/core/jni/android_util_Binder.cpp
...
static const JNINativeMethod gBinderProxyMethods[] = {
...
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}
...
}
-对应的JNI函数为android_os_BinderProxy_transact
/frameworks/base/core/jni/android_util_Binder.cpp
...
static jboolean android_os_BinderProxy_transact(JNIEnv* env,
jobject obj, jint code, jobject dataObj,
jobject replyObj, jint flags)
{
...
Parcel* data = parcelForJavaObject(env, dataObj);
...
Parcel* reply = parcelForJavaObject(env, replyObj);
...
//前面存到BinderProxyNativeData中拿到bpBinder
IBinder* target = getBPNativeData(env, obj)->mObject.get();
...
status_t err = target->transact(code, *data, reply, flags);
...
}
...
这里实际上就是拿到前面获取过的BpBinder(0),然后调用BpBinder(0)#transact()去发起binder查找通信,service服务的查找清参考老罗的Android的Binder系列
回到ServiceManagerProxy#getService,最终会从ipc通信reply中拿到一个IBinder对象
Parcel#readStrongBinder
/frameworks/base/core/java/android/os/Parcel.java
public final class Parcel {
...
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
...
}
查看jni调用
/frameworks/base/core/jni/android_os_Parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
//封装成BinderProxy返回给java层
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
...
static const JNINativeMethod gParcelMethods[] = {
...
{"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}
...
}
android_os_Parcel_readStrongBinder主要是就是调用parcel->readStrongBinder拿到对应的BpBinder引用对象
Parcel::readStrongBinder
接下来我们来看是怎么解析到servce_manager返回的BpBinder代理对象的
/frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
status_t status = readNullableStrongBinder(val);
if (status == OK && !val->get()) {
status = UNEXPECTED_NULL;
}
return status;
}
status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
return unflatten_binder(ProcessState::self(), *this, val);
}
...
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, sp<IBinder>* out)
{
const flat_binder_object* flat = in.readObject(false);
if (flat) {
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(nullptr, *flat, in);
case BINDER_TYPE_HANDLE:
//前文分析过这个就是获取handle持有的BpBinder
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
调用链readStrongBinder->readNullableStrongBinder->unflatten_binder,我在Binder那篇中关于binder通信数据传递有一张图
同样适用于这里,通过service_manager查找服务返回的type是BINDER_TYPE_HANDLE,这里不解释为啥,自己去看/frameworks/native/cmds/servicemanager/service_manager.c中查找服务的实现
回到android_os_Parcel_readStrongBinder,接下来调用javaObjectForIBinder讲查到的installd的BpBinder封装成一个BinderProxy返回给java层,在这之后Java层就可以通过这个BinderProxy与installd通信
Installer#invalidateMounts
回到Installer#connect中,有了installd的代理Binder对象以后,先绑定死亡通知重连,之后讲installd的代理Binder对象再包一层,赋值给mInstalld最后调用invalidateMounts
/frameworks/base/services/core/java/android/server/pm/installer.java
public class Installer extends SystemService {
...
public void invalidateMounts() throws InstallerException {
...
try {
mInstalld.invalidateMounts();
} catch (Exception e) {
throw InstallerException.from(e);
}
}
...
}
mInstalld怎么去做ipc调用的不再细述,上一篇installd进程启动分析中,installd启动时候注册的Service是InstalldNativeService
InstalldNativeService::invalidateMounts
InstalldNativeService定义在/frameworks/native/cmds/installd/InstalldNativeService.h中,不再贴了读者感兴趣可以看其定义,直接来看invalidateMounts实现
/frameworks/native/cmds/installd/InstalldNativeService.cpp
...
binder::Status InstalldNativeService::invalidateMounts() {
ENFORCE_UID(AID_SYSTEM);
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
//清理cache
mStorageMounts.clear();
//BYPASS_QUOTA == 0
#if !BYPASS_QUOTA
if (!InvalidateQuotaMounts()) {
...
}
#endif
//检查mounts授权
std::ifstream in("/proc/mounts");
if (!in.is_open()) {
return error("Failed to read mounts");
}
std::string source;
std::string target;
std::string ignored;
/**
* tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,size=1812472k,nr_inodes=453118,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,mode=600,ptmxmode=000 0 0
*/
while (!in.eof()) {
//获取source devpts
std::getline(in, source, ' ');
//获取target路径 /dev/pts
std::getline(in, target, ' ');
std::getline(in, ignored);
#if !BYPASS_SDCARDFS
//SDCARD 检查
if (target.compare(0, 21, "/mnt/runtime/default/") == 0) {
...
mStorageMounts[source] = target;
}
#endif
}
return ok();
}
...
bool InvalidateQuotaMounts() {
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
mQuotaReverseMounts.clear();
std::ifstream in("/proc/mounts");
if (!in.is_open()) {
return false;
}
std::string source;
std::string target;
std::string ignored;
while (!in.eof()) {
std::getline(in, source, ' ');
std::getline(in, target, ' ');
std::getline(in, ignored);
if (source.compare(0, 11, "/dev/block/") == 0) {
struct dqblk dq;
//Get disk quota limits and current usage for user or group id
if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0,
reinterpret_cast<char*>(&dq)) == 0) {
...
mQuotaReverseMounts[target] = source;
}
}
}
return true;
}
...
- /proc/monuts文件长这样
解析过程中,例如第一行中
source = proc
target = /proc
ignored = proc rw,relatime,gid=3009,hidepid=2 0 0
首先调用InvalidateQuotaMounts去检查用户磁盘配额quotactl并存到mQuotaReverseMounts中
然后去sdcard是否已经mount授权,并存到mStorageMounts中
总结
至此,整个installer就启动完成,总结下来,installer回去查installd守护进程并将获取到的Binder代理对象cache到mInstalld中便于后续交互通信,启动过程中如果binder不小心跪了,会有重连策略,初始化最终的目的是解析用户磁盘授权+sdcard的授权