2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-29 13:17:43 +00:00

Made sendPackage sync, so mutex hack in Device is no longer needed

This commit is contained in:
Albert Vaca 2013-10-05 17:25:59 +02:00
parent a07c9a9fb7
commit 07bf1e9ebc
3 changed files with 56 additions and 50 deletions

View File

@ -56,7 +56,7 @@ public abstract class BaseLink {
} }
} }
//TO OVERRIDE //TO OVERRIDE, should be sync
public abstract boolean sendPackage(NetworkPackage np); public abstract boolean sendPackage(NetworkPackage np);
public abstract boolean sendPackageEncrypted(NetworkPackage np, PublicKey key); public abstract boolean sendPackageEncrypted(NetworkPackage np, PublicKey key);

View File

@ -1,36 +1,20 @@
package org.kde.kdeconnect.Backends.LanBackend; package org.kde.kdeconnect.Backends.LanBackend;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log; import android.util.Log;
import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession; import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.json.JSONObject; import org.json.JSONObject;
import org.kde.kdeconnect.Backends.BaseLink; import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider; import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.NetworkPackage; import org.kde.kdeconnect.NetworkPackage;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
public class LanLink extends BaseLink { public class LanLink extends BaseLink {
@ -46,10 +30,12 @@ public class LanLink extends BaseLink {
this.session = session; this.session = session;
} }
private JSONObject sendPayload(final InputStream stream) { private Thread sendPayload(NetworkPackage np) {
try { try {
final InputStream stream = np.getPayload();
ServerSocket candidateServer = null; ServerSocket candidateServer = null;
boolean success = false; boolean success = false;
int tcpPort = 1739; int tcpPort = 1739;
@ -61,14 +47,17 @@ public class LanLink extends BaseLink {
} catch(Exception e) { } catch(Exception e) {
Log.e("LanLink", "Exception openning serversocket: "+e); Log.e("LanLink", "Exception openning serversocket: "+e);
tcpPort++; tcpPort++;
if (tcpPort >= 1764) return new JSONObject(); if (tcpPort >= 1764) {
Log.e("LanLink", "No more ports available");
return null;
}
} }
} }
JSONObject payloadTransferInfo = new JSONObject(); JSONObject payloadTransferInfo = new JSONObject();
payloadTransferInfo.put("port", tcpPort); payloadTransferInfo.put("port", tcpPort);
final ServerSocket server = candidateServer; final ServerSocket server = candidateServer;
new Thread(new Runnable() { Thread thread = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
//TODO: Timeout when waiting for a connection and close the socket //TODO: Timeout when waiting for a connection and close the socket
@ -93,9 +82,12 @@ public class LanLink extends BaseLink {
try { server.close(); } catch(Exception e) { } try { server.close(); } catch(Exception e) { }
} }
} }
}).start(); });
thread.start();
return payloadTransferInfo; np.setPayloadTransferInfo(payloadTransferInfo);
return thread;
} catch(Exception e) { } catch(Exception e) {
@ -108,19 +100,33 @@ public class LanLink extends BaseLink {
} }
@Override @Override
public boolean sendPackage(final NetworkPackage np) { public boolean sendPackage(final NetworkPackage np) {
if (session == null) { if (session == null) {
Log.e("LanLink", "sendPackage failed: not yet connected"); Log.e("LanLink", "sendPackage failed: not yet connected");
return false; return false;
} }
if (np.hasPayload()) { try {
JSONObject transferInfo = sendPayload(np.getPayload()); Thread thread = null;
np.setPayloadTransferInfo(transferInfo); if (np.hasPayload()) {
thread = sendPayload(np);
if (thread == null) return false;
}
WriteFuture future = session.write(np.serialize());
if (!future.await().isWritten()) return false;
if (thread != null) {
thread.join(); //Wait for thread to finish
}
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLink", "sendPackage exception");
return false;
} }
session.write(np.serialize());
return true;
} }
@Override @Override
@ -133,19 +139,25 @@ public class LanLink extends BaseLink {
try { try {
Thread thread = null;
if (np.hasPayload()) { if (np.hasPayload()) {
JSONObject transferInfo = sendPayload(np.getPayload()); thread = sendPayload(np);
np.setPayloadTransferInfo(transferInfo); if (thread == null) return false;
} }
np.encrypt(key); np.encrypt(key);
WriteFuture future = session.write(np.serialize());
if (!future.await().isWritten()) return false;
session.write(np.serialize()); if (thread != null) {
thread.join(); //Wait for thread to finish
}
return true; return true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("LanLink", "Encryption exception"); Log.e("LanLink", "sendPackageEncrypted exception");
return false; return false;
} }

View File

@ -7,7 +7,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -33,8 +32,6 @@ import java.util.HashMap;
import java.util.Set; import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Device implements BaseLink.PackageReceiver { public class Device implements BaseLink.PackageReceiver {
@ -443,23 +440,22 @@ public class Device implements BaseLink.PackageReceiver {
sendPackage(np,null); sendPackage(np,null);
} }
private Lock mutex = new ReentrantLock(true); //Async
public void sendPackage(final NetworkPackage np, final SendPackageFinishedCallback callback) { public void sendPackage(final NetworkPackage np, final SendPackageFinishedCallback callback) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
mutex.lock(); //Log.e("sendPackage", "Sending package...");
//Log.e("sendPackage", "Sending...");
boolean useEncryption = (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR) && isPaired()); boolean useEncryption = (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR) && isPaired());
//We need a copy to avoid concurrent modification exception if the original list changes
ArrayList<BaseLink> mLinks = new ArrayList<BaseLink>(links);
boolean success = false; boolean success = false;
for(BaseLink link : links) { for(BaseLink link : mLinks) {
if (useEncryption) { if (useEncryption) {
success = link.sendPackageEncrypted(np, publicKey); success = link.sendPackageEncrypted(np, publicKey);
} else { } else {
@ -468,18 +464,16 @@ public class Device implements BaseLink.PackageReceiver {
if (success) break; if (success) break;
} }
if (callback != null) {
if (success) callback.sendSuccessful();
else callback.sendFailed();
}
if (success) { if (success) {
//Log.e("sendPackage","sent"); // Log.e("sendPackage","Package sent");
} else { } else {
Log.e("sendPackage","Error: Package could not be sent ("+links.size()+" links available)"); Log.e("sendPackage","Error: Package could not be sent ("+links.size()+" links available)");
} }
mutex.unlock(); if (callback != null) {
if (success) callback.sendSuccessful();
else callback.sendFailed();
}
} }
}).start(); }).start();