跟上篇Binder使用一样,先通过例子来跟踪Java层Binder机制。本文参考了Binder In java
(http://www.cnblogs.com/angeldevil/p/3328748.html),只作为研究android记忆用
在Init进程的init2阶段,系统启动了ServerThread,在ServerThread中会启动很多用Java实现的系统服务
(frameworks/base/services/java/com/android/server/SystemServer.java)
代码
power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power); context = ActivityManagerService.main(factoryTest); Slog.i(TAG, "Display Manager"); display = new DisplayManagerService(context, wmHandler, uiHandler); ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
通过ServiceManager的addService注册为binder 的server端。
我们以PowerManagerService为例,
(frameworks/base/services/java/com/android/server/power/)
PowerManagerService继承于IPowerManager.stub,而IPowerManager.stub位于
(frameworks/base/core/java/com/android/os/IPowerManager.aidl)
package android.os; import android.os.WorkSource; /** @hide */ interface IPowerManager { // WARNING: The first two methods must remain the first two methods because their // transaction numbers must not change unless IPowerManager.cpp is also updated. void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws); void releaseWakeLock(IBinder lock, int flags); void updateWakeLockWorkSource(IBinder lock, in WorkSource ws); boolean isWakeLockLevelSupported(int level); void userActivity(long time, int event, int flags); void wakeUp(long time); void goToSleep(long time, int reason); void nap(long time); boolean isScreenOn(); void reboot(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, boolean wait); void crash(String message); void setStayOnSetting(int val); void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs); // temporarily overrides the screen brightness settings to allow the user to // see the effect of a settings change without applying it immediately void setTemporaryScreenBrightnessSettingOverride(int brightness); void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj); // sets the attention light (used by phone app only) void setAttentionLight(boolean on, int color); }
Aidl是android内部进程通信接口的描述语言,通过编译我们可以编译出
package android.os; /** @hide */ public interface IPowerManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.os.IPowerManager { private static final java.lang.String DESCRIPTOR = "android.os.IPowerManager"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an android.os.IPowerManager interface, * generating a proxy if needed. */ public static android.os.IPowerManager asInterface( android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof android.os.IPowerManager))) { return ((android.os.IPowerManager) iin); } return new android.os.IPowerManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_acquireWakeLock: { data.enforceInterface(DESCRIPTOR); android.os.IBinder _arg0; _arg0 = data.readStrongBinder(); int _arg1; _arg1 = data.readInt(); java.lang.String _arg2; _arg2 = data.readString(); android.os.WorkSource _arg3; if ((0 != data.readInt())) { _arg3 = android.os.WorkSource.CREATOR .createFromParcel(data); } else { _arg3 = null; } this.acquireWakeLock(_arg0, _arg1, _arg2, _arg3); reply.writeNoException(); return true; } case TRANSACTION_releaseWakeLock: { data.enforceInterface(DESCRIPTOR); android.os.IBinder _arg0; _arg0 = data.readStrongBinder(); int _arg1; _arg1 = data.readInt(); this.releaseWakeLock(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_updateWakeLockWorkSource: { data.enforceInterface(DESCRIPTOR); android.os.IBinder _arg0; _arg0 = data.readStrongBinder(); android.os.WorkSource _arg1; if ((0 != data.readInt())) { _arg1 = android.os.WorkSource.CREATOR .createFromParcel(data); } else { _arg1 = null; } this.updateWakeLockWorkSource(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_isWakeLockLevelSupported: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); boolean _result = this.isWakeLockLevelSupported(_arg0); reply.writeNoException(); reply.writeInt(((_result) ? (1) : (0))); return true; } case TRANSACTION_userActivity: { data.enforceInterface(DESCRIPTOR); long _arg0; _arg0 = data.readLong(); int _arg1; _arg1 = data.readInt(); int _arg2; _arg2 = data.readInt(); this.userActivity(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_wakeUp: { data.enforceInterface(DESCRIPTOR); long _arg0; _arg0 = data.readLong(); this.wakeUp(_arg0); reply.writeNoException(); return true; } case TRANSACTION_goToSleep: { data.enforceInterface(DESCRIPTOR); long _arg0; _arg0 = data.readLong(); int _arg1; _arg1 = data.readInt(); this.goToSleep(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_nap: { data.enforceInterface(DESCRIPTOR); long _arg0; _arg0 = data.readLong(); this.nap(_arg0); reply.writeNoException(); return true; } case TRANSACTION_isScreenOn: { data.enforceInterface(DESCRIPTOR); boolean _result = this.isScreenOn(); reply.writeNoException(); reply.writeInt(((_result) ? (1) : (0))); return true; } case TRANSACTION_reboot: { data.enforceInterface(DESCRIPTOR); boolean _arg0; _arg0 = (0 != data.readInt()); java.lang.String _arg1; _arg1 = data.readString(); boolean _arg2; _arg2 = (0 != data.readInt()); this.reboot(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_shutdown: { data.enforceInterface(DESCRIPTOR); boolean _arg0; _arg0 = (0 != data.readInt()); boolean _arg1; _arg1 = (0 != data.readInt()); this.shutdown(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_crash: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); this.crash(_arg0); reply.writeNoException(); return true; } case TRANSACTION_setStayOnSetting: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.setStayOnSetting(_arg0); reply.writeNoException(); return true; } case TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.setMaximumScreenOffTimeoutFromDeviceAdmin(_arg0); reply.writeNoException(); return true; } case TRANSACTION_setTemporaryScreenBrightnessSettingOverride: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.setTemporaryScreenBrightnessSettingOverride(_arg0); reply.writeNoException(); return true; } case TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride: { data.enforceInterface(DESCRIPTOR); float _arg0; _arg0 = data.readFloat(); this.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(_arg0); reply.writeNoException(); return true; } case TRANSACTION_setAttentionLight: { data.enforceInterface(DESCRIPTOR); boolean _arg0; _arg0 = (0 != data.readInt()); int _arg1; _arg1 = data.readInt(); this.setAttentionLight(_arg0, _arg1); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements android.os.IPowerManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } // WARNING: The first two methods must remain the first two methods // because their // transaction numbers must not change unless IPowerManager.cpp is // also updated. @Override public void acquireWakeLock(android.os.IBinder lock, int flags, java.lang.String tag, android.os.WorkSource ws) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeStrongBinder(lock); _data.writeInt(flags); _data.writeString(tag); if ((ws != null)) { _data.writeInt(1); ws.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_acquireWakeLock, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void releaseWakeLock(android.os.IBinder lock, int flags) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeStrongBinder(lock); _data.writeInt(flags); mRemote.transact(Stub.TRANSACTION_releaseWakeLock, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void updateWakeLockWorkSource(android.os.IBinder lock, android.os.WorkSource ws) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeStrongBinder(lock); if ((ws != null)) { _data.writeInt(1); ws.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_updateWakeLockWorkSource, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public boolean isWakeLockLevelSupported(int level) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(level); mRemote.transact(Stub.TRANSACTION_isWakeLockLevelSupported, _data, _reply, 0); _reply.readException(); _result = (0 != _reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void userActivity(long time, int event, int flags) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeLong(time); _data.writeInt(event); _data.writeInt(flags); mRemote.transact(Stub.TRANSACTION_userActivity, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void wakeUp(long time) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeLong(time); mRemote.transact(Stub.TRANSACTION_wakeUp, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void goToSleep(long time, int reason) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeLong(time); _data.writeInt(reason); mRemote.transact(Stub.TRANSACTION_goToSleep, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void nap(long time) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeLong(time); mRemote.transact(Stub.TRANSACTION_nap, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public boolean isScreenOn() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_isScreenOn, _data, _reply, 0); _reply.readException(); _result = (0 != _reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void reboot(boolean confirm, java.lang.String reason, boolean wait) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(((confirm) ? (1) : (0))); _data.writeString(reason); _data.writeInt(((wait) ? (1) : (0))); mRemote.transact(Stub.TRANSACTION_reboot, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void shutdown(boolean confirm, boolean wait) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(((confirm) ? (1) : (0))); _data.writeInt(((wait) ? (1) : (0))); mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void crash(java.lang.String message) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(message); mRemote.transact(Stub.TRANSACTION_crash, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void setStayOnSetting(int val) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(val); mRemote.transact(Stub.TRANSACTION_setStayOnSetting, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(timeMs); mRemote.transact( Stub.TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } // temporarily overrides the screen brightness settings to allow the // user to // see the effect of a settings change without applying it // immediately @Override public void setTemporaryScreenBrightnessSettingOverride( int brightness) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(brightness); mRemote.transact( Stub.TRANSACTION_setTemporaryScreenBrightnessSettingOverride, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride( float adj) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeFloat(adj); mRemote.transact( Stub.TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } // sets the attention light (used by phone app only) @Override public void setAttentionLight(boolean on, int color) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(((on) ? (1) : (0))); _data.writeInt(color); mRemote.transact(Stub.TRANSACTION_setAttentionLight, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_acquireWakeLock = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_releaseWakeLock = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_updateWakeLockWorkSource = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_isWakeLockLevelSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); static final int TRANSACTION_userActivity = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); static final int TRANSACTION_wakeUp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); static final int TRANSACTION_goToSleep = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); static final int TRANSACTION_nap = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); static final int TRANSACTION_isScreenOn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); static final int TRANSACTION_reboot = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9); static final int TRANSACTION_shutdown = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10); static final int TRANSACTION_crash = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11); static final int TRANSACTION_setStayOnSetting = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12); static final int TRANSACTION_setMaximumScreenOffTimeoutFromDeviceAdmin = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13); static final int TRANSACTION_setTemporaryScreenBrightnessSettingOverride = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14); static final int TRANSACTION_setTemporaryScreenAutoBrightnessAdjustmentSettingOverride = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15); static final int TRANSACTION_setAttentionLight = (android.os.IBinder.FIRST_CALL_TRANSACTION + 16); } // WARNING: The first two methods must remain the first two methods because // their // transaction numbers must not change unless IPowerManager.cpp is also // updated. public void acquireWakeLock(android.os.IBinder lock, int flags, java.lang.String tag, android.os.WorkSource ws) throws android.os.RemoteException; public void releaseWakeLock(android.os.IBinder lock, int flags) throws android.os.RemoteException; public void updateWakeLockWorkSource(android.os.IBinder lock, android.os.WorkSource ws) throws android.os.RemoteException; public boolean isWakeLockLevelSupported(int level) throws android.os.RemoteException; public void userActivity(long time, int event, int flags) throws android.os.RemoteException; public void wakeUp(long time) throws android.os.RemoteException; public void goToSleep(long time, int reason) throws android.os.RemoteException; public void nap(long time) throws android.os.RemoteException; public boolean isScreenOn() throws android.os.RemoteException; public void reboot(boolean confirm, java.lang.String reason, boolean wait) throws android.os.RemoteException; public void shutdown(boolean confirm, boolean wait) throws android.os.RemoteException; public void crash(java.lang.String message) throws android.os.RemoteException; public void setStayOnSetting(int val) throws android.os.RemoteException; public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) throws android.os.RemoteException; // temporarily overrides the screen brightness settings to allow the user to // see the effect of a settings change without applying it immediately public void setTemporaryScreenBrightnessSettingOverride(int brightness) throws android.os.RemoteException; public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride( float adj) throws android.os.RemoteException; // sets the attention light (used by phone app only) public void setAttentionLight(boolean on, int color) throws android.os.RemoteException; }
我们可以从代码中看到Stub是一个抽象类,里面还有个proxy类
Stub提供asInterface, asBinder, onTransact,
PowerManagerService
其实这个是不是看起来很熟悉呢,我们回忆下MediaplayerService,MediaplayerService 继承于BnMediaPlayerService,而BnMediaPlayerService刚好跟这个Stub很类似,
然后我们再看看proxy类是不是跟BpMediaPlayerService类似,而IPowerManager则跟IMediaPlayerService类似,而PowerManagerServic则跟MediaplayerService一样实现功能。
并Stub继承于Binder,而在Binder构造函数中调用native的init
(framework\base\core\jni\android_util_Binder.cpp)
static void android_os_Binder_init(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = new JavaBBinderHolder(); if (jbh == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return; } ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); jbh->incStrong((void*)android_os_Binder_init); env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); }
可以看出创建了一个JavaBBinderHolder,然后把值强制转int,返回给java层Binder类的
private int mObject;
</pre><p class="p0" style="margin-bottom:0pt; margin-top:0pt"><span style="font-size:10pt; font-family:宋体">在<span style="font-family:Consolas">AndroidRuntine::startReg</span><span style="font-family:宋体">中会调用</span><span style="font-family:Consolas">register_android_os_Binder</span><span style="font-family:宋体">,</span><span style="font-family:Consolas">register_android_os_Binder</span><span style="font-family:宋体">会调用</span><span style="font-family:Consolas">int_register_android_os_Binder</span><span style="font-family:宋体">等函数建立</span><span style="font-family:Consolas">Java</span><span style="font-family:宋体">层</span><span style="font-family:Consolas">Binder</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">BinderProxy</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">BinderInternal</span><span style="font-family:宋体">、</span><span style="font-family:Consolas">Log</span><span style="font-family:宋体">等与</span><span style="font-family:Consolas">Native</span><span style="font-family:宋体">层的映射关系</span></span><span style="font-size:10pt; font-family:宋体"></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt"><span style="font-size:10pt; font-family:宋体">Native<span style="font-family:宋体">层对</span><span style="font-family:Consolas">java</span><span style="font-family:宋体">层的反射</span></span><span style="font-size:10pt; font-family:宋体"></span></p><pre code_snippet_id="422453" snippet_file_name="blog_20140708_7_4207713" name="code" class="cpp">static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBinderPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }
那JavaBBinderHolder是什么呢?
在android_os_Binder_init中new了一个JavaBBinderHolder,JavaBBinderHolder 的get()函数new了一个JavaBBinder保存到了自己的成员sp<JavaBBinder> mBinder中。而JavaBBinder继承自Native层的BBinder,还记得在IPC thread中接收binder的数据,并且通过BBinder回调的,然后再调用BnXX的onTransact执行Server端的相关命令
有了这些我们可以猜测IPowerManager.aidl编译出来的文件就是binder机制中Server端
现在既然知道了PowerManagerService是binder的server端,那他怎么在java层向binder注册呢,还有client端怎么在java层获取Service呢
首先,按着binder的机制,ServiceManager.addService(Context.POWER_SERVICE, power);
我们查看ServiceManager类
(frameworks/base/core/java/android/os/ServiceManager.java)
public static void addService(String name, IBinder service, boolean allowIsolated) { try { getIServiceManager().addService(name, service, allowIsolated); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
从代码可以看出addService是调用了ServiceManagerNative,而asInterface则是传入一个IBinder对象,并创建出ServiceManagerProxy,是不是跟Mediaplayer Server获取binder smgr有点类似?
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
我们在看看BinderInternal.getContextObject(),他是一个native函数,我们到native层看看是不是跟Mediaplayer Server一样通过new Bpbinder(0),获取到Binder smgr。
(framework\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); }
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) {// BpBinder没重写,返回false // One of our own! jobject object = static_cast<JavaBBinder*>(val.get())->object(); LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); return object; } // For the rest of the function we will hold this lock, to serialize // looking/creation of Java proxies for native Binder proxies. AutoMutex _l(mProxyLock); // Someone else's... do we know about it? // BpBinder没有带proxy过来 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = jniGetReferent(env, object); if (res != NULL) { ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res); return res; } LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get()); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } // 因为proxy,创建一个proxy // const char* const kBinderProxyPathName = "android/os/BinderProxy"; object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object); // The proxy holds a reference to the native object. env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); // 把BpBinder(0)赋值给BinderProxy 的mObject val->incStrong((void*)javaObjectForIBinder); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Also remember the death recipients registered on this proxy sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }
可以看出返回了android.os.BinderProxy
也就是说ServiceManagerProxy的mRemote带的BinderProxy
frameworks/base/core/java/com/android/os/Binder.java)
而里面的Transact是调用native层的android_os_BinderProxy_transact
frameworks/base/core/jni/android/android.util.Binder.cpp)
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { if (dataObj == NULL) { jniThrowNullPointerException(env, NULL); return JNI_FALSE; } Parcel* data = parcelForJavaObject(env, dataObj); if (data == NULL) { return JNI_FALSE; } Parcel* reply = parcelForJavaObject(env, replyObj); if (reply == NULL && replyObj != NULL) { return JNI_FALSE; } IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); //此时的mObject为BpBinder(0); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } ALOGV("Java code calling transact on %p in Java object %p with code %d\n", target, obj, code); // Only log the binder call duration for things on the Java-level main thread. // But if we don't const bool time_binder_calls = should_time_binder_calls(); int64_t start_millis; if (time_binder_calls) { start_millis = uptimeMillis(); } //printf("Transact from Java code to %p sending: ", target); data->print(); status_t err = target->transact(code, *data, reply, flags); //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); if (time_binder_calls) { conditionally_log_binder_call(start_millis, target, code); } if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); return JNI_FALSE; }
看出status_t err = target->transact(code, *data, reply, flags);
是调用了BinderProxy里面mObject(Bpbinder(0))的transact来传输数据
可以看到跟Mediaplayer Server一样 获取了smgr binder,并通过他通讯给smgr binder
那我们可以归结出ServiceManagerProxy 为BpServicemanager,并带入了smgr binder,跟binder通讯
其次,我们在java层获取Service是通过
Context.getSystemService(Context.POWER_SERVICE);
getSystemService位于ContextImpl中
(frameworks/base/core/java/com/android/app/ContextImpl.java)
@Override public Object getSystemService(String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this); }
Static{ .... registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler()); }}); .... };
static class ServiceFetcher { int mContextCacheIndex = -1; /** * Main entrypoint; only override if you don't need caching. */ public Object getService(ContextImpl ctx) { ArrayList<Object> cache = ctx.mServiceCache; Object service; synchronized (cache) { if (cache.size() == 0) { // Initialize the cache vector on first access. // At this point sNextPerContextServiceCacheIndex // is the number of potential services that are // cached per-Context. for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) { cache.add(null); } } else { service = cache.get(mContextCacheIndex); if (service != null) { return service; } } service = createService(ctx); cache.set(mContextCacheIndex, service); return service; } } /** * Override this to create a new per-Context instance of the * service. getService() will handle locking and caching. */ public Object createService(ContextImpl ctx) { throw new RuntimeException("Not implemented"); } }
从代码里面看出,要是从cache中获取不到service,那么
Static{ .... registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler()); }}); .... };
通过ServiceManager获取到PowerService,并通过Stub转化成IPowerManager,并创建了PowerManager返回给客户端调用。
而getService函数就跟addService一样,先获取smgr,然后用ServiceManagerProxy 的getService获取到binder,然后通过stub的asInterface转化为IPowerManager(实际是让其带Service的Binder)
public static android.os.IPowerManager asInterface( android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof android.os.IPowerManager))) { return ((android.os.IPowerManager) iin); } return new android.os.IPowerManager.Stub.Proxy(obj); }
Proxy(android.os.IBinder remote) { mRemote = remote; }