2024-03-27
·
32 min read
·
#Binder
Binder Framework 层(基于android 12.0/S)
Binder在Fwk层通过JNI访问到Binder Native的框架,并且主要的操作是交由Binder Na […]
> 原文发布于主站:[查看原文](https://zhinengzuocang.cn/2024/03/27/binder-framework-%e5%b1%82%e5%9f%ba%e4%ba%8eandroid-12-0-s/)
<p>Binder在Fwk层通过JNI访问到Binder Native的框架,并且主要的操作是交由Binder Native进行处理的。</p>
<p>Bp:BinderProxy 代理肯定是client端</p>
<p>Bn: BinderNative native是server端</p>
<p>Binder 服务的启动是由zygote进程调用AndroidRuntime.cpp 中的startReg 通过JNI进行注册的,本文主要侧重FWK层的其他流程,Binder启动过程可以参考一下其他的博客。</p>
<p>Fwk层的ServiceManager位于:</p>
<p>/frameworks/base/core/java/android/os/ServiceManager.java</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="487" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-7-1024x487.png" alt="" class="wp-image-382" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-7-1024x487.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-7-300x143.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-7-768x365.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-7.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<h3 class="wp-block-heading">添加服务:</h3>
<p>ServiceManager 类中一共有三个重载的addService方法</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="422" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-8-1024x422.png" alt="" class="wp-image-383" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-8-1024x422.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-8-300x124.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-8-768x316.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-8.png 1127w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="450" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-9-1024x450.png" alt="" class="wp-image-384" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-9-1024x450.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-9-300x132.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-9-768x338.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-9.png 1228w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>最终都会附加参数调用到下面的方法:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="446" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-10-1024x446.png" alt="" class="wp-image-385" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-10-1024x446.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-10-300x131.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-10-768x334.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-10.png 1181w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>前两个重载方法中的DUMP_FLAG_PRIORITY_DEFAULT 是dump的级别,这里采用默认级别即可。</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="358" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-11-1024x358.png" alt="" class="wp-image-386" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-11-1024x358.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-11-300x105.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-11-768x268.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-11.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>addService中 首先通过getIServiceManager获取到ServiceManager的代理,然后执行addService方法将服务添加到ServiceManager的管理中。</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="519" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-12-1024x519.png" alt="" class="wp-image-387" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-12-1024x519.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-12-300x152.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-12-768x389.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-12.png 1151w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>拆解如下:</p>
<p>BinderInternal.getContextObject()</p>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="1022" height="401" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-13.png" alt="" class="wp-image-388" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-13.png 1022w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-13-300x118.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-13-768x301.png 768w" sizes="(max-width: 1022px) 100vw, 1022px" /></figure>
<p>通过JNI 调用到 android_util_Binder中的方法,实现了Java到C++的转换。</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="332" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-14-1024x332.png" alt="" class="wp-image-389" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-14-1024x332.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-14-300x97.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-14-768x249.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-14.png 1172w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>Process::self()->getContextObject 这块在Android Binder 之 ServiceManager 文章中有拆解</p>
<p>getContextObject最终会返回serviceManager的BpBinder对象。然后通过JavaObjectForIBinder()根据C++的BpBinder生成Java的BinderProxy对象。</p>
<pre class="wp-block-code"><code>// If the argument is a JavaBBinder, return the Java object that was used to create it.// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val){
// N.B. This function is called from a @FastNative JNI method, so don't take locks around// calls to Java code or block the calling thread for a long time for any reason.
if (val == NULL) return NULL;
//已经有Java 对象了,直接返回
if (val->checkSubclass(&gBinderOffsets)) {
// It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
// In the exception case, getInstance still took ownership of nativeData.return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData == nativeData) {
// Created a new Proxy
uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
// Multiple threads can get here, make sure only one of them gets to// update the warn counter.if (gProxiesWarned.compare_exchange_strong(numLastWarned,
numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
}
}
} else {
delete nativeData;
}
return object;
}</code></pre>
<p><code>ServiceManagerNative.asInterface:</code></p>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="988" height="815" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-15.png" alt="" class="wp-image-390" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-15.png 988w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-15-300x247.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-15-768x634.png 768w" sizes="(max-width: 988px) 100vw, 988px" /></figure>
<p>将 Binder 对象转换成 IServiceManager对象</p>
<pre class="wp-block-code"><code>class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
mServiceManager = IServiceManager.Stub.asInterface(remote);
}
public IBinder asBinder() { return mRemote;
}
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException{
// Same as checkService (old versions of servicemanager had both methods).
return mServiceManager.checkService(name);
}
public IBinder checkService(String name) throws RemoteException{
return mServiceManager.checkService(name);
}
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) throws RemoteException {
mServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
public String[] listServices(int dumpPriority) throws RemoteException {
return mServiceManager.listServices(dumpPriority);
}
public void registerForNotifications(String name, IServiceCallback cb) throws RemoteException {
throw new RemoteException();
}
public void unregisterForNotifications(String name, IServiceCallback cb) throws RemoteException {
throw new RemoteException();
}
public boolean isDeclared(String name) throws RemoteException { return mServiceManager.isDeclared(name);
}
public String[] getDeclaredInstances(String iface) throws RemoteException {
return mServiceManager.getDeclaredInstances(iface);
}
public String updatableViaApex(String name) throws RemoteException {
return mServiceManager.updatableViaApex(name);
}
public void registerClientCallback(String name, IBinder service, IClientCallback cb) throws RemoteException {
throw new RemoteException();
}
public void tryUnregisterService(String name, IBinder service) throws RemoteException {
throw new RemoteException();
}
public ServiceDebugInfo[] getServiceDebugInfo() throws RemoteException {
return mServiceManager.getServiceDebugInfo();
}
/**
* Same as mServiceManager but used by apps.
*
* Once this can be removed, ServiceManagerProxy should be removed entirely.
*/
@UnsupportedAppUsageprivate IBinder mRemote;
private IServiceManager mServiceManager;
}</code></pre>
<p>ServiceManagerNative.asInterface = new ServiceManagerProxy(),所以梳理一下获取服务的接口 getIServiceManager 就等于 new ServiceManagerProxy(new BinderProxy(BpBinder(0))),所以最后就拿到了native ServiceManager的代理。</p>
<p>继续看addService方法的拆解,下图是serviceManagerProxy中的addService方法:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="309" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-17-1024x309.png" alt="" class="wp-image-392" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-17-1024x309.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-17-300x90.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-17-768x232.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-17.png 1370w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>其中mServiceManager是在构造方法中设置的:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="440" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-18-1024x440.png" alt="" class="wp-image-393" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-18-1024x440.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-18-300x129.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-18-768x330.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-18.png 1109w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>获取服务:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="568" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-19-1024x568.png" alt="" class="wp-image-394" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-19-1024x568.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-19-300x166.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-19-768x426.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-19.png 1339w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>sCache中记录了常见的服务的信息,在ActivityThread的bindApplication 中调用initServiceCache进行了初始化操作。</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="327" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-20-1024x327.png" alt="" class="wp-image-395" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-20-1024x327.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-20-300x96.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-20-768x245.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-20.png 1170w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="458" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-21-1024x458.png" alt="" class="wp-image-396" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-21-1024x458.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-21-300x134.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-21-768x344.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-21.png 1220w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="939" height="351" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-23.png" alt="" class="wp-image-398" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-23.png 939w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-23-300x112.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-23-768x287.png 768w" sizes="(max-width: 939px) 100vw, 939px" /></figure>
<p>如果sCache中并没有我们想要找的service,那么会通过Binder.allowBlocking(<strong>rawGetService</strong>()) 获取到服务的IBinder对象</p>
<pre class="wp-block-code"><code> private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
//通过BpBinder(0).getService去获取IBinder对象
final IBinder binder = getIServiceManager().getService(name);
final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
final int myUid = Process.myUid();
final boolean isCore = UserHandle.isCore(myUid);
//getService的数据统计,性能分析打点
final long slowThreshold = isCore
? GET_SERVICE_SLOW_THRESHOLD_US_CORE
: GET_SERVICE_SLOW_THRESHOLD_US_NON_CORE;
synchronized (sLock) {
sGetServiceAccumulatedUs += time;
sGetServiceAccumulatedCallCount++;
final long nowUptime = SystemClock.uptimeMillis();
// Was a slow call?if (time >= slowThreshold) {
// We do a slow log:// - At most once in every SLOW_LOG_INTERVAL_MS// - OR it was slower than the previously logged slow call.
if ((nowUptime > (sLastSlowLogUptime + SLOW_LOG_INTERVAL_MS))
|| (sLastSlowLogActualTime < time)) {
EventLogTags.writeServiceManagerSlow(time / 1000, name);
sLastSlowLogUptime = nowUptime;
sLastSlowLogActualTime = time;
}
}
// Every GET_SERVICE_LOG_EVERY_CALLS calls, log the total time spent in getService().final int logInterval = isCore
? GET_SERVICE_LOG_EVERY_CALLS_CORE
: GET_SERVICE_LOG_EVERY_CALLS_NON_CORE;
if ((sGetServiceAccumulatedCallCount >= logInterval)
&& (nowUptime >= (sLastStatsLogUptime + STATS_LOG_INTERVAL_MS))) {
EventLogTags.writeServiceManagerStats(
sGetServiceAccumulatedCallCount, // Total # of getService() calls.
sGetServiceAccumulatedUs / 1000, // Total time spent in getService() calls.
(int) (nowUptime - sLastStatsLogUptime)); // Uptime duration since last log.
sGetServiceAccumulatedCallCount = 0;
sGetServiceAccumulatedUs = 0;
sLastStatsLogUptime = nowUptime;
}
}
return binder;
}</code></pre>
<p>android 8.0.0_r36 之前都是如下结构,没有通过rawGetService方法,而是直接在getService中通过<code>return getIServiceManager().getService(name);</code>获取到Ibinder对象。</p>
<p>FWK 应用实例:<br>addService:</p>
<p>开机过程中在init 进程启动zygote 以后,zygote会通过fork操作创建出systemServer进程,PackageManagerService 就是systemSever中一个比较重要的线程。PackageManagerService 启动流程中会调用其中的main方法并在main方法中以“package”和“package_native”为名将PackageManagerService 和PackageManagerServiceNative添加到ServiceManager的管理中去。</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="561" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-24-1024x561.png" alt="" class="wp-image-399" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-24-1024x561.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-24-300x164.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-24-768x421.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-24.png 1278w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
<p>值得一提的是 ,因为Fwk层的ServiceManager类是final的,所以不需要创建实例就可以直接调用类中方法。</p>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="820" height="482" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-25.png" alt="" class="wp-image-400" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-25.png 820w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-25-300x176.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-25-768x451.png 768w" sizes="(max-width: 820px) 100vw, 820px" /></figure>
<h4 class="wp-block-heading">getService:</h4>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="239" src="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26-1024x239.png" alt="" class="wp-image-401" srcset="https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26-1024x239.png 1024w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26-300x70.png 300w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26-768x179.png 768w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26-1536x358.png 1536w, https://zhinengzuocang.cn/wp-content/uploads/2024/03/图片-26.png 1797w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>