Java层Binder使用(ServiceManager)
来源:互联网 发布:pkpm结构软件下载 编辑:程序博客网 时间:2024/05/19 03:19
转自:http://blog.csdn.net/jacklam200/article/details/37567409
跟上篇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;
- }
- Java层Binder使用(ServiceManager)
- Java层Binder使用(ServiceManager)
- android binder机制---Java层获取ServiceManager
- binder详解(一)_初始化servicemanager
- 红茶一杯话Binder(ServiceManager篇)
- Binder源码分析之ServiceManager(原)
- 红茶一杯话Binder(ServiceManager篇)
- Binder源码分析之ServiceManager(原)
- 红茶一杯话Binder(ServiceManager篇)
- 红茶一杯话Binder(ServiceManager篇)
- (OK) 话Binder(ServiceManager篇)
- 红茶一杯话Binder(ServiceManager篇)
- Binder Java层的使用介绍
- Java 层Binder的使用(Android framework)
- 【android】binder机制-servicemanager
- Android - Binder机制 - ServiceManager
- Android binder -serviceManager
- android binder 机制 (ServiceManager)
- 中国象棋之将帅不在同一直线上
- HBase总结(九)Bloom Filter概念和原理
- Linux下常用的shell命令
- 动效设计的物理法则
- 关于注解@ResponseBody 和 @RequestMapping
- Java层Binder使用(ServiceManager)
- linux之间互传文件(ubuntu为例)
- iOS 多线程简单使用的详解
- 动效-APP设计的肢体语言
- FreeMarker教程
- C++实验3-3
- [后缀数组 set] BZOJ 4516 [Sdoi2016]生成魔咒
- 解析ANDROID ps命令执行后各项参数的含义
- 避免同一activity下 多个fragment 切换时重复执行onCreateView方法