跟上篇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;
在AndroidRuntine::startReg中会调用register_android_os_Binder,register_android_os_Binder会调用int_register_android_os_Binder等函数建立Java层Binder、BinderProxy、BinderInternal、Log等与Native层的映射关系
Native层对java层的反射
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
有了这些我们可以猜测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 b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {// BpBinder没重写,返回false
// One of our own!
jobject object = static_cast(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 drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(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
从代码里面看出,要是从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;
}