Skip to content

ASAPActivity

Thomas Schwotzer edited this page Sep 4, 2020 · 35 revisions

This library is meant to support implementing interactive Android apps. Such applications use activities. Any activity of your application that has anything to do with ASAP must be a subclass of ASAPActivity

Constructor

ASAPActivities must be constructed with its ASAPApplication.

Here is code from our example application. Less code is hardly possible:

public class ASAPExampleRootActivity extends ASAPActivity {
    public ASAPExampleRootActivity() {
        super(ASAPExampleApplication.getASAPApplication());
    }
}

We have defined a root activity for our application. The real activities (those with application logic) can derive from it. There is no need for a constructor any longer, see e.g. ASAPExampleActivity.

Two aspects are important: First, it is maybe just an interesting fact that getASAPApplication() is derived from ASAPApplication. It refers to an ASAPApplication object after initialization.

And here is the second and more important issue.

Initial activity

We have a classical chicken-egg-problem. This one has a clear answer, though. That's the problem:

An ASAPApplication must be constructed with an activity. An ASAPActivity must be constructed with an ASAPApplication. There is just one solution: That initial activity is not subclass of ASAPActivity. It's a simple solution, see here.

Life cycle

ASAPActivity performs a number of things when a change in the life cycle happens. It binds and unbinds from the ASAPService on start/resume pause/destroy. It activates or stops issuing broadcasts. You do not have to deal with those things at all. One thing is important if you also plan to overwrite life-cyle-methods.

Don't forget to call the super method. We try to force you with appropriate code annotations. In case we have forgotten: Call super at any time, e.g.

protected void onStart() {
    super.onStart(); // really important!
}

Layer 2 network management

This library allows you to ignore nearly any detail of layer 2 connections management.

YourActivity yourActivity = ..; //

yourActivity.startBluetooth();
yourActivity.stopBluetooth();

yourActivity.startBluetoothDiscoverable();
yourActivity.startBluetoothDiscovery();

Hopefully, it is self-explaining. Bluetooth environment is started and stopped.

It is tried to re-establish a connection to paired devices in certain intervals as long as the layer 2 protocol is running.

A pairing is made by a discovery procedure, see Android Developer Guide. A device must be discoverable to be found. Devices must look for each other by initiating a discovery. Both processes can only be switched on. The shut down automatically after less then a view minutes.

Alternative protocols

We work on that. There are already some prototypical implementation in the library for Wifi Direct. We also plan to support LoRa but also Internet protocols, especially e-mail and secure channels via TOR.

Send ASAP Messages

Open channels

Your application must be able to produce a byte code message. ASAP is going to transmit this message.

// we took this name in ASAPApplication example
CharSequence appName = "application/x-mySuperAppMessenger";
// choose a uri to distingush messages within your app
CharSequence uri = "mySchema://openChat";
// your message
byte[] message = ...;
/* 
true: message will be stored and delivered as soon as possible and presumably several times
false: message will be sent over open connections and forgotten
true is the better choice.
*/
boolean persistent = true;

try {
    yourActivity.sendASAPMessage(appName, uri, message, persistent);
}
catch(ASAPException e) {
    // do something, e.g. inform users...
}

That is the very nature of ASAP. Your applications wants a message to be delivered. It tags it with application name and describes it in more details with a uri. We are in an ad-hoc environment. Your application should not need to know about current connections. One A in ASAP stands for asynchronous. Use persistent=true.

This message is sent to the ASAPService which stores it for further delivery. This message is delivered during each new peer encounter. ASAP makes sure that this delivery is made only once. (See the era concept for details.)

That's it. Receiver application will be informed with listener about newly arrived messages.

Leaving recipient list empty establishes an open channel. Messages are transmitted to any other peer. That's the first step, though. Peers do not relay messages per default. Your application can decide if peers forward message from other peers with their own. Your application can write their own recipient list inside your message bytes. Your are also free to encrypt your messages. ASAP is just a routing protocol.

Nevertheless, the closed channel concept, restrains this gossip behaviour in the first place. It comes with a price, though.

Closed channels

CharSequence appName = "application/x-mySuperAppMessenger";
CharSequence uri = "mySchema://chatAliceBob";

Collection<CharSequence> recipients = new List<>();
recipients.add("Bob"); // assumed you are Alice

yourActivity.createClosedASAPChannel(appName, uri, recipients);
byte[] message = ...;
// message would only reach Bob
yourActivity.sendASAPMessage(appName, uri, message, true);

createClosedASAPChannel defines that each further message with appNameand uri would only be delivered to one of the peers with an IDthat is in the recipient list.

Recipients in ASAP messages can be seen as filter. Messages without a recipient list are sent to any peer. Messages with recipients are only transmitted to peers in recipient list. Think of the distributed nature of your decentralized application. There is no server anywhere. By reducing recipients to Bob this message would only be delivered to Bob.

Your app would not put it on a server with some fancy flags asking not to read it. Your app would not send this message to Clara even if she plans to visit Bob. ASAP is like verbal communication. This message would only be sent to Bob directly or it would remain on the peer. Our peer has to encounter Bob to deliver this message. That's secure. And this should your application be aware of.

You could implement real high secure messanger apps. You could follow and proof who ever got even wind of the existing of this message. There is no server which could be blamed. Unfortunately, this feature hinders message propagation as well and an open channel would be better. It depends on your application.

Message encryption helps to relax the situation. It allows to establish groups of trusted peers who are allowed to relay their messages. Encryption would ensure end-to-end security. Group members would be aware of the fact of a message transfer (which can be critical. It is basis of social profiling!) without knowing the actual message content. ASAP allows keeping track of deliverers. Communication gets more transparent. But encryption and certificates that's another topic, see below and ASAPCertificates.

Anything comes with a price. Server based applications are often easier to implement but requires you to trust providers. Decentralized systems require a bit more complex algorithms. You get more security in return.

We can implement marvellous and nearly unbreakable applications with this.

Receiving ASAP Messages

ASAPChunkReceivedListener

You have to implement a listener and subscribe with your ASAPApplication object, see description

Advanced Topics

ASAPUriContentChangedListener

ASAPUriContentChangedListener is another listener which can be subscribed to ASAPApplication

// somewhere initialized
ASAPExampleApplication asapApp = ... ;
ASAPUriContentChangedListener yourUriListener = new YourUriListener();
asapApp.ASAPUriContentChangedListener("application/x-mySuperAppMessenger", yourUriListener);

...
public class YourUriListener implements ASAPUriContentChangedListener {
...
    public void asapUriContentChanged(CharSequence uri) {
        // do something, e.g. redraw chat activitiy   
    }
 ...
}

This listener notifies about incoming message with a uri. Your application is informed that one or more messages tagged with this uri arrived. Messages itself are not propagated. This variant is useful if your application directly access the ASAPStorage which is another topic.

Notifications

This lib has two parts: Android service and the application site. ASAPApplication and ASAPActivity are mediators between your application and the servoe which makes the actual work.

The service informs applications side about changes by sending broadcast. Your can those broadcasts as well. You could also overwrite methods.

YourActivity extends ASAPActivity {
...
    @Override
    public void asapNotifyOnlinePeersChanged(List<CharSequence> peerList) {
        super.asapNotifyOnlinePeersChanged(peerList);
        // now you know a connection(s) are established or broken
    }

...
}

Don't forget to call the super method. It would have serious impacts on the lib otherwise. Method names speak for themselves. Look for methods which start with asapNotify in the javadoc.

Direct access to ASAPStorage

Advanced topic. [TODO]

Message encryption

Advanced topic. [TODO]

Example

This repository contains an example which was implemented for testing purpose only, see example package and namely ASAPExampleActivity

SN2 is going to become a decentralized messager based on asap.

Clone this wiki locally