mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 18:07:55 +00:00
Implemented bi-directional communication using tcp.
This commit is contained in:
parent
8347c760f5
commit
c7557f0dc6
@ -1,12 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$/build.gradle" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
|
@ -3,8 +3,9 @@
|
||||
<component name="FacetManager">
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_BUILD_VARIANT" value="Debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
@ -17,7 +18,8 @@
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" />
|
||||
|
@ -3,7 +3,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.4'
|
||||
classpath 'com.android.tools.build:gradle:0.5.+'
|
||||
}
|
||||
}
|
||||
apply plugin: 'android'
|
||||
|
@ -11,6 +11,7 @@ import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.ComputerLinks.BaseComputerLink;
|
||||
import org.kde.connect.LinkProviders.AvahiTcpLinkProvider;
|
||||
import org.kde.connect.LinkProviders.BaseLinkProvider;
|
||||
import org.kde.connect.LinkProviders.AvahiLinkProvider;
|
||||
import org.kde.connect.PackageEmitters.BasePackageEmitter;
|
||||
@ -20,38 +21,22 @@ import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
import org.kde.connect.PackageReceivers.PingPackageReceiver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BackgroundService extends Service {
|
||||
|
||||
SharedPreferences settings;
|
||||
|
||||
ArrayList<BaseLinkProvider> locators = new ArrayList<BaseLinkProvider>();
|
||||
ArrayList<BaseComputerLink> computerLinks = new ArrayList<BaseComputerLink>();
|
||||
|
||||
ArrayList<BasePackageEmitter> emitters = new ArrayList<BasePackageEmitter>();
|
||||
ArrayList<BasePackageReceiver> receivers = new ArrayList<BasePackageReceiver>();
|
||||
|
||||
HashMap<String, Device> devices = new HashMap<String, Device>();
|
||||
|
||||
PingPackageEmitter pingEmitter;
|
||||
|
||||
private void clearComputerLinks() {
|
||||
Log.i("BackgroundService","clearComputerLinks");
|
||||
for(BasePackageEmitter pe : emitters) pe.clearComputerLinks();
|
||||
computerLinks.clear();
|
||||
}
|
||||
|
||||
private void removeComputerLink(BaseComputerLink cl) {
|
||||
Log.i("BackgroundService","removeComputerLink");
|
||||
for(BasePackageEmitter pe : emitters) pe.removeComputerLink(cl);
|
||||
computerLinks.remove(cl);
|
||||
}
|
||||
|
||||
private void addComputerLink(BaseComputerLink cl) {
|
||||
Log.i("BackgroundService","addComputerLink");
|
||||
computerLinks.add(cl);
|
||||
for(BasePackageEmitter pe : emitters) pe.addComputerLink(cl);
|
||||
for(BasePackageReceiver pr : receivers) cl.addPackageReceiver(pr);
|
||||
}
|
||||
|
||||
private void registerEmitters() {
|
||||
if (settings.getBoolean("emit_call", true)) {
|
||||
emitters.add(new CallPackageEmitter(getApplicationContext()));
|
||||
@ -69,11 +54,22 @@ public class BackgroundService extends Service {
|
||||
}
|
||||
|
||||
public void registerAnnouncers() {
|
||||
if (settings.getBoolean("announce_avahi", true)) {
|
||||
/*if (settings.getBoolean("announce_avahi", true)) {
|
||||
locators.add(new AvahiLinkProvider(this));
|
||||
}*/
|
||||
if (settings.getBoolean("announce_avahi_tcp", true)) {
|
||||
locators.add(new AvahiTcpLinkProvider(this));
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<String> getVisibleDevices() {
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
for(Device d : devices.values()) {
|
||||
list.add(d.getName());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
//This will be called for each intent launch, even if the service is already started and is reused
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
@ -85,15 +81,36 @@ public class BackgroundService extends Service {
|
||||
return Service.START_STICKY;
|
||||
}
|
||||
|
||||
public void reachComputers() {
|
||||
clearComputerLinks();
|
||||
private void startDiscovery() {
|
||||
Log.e("StartDiscovery","Registering connection receivers");
|
||||
for (BaseLinkProvider a : locators) {
|
||||
Log.e("Registerign", a.toString());
|
||||
a.reachComputers(new BaseLinkProvider.ConnectionReceiver() {
|
||||
@Override
|
||||
public void onConnectionAccepted(BaseComputerLink link) {
|
||||
public void onConnectionAccepted(String deviceId, String name, BaseComputerLink link) {
|
||||
Log.e("BackgroundService", "Connection accepted!");
|
||||
//TODO: Check if there are other links available, and keep the best one
|
||||
addComputerLink(link);
|
||||
|
||||
if (devices.containsKey(deviceId)) {
|
||||
Log.e("BackgroundService", "known device");
|
||||
devices.get(deviceId).addLink(link);
|
||||
} else {
|
||||
Log.e("BackgroundService", "unknown device");
|
||||
Device device = new Device(deviceId, name, link);
|
||||
devices.put(deviceId, device);
|
||||
for (BasePackageEmitter pe : emitters) pe.addDevice(device);
|
||||
for (BasePackageReceiver pr : receivers) device.addPackageReceiver(pr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionLost(BaseComputerLink link) {
|
||||
Device d = devices.get(link.getDeviceId());
|
||||
if (d != null) {
|
||||
d.removeLink(link);
|
||||
//if (d.countLinkedDevices() == 0) devices.remove(link.getDeviceId);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -117,9 +134,15 @@ public class BackgroundService extends Service {
|
||||
registerEmitters();
|
||||
registerReceivers();
|
||||
registerAnnouncers();
|
||||
startDiscovery();
|
||||
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
devices.clear();
|
||||
startDiscovery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.e("BackgroundService", "Destroying");
|
||||
@ -141,11 +164,11 @@ public class BackgroundService extends Service {
|
||||
}
|
||||
|
||||
private static ArrayList<InstanceCallback> callbacks = new ArrayList<InstanceCallback>();
|
||||
/*
|
||||
|
||||
public static void Start(Context c) {
|
||||
RunCommand(c, null);
|
||||
}
|
||||
*/
|
||||
|
||||
public static void RunCommand(Context c, final InstanceCallback callback) {
|
||||
if (callback != null) callbacks.add(callback);
|
||||
Intent serviceIntent = new Intent(c, BackgroundService.class);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.kde.connect.ComputerLinks;
|
||||
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.LinkProviders.BaseLinkProvider;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
|
||||
@ -8,6 +10,27 @@ import java.util.ArrayList;
|
||||
|
||||
public abstract class BaseComputerLink {
|
||||
|
||||
private BaseLinkProvider linkProvider;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
public BaseComputerLink(BaseLinkProvider linkProvider) {
|
||||
this.linkProvider = linkProvider;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public BaseLinkProvider getLinkProvider() {
|
||||
return linkProvider;
|
||||
}
|
||||
|
||||
|
||||
ArrayList<BasePackageReceiver> receivers = new ArrayList<BasePackageReceiver>();
|
||||
|
||||
public void addPackageReceiver(BasePackageReceiver pr) {
|
||||
@ -18,17 +41,13 @@ public abstract class BaseComputerLink {
|
||||
}
|
||||
|
||||
//Should be called from a background thread listening to packages
|
||||
protected void packageReceived(NetworkPackage np) {
|
||||
protected void packageReceived(Device d, NetworkPackage np) {
|
||||
for(BasePackageReceiver pr : receivers) {
|
||||
pr.onPackageReceived(np);
|
||||
pr.onPackageReceived(d, np);
|
||||
}
|
||||
}
|
||||
|
||||
//TO OVERRIDE
|
||||
|
||||
|
||||
//Should be async
|
||||
public abstract void sendPackage(NetworkPackage np);
|
||||
|
||||
public abstract boolean sendPackage(NetworkPackage np); //Should be async
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,148 @@
|
||||
package org.kde.connect.ComputerLinks;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.LinkProviders.BaseLinkProvider;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class TcpComputerLink extends BaseComputerLink {
|
||||
|
||||
private boolean listenign = false;
|
||||
private SocketChannel sChannel;
|
||||
private Charset charset = Charset.forName("US-ASCII");
|
||||
|
||||
public TcpComputerLink(BaseLinkProvider linkProvider, InetAddress ip, int port) throws java.io.IOException {
|
||||
super(linkProvider);
|
||||
|
||||
sChannel = SocketChannel.open();
|
||||
sChannel.connect(new InetSocketAddress(ip, port));
|
||||
sChannel.configureBlocking(false);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendPackage(NetworkPackage np) {
|
||||
Log.e("TcpComputerLink","sendPackage");
|
||||
try {
|
||||
String s = np.serialize();
|
||||
Log.e("SendPackage",s);
|
||||
|
||||
CharsetEncoder enc = charset.newEncoder();
|
||||
ByteBuffer bytes = enc.encode(CharBuffer.wrap(s));
|
||||
Log.e("asdads",""+bytes.array().length);
|
||||
int written = sChannel.write(bytes);
|
||||
|
||||
Log.e("SendPackage","sent "+written+" bytes");
|
||||
} catch(Exception e) {
|
||||
Log.e("TcpComputerLink","Exception");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPackageReceiver(BasePackageReceiver pr) {
|
||||
Log.e("TcpComputerLink","addPacakgeReceiver");
|
||||
super.addPackageReceiver(pr);
|
||||
if (!listenign) startReceivingPackages();
|
||||
}
|
||||
|
||||
public void startReceivingPackages() {
|
||||
listenign = true;
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
Log.e("TcpComputerLink","start receiving packages");
|
||||
InputStreamReader reader = new InputStreamReader(socket.getInputStream());
|
||||
Log.e("TcpComputerLink","Entering loop");
|
||||
|
||||
while (socket.isConnected()) {
|
||||
if (serverMessage == null) {
|
||||
//wait(100);
|
||||
continue;
|
||||
}
|
||||
NetworkPackage np = NetworkPackage.unserialize(serverMessage);
|
||||
Log.e("TcpComputerLink",serverMessage);
|
||||
packageReceived(np);
|
||||
}*/
|
||||
|
||||
|
||||
final Selector selector = Selector.open();
|
||||
sChannel.register(selector, SelectionKey.OP_CONNECT + SelectionKey.OP_READ);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
selector.select(); //blocking
|
||||
Iterator it = selector.selectedKeys().iterator();
|
||||
// Process each key at a time
|
||||
while (it.hasNext()) {
|
||||
// Get the selection key
|
||||
SelectionKey selKey = (SelectionKey)it.next();
|
||||
|
||||
// Remove it from the list to indicate that it is being processed
|
||||
it.remove();
|
||||
|
||||
if (selKey.isValid() && selKey.isConnectable()) {
|
||||
// Get channel with connection request
|
||||
SocketChannel sChannel = (SocketChannel)selKey.channel();
|
||||
|
||||
boolean success = sChannel.finishConnect();
|
||||
if (!success) {
|
||||
// An error occurred; handle it
|
||||
|
||||
// Unregister the channel with this selector
|
||||
selKey.cancel();
|
||||
}
|
||||
}
|
||||
if (selKey.isValid() && selKey.isReadable()) {
|
||||
// Get channel with bytes to read
|
||||
|
||||
SocketChannel sChannel = (SocketChannel)selKey.channel();
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4096);
|
||||
int read = sChannel.read(buffer);
|
||||
//TODO: Check if there is more to read (or we have read more than one package)
|
||||
String s = new String( buffer.array(), 0, read, charset );
|
||||
Log.e("readable","Read "+read+" bytes: "+s);
|
||||
|
||||
NetworkPackage np = NetworkPackage.unserialize(s);
|
||||
packageReceived(null, np);
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("TcpComputerLink","Inner loop exception");
|
||||
e.printStackTrace();
|
||||
listenign = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Log.e("TcpComputerLink","Exiting loop");
|
||||
}
|
||||
}).run();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("TcpComputerLink","Exception");
|
||||
listenign = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -3,66 +3,78 @@ package org.kde.connect.ComputerLinks;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.LinkProviders.AvahiLinkProvider;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
|
||||
public class UdpComputerLink extends BaseComputerLink {
|
||||
|
||||
DatagramSocket socket = null;
|
||||
int UDP_PORT;
|
||||
InetAddress IP;
|
||||
|
||||
final int BUFFER_SIZE = 5*1024;
|
||||
|
||||
public UdpComputerLink(InetAddress ip, int port) {
|
||||
public UdpComputerLink(AvahiLinkProvider linkProvider, InetAddress ip, int port) throws IOException {
|
||||
super(linkProvider);
|
||||
UDP_PORT = port;
|
||||
IP = ip;
|
||||
}
|
||||
|
||||
Log.e("UdpComputerLink","" + ip + ":" + UDP_PORT);
|
||||
/*
|
||||
new AsyncTask<Void,Void,Void>() {
|
||||
@Override
|
||||
public boolean sendPackage(NetworkPackage np) {
|
||||
if (socket == null) startReceivingPackages();
|
||||
Log.e("UdpComputerLink","sendPackage");
|
||||
final String messageStr = np.serialize();
|
||||
Log.e("UdpComputerLink", "aboutToSend");
|
||||
int msg_length = messageStr.length();
|
||||
byte[] message = messageStr.getBytes();
|
||||
DatagramPacket p = new DatagramPacket(message, msg_length, IP, UDP_PORT);
|
||||
Log.e("UdpComputerLink", "aboutToSend " + IP + ":" + UDP_PORT);
|
||||
try {
|
||||
socket.send(p);
|
||||
} catch (Exception e) {
|
||||
Log.e("UdpComputerLink", "Exception!");
|
||||
}
|
||||
Log.e("UdpComputerLink", "sent");
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public void addPackageReceiver(BasePackageReceiver pr) {
|
||||
super.addPackageReceiver(pr);
|
||||
if (socket == null) startReceivingPackages();
|
||||
}
|
||||
|
||||
private void startReceivingPackages() {
|
||||
try {
|
||||
socket = new DatagramSocket(UDP_PORT);
|
||||
}catch(Exception e) {
|
||||
Log.e("UdpComputerLink","Exception");
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.e("UdpComputerLink","" + IP + ":" + UDP_PORT);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
public void run() {
|
||||
try {
|
||||
Log.e("UdpComputerLink","Waiting for udp datagrams");
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
DatagramSocket socket = new DatagramSocket(UDP_PORT);
|
||||
while(true){
|
||||
DatagramPacket packet = new DatagramPacket(buffer, buffer.length );
|
||||
socket.receive(packet);
|
||||
String s = new String(packet.getData(), 0, packet.getLength());
|
||||
packageReceived(NetworkPackage.fromString(s));
|
||||
packageReceived(null,NetworkPackage.unserialize(s));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("UdpComputerLink","Exception");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPackage(NetworkPackage np) {
|
||||
Log.e("UdpComputerLink","sendPackage");
|
||||
final String messageStr = np.serialize();
|
||||
new AsyncTask<Void,Void,Void>(){
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
try {
|
||||
DatagramSocket s = new DatagramSocket();
|
||||
int msg_length = messageStr.length();
|
||||
byte[] message = messageStr.getBytes();
|
||||
DatagramPacket p = new DatagramPacket(message, msg_length,IP,UDP_PORT);
|
||||
s.send(p);
|
||||
Log.e("Sent", messageStr);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}).run();
|
||||
}
|
||||
}
|
||||
|
92
KdeConnect/src/main/java/org/kde/connect/Device.java
Normal file
92
KdeConnect/src/main/java/org/kde/connect/Device.java
Normal file
@ -0,0 +1,92 @@
|
||||
package org.kde.connect;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.ComputerLinks.BaseComputerLink;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class Device {
|
||||
|
||||
private ArrayList<BaseComputerLink> links = new ArrayList<BaseComputerLink>();
|
||||
private ArrayList<BasePackageReceiver> receivers = new ArrayList<BasePackageReceiver>();
|
||||
|
||||
private String deviceId;
|
||||
private String name;
|
||||
|
||||
|
||||
Device(String deviceId, String name, BaseComputerLink dl) {
|
||||
this.deviceId = deviceId;
|
||||
this.name = name;
|
||||
addLink(dl);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void addLink(BaseComputerLink link) {
|
||||
Log.e("Device","addLink "+link.getLinkProvider().getName()+" -> "+getName());
|
||||
links.add(link);
|
||||
Collections.sort(links, new Comparator<BaseComputerLink>() {
|
||||
@Override
|
||||
public int compare(BaseComputerLink o, BaseComputerLink o2) {
|
||||
return o2.getLinkProvider().getPriority() - o.getLinkProvider().getPriority();
|
||||
}
|
||||
});
|
||||
|
||||
link.addPackageReceiver(new BasePackageReceiver() {
|
||||
@Override
|
||||
public void onPackageReceived(Device d, NetworkPackage np) {
|
||||
for (BasePackageReceiver receiver : receivers) {
|
||||
receiver.onPackageReceived(Device.this, np);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void removeLink(BaseComputerLink link) {
|
||||
links.remove(link);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Send and receive interfaces
|
||||
|
||||
public void addPackageReceiver(BasePackageReceiver receiver) {
|
||||
receivers.add(receiver);
|
||||
}
|
||||
|
||||
public boolean sendPackage(final NetworkPackage np) {
|
||||
Log.e("Device","sendPackage");
|
||||
|
||||
new AsyncTask<Void,Void,Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
Log.e("sendPackage","Do in background");
|
||||
for(BaseComputerLink link : links) {
|
||||
Log.e("sendPackage","Trying "+link.getLinkProvider().getName());
|
||||
if (link.sendPackage(np)) {
|
||||
Log.e("sent using", link.getLinkProvider().getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Log.e("sendPackage","Error: Package could not be sent");
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
Log.e("Device","/sendPackage");
|
||||
return true; //FIXME
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,9 @@ import android.net.nsd.NsdServiceInfo;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.ComputerLinks.UdpComputerLink;
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
|
||||
import java.lang.Override;
|
||||
import java.util.ArrayList;
|
||||
@ -21,6 +23,8 @@ public class AvahiLinkProvider implements BaseLinkProvider {
|
||||
|
||||
Context ctx;
|
||||
|
||||
private NsdManager.DiscoveryListener oldListener = null;
|
||||
|
||||
public AvahiLinkProvider(Context context) {
|
||||
mNsdManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
|
||||
ctx = context;
|
||||
@ -31,34 +35,50 @@ public class AvahiLinkProvider implements BaseLinkProvider {
|
||||
|
||||
visibleComputers.clear();
|
||||
|
||||
if (oldListener != null) mNsdManager.stopServiceDiscovery(oldListener);
|
||||
|
||||
Log.e("AvahiLinkProvider", "Discovering computers...");
|
||||
|
||||
final NsdManager.ResolveListener mResolveListener = new NsdManager.ResolveListener() {
|
||||
|
||||
@Override
|
||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
|
||||
Log.e("AvahiLinkProvider", "Resolve failed" + errorCode);
|
||||
Log.e("AvahiLinkProvider", "Resolve failed: " + errorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceResolved(NsdServiceInfo serviceInfo) {
|
||||
Log.e("AvahiLinkProvider", "Resolve Succeeded. " + serviceInfo);
|
||||
|
||||
//Computer found
|
||||
public void onServiceResolved(final NsdServiceInfo serviceInfo) {
|
||||
Log.e("AvahiLinkProvider", "Resolve Succeeded: " + serviceInfo);
|
||||
|
||||
//Handshake link
|
||||
UdpComputerLink link = new UdpComputerLink(serviceInfo.getHost(),serviceInfo.getPort());
|
||||
NetworkPackage np = NetworkPackage.createIdentityPackage(ctx);
|
||||
link.sendPackage(np);
|
||||
try {
|
||||
UdpComputerLink link = new UdpComputerLink(AvahiLinkProvider.this,serviceInfo.getHost(),serviceInfo.getPort());
|
||||
link.addPackageReceiver(new BasePackageReceiver() {
|
||||
@Override
|
||||
public void onPackageReceived(Device d, NetworkPackage np) {
|
||||
Log.e("AvahiLinkProvider","Received reply");
|
||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
||||
String id = np.getString("deviceId");
|
||||
String name = np.getString("deviceName");
|
||||
//Real data link
|
||||
try {
|
||||
UdpComputerLink link2 = new UdpComputerLink(AvahiLinkProvider.this,serviceInfo.getHost(),10603);
|
||||
visibleComputers.add(link2);
|
||||
cr.onConnectionAccepted(id, name, link2);
|
||||
} catch (Exception e) {
|
||||
|
||||
//TODO: Wait for computer confirmation and ensure this is the device we want (requiring user interaction)
|
||||
//link.addPackageReceiver();
|
||||
|
||||
//Real data link
|
||||
UdpComputerLink link2 = new UdpComputerLink(serviceInfo.getHost(),10600);
|
||||
visibleComputers.add(link2);
|
||||
cr.onConnectionAccepted(link2);
|
||||
}
|
||||
} else {
|
||||
Log.e("AvahiLinkProvider","Received non-identity package");
|
||||
}
|
||||
}
|
||||
});
|
||||
Log.e("AvahiLinkProvider","Sending identity package");
|
||||
NetworkPackage np = NetworkPackage.createIdentityPackage(ctx);
|
||||
link.sendPackage(np);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@ -85,8 +105,7 @@ public class AvahiLinkProvider implements BaseLinkProvider {
|
||||
|
||||
@Override
|
||||
public void onServiceLost(NsdServiceInfo service) {
|
||||
Log.e("AvahiLinkProvider", "service lost" + service);
|
||||
visibleComputers.remove(service);
|
||||
Log.e("AvahiLinkProvider", "Service lost: " + service);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -107,9 +126,21 @@ public class AvahiLinkProvider implements BaseLinkProvider {
|
||||
}
|
||||
};
|
||||
|
||||
oldListener = mDiscoveryListener;
|
||||
mNsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AvahiUdpLinkProvider";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,150 @@
|
||||
package org.kde.connect.LinkProviders;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.ComputerLinks.TcpComputerLink;
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
import org.kde.connect.PackageReceivers.BasePackageReceiver;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class AvahiTcpLinkProvider implements BaseLinkProvider {
|
||||
|
||||
String serviceType = "_kdeconnect._tcp";
|
||||
|
||||
NsdManager mNsdManager;
|
||||
|
||||
HashMap<InetAddress, TcpComputerLink> visibleComputers = new HashMap<InetAddress, TcpComputerLink>();
|
||||
|
||||
Context ctx;
|
||||
private NsdManager.DiscoveryListener oldListener = null;
|
||||
|
||||
public AvahiTcpLinkProvider(Context context) {
|
||||
mNsdManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
|
||||
ctx = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reachComputers(final ConnectionReceiver cr) {
|
||||
|
||||
visibleComputers.clear();
|
||||
|
||||
if (oldListener != null) mNsdManager.stopServiceDiscovery(oldListener);
|
||||
|
||||
Log.e("AvahiTcpLinkProvider", "Discovering computers...");
|
||||
|
||||
final NsdManager.ResolveListener mResolveListener = new NsdManager.ResolveListener() {
|
||||
|
||||
@Override
|
||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
|
||||
Log.e("AvahiTcpLinkProvider", "Resolve failed" + errorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceResolved(NsdServiceInfo serviceInfo) {
|
||||
Log.e("AvahiTcpLinkProvider", "Resolve Succeeded. " + serviceInfo);
|
||||
|
||||
try {
|
||||
Log.e("AvahiTcpLinkProvider", "Creating link");
|
||||
final InetAddress host = serviceInfo.getHost();
|
||||
final int port = serviceInfo.getPort();
|
||||
final TcpComputerLink link = new TcpComputerLink(AvahiTcpLinkProvider.this,host,port);
|
||||
Log.e("AvahiTcpLinkProvider", "Waiting identity package");
|
||||
link.addPackageReceiver(new BasePackageReceiver() {
|
||||
@Override
|
||||
public void onPackageReceived(Device d, NetworkPackage np) {
|
||||
|
||||
Log.e("AvahiTcpLinkProvider", "Received package: " + np.getType());
|
||||
|
||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
||||
String id = np.getString("deviceId");
|
||||
String name = np.getString("deviceName");
|
||||
|
||||
link.setDeviceId(id);
|
||||
link.sendPackage(NetworkPackage.createIdentityPackage(ctx));
|
||||
visibleComputers.put(host,link);
|
||||
cr.onConnectionAccepted(id,name,link);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
link.startReceivingPackages();
|
||||
} catch (Exception e) {
|
||||
Log.e("AvahiTcpLinkProvider","Exception");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
NsdManager.DiscoveryListener mDiscoveryListener = new NsdManager.DiscoveryListener() {
|
||||
|
||||
@Override
|
||||
public void onDiscoveryStarted(String regType) {
|
||||
Log.e("AvahiTcpLinkProvider", "Service discovery started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceFound(NsdServiceInfo service) {
|
||||
Log.e("AvahiTcpLinkProvider", "Service discovery success" + service);
|
||||
|
||||
if (!service.getServiceType().startsWith(serviceType)) {
|
||||
Log.e("AvahiTcpLinkProvider", "Unknown Service Type: " + service.getServiceType());
|
||||
} else {
|
||||
Log.e("AvahiTcpLinkProvider", "Computer found, resolving...");
|
||||
mNsdManager.resolveService(service, mResolveListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceLost(NsdServiceInfo service) {
|
||||
Log.e("AvahiTcpLinkProvider", "service lost" + service);
|
||||
TcpComputerLink link = visibleComputers.remove(service.getHost());
|
||||
if (link != null) cr.onConnectionLost(link);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDiscoveryStopped(String serviceType) {
|
||||
Log.e("AvahiTcpLinkProvider", "Discovery stopped: " + serviceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
|
||||
Log.e("AvahiTcpLinkProvider", "Discovery failed: Error code:" + errorCode);
|
||||
mNsdManager.stopServiceDiscovery(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
|
||||
Log.e("AvahiTcpLinkProvider", "Discovery failed: Error code:" + errorCode);
|
||||
mNsdManager.stopServiceDiscovery(this);
|
||||
}
|
||||
};
|
||||
|
||||
oldListener = mDiscoveryListener;
|
||||
mNsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 101;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AvahiTcpLinkProvider";
|
||||
}
|
||||
}
|
@ -5,11 +5,13 @@ import org.kde.connect.ComputerLinks.BaseComputerLink;
|
||||
public interface BaseLinkProvider {
|
||||
|
||||
public interface ConnectionReceiver {
|
||||
public void onConnectionAccepted(BaseComputerLink link);
|
||||
public void onConnectionAccepted(String deviceId, String name, BaseComputerLink link);
|
||||
public void onConnectionLost(BaseComputerLink link);
|
||||
}
|
||||
|
||||
//To override
|
||||
public void reachComputers(ConnectionReceiver cr);
|
||||
|
||||
public int getPriority();
|
||||
public String getName();
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import org.kde.kdeconnect.R;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
@ -23,18 +27,17 @@ public class MainActivity extends Activity {
|
||||
BackgroundService.RunCommand(MainActivity.this, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
service.reachComputers();
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Log.i("MainActivity","Button2");
|
||||
Log.i("MainActivity","Button1");
|
||||
BackgroundService.RunCommand(MainActivity.this, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
service.reachComputers();
|
||||
service.restart();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -43,7 +46,7 @@ public class MainActivity extends Activity {
|
||||
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Log.i("MainActivity","Button3");
|
||||
Log.i("MainActivity","Button2");
|
||||
BackgroundService.RunCommand(MainActivity.this, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
@ -54,6 +57,28 @@ public class MainActivity extends Activity {
|
||||
}
|
||||
});
|
||||
|
||||
final ListView list = (ListView)findViewById(R.id.listView1);
|
||||
|
||||
|
||||
findViewById(R.id.button3).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Log.i("MainActivity","Button3");
|
||||
BackgroundService.RunCommand(MainActivity.this, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(final BackgroundService service) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String[] listContent = service.getVisibleDevices().toArray(new String[0]);
|
||||
list.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, listContent));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,31 +1,42 @@
|
||||
package org.kde.connect.PackageEmitters;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.ComputerLinks.BaseComputerLink;
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class BasePackageEmitter {
|
||||
|
||||
private ArrayList<BaseComputerLink> mBaseComputerLinks = new ArrayList<BaseComputerLink>();
|
||||
private ArrayList<Device> mDevices = new ArrayList<Device>();
|
||||
|
||||
public void addComputerLink(BaseComputerLink cl) {
|
||||
mBaseComputerLinks.add(cl);
|
||||
public void addDevice(Device d) {
|
||||
mDevices.add(d);
|
||||
}
|
||||
public void removeComputerLink(BaseComputerLink cl) {
|
||||
mBaseComputerLinks.remove(cl);
|
||||
|
||||
public void removeDevice(Device d) {
|
||||
mDevices.remove(d);
|
||||
}
|
||||
|
||||
public void clearComputerLinks() {
|
||||
mBaseComputerLinks.clear();
|
||||
mDevices.clear();
|
||||
}
|
||||
|
||||
protected int countLinkedComputers() {
|
||||
return mBaseComputerLinks.size();
|
||||
public int countLinkedDevices() {
|
||||
return mDevices.size();
|
||||
}
|
||||
|
||||
protected void sendPackage(NetworkPackage np) {
|
||||
for(BaseComputerLink cl : mBaseComputerLinks) {
|
||||
cl.sendPackage(np);
|
||||
|
||||
protected boolean sendPackage(NetworkPackage np) {
|
||||
if (mDevices.isEmpty()) return false;
|
||||
for(Device d : mDevices) {
|
||||
d.sendPackage(np);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package org.kde.connect.PackageEmitters;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
|
||||
|
||||
@ -11,8 +12,14 @@ public class PingPackageEmitter extends BasePackageEmitter {
|
||||
public PingPackageEmitter(Context ctx) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDevice(Device d) {
|
||||
super.addDevice(d);
|
||||
Log.e("PinkPackageEmitter","addDevice: "+d.getName());
|
||||
}
|
||||
|
||||
public void sendPing() {
|
||||
Log.e("PingPackageEmitter", "sendPing to "+countLinkedComputers());
|
||||
Log.e("PingPackageEmitter", "sendPing to "+countLinkedDevices());
|
||||
|
||||
NetworkPackage lastPackage = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PING);
|
||||
sendPackage(lastPackage);
|
||||
|
@ -1,9 +1,10 @@
|
||||
package org.kde.connect.PackageReceivers;
|
||||
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
|
||||
public interface BasePackageReceiver {
|
||||
|
||||
public void onPackageReceived(NetworkPackage np);
|
||||
public void onPackageReceived(Device d, NetworkPackage np);
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
package org.kde.connect.PackageReceivers;
|
||||
|
||||
import android.R;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.kde.connect.BackgroundToast;
|
||||
import org.kde.connect.Device;
|
||||
import org.kde.connect.NetworkPackage;
|
||||
|
||||
public class PingPackageReceiver implements BasePackageReceiver {
|
||||
@ -14,9 +20,23 @@ public class PingPackageReceiver implements BasePackageReceiver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageReceived(NetworkPackage np) {
|
||||
if (np.getType() == "kdeconnect.ping") {
|
||||
Toast.makeText(context, "Ping!", Toast.LENGTH_LONG).show();
|
||||
public void onPackageReceived(Device d, NetworkPackage np) {
|
||||
Log.e("PingPackageReceiver", "onPackageReceived");
|
||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_PING)) {
|
||||
Log.e("PingPackageReceiver", "was a ping!");
|
||||
|
||||
Notification noti = new Notification.Builder(context)
|
||||
.setContentTitle(d.getName())
|
||||
.setContentText("Ping!")
|
||||
.setTicker("Ping!")
|
||||
.setSmallIcon(R.drawable.ic_dialog_alert)
|
||||
.setAutoCancel(true)
|
||||
.setDefaults(Notification.DEFAULT_SOUND)
|
||||
.build();
|
||||
|
||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(0, noti);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class ServiceLauncher extends BroadcastReceiver
|
||||
BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
service.reachComputers();
|
||||
|
||||
}
|
||||
});
|
||||
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
|
||||
@ -34,15 +34,16 @@ public class ServiceLauncher extends BroadcastReceiver
|
||||
BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
service.reachComputers();
|
||||
|
||||
}
|
||||
});
|
||||
} else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
|
||||
} else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)
|
||||
|| action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
|
||||
Log.e("KdeConnect", "Connection state changed, trying to connect");
|
||||
BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
public void onServiceStart(BackgroundService service) {
|
||||
service.reachComputers();
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -12,4 +12,11 @@
|
||||
<Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Restart service"/>
|
||||
<Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send ping"/>
|
||||
|
||||
<Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="List paired computers"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/listView1"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
Loading…
x
Reference in New Issue
Block a user