eneter.messaging.messagingsystems.androidusbcablemessagingsystem
Class AndroidUsbCableMessagingFactory

java.lang.Object
  extended by eneter.messaging.messagingsystems.androidusbcablemessagingsystem.AndroidUsbCableMessagingFactory
All Implemented Interfaces:
IMessagingSystemFactory

public class AndroidUsbCableMessagingFactory
extends java.lang.Object
implements IMessagingSystemFactory

Messaging system interacting with an Android device via the USB cable. When Android device is connected to the computer via the USB cable the process adb (Android Debug Bridge) is started on the computer and adbd (Android Debug Bridge Daemon) is started on the Android device. These processes then communicate via the USB cable.

How this messaging works:

  1. Your desktop application sends a message via the output channel created by AndroidUsbCableMessagingFactory
  2. The output channel internally sends the message via TCP to the adb service.
  3. adb service receives data and transfers it via USB cable to adbd.
  4. adbd in the Android device receives data and forwards it via TCP to the desired port.
  5. Android application listening on that port receives the message and processes it.
Notice there is a restriction for this type of communication:
The Android application must be a listener (service) and the computer application must be the client.

The example shows a service on the Android side that will receive messages via the USB cable.
 public class AndroidUsbCableServiceActivity extends Activity
 {
     // Eneter communication.
     private IDuplexTypedMessageReceiver<String, String> myEchoReceiver;
     
     
     // Called when the activity is first created.
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         
         // Start listening.
         startListening();
     }
     
     @Override
     public void onDestroy()
     {
         stopListening();
         
         super.onDestroy();
     }
     
     private void startListening()
     {
         try
         {
             // Create message receiver.
             IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
             myEchoReceiver = aReceiverFactory.createDuplexTypedMessageReceiver(String.class, String.class);
             
             // Subscribe to receive messages.
             myEchoReceiver.messageReceived().subscribe(new EventHandler<TypedRequestReceivedEventArgs<String>>()
                 {
                     @Override
                     public void onEvent(Object sender, TypedRequestReceivedEventArgs<String> e)
                     {
                         // Response back with the same message.
                         try
                         {
                             myEchoReceiver.sendResponseMessage(e.getResponseReceiverId(), e.getRequestMessage());
                         }
                         catch (Exception err)
                         {
                             EneterTrace.error("Sending echo response failed.", err);
                         }
                     }
                 });
             
             // Create TCP messaging.
             // Note: When adbd receives a message from the USB cable it will forward it
             //       to 127.0.0.1 (loopback) and desired port.
             IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
             IDuplexInputChannel anInputChannel = aMessaging.createDuplexInputChannel("tcp://127.0.0.1:8090/");
             
             // Attach the input channel to the receiver and start listening.
             myEchoReceiver.attachDuplexInputChannel(anInputChannel);
         }
         catch (Exception err)
         {
             EneterTrace.error("OpenConnection failed.", err);
         }
     }
     
     private void stopListening()
     {
         // Detach input channel and stop listening.
         myEchoReceiver.detachDuplexInputChannel();
     }
 }
 
The example shows a client communicating with the Android service via the USB cable.
 public class Program
 {
     private static ISyncDuplexTypedMessageSender<String, String> mySender;
 
     public static void main(String[] args)
     {
         try
         {
             // Use messaging via Android USB cable.
             IMessagingSystemFactory aMessaging = new AndroidUsbCableMessagingFactory();
             
             // Specify that the android application will listen on the port 8090.
             // Note: adb (on PC) and adbd (on Android) will be configured to forward the
             //       the communication to the port 8090.
             IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("8090");
         
             // Create message sender.
             IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
             mySender = aSenderFactory.createSyncDuplexTypedMessageSender(String.class, String.class);
             
             // Attach the output channel using Android USB cable and
             // be able to send messages and receive responses.
             mySender.attachDuplexOutputChannel(anOutputChannel);
             
             // Send request and wait for response.
             String aResponse = mySender.sendRequestMessage("Hello");
             
             // Detach output channel and close the connection.
             mySender.detachDuplexOutputChannel();
             
             System.out.println("Android responded: " + aResponse);
         }
         catch (Exception err)
         {
             EneterTrace.error("Error detected.", err);
         }
     }
 
 }
 


Constructor Summary
AndroidUsbCableMessagingFactory()
          Constructs the messaging which communicates with Android via the USB cable.
AndroidUsbCableMessagingFactory(int adbHostPort, IProtocolFormatter protocolFormatter)
          Constructs the messaging which communicates with Android via the USB cable.
 
Method Summary
 IDuplexInputChannel createDuplexInputChannel(java.lang.String channelId)
          Not supported.
 IDuplexOutputChannel createDuplexOutputChannel(java.lang.String channelId)
          Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable.
 IDuplexOutputChannel createDuplexOutputChannel(java.lang.String channelId, java.lang.String responseReceiverId)
          Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable.
 IClientSecurityFactory getClientSecurity()
          Gets the socket factory allowing to set the communication timeouts with the adb service.
 IThreadDispatcherProvider getOutputChannelThreading()
          Gets threading mode used for output channels.
 AndroidUsbCableMessagingFactory setOutputChannelThreading(IThreadDispatcherProvider outputChannelThreading)
          Sets threading mode for output channels.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AndroidUsbCableMessagingFactory

public AndroidUsbCableMessagingFactory()
Constructs the messaging which communicates with Android via the USB cable. It expects the adb service is running and listening on default port 5037. The adb service typically starts automatically when you connect the Android device via the USB cable.


AndroidUsbCableMessagingFactory

public AndroidUsbCableMessagingFactory(int adbHostPort,
                                       IProtocolFormatter protocolFormatter)
Constructs the messaging which communicates with Android via the USB cable. The adb service typically starts automatically when you connect the Android device via the USB cable.

Parameters:
adbHostPort - Port where adb service is listening to commands. Default value is 5037.
protocolFormatter - Low level formatting used for encoding messages between channels. EneterProtocolFormatter() can be used by default.
Method Detail

createDuplexOutputChannel

public IDuplexOutputChannel createDuplexOutputChannel(java.lang.String channelId)
                                               throws java.lang.Exception
Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable.

Specified by:
createDuplexOutputChannel in interface IMessagingSystemFactory
Parameters:
channelId - Port number where the Android application is listening.
Returns:
output channel
Throws:
java.lang.Exception

createDuplexOutputChannel

public IDuplexOutputChannel createDuplexOutputChannel(java.lang.String channelId,
                                                      java.lang.String responseReceiverId)
                                               throws java.lang.Exception
Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable. Using AndroidUsbCableMessagingFactory to create a client on the computer.
 // Create messaging using Android USB cable.
 IMessagingSystemFactory aMessaging = new AndroidUsbCableMessagingFactory();
 
 // Create duplex output channel that will communicate via the port 7634.
 IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("7634");
 
 // Create message sender that will send messages.
 ISyncTypedMessagesFactory aSenderFactory = new SyncTypedMessagesFactory();
 ISyncTypedMessageSender aSender = aSenderFactory.createSyncMessageSender<string,string>();
 
 // Attach the output channel and be able to send messages and receive responses.
 // Note: It will configure adb to listen on the port 7634 and forward incoming data via the cable
 //       to Android where adbd will forward it to the port 7634.
 aSender.attachDuplexOutputChannel(anOutputChannel);
 
 // Send message and wait for the response.
 string aResponse = aSender.sendRequestMessage("Hello.");
 ...
 
Service code on the Android side.
 Create TCP messaging listening on the same port 7634.
 // Note: Use standard TCP messaging, just listen to the specified port.
 IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
 IDuplexInputChannel anInputChannel = aMessaging.createDuplexInputChannel("tcp://127.0.0.1:7634/");
 
 // Create message receiver.
 IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
 myReceiver = aReceiverFactory.createDuplexTypedMessageReceiver(String.class, String.class);
 
 // Subscribe to receive messages.
 myReceiver.messageReceived().subscribe(new EventHandler<TypedRequestReceivedEventArgs<String>>()
 {
    @Override
    public void onEvent(Object sender, TypedRequestReceivedEventArgs<String> e)
    {
       // Response back with the same message.
       try
       {
           myReceiver.sendResponseMessage(e.getResponseReceiverId(), e.getRequestMessage());
       }
       catch (Exception err)
       {
           EneterTrace.error("Sending echo response failed.", err);
       }
   }
 });
  
 // Attach the input channel to the receiver and start listening.
 myReceiver.attachDuplexInputChannel(anInputChannel);
 

Specified by:
createDuplexOutputChannel in interface IMessagingSystemFactory
Parameters:
channelId - Port number where the Android application is listening.
responseReceiverId - Identifies the response receiver of this duplex output channel.
Returns:
duplex output channel
Throws:
java.lang.Exception

createDuplexInputChannel

public IDuplexInputChannel createDuplexInputChannel(java.lang.String channelId)
                                             throws java.lang.Exception
Not supported. The known restriction is that Android cannot be client. Therefore, .NET or Java application running on PC cannot be a service using the duplex input chanel for listening. :-(

Specified by:
createDuplexInputChannel in interface IMessagingSystemFactory
Parameters:
channelId - address of the input channel.
Returns:
input channel
Throws:
java.lang.Exception

getClientSecurity

public IClientSecurityFactory getClientSecurity()
Gets the socket factory allowing to set the communication timeouts with the adb service.

Returns:
client security factory

setOutputChannelThreading

public AndroidUsbCableMessagingFactory setOutputChannelThreading(IThreadDispatcherProvider outputChannelThreading)
Sets threading mode for output channels. Default setting is that received response messages are routed into one working thread.

Parameters:
outputChannelThreading - thread dispatcher
Returns:
this factory

getOutputChannelThreading

public IThreadDispatcherProvider getOutputChannelThreading()
Gets threading mode used for output channels. Default setting is that received response messages are routed into one working thread.

Returns:
thread dispatcher