Java层Binder使用(ServiceManager)

跟上篇Binder使用一样,先通过例子来跟踪JavaBinder机制。本文参考了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);

通过ServiceManageraddService注册为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);
}

Aidlandroid内部进程通信接口的描述语言,通过编译我们可以编译出



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 

Java层Binder使用(ServiceManager)_第1张图片

                    PowerManagerService


Java层Binder使用(ServiceManager)_第2张图片


其实这个是不是看起来很熟悉呢,我们回忆下MediaplayerServiceMediaplayerService 继承于BnMediaPlayerService,BnMediaPlayerService刚好跟这个Stub很类似,

然后我们再看看proxy类是不是跟BpMediaPlayerService类似,而IPowerManager则跟IMediaPlayerService类似,而PowerManagerServic则跟MediaplayerService一样实现功能。

Stub继承于Binder,而在Binder构造函数中调用nativeinit

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,返回给javaBinder类的

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_initnew了一个JavaBBinderHolderJavaBBinderHolder get()函数new了一个JavaBBinder保存到了自己的成员sp<JavaBBinder> mBinder中。而JavaBBinder继承自Native层的BBinder,还记得在IPC thread中接收binder的数据,并且通过BBinder回调的,然后再调用BnXXonTransact执行Server端的相关命令

有了这些我们可以猜测IPowerManager.aidl编译出来的文件就是binder机制中Server


 

 

现在既然知道了PowerManagerServicebinderserver端,那他怎么在java层向binder注册呢,还有client端怎么在java层获取Service

 

首先,按着binder的机制,ServiceManager.addService(Context.POWER_SERVICE, power);

我们查看ServiceManager

Java层Binder使用(ServiceManager)_第3张图片

(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

也就是说ServiceManagerProxymRemote带的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里面mObjectBpbinder(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,然后通过stubasInterface转化为IPowerManager(实际是让其带ServiceBinder

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))