Loading core/java/com/android/internal/util/AsyncChannel.java +153 −56 Original line number Diff line number Diff line Loading @@ -44,16 +44,16 @@ import java.util.Stack; * In this usage model there is no need for the destination to * use the connect methods. The typical sequence of operations is:</p> *<ol> * <li>Client calls AsyncChannel#connect</li> * <li>Client calls AsyncChannel#connectSync or Asynchronously:</li> * <ol>For an asynchronous half connection client calls AsyncChannel#connect.</ol> * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * </ol> * <li><code>comm-loop:</code></li> * <li>Client calls AsyncChannel#sendMessage(msgX)</li> * <li>Server receives and processes msgX</li> * <li>Server optionally calls AsyncChannel#replyToMessage(msgY) * and if sent Client receives and processes msgY</li> * <li>Client calls AsyncChannel#sendMessage</li> * <li>Server processes messages and optionally replies using AsyncChannel#replyToMessage * <li>Loop to <code>comm-loop</code> until done</li> * <li>When done Client calls {@link AsyncChannel#disconnect(int)}</li> * <li>Client receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> * <li>When done Client calls {@link AsyncChannel#disconnect}</li> * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> *</ol> *<br/> * <p>A second usage model is where the server/destination needs to know Loading @@ -62,21 +62,26 @@ import java.util.Stack; * different state for each client. In this model the server will also * use the connect methods. The typical sequence of operation is:</p> *<ol> * <li>Client calls AsyncChannel#connect</li> * <li>Client calls AsyncChannel#fullyConnectSync or Asynchronously:<li> * <ol>For an asynchronous full connection it calls AsyncChannel#connect</li> * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li> * </ol> * <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li> * <li>Server calls AsyncChannel#connect</li> * <li>Server receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * <li>Server calls AsyncChannel#connected</li> * <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li> * <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li> * <li><code>comm-loop:</code></li> * <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage * to communicate and perform work</li> * <li>Loop to <code>comm-loop</code> until done</li> * <li>When done Client/Server calls {@link AsyncChannel#disconnect(int)}</li> * <li>When done Client/Server calls {@link AsyncChannel#disconnect}</li> * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> *</ol> * * TODO: Consider simplifying where we have connect and fullyConnect with only one response * message RSP_CHANNEL_CONNECT instead of two, CMD_CHANNEL_HALF_CONNECTED and * CMD_CHANNEL_FULLY_CONNECTED. We'd also change CMD_CHANNEL_FULL_CONNECTION to REQ_CHANNEL_CONNECT. */ public class AsyncChannel { /** Log tag */ Loading @@ -85,6 +90,8 @@ public class AsyncChannel { /** Enable to turn on debugging */ private static final boolean DBG = false; private static final int BASE = Protocol.BASE_SYSTEM_ASYNC_CHANNEL; /** * Command sent when the channel is half connected. Half connected * means that the channel can be used to send commends to the destination Loading @@ -98,7 +105,7 @@ public class AsyncChannel { * msg.obj == the AsyncChannel * msg.replyTo == dstMessenger if successful */ public static final int CMD_CHANNEL_HALF_CONNECTED = -1; public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0; /** * Command typically sent when after receiving the CMD_CHANNEL_HALF_CONNECTED. Loading @@ -107,7 +114,7 @@ public class AsyncChannel { * * msg.replyTo = srcMessenger. */ public static final int CMD_CHANNEL_FULL_CONNECTION = -2; public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1; /** * Command typically sent after the destination receives a CMD_CHANNEL_FULL_CONNECTION. Loading @@ -115,31 +122,33 @@ public class AsyncChannel { * * msg.arg1 == 0 : Accept connection * : All other values signify the destination rejected the connection * and {@link AsyncChannel#disconnect(int)} would typically be called. * and {@link AsyncChannel#disconnect} would typically be called. */ public static final int CMD_CHANNEL_FULLY_CONNECTED = -3; public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2; /** * Command sent when one side or the other wishes to disconnect. The sender * may or may not be able to receive a reply depending upon the protocol and * the state of the connection. The receiver should call {@link AsyncChannel#disconnect(int)} * the state of the connection. The receiver should call {@link AsyncChannel#disconnect} * to close its side of the channel and it will receive a CMD_CHANNEL_DISCONNECTED * when the channel is closed. * * msg.replyTo = messenger that is disconnecting */ public static final int CMD_CHANNEL_DISCONNECT = -4; public static final int CMD_CHANNEL_DISCONNECT = BASE + 3; /** * Command sent when the channel becomes disconnected. This is sent when the * channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT. * * msg.arg1 == 0 : STATUS_SUCCESSFUL * 1 : STATUS_BINDING_UNSUCCESSFUL * 2 : STATUS_SEND_UNSUCCESSFUL * : All other values signify failure and the channel state is indeterminate * msg.obj == the AsyncChannel * msg.replyTo = messenger disconnecting or null if it was never connected. */ public static final int CMD_CHANNEL_DISCONNECTED = -5; public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4; /** Successful status always 0, !0 is an unsuccessful status */ public static final int STATUS_SUCCESSFUL = 0; Loading @@ -147,6 +156,12 @@ public class AsyncChannel { /** Error attempting to bind on a connect */ public static final int STATUS_BINDING_UNSUCCESSFUL = 1; /** Error attempting to send a message */ public static final int STATUS_SEND_UNSUCCESSFUL = 2; /** CMD_FULLY_CONNECTED refused because a connection already exists*/ public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3; /** Service connection */ private AsyncChannelConnection mConnection; Loading @@ -169,9 +184,7 @@ public class AsyncChannel { } /** * Connect handler to named package/class. * * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete. * Connect handler to named package/class synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED Loading @@ -179,8 +192,10 @@ public class AsyncChannel { * @param dstPackageName is the destination package name * @param dstClassName is the fully qualified class name (i.e. contains * package name) * * @return STATUS_SUCCESSFUL on success any other value is an error. */ private void connectSrcHandlerToPackage( public int connectSrcHandlerToPackageSync( Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) { if (DBG) log("connect srcHandler to dst Package & class E"); Loading @@ -202,11 +217,61 @@ public class AsyncChannel { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setClassName(dstPackageName, dstClassName); boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); if (!result) { replyHalfConnected(STATUS_BINDING_UNSUCCESSFUL); if (DBG) log("connect srcHandler to dst Package & class X result=" + result); return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL; } if (DBG) log("connect srcHandler to dst Package & class X result=" + result); /** * Connect a handler to Messenger synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstMessenger is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("halfConnectSync srcHandler to the dstMessenger E"); // We are connected connected(srcContext, srcHandler, dstMessenger); if (DBG) log("halfConnectSync srcHandler to the dstMessenger X"); return STATUS_SUCCESSFUL; } /** * connect two local Handlers synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstHandler is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) { return connectSync(srcContext, srcHandler, new Messenger(dstHandler)); } /** * Fully connect two local Handlers synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstHandler is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) { int status = connectSync(srcContext, srcHandler, dstHandler); if (status == STATUS_SUCCESSFUL) { Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION); status = response.arg1; } return status; } /** Loading Loading @@ -241,8 +306,11 @@ public class AsyncChannel { mDstClassName = dstClassName; } @Override public void run() { connectSrcHandlerToPackage(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName); int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName); replyHalfConnected(result); } } Loading Loading @@ -281,6 +349,28 @@ public class AsyncChannel { public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connect srcHandler to the dstMessenger E"); // We are connected connected(srcContext, srcHandler, dstMessenger); // Tell source we are half connected replyHalfConnected(STATUS_SUCCESSFUL); if (DBG) log("connect srcHandler to the dstMessenger X"); } /** * Connect handler to messenger. This method is typically called * when a server receives a CMD_CHANNEL_FULL_CONNECTION request * and initializes the internal instance variables to allow communication * with the dstMessenger. * * @param srcContext * @param srcHandler * @param dstMessenger */ public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connected srcHandler to the dstMessenger E"); // Initialize source fields mSrcContext = srcContext; mSrcHandler = srcHandler; Loading @@ -289,21 +379,12 @@ public class AsyncChannel { // Initialize destination fields mDstMessenger = dstMessenger; if (DBG) log("tell source we are half connected"); // Tell source we are half connected replyHalfConnected(STATUS_SUCCESSFUL); if (DBG) log("connect srcHandler to the dstMessenger X"); if (DBG) log("connected srcHandler to the dstMessenger X"); } /** * Connect two local Handlers. * * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete. * msg.arg1 = status * msg.obj = the AsyncChannel * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages Loading Loading @@ -331,6 +412,7 @@ public class AsyncChannel { * To close the connection call when handler receives CMD_CHANNEL_DISCONNECTED */ public void disconnected() { mSrcContext = null; mSrcHandler = null; mSrcMessenger = null; mDstMessenger = null; Loading @@ -341,15 +423,11 @@ public class AsyncChannel { * Disconnect */ public void disconnect() { if (mConnection != null) { if ((mConnection != null) && (mSrcContext != null)) { mSrcContext.unbindService(mConnection); } if (mSrcHandler != null) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = STATUS_SUCCESSFUL; msg.obj = this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); replyDisconnected(STATUS_SUCCESSFUL); } } Loading @@ -363,7 +441,7 @@ public class AsyncChannel { try { mDstMessenger.send(msg); } catch (RemoteException e) { log("TODO: handle sendMessage RemoteException" + e); replyDisconnected(STATUS_SEND_UNSUCCESSFUL); } } Loading Loading @@ -444,6 +522,7 @@ public class AsyncChannel { */ public void replyToMessage(Message srcMsg, Message dstMsg) { try { dstMsg.replyTo = mSrcMessenger; srcMsg.replyTo.send(dstMsg); } catch (RemoteException e) { log("TODO: handle replyToMessage RemoteException" + e); Loading Loading @@ -694,11 +773,15 @@ public class AsyncChannel { private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) { SyncMessenger sm = SyncMessenger.obtain(); try { if (dstMessenger != null && msg != null) { msg.replyTo = sm.mMessenger; dstMessenger.send(msg); synchronized (sm.mHandler.mLockObject) { dstMessenger.send(msg); sm.mHandler.mLockObject.wait(); } } else { sm.mHandler.mResultMsg = null; } } catch (InterruptedException e) { sm.mHandler.mResultMsg = null; } catch (RemoteException e) { Loading @@ -712,6 +795,7 @@ public class AsyncChannel { /** * Reply to the src handler that we're half connected. * see: CMD_CHANNEL_HALF_CONNECTED for message contents * * @param status to be stored in msg.arg1 */ Loading @@ -723,6 +807,21 @@ public class AsyncChannel { mSrcHandler.sendMessage(msg); } /** * Reply to the src handler that we are disconnected * see: CMD_CHANNEL_DISCONNECTED for message contents * * @param status to be stored in msg.arg1 */ private void replyDisconnected(int status) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = status; msg.obj = this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); } /** * ServiceConnection to receive call backs. */ Loading @@ -730,17 +829,15 @@ public class AsyncChannel { AsyncChannelConnection() { } @Override public void onServiceConnected(ComponentName className, IBinder service) { mDstMessenger = new Messenger(service); replyHalfConnected(STATUS_SUCCESSFUL); } @Override public void onServiceDisconnected(ComponentName className) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = STATUS_SUCCESSFUL; msg.obj = AsyncChannel.this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); replyDisconnected(STATUS_SUCCESSFUL); } } Loading core/java/com/android/internal/util/Protocol.java +11 −3 Original line number Diff line number Diff line Loading @@ -31,7 +31,15 @@ package com.android.internal.util; public class Protocol { public static final int MAX_MESSAGE = 0x0000FFFF; public static final int BASE_WIFI = 0x00010000; public static final int BASE_DHCP = 0x00020000; /** Base reserved for system */ public static final int BASE_SYSTEM_RESERVED = 0x00010000; public static final int BASE_SYSTEM_ASYNC_CHANNEL = 0x00011000; /** Non system protocols */ public static final int BASE_WIFI = 0x00020000; public static final int BASE_DHCP = 0x00030000; public static final int BASE_DATA_CONNECTION = 0x00040000; public static final int BASE_DATA_CONNECTION_TRACKER = 0x00050000; //TODO: define all used protocols } Loading
core/java/com/android/internal/util/AsyncChannel.java +153 −56 Original line number Diff line number Diff line Loading @@ -44,16 +44,16 @@ import java.util.Stack; * In this usage model there is no need for the destination to * use the connect methods. The typical sequence of operations is:</p> *<ol> * <li>Client calls AsyncChannel#connect</li> * <li>Client calls AsyncChannel#connectSync or Asynchronously:</li> * <ol>For an asynchronous half connection client calls AsyncChannel#connect.</ol> * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * </ol> * <li><code>comm-loop:</code></li> * <li>Client calls AsyncChannel#sendMessage(msgX)</li> * <li>Server receives and processes msgX</li> * <li>Server optionally calls AsyncChannel#replyToMessage(msgY) * and if sent Client receives and processes msgY</li> * <li>Client calls AsyncChannel#sendMessage</li> * <li>Server processes messages and optionally replies using AsyncChannel#replyToMessage * <li>Loop to <code>comm-loop</code> until done</li> * <li>When done Client calls {@link AsyncChannel#disconnect(int)}</li> * <li>Client receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> * <li>When done Client calls {@link AsyncChannel#disconnect}</li> * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> *</ol> *<br/> * <p>A second usage model is where the server/destination needs to know Loading @@ -62,21 +62,26 @@ import java.util.Stack; * different state for each client. In this model the server will also * use the connect methods. The typical sequence of operation is:</p> *<ol> * <li>Client calls AsyncChannel#connect</li> * <li>Client calls AsyncChannel#fullyConnectSync or Asynchronously:<li> * <ol>For an asynchronous full connection it calls AsyncChannel#connect</li> * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li> * </ol> * <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li> * <li>Server calls AsyncChannel#connect</li> * <li>Server receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li> * <li>Server calls AsyncChannel#connected</li> * <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li> * <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li> * <li><code>comm-loop:</code></li> * <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage * to communicate and perform work</li> * <li>Loop to <code>comm-loop</code> until done</li> * <li>When done Client/Server calls {@link AsyncChannel#disconnect(int)}</li> * <li>When done Client/Server calls {@link AsyncChannel#disconnect}</li> * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li> *</ol> * * TODO: Consider simplifying where we have connect and fullyConnect with only one response * message RSP_CHANNEL_CONNECT instead of two, CMD_CHANNEL_HALF_CONNECTED and * CMD_CHANNEL_FULLY_CONNECTED. We'd also change CMD_CHANNEL_FULL_CONNECTION to REQ_CHANNEL_CONNECT. */ public class AsyncChannel { /** Log tag */ Loading @@ -85,6 +90,8 @@ public class AsyncChannel { /** Enable to turn on debugging */ private static final boolean DBG = false; private static final int BASE = Protocol.BASE_SYSTEM_ASYNC_CHANNEL; /** * Command sent when the channel is half connected. Half connected * means that the channel can be used to send commends to the destination Loading @@ -98,7 +105,7 @@ public class AsyncChannel { * msg.obj == the AsyncChannel * msg.replyTo == dstMessenger if successful */ public static final int CMD_CHANNEL_HALF_CONNECTED = -1; public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0; /** * Command typically sent when after receiving the CMD_CHANNEL_HALF_CONNECTED. Loading @@ -107,7 +114,7 @@ public class AsyncChannel { * * msg.replyTo = srcMessenger. */ public static final int CMD_CHANNEL_FULL_CONNECTION = -2; public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1; /** * Command typically sent after the destination receives a CMD_CHANNEL_FULL_CONNECTION. Loading @@ -115,31 +122,33 @@ public class AsyncChannel { * * msg.arg1 == 0 : Accept connection * : All other values signify the destination rejected the connection * and {@link AsyncChannel#disconnect(int)} would typically be called. * and {@link AsyncChannel#disconnect} would typically be called. */ public static final int CMD_CHANNEL_FULLY_CONNECTED = -3; public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2; /** * Command sent when one side or the other wishes to disconnect. The sender * may or may not be able to receive a reply depending upon the protocol and * the state of the connection. The receiver should call {@link AsyncChannel#disconnect(int)} * the state of the connection. The receiver should call {@link AsyncChannel#disconnect} * to close its side of the channel and it will receive a CMD_CHANNEL_DISCONNECTED * when the channel is closed. * * msg.replyTo = messenger that is disconnecting */ public static final int CMD_CHANNEL_DISCONNECT = -4; public static final int CMD_CHANNEL_DISCONNECT = BASE + 3; /** * Command sent when the channel becomes disconnected. This is sent when the * channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT. * * msg.arg1 == 0 : STATUS_SUCCESSFUL * 1 : STATUS_BINDING_UNSUCCESSFUL * 2 : STATUS_SEND_UNSUCCESSFUL * : All other values signify failure and the channel state is indeterminate * msg.obj == the AsyncChannel * msg.replyTo = messenger disconnecting or null if it was never connected. */ public static final int CMD_CHANNEL_DISCONNECTED = -5; public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4; /** Successful status always 0, !0 is an unsuccessful status */ public static final int STATUS_SUCCESSFUL = 0; Loading @@ -147,6 +156,12 @@ public class AsyncChannel { /** Error attempting to bind on a connect */ public static final int STATUS_BINDING_UNSUCCESSFUL = 1; /** Error attempting to send a message */ public static final int STATUS_SEND_UNSUCCESSFUL = 2; /** CMD_FULLY_CONNECTED refused because a connection already exists*/ public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3; /** Service connection */ private AsyncChannelConnection mConnection; Loading @@ -169,9 +184,7 @@ public class AsyncChannel { } /** * Connect handler to named package/class. * * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete. * Connect handler to named package/class synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED Loading @@ -179,8 +192,10 @@ public class AsyncChannel { * @param dstPackageName is the destination package name * @param dstClassName is the fully qualified class name (i.e. contains * package name) * * @return STATUS_SUCCESSFUL on success any other value is an error. */ private void connectSrcHandlerToPackage( public int connectSrcHandlerToPackageSync( Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) { if (DBG) log("connect srcHandler to dst Package & class E"); Loading @@ -202,11 +217,61 @@ public class AsyncChannel { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setClassName(dstPackageName, dstClassName); boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); if (!result) { replyHalfConnected(STATUS_BINDING_UNSUCCESSFUL); if (DBG) log("connect srcHandler to dst Package & class X result=" + result); return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL; } if (DBG) log("connect srcHandler to dst Package & class X result=" + result); /** * Connect a handler to Messenger synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstMessenger is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("halfConnectSync srcHandler to the dstMessenger E"); // We are connected connected(srcContext, srcHandler, dstMessenger); if (DBG) log("halfConnectSync srcHandler to the dstMessenger X"); return STATUS_SUCCESSFUL; } /** * connect two local Handlers synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstHandler is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) { return connectSync(srcContext, srcHandler, new Messenger(dstHandler)); } /** * Fully connect two local Handlers synchronously. * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages * @param dstHandler is the hander to send messages to. * * @return STATUS_SUCCESSFUL on success any other value is an error. */ public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) { int status = connectSync(srcContext, srcHandler, dstHandler); if (status == STATUS_SUCCESSFUL) { Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION); status = response.arg1; } return status; } /** Loading Loading @@ -241,8 +306,11 @@ public class AsyncChannel { mDstClassName = dstClassName; } @Override public void run() { connectSrcHandlerToPackage(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName); int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName); replyHalfConnected(result); } } Loading Loading @@ -281,6 +349,28 @@ public class AsyncChannel { public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connect srcHandler to the dstMessenger E"); // We are connected connected(srcContext, srcHandler, dstMessenger); // Tell source we are half connected replyHalfConnected(STATUS_SUCCESSFUL); if (DBG) log("connect srcHandler to the dstMessenger X"); } /** * Connect handler to messenger. This method is typically called * when a server receives a CMD_CHANNEL_FULL_CONNECTION request * and initializes the internal instance variables to allow communication * with the dstMessenger. * * @param srcContext * @param srcHandler * @param dstMessenger */ public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connected srcHandler to the dstMessenger E"); // Initialize source fields mSrcContext = srcContext; mSrcHandler = srcHandler; Loading @@ -289,21 +379,12 @@ public class AsyncChannel { // Initialize destination fields mDstMessenger = dstMessenger; if (DBG) log("tell source we are half connected"); // Tell source we are half connected replyHalfConnected(STATUS_SUCCESSFUL); if (DBG) log("connect srcHandler to the dstMessenger X"); if (DBG) log("connected srcHandler to the dstMessenger X"); } /** * Connect two local Handlers. * * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete. * msg.arg1 = status * msg.obj = the AsyncChannel * * @param srcContext is the context of the source * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED * messages Loading Loading @@ -331,6 +412,7 @@ public class AsyncChannel { * To close the connection call when handler receives CMD_CHANNEL_DISCONNECTED */ public void disconnected() { mSrcContext = null; mSrcHandler = null; mSrcMessenger = null; mDstMessenger = null; Loading @@ -341,15 +423,11 @@ public class AsyncChannel { * Disconnect */ public void disconnect() { if (mConnection != null) { if ((mConnection != null) && (mSrcContext != null)) { mSrcContext.unbindService(mConnection); } if (mSrcHandler != null) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = STATUS_SUCCESSFUL; msg.obj = this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); replyDisconnected(STATUS_SUCCESSFUL); } } Loading @@ -363,7 +441,7 @@ public class AsyncChannel { try { mDstMessenger.send(msg); } catch (RemoteException e) { log("TODO: handle sendMessage RemoteException" + e); replyDisconnected(STATUS_SEND_UNSUCCESSFUL); } } Loading Loading @@ -444,6 +522,7 @@ public class AsyncChannel { */ public void replyToMessage(Message srcMsg, Message dstMsg) { try { dstMsg.replyTo = mSrcMessenger; srcMsg.replyTo.send(dstMsg); } catch (RemoteException e) { log("TODO: handle replyToMessage RemoteException" + e); Loading Loading @@ -694,11 +773,15 @@ public class AsyncChannel { private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) { SyncMessenger sm = SyncMessenger.obtain(); try { if (dstMessenger != null && msg != null) { msg.replyTo = sm.mMessenger; dstMessenger.send(msg); synchronized (sm.mHandler.mLockObject) { dstMessenger.send(msg); sm.mHandler.mLockObject.wait(); } } else { sm.mHandler.mResultMsg = null; } } catch (InterruptedException e) { sm.mHandler.mResultMsg = null; } catch (RemoteException e) { Loading @@ -712,6 +795,7 @@ public class AsyncChannel { /** * Reply to the src handler that we're half connected. * see: CMD_CHANNEL_HALF_CONNECTED for message contents * * @param status to be stored in msg.arg1 */ Loading @@ -723,6 +807,21 @@ public class AsyncChannel { mSrcHandler.sendMessage(msg); } /** * Reply to the src handler that we are disconnected * see: CMD_CHANNEL_DISCONNECTED for message contents * * @param status to be stored in msg.arg1 */ private void replyDisconnected(int status) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = status; msg.obj = this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); } /** * ServiceConnection to receive call backs. */ Loading @@ -730,17 +829,15 @@ public class AsyncChannel { AsyncChannelConnection() { } @Override public void onServiceConnected(ComponentName className, IBinder service) { mDstMessenger = new Messenger(service); replyHalfConnected(STATUS_SUCCESSFUL); } @Override public void onServiceDisconnected(ComponentName className) { Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED); msg.arg1 = STATUS_SUCCESSFUL; msg.obj = AsyncChannel.this; msg.replyTo = mDstMessenger; mSrcHandler.sendMessage(msg); replyDisconnected(STATUS_SUCCESSFUL); } } Loading
core/java/com/android/internal/util/Protocol.java +11 −3 Original line number Diff line number Diff line Loading @@ -31,7 +31,15 @@ package com.android.internal.util; public class Protocol { public static final int MAX_MESSAGE = 0x0000FFFF; public static final int BASE_WIFI = 0x00010000; public static final int BASE_DHCP = 0x00020000; /** Base reserved for system */ public static final int BASE_SYSTEM_RESERVED = 0x00010000; public static final int BASE_SYSTEM_ASYNC_CHANNEL = 0x00011000; /** Non system protocols */ public static final int BASE_WIFI = 0x00020000; public static final int BASE_DHCP = 0x00030000; public static final int BASE_DATA_CONNECTION = 0x00040000; public static final int BASE_DATA_CONNECTION_TRACKER = 0x00050000; //TODO: define all used protocols }